LINUX.ORG.RU
ФорумTalks

Про функциональные языки...

 geekporno,


1

1

Немного почитал про функциональные языки. Я с детства (черепашка, паскаль) сначала рисую блок-схемы. Хотя бы в голове. Т.е. Я думаю вот этими прямоугольниками и ветвлениями. Фанаты хаскеля умеют их изощренно транслировать, или научились мыслить как-то по-другому?

Судя по разгребаемому мной js, большинство фронт-эндеров страдают, как и я, от асинхронности, но так кпк ничего лучше не видели, изобретают костыли.
Есть ли способ научиться планировать с конца/середины, и не оперировать моделями реальных объектов? Да, наверно, я поздно родился и мне надо программировать на коболе.

★★★★★

Последнее исправление: Shadow (всего исправлений: 1)

Ответ на: комментарий от Shadow

Мне не нужно, например, лезть в доки, чтобы выяснять синтаксис .filter()

Тебе нужно лезть за append.

и особенности реализации стрелки.

«Реализации стрелки»? Это синтаксис лямбды, насколько я понял.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Это синтаксис лямбды, насколько я понял.

только это JS а там есть две лямбды и они по разному захватывают контекст

Deleted
()
Ответ на: комментарий от Deleted

А... ну, если переформулировать «а без лямбд можно писать, зная только часть языка», тогда конечно.

они по разному захватывают контекст

И для этого примера есть разница?

tailgunner ★★★★★
()
Ответ на: комментарий от Deleted

многие пишут же 8)

Ну да. Интересно, сколько таких среди ненужнистов.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Вот честно, скажи мне, ЧЕМ может являться .append кроме того, что все подумали. Brainfuck тоже язык программирования.

Shadow ★★★★★
() автор топика
Последнее исправление: Shadow (всего исправлений: 1)
Ответ на: комментарий от Shadow

- СРАЗУ понятно, что происходит.

А что в моём примере не понятного? Мой пример гораздо компактнее. Вот пример ещё один пример. Есть массив пользователей. У пользователя может быть профиль - в нём хранятся аватар, языковые настройки... Задача: получить url аватара. Это можно написать типа того

var url = FindUser("nickname").Maybe(i => i.Profile).Maybe(i => i.Avatar.Url);
А можно писать по старинке
var url = null;
var user = FindUser("nickname");
if(user != null && user.Profile != null) {
    url = user.Profile;
  }
}
Это относительно простой пример, в котором достаточно всего лишь 2 проверок. Но уже можно заметить разный объём кода. А что если кроме получения аватара нужно что-то ещё сделать? Один if превращается в 2.
var url = null;
var user = FindUser("nickname");
if(user != null) {
  user.Messages.Add("hello");
  if(user.Profile != null) {
    url = user.Profile;
  }
}
В то время как пример с монадами изменится почти только на длину user.Messages.Add(«hello»); (в зависимости от синтаксиса количество символов отличается.
var url = FindUser("nickname").Maybe(i => i.Messages.Add("hello"); i.Profile).Maybe(i => i.Avatar.Url);
Если тяжело читать, то можно разбить на несколько строк
var url = FindUser("nickname")
  .Maybe(i => i.Messages.Add("hello"); i.Profile)
  .Maybe(i => i.Avatar.Url);

Мне не нужно, например, лезть в доки, чтобы выяснять синтаксис .filter()

Что ты имеешь в виду под синтаксисом .filter()?

и особенности реализации стрелки.

Это значит ты не понимаешь лямбды. Мне понравилась фраза одного разработчика.

Спасибо за ваше видео. Теперь я использую монады [...] и другие разработчики боятся моего кода.

NextGenenration ★★
()
Ответ на: комментарий от Shadow

не ограниченная питоновская лямбда, а развесистая функция.

питонопроблемы. в C# однострочная лямбда отличается от многострочной лишь отсутствием фигурных скобочек и точки с запятой в конце метода.

NextGenenration ★★
()
Ответ на: комментарий от unt1tled

Больше информации влезает на экран. Меньше прописывать логики. В некоторых случаях это ещё и дополнительная защита от ошибок.

NextGenenration ★★
()
Ответ на: комментарий от Deleted

Лично я на js почти ничего не писал. Про особенности могу быть не в курсе. А то разница между new Array(5)[0] и new Array(5, 1)[0] не для всех очевидна.

NextGenenration ★★
()
Ответ на: комментарий от Shadow

Вот честно, скажи мне, ЧЕМ может являться .append кроме того, что все подумали.

А чем ещё может заниматься ForEach и Maybe кроме того о чём подумали?

NextGenenration ★★
()
Ответ на: комментарий от NextGenenration

Это значит ты не понимаешь лямбды

Я 20 лет назад на Perl писал!
Возможно, это травма юности.

Shadow ★★★★★
() автор топика
Ответ на: комментарий от Shadow

лупы все понятные.

если у нас есть стримы, то можно сделать что-то вроде

stream
// .parallel
.filter
.map (method)

// тут много дебага.

и дальше клевый фокус:

stream
.parallel
//.filter
.map (method)

и из шляпы можно достать «дешевую» многопоточность. да, надо заренее иметь некоторый «прицел», но в целом вот этот «parallel» мне нравится.

Rastafarra ★★★★
()
Ответ на: комментарий от Shadow

Большинство подобных функций пишутся на коленке и являются функциями высшего порядка. Maybe проверяет значение на null и если не равно вызывает функцию(в данном примере лямбду). А уже лямбда возвращает что-то. А Maybe возвращает то что возвратила лямбда.

NextGenenration ★★
()
Ответ на: комментарий от Shadow

Вот честно, скажи мне, ЧЕМ может являться .append кроме того, что все подумали

Тот же вопрос про foreach (который ты тоже написал) и filter.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Фильтр может принимать скаляр ИЛИ массив (append-у это без разницы), он может фильтровать по регэкспам (что в первую очередь приходит в голову, ведь иначе это был бы conditin или типа того).

Shadow ★★★★★
() автор топика
Ответ на: комментарий от Shadow

Фильтр может принимать скаляр ИЛИ массив

Хм. Это где такой фильтр?

он может фильтровать по регэкспам (что в первую очередь приходит в голову

А... прочитал про перловое прошлое. Извини.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Думаю, перл надо запретить.

Shadow ★★★★★
() автор топика

Конечно немного не совсем хипстота, но асинхронное программирование в Python довольно неплохо запилили (см. asyncio). С целью именно сделать асинхронное программирование выглядящим как синхронное.

https://docs.python.org/3/library/asyncio-task.html

Не знаю, как оно в js

michwill ★★★★★
()
Последнее исправление: michwill (всего исправлений: 1)

Я думаю вот этими прямоугольниками и ветвлениями.

Тебя уже не исправить. Только эвтаназия.

Фанаты хаскеля умеют их изощренно транслировать, или научились мыслить как-то по-другому?

Ты когда на языке человеческом говоришь предварительно схему предложения в голове составляешь? Большинство просто говорит.

Есть ли способ научиться планировать с конца/середины, и не оперировать моделями реальных объектов?

В функциональном программировании тоже оперируют объектами, просто вместо «структуры с функциями» ака класс объектом выступает сама функция, что даже более интуитивно.
PS Тут можно аналогию с вождением привести. Мотоциклом проще управлять чем автомобилем, так как действия более интуитивные. Но цена ошибки выше и ездить по навигатору не получится, схему маршрута нужно в голове держать. Если ты тридцать лет ездишь по знакомому городу с навигатором то это географический кретинизм (им женщины часто страдают) и он не лечится.

DNA_Seq ★★☆☆☆
()
Ответ на: комментарий от DNA_Seq

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

Именно поэтому я не смог выучить немецкий (отличается от английского, шведского или голландского как обратная польская запись от обычной).

Shadow ★★★★★
() автор топика
Ответ на: комментарий от NextGenenration

Во сколько элементов выльется такой код на псевдокоде?

Давай отойдем от примеров из туториалов для начинающих и усложним: у каждого элемента есть поля type, name и value. Нужно сложить все элементы с type == 1 в ассоциативный массив name => value.

В императивном коде минимальные изменения:

items = dict()
foreach elem in arr:
    if elem.type == 1:
        items[elem.name] = elem.value

Имхо прочитать, написать и осознать этот вариант гораздо проще чем отдельно объявлять переменную, отдельно запускать цикл...

Да, это твой humble opinion. Подавляющее большинство его не разделяет. Я также порицаю это псевдофункциональное убожество.

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

В императивном коде минимальные изменения:

Хочешь сказать что тут целую простыню написать придётся? Просто после фильтра проходимся по всем элементам и добавляем их в словарь.

NextGenenration ★★
()
Ответ на: комментарий от NextGenenration

Просто после фильтра проходимся по всем элементам и добавляем их в словарь.

Ну так покажи, как ты «просто добавляешь их в словарь». Мне интересно, насколько мало «адепты ФП» об этом самом ФП знают.

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

Элементарно, Ватсон.

items = {}
arr.filter(function(i) { return i.type == 1; }).forEach(function(i) { items[i.name] = i.value; });

Мне интересно, насколько мало «адепты ФП» об этом самом ФП знают.

Я не адепт фп в чистом виде. Но некоторые идеи мне нравятся.

NextGenenration ★★
()
Ответ на: комментарий от NextGenenration

Элементарно, Ватсон.

Итого: больше букв, чем в императивном подходе, начисто убито отсутствие side-effect-ов и, как следствие, потенциал parallel принципиально не раскрываем.

Читд: вся эта псевдоэлегантность дальше helloworld-ов редко распространяется.

kawaii_neko ★★★★
()
Ответ на: комментарий от tailgunner

без сайд эффектов тоже можно же, только в js структуры мутабельны и городить каноничный редюс (с конкатенацией словарей - зело странно)

Deleted
()
Ответ на: комментарий от tailgunner

хочет сайд-эффект

В каком месте? Я хочу получить словарь из некоторых элементов списка. «Сайд-эффект» тут только у одептов функциональщины, чиь чистые монады с грохотом разбились о суровую реальность.

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

хочет сайд-эффект

В каком месте?

Вот в этом:

kawaii_neko> добавляешь их в словарь

Я хочу получить словарь из некоторых элементов списка

Ты вполне ясно сказал «добавить в словарь». Не «создать новый», а «добавить».

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

на псевдокоде:

dict1 = {};
dict2 = concat(dict1, {one:"1"});
dict3 = concat(dict2, {two:"2"});
print(dict1, dict2, dict3);
>>>
dict1:
{}

dict2:
{one:"1"}

dict3:
{one:"1", two:"2"}

Deleted
()
Ответ на: комментарий от tailgunner

тебя не смущает то что для иммутабельных структур операция «добавить» возвращает копию структуры с новым элементом?

Deleted
()
Ответ на: комментарий от Deleted

тебя не смущает то что для иммутабельных структур операция «добавить» возвращает копию структуры с новым элементом?

Меня смущает, что вместо ответа на вопрос «где добавление» ты заговорил об иммутабельных объектах.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Оу, тогда расскажи как у тебя уживаются мутабельные объекты и отсутствие сайд эффектов?

Deleted
()
Ответ на: комментарий от Deleted

Оу, тогда расскажи как у тебя уживаются мутабельные объекты и отсутствие сайд эффектов?

Какой бессмысленный вопрос. Но, если ты спросил, то вот:

def foo(d, i):
    return None

foo({}, 0)

dict мутабельный, int иммутабельный, foo без сайд-эффектов.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Зачем ты тратил столько букв, вот так но было:

  
     
   

Этот код гораздо демонстрирует содержание твоего поста.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Зачем ты тратил столько букв

Ну ты же потратил, так что я просто из вежливости.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ты вполне ясно сказал «добавить в словарь». Не «создать новый», а «добавить».

Okay, от слов «создать словарь из элементов с type == 1» что-то изменится?

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

от слов «создать словарь из элементов с type == 1» что-то изменится?

Да. Это можно легко сделать без сайд-эффектов:

d0 = {"a": 1, "b": 2}
d1 = {k:d0[k] for k in d0 if k == "a"}
tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.