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 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.