ФлеймФорумПрограммирование

Выпрямление императивного кода (2 стр)

Страницы: 1 2 3 49 Следующая »
#15
7:21, 1 мая 2021

Delfigamer
> Ты уверен?

Да, это же просто отступ на 1 уровень вверх в AST. А operator.> это просто модификатор AST на этапе его построения.

> Казалось бы, что может пойти не так?

Хорошее замечание, но преимуществ, имхо, это не перевешивает.

#16
7:24, 1 мая 2021

=A=L=X=
> преимуществ
Каких?
obj1.>func1.>func2.>func3( _$$, _$ ) - это не преимущество, это пердимонокль.

#17
7:25, 1 мая 2021

Delfigamer
> это не преимущество, это пердимонокль.
>
Спасибо, ваше мнение нам всем очень важно.

#18
7:28, 1 мая 2021

entryway
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference…
> line_operator

Интересно, что все дружно взялись писать оператор как |>. Общий предок? В пропозале от C++ явно сперва проговаривается про operator|.
Имхо, .> тут более естественна, т.к. продолжает семантику цепочечных вызовов ООП, а | в оригинале в сишных языках наоборот обрывает вычисление на первом же труфи.

#19
7:31, 1 мая 2021

=A=L=X=
> Интересно, что все дружно взялись писать оператор как |>. Общий предок?

4.3 Prior Art (in C++ and elsewhere)

The particular form of the operator this paper is proposing comes from the Elixir programming language, where it is known as the pipe operator [elixir.pipe]. Its semantics are the same as are being proposed here. From the docs:

iex> "Elixir rocks" |> String.upcase() |> String.split()
["ELIXIR", "ROCKS"]

F# [f-sharp.pipe], Julia [julia.pipe], Elm [elm.pipe], and OCaml also have an operator named |>

#20
7:36, 1 мая 2021

entryway
> F# Julia Elm OCaml

Ну понятно - через функциональщину и пролезло. Ожидаемо, ожидаемо...
А в хаскелле $ или типа того, не помню уже.
Там уже выбор символа мог быть от балды конечно.

#21
7:42, 1 мая 2021

=A=L=X=
> А в хаскелле $ или типа того, не помню уже.
Чтобы функция была справа - это амперсанд.
А если ещё нужны побочные эффекты - то это байнд.

(&) :: a -> (a -> b) -> b
x & f = f x

(>>=) :: (Monad m) => m a -> (a -> m b) -> m b

a :: [Text.Text]
a = "lorem ipsum" & Text.map Char.toUpper & Text.words

b :: IO ()
b = pure [10, 20, 30] >>= mapM (\i -> print i >> pure (i*2)) >>= print

main = do
  print a
  b

{-
["LOREM","IPSUM"]
10
20
30
[20,40,60]
-}

Но обычно в ситуациях, аналогичных ОПу, используют оператор композиции (.), а в нём порядок получается справа налево. Люди хавают.

Да, и злоупотребление этими операторами в ущерб читаемости - это говнокод.

#22
8:20, 1 мая 2021

Вообще меня поднапрягло сходу придумать пример который бы рационально использует ссылку на предыдущий плейсхолдер (т.е. _$$), но помозговав родил такое:

(str1+str2).>substr(0,1).>replace(_$$,_$,"")

Т.е. тут мы берём первый символ (как строку) выражения и потом удаляем его из... выражения же. Здесь как раз надо сослаться на результат из предыдущего вызова функции.
Соглашусь, что непривычно и модифицировать такой код надо с осторожностью, что подводит к следующей эволюции концепта: внедрить в него точки именования результатов для ссылок назад.
Предлагаю расширить тогда оператор .> фигурностями вида .{name}> - при таком использовании выражение слева заимеет псевдоним name который можно использовать справа:

(str1 + str2).{_sum}>substr(0, 1).>replace(_sum, _$, "")

Тут как бы результат "протягивается" через псевдоним _sum и его можно использовать правее.
Нагляднее, конечно, выписывать такой код в столбец:

    (str1 + str2).{_sum}>
    substr(0, 1).>
    replace(_sum, _$, "")
#23
8:48, 1 мая 2021

=A=L=X=
> А добавив свою функцию some( str ) мы просто уже не можем её воткнуть в эту
> последовательность таким же выпрямленным образом. Получится опять что-то
> неприятное вида:
>
> ... some( str.split( "," ).join( ";" ) ).replace( "\n", " " ) ...

Я как говорил ранее в JS это решается добавлением своего прототипа
String.prototype.some = function(){}

и код становиться по прежнему красивым

str.split( "," ).join( ";" ).some().replace( "\n", " " )

#24
9:23, 1 мая 2021

Так. Пока ходил в магазин придумал идеальный, кмк, синтаксис. .{name}> из выше всё-таки плохо читаемо до уродливости.
Кроме того оно вводит 2 новых лексемы .{ и }> к имеющейся новой одной .> и это тоже переголова.
На самом деле пусть оператор .> работает как выше описано, а к нему мы добавим еще один новый оператор: |> . Он как раз совпадает с общепринятым, но отличается по смыслу.
Оператор |> в выражении вводит в точке своей встречи идентификатор записанный справа от себя и приравнивает его выражению записанному слева от себя: expr |> name
При этом результатом является само выражение - здесь как бы просто вводится имя для всего написанного справа, при этом оно становится видно до конца выражения справа от оператора.
Таким образом сочетая .> и |> можно как раз конструировать легко читаемые "выпрямленные" линейные выражения.
Перепишем последнее мной написанное, получается намного лучше:

    (str1 + str2) |> _sum .> substr(0, 1) .> replace(_sum, _$, "")

или

    (str1 + str2) |> _sum .> 
    substr(0, 1) .> 
    replace(_sum, _$, "")
#25
9:24, 1 мая 2021

NetSpider
> и код становиться по прежнему красивым

...но глюкодромным.
Как раз из обсуждения у тебя в теме эта и родилась - как предложение сделать всё красиво. И без глюкобажия и без многословия.

#26
9:34, 1 мая 2021

=A=L=X=

Да почему глюкодромным-то?
Какая-то патологическая неприязнь расширять не свои объекты. Словно позвонили неизвестные по телефону, сказали "расширь чужой объект" и деньги с карточки списали. Шизофрения же.
Случайно попасть в пространство имен новой версии языка - мизерное. Ну раз прям боишься, ну добавь свой префикс к имени типа myReplaceAll. Как вы любите создать проблем на ровном месте, я удивляюсь

#27
9:50, 1 мая 2021

=A=L=X=
> Т.е. тут мы берём первый символ (как строку) выражения и потом удаляем его
> из... выражения же. Здесь как раз надо сослаться на результат из предыдущего
> вызова функции.

Вот тут как раз и плавно приближаемся почему this в JS реализован так как реализован.
В JS в частности this является тем объектом в контексте которого произошел вызов метода или функции. Выглядит примерно так:

str -> this -> split( "," ) -> this -> join( ";" )

Поэтому в других языках вы не сможете реализовать такую возможность, потому что this используется как указатель на текущий объект. Даже если мы присобачим выдуманный оператор ".>" Получится:
str.>split( "," ).>join( ";" )
А куда будет ссылаться this в таком случае метода join? Сам на себя! Он не получит никаких данных по цепочке.

#28
10:24, 1 мая 2021

NetSpider
> Да почему глюкодромным-то?

Я устал это объяснять уже десятый раз уже в той теме поэтому в этой обсуждение этого вопроса проводить не буду.

> А куда будет ссылаться this в таком случае метода join? Сам на себя! Он не получит никаких данных по цепочке.

В языке типа C++ join это свободная функция и "this" это просто первый параметр. Всё просто. Это не вмешательство внутрь объекта, а просто его использование в функции в синтаксисе похожем на вызов метода, но это не вызов метода. Конкретный пример как это выглядит есть во втором комментарии этой темы.
При этом если хочется в этом стиле передать параметр в метод существующего объекта, то это тоже не запрещено, например:

str1 .> (str2.replace)( "" )

Это эквивалентно

str2.replace( str1, "" )

Т.е. this у replace будет str2, а в параметры пойдут str1 и "". Скобки нужны чтобы callable объект правильно вычленялся.

#29
10:53, 1 мая 2021

=A=L=X=
> _$$

А если вместо этого попробовать придумать синтаксис для явного (но, естественно, опционального) именования результатов каждого этапа цепочки?

Тут сразу еще одно замечание - в первопосте было раскритиковано введение промежуточных переменных в императивном коде - но ведь они по факту за кулисами ничего не меняют, в любом случае промежуточное значение живет некоторое время в стеке, другой вопрос - именовано это промежуточное значение или анонимно.

Так может быть нет ничего страшного в том, чтоб именовать промежуточные результаты, но только для цепочечного случая придумать синтаксис такой, чтоб время жизни и область видимости не торчали до самого конца блока, а ограничивались только цепочкой?

UPD. А, Алекс уже придумал, оказывается, не дочитал :)

Страницы: 1 2 3 49 Следующая »
ФлеймФорумПрограммирование