LINUX.ORG.RU
Форум — Talks  

лямбды в новых язычках - PR или реальные полезняшки?

 , ,


7

7

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

Ну что есть lambda в каком-нибудь lisp я представляю и даже понимаю зачем оно и как им пользоваться. В lisp'е. А что имеется ввиду под «лямбдой» например, в C#?

Хотелось бы увидеть не только цитаты из википедии, а простенькие примеры того, как эта лямбда сильно упрощает жизнь, удобство даёт и всё такое. В виде примера кода, разумеется, с пояснениями почему тут именно лямбда крута и без неё некузяво.

Только чтобы это не было аналогом перлового однострочника типа

perl -e 'print sub{ $_[0] + $_[1]; }->(1,2)."\n";'
ибо в этом никаких новшеств и преимуществ нету.

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

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

Прочитай что ли свои комментарии к функциям.

зачем, я и так помню - «специально для Ritmik...»

Достаточно написать было этот комментарий один раз. И тут вы не можете без копипасты.

100000 элементов для факториала, который влазит в int? действительно Ппц

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

Вот это «static int r[ MAX_F ]» у тебя будет храниться в памяти постоянно, а не один int.

int ...( int m ) {
 int ...=0; for( ...; fact(...)<m ; ++...); 
 return ...;
}

это просто цирк :)

Я так понимаю, ты даже не видишь, что у тебя идет копипаста? Ну и дела.

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

для факториала, который влазит в int

Ты в своем былдокоде не можешь разобраться, что ли?
Вот это «static int r[ MAX_F ]» у тебя будет храниться в памяти постоянно, а не один int.

напряги извилину - подумай о чем я написал

Я так понимаю, ты даже не видишь, что у тебя идет копипаста? Ну и дела.

да, особенно часто я копипастил int/for/return и скобочки, надо что-то с этим делать )

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

Напиши тоже самое в Си через списки и посмотри на время =)

вот вас заклинило на списках ) это моя задача - тут нет списков, решайте как хотите

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

Вот это и есть реюз кода о котором тебе писали выше
Так вот, когда речь идёт о foreach,map,filter и прочих очень удобно использовать лямбды.

чушь:

for( int& t : a ) t++;

вот этого не хватает в С, простого «сахара»

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

Сравнение говорит лишь об одном, что увеличение переменной на 1 сто раз работает быстрее чем генерация списка из 100 элементов и расчёт суммы. Это любому понятно. Бенчмарк не обязательно было делать.

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

Сравнение говорит лишь об одном, что увеличение переменной на 1 сто раз работает быстрее чем генерация списка из 100 элементов и расчёт суммы. Это любому понятно. Бенчмарк не обязательно было делать.

а Ritmik говорит, что это оптимально, кому верить? ;) ну и я не спорю, я сразу написал - давайте другое решение

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

Говорили про факториал, потом переключились на сумму...

Факториал на списках и с GMP на Си покажет примерно такую же скорость.

Конечно, абстракции, ФВП, лямбды, сборщик мусора, списки не «бесплатны», но для меня удобство решает.

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

Говорили про факториал, потом переключились на сумму...

примитивная задача - напишите и все, я не буду придираться и что-то требовать как Ritmic, главное, чтоб сумма реально вычислялась, а не получалась по формуле или при компиляции

Факториал на списках и с GMP на Си покажет примерно такую же скорость.

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

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

В ембеддед Lisp используется и сейчас для кодогенерации в целевой язык - C, system verilog, прочие hdl. Но это ни разу не «массовое» применение, поэтому и не рассматривал + использование высокоуровневого яп весьма ограничено требованиям по скорости конкретной шилизяки. И вообще - с нормальными яп для ембеддед в тыщу раз более беда, чем для прикладного программирования: старое, монструозное неюзабельное уг с трендовым систайл-ооп (накуя?) без просвета... Поэтому чтобы не сидеть на антидепрессантах, херячя описание аппаратуры в system verilog - его кодогенерируют. Хотя нужны просто норм DSL.

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

при том java в памяти отъела 1.3Гб в каждом случае, может просто потому-что у меня памяти много в системе, но, блин, эти люди запрещают использовать массив для факториалов, которые вмещаются в int

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

Ну мы же не это обсуждаем... Скорость clojure vs C на простейших вещах это мимо.

Разговор был про удобство.

Нужны лямбды в новых языках или нет? Имхо, нужны.

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

Скорость clojure vs C на простейших вещах это мимо.

если б Ritmic не придирался к варианту на С по ее поводу -я б про нее и не вспомнил

Нужны лямбды в новых языках или нет? Имхо, нужны.

а тут говорить нечего - нужны, но без фанатизма

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

Сравнение говорит лишь об одном, что увеличение переменной на 1 сто раз работает быстрее чем генерация списка из 100 элементов и расчёт суммы. Это любому понятно. Бенчмарк не обязательно было делать.

а Ritmik говорит, что это оптимально, кому верить? ;) ну и я не спорю, я сразу написал - давайте другое решение

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

Факториал на асме, кстати, будет еще быстрее.

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

и с этим не спорю, это все в сторону Ritmik, которому то факториал надо не вычислять несколько раз, то массив заводить - слишком жирно

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

а теперь моя очередь сравнить С и Clojure:

~$ cat ./1.c
#include <stdio.h>
int main(int argc,char** argv)
{
   long n = atoi(argv[1]);

   long s=0, i=1;
   for( ; i<n ; ++i ) s+=i;
   printf( "%ld\n", s );
}

~$ gcc -Ofast ./1.c && time ./a.out 1000000000
499999999500000000

real	0m0.167s
user	0m0.160s
sys	0m0.004s

Очень неплохо. Теперь мое решение этой задачи на clojure

(defn sum [n]
  (/ (* (dec n) (+ 1 (dec n))) 2))

Проверяем

(time (sum 1000000000))
"Elapsed time: 0.048416 msecs"
499999999500000000

У меня код быстрее.

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

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

Мы один и тот же код читаем?

т.к. решение получается через одно место и неоптимальное

Неоптимальное по какому критерию? Как ты выявил этот критерий?

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

Мы один и тот же код читаем?
неоптимальное по какому критерию? Как ты выявил этот критерий?

да::

лямбды в новых язычках - PR или реальные полезняшки? (комментарий)

код через списки, как был предоставлен Ritmik, получаем список - используем, а критерий прост - «императивный» код на том же Clojure намного быстрее, правда все-равно очень медленный по сравнению с С, и, что важно!, он не реюзабелен

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

Правда? Ни одной? чудеса.

Clojure я просмотрел.
Да, на Java бибилиотеки есть. Но он imho ещё дальше от народа чем Scala. найти хотя-бы три программиста готовых писать на лиспе одновременно в отделе imho невозможно.
Тем не менее, ближе всего к реализации проекта на ФП языке мы подошли когда делали прототип на F# для трэйдеров.
Но дальше прототипа не профинансировали.

А сколько платите?

Обычно.
$50/h-$70/h контракторам и ~$60-$90k в год тем кто на ставке.

Писал на лиспе массу SOAP-сервисов, ЧЯДНТ?

Хз.

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

Язык clojure создан в 2007 и соответствует спекам clojure.

Т.е. лисп развивается полной ломкой совместимости.
imho гораздо хуже

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

Библиотеки есть. С персоналом напряженка, да. С другой стороны, их много и не требуется, достаточно обеспечить нормальную «смену поколений».

Хотя бы один.

С одной стороны я не спрашивал, с другой стороны, когда заводится разговор то в глазах непонимание.

Для веба задача нетипичная.

Single Sign On - как-же без него?

Кто мешает? Для CL точно есть mysql, pg, mongo, и, кстати, ldap

По ссылке нет Oracle, MS SQL, DB2

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

да::

Тогда читай внимательнее, там все есть.

лямбды в новых язычках - PR или реальные полезняшки? (комментарий)

я видел, но зачем это здесь? мы не твой код обсуждаем

«императивный» код на том же Clojure намного быстрее, правда все-равно очень медленный по сравнению с С, и, что важно!, он не реюзабелен

Повторю вопрос: как ты узнал, что оптимизировать надо по скорости выполнения?

он не реюзабелен

4.2

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

Тогда читай внимательнее, там все есть.

сам читай - внимательно читай: (count (min-n-fact m)))

я видел, но зачем это здесь? мы не твой код обсуждаем

значит ты видел и другое - я попросил привести «правильный» код, Ritmik слился

Повторю вопрос: как ты узнал, что оптимизировать надо по скорости выполнения?

и ты тоже сливаешься

4.2

ты умеешь оценивать код, который ты не видел? круто

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

сам читай - внимательно читай: (count (min-n-fact m)))

читаю:

defn min-n-fact [m]
  (take-while (fn [fact] (< fact m)) (lazy-fact 1 1)))

тебе в слове «lazy-fact» какая буква непонятна?

ты умеешь оценивать код, который ты не видел? круто

Видел, никакого секрета

и ты тоже сливаешься

ой, ты меня затроллил!

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

придется «кричать»

тебе в слове «lazy-fact» какая буква непонятна?

ну не тупи:

«Для реюза достаточно общий код вынести в min-n-fact:»

ДЛЯ РЕЮЗА

думай

Видел, никакого секрета

«императивный» код на том же Clojure намного быстрее, правда все-равно очень медленный по сравнению с С, и, что важно!, он не реюзабелен" - ТЫ ЕГО НЕ ВИДЕЛ, Я ЕГО У СЕБЯ ТЕСТИРОВАЛ

ой, ты меня затроллил!

я пишу, что код не оптимальный, а ты мне доказываешь, что я не знаю, что я имел ввиду - это вообще нормально?

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

Хотя бы один.

Абсолютно согласен. Но язык тут не при чем. И даже специальность. Проблема кадров общеизвестна.

Single Sign On - как-же без него?

ненене, ты говорил конкретно об AD, я точно помню. Либо я тебя не понял совсем.

По ссылке нет Oracle, MS SQL, DB2

По ссылке нет, но изначально никаких условий не было, поэтому не расценивай мой ответ больше, чем иллюстрацию.

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

так что давай реальное вычисление

(defn sum* ^long [^long res ^long i ^long n]
  (if (< i n)
    (recur (+ i res) (+ 1 i) n)
    res))

(defn sum [n]
  (sum* 0 1 n))

Время выполнения

(time (sum n))
"Elapsed time: 2104.84474 msecs"

Почти в 13 раз медленнее сишного варианта.

Это еще доказывает, что на критических по времени численных алгоритмах код лучше писать на низкоуровневых языках, близких к железу, например, на C/C++, даже иногда достаточно джавы. И уже подключать как библиотечные функции к лиспу и дальше писать логику на нем. Так собственно и делалось испокон веков.

З.Ы. Завтра на работе, будет время, проверю на чистой джаве.

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

думай

Думаю, ты бредишь. Высрал тут поток сознания какой-то, зачем он мне? Читай код, там все есть.

и, что важно!, он не реюзабелен" - ТЫ ЕГО НЕ ВИДЕЛ, Я ЕГО У СЕБЯ ТЕСТИРОВАЛ

Да, был не прав, извини. Но теперь я, кажется, все правильно понял: твой секретный код не реюзабелен, и ты предъявляешь это Ritmik'у? Одобряю!

и да, _твой_ код мы _не обсуждаем_

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

я пишу, что код не оптимальный, а ты мне доказываешь, что я не знаю, что я имел ввиду - это вообще нормально?

Это нормально. Чтобы быть в теме и сравнивать, нужно знать парадигмы программирования в Си и лиспе.

Я показал, что ты пишешь код на простые примеры (и то не с первой попытки смог) методом копипаста (явно показал, что реюза у тебя нет, и как он может осуществляться в высокоуровневых языках).

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

Еще раз повторю для тебя. Главная задача программиста (инженера) это борьба со сложностью в больших задачах. В этой борьбе помогают высокоуровневые языки. А низкоуровневые языки могут быть только использованы для близких к железу задач.

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

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

Думаю, ты бредишь. Высрал тут поток сознания какой-то, зачем он мне? Читай код, там все есть.

лямбды в новых язычках - PR или реальные полезняшки? (комментарий)

«Для реюза достаточно общий код вынести в min-n-fact:»"

вот на это я отвечал и процитировал эту фразу, ты отвечал на мой ответ на эту фразу, если ты не читаешь на то отвечаешь - это только твои проблемы

Да, был не прав

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

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

^long [^long res ^long i ^long n]

не так читабельно, как в примерах на публику ;)

Почти в 13 раз медленнее сишного варианта.

и не реюзабельно, нельзя использовать для вычисления произведения, например

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

Я показал, что ты пишешь код на простые примеры (и то не с первой попытки смог) методом копипаста

ты _ничего_не показал, все что ты смог - попросил добавить к одной строке кода еще три для создания функции, а потом ВНЕЗАПНО сказал, что у меня копипаста, т.к. эти три строки везде похожи, даже в банальном цикле (та самая строка кода) ты «нашел» копипасту в виде инкремента _разных_ переменных и клюевого слова for

Главная задача программиста (инженера) это борьба со сложностью в больших задачах. В этой борьбе помогают высокоуровневые языки. А низкоуровневые языки могут быть только использованы для близких к железу задач.

расскажи авторам OS X - они посмеются

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

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

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

«Для реюза достаточно общий код вынести в min-n-fact:»

вот на это я отвечал и процитировал эту фразу

Эта фраза абсолютно бессмысленна вне контекста сообщения, на которое ты отвечал, значит тянем этот контекст с собой. Контекст создает код, демонстрирующий возможности реюза. Почему приходится объяснять такие очевидные вещи?

тратить время на тех, кто отвечает, не читая, я не собираюсь

В чем проблема? Я тебе уже дважды сказал — твой код меня не интересует, ты поэтому обиделся?

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

Язык clojure создан в 2007 и соответствует спекам clojure.

Т.е. лисп развивается полной ломкой совместимости.

imho гораздо хуже

Clojure - не лисп. Скорее - недолиспик.

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

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

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

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

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

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

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

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

я написал самодостаточную строку, где есть вся логика для решения задачи,

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

вы там договоритесь между собой до какого уровня и что надо выносить в функции

Читай код код Ritmik'а, там все есть. Что непонятно - спрашивай.

linuxnewb ★
()
Ответ на: комментарий от linuxnewb
;; список элементов последовательности n! меньше числа m
(defn min-n-fact [m]
  (take-while (fn [fact] (< fact m)) (lazy-fact 1 1)))

;; сколько элементов последовательности n! меньше числа m
(defn min-n-size-fact [m]
  (count (min-n-fact m)))

и еще момент - это _кривое_ решение, не надо получать список с факториалами, чтоб всего-лишь узнать кол-во «n! меньше числа m», это лишние, побочные и абсолютно ненужные действия, это как если б сортировку массива строк сделать через выгрузку их файл, sort и обратную загрузку- т.к. код для сортировки файла у нас был, а просто массива строк - нет, значит не надо писать «лишний» код, все работает, все типа хорошо

wota ★★
()
Вы не можете добавлять комментарии в эту тему: топик перемещен в архив.