LINUX.ORG.RU
ФорумTalks

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

 , ,


7

7

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

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

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

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

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

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

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

коли не шутишь - use syntax.. в них плох use syntax.. зачастую такое ощущение что проще обычную функцию написать чем лямбду с use.

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

это если скромно промолчать про create_functoin syntax...

AndreyKl ★★★★★
()

На жабке это было бы мраком

list.filter(_>10).map(_*20).map(_.toString).takeWhile(_<40)

Или

def sum(xs:List[Int])=xs.foldLeft(0)((acc,x)=>x+acc) 

def product(xs:List[Int])=xs.foldLeft(1)((acc,x)=>x*acc) 

def join(xs:List[String])="("+xs.tail.foldLeft(xs.head.toString)((acc,x)=>acc+","+x)+")"
vertexua ★★★★★
()

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

Не знаю как в шарпах, но обычно они еще умеют замыкать контекст и каррирование

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

чем лямбду с use.

с юзом - это не лямбда, это замыкание

они там где-то в бложике писали, что после долгого анализа движка похапэ-5 пришли к выводу, что на данном этапе развития (а может быть и вообще) нормальные замыкания невозможны. Особенный бугурт, емнип, им доставили переменные переменные, evalы и инклуды. Они не могут определить, что в данной точке выполнения есть environment, и как собирать в GC то, что они там понавытягивали, поэтому все эти решения с конпелятора переносятся на пользователя в виде ручного описания юза. Так что, придется хавать что дают еще несколько лет :)

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

лямбды это всегда удобно.

Даже если это распечатка кода с лямбдами, свернутая в рулон и вставленная в ухо?

Tark ★★
()

Чаще всего — распиаренные баззворды, еще и выглядящие ужасно. Видел не так давно код на C++11 с кучей лямбд — теперь использую алфавит Брайля.

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

Но их решение заключается в автоимплементации интерфейса. Это обеспечивает совместимость. Но отдельного класса Function или сокращения для типа не будет

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

Да собстна синтаксис. Учитывая, что язык чуть ли не весь из лямб состоит, писать и читать постоянно function ... return несколько задалбывает.

А в плане семантики как раз всё нормально.

geekless ★★
()

Если вы ищете язык с ФП как основной парадигмой - посмотрите на F#

Кстати, а чем примеры в вики не понравились?

Самое приятное и налядно-полезное применение лямбд - это LINQ(linq2XML, linq2sql, linq2Object)

Простой пример живого кода - разбор параметров коммандной строки:

           
 IsCaseSecitive = !args.Contains(ignorecaseParam);

 var outParam = args.Where(x => x.StartsWith(outFileNameParam)).FirstOrDefault();
 if (!string.IsNullOrEmpty(outParam)) OutFile = outParam.Substring(outFileNameParam.Length);

 var ignoreAttrs = args.Where(x => x.StartsWith(ignoreAttrsParam)).FirstOrDefault();
 if (!string.IsNullOrEmpty(ignoreAttrs)) Attrs2Ignore = ignoreAttrs.Substring(ignoreTagParam.Length).Split(',');

просто пример:

var join = from a in arr1 
    join b in arr2 on a equals b
    where j>5
     select a;

из живого кода - работа с XML нодами:

var tObjects = ((XElement)tanXDoc.FirstNode).Elements().Where(n => n.Name == "Objects").Elements();
var oObjects = ((XElement)ontXDoc.FirstNode).Elements().Where(n => n.Name == "Objects").Elements();

var tIds = from x in tObjects select NormalizeString(x.Attribute("IdString").Value);
var oIds = from x in oObjects select NormalizeString(x.Attribute("IdString").Value);

var tDeltaIds = tIds.Except(oIds);
var oDeltaIds = oIds.Except(tIds);

Сложнее:

//TextWriter tw, IEnumerable<XElement> tObjects, IEnumerable<XElement> oObjects)
 var delta = from to in tObjects
    join oo in oObjects on NormalizeString(to.Attribute("IdString").Value) equals NormalizeString(oo.Attribute("IdString").Value)
       let tSerial =
           from t in to.Descendants() where Tag2Ignore == null || t.Name.LocalName != Tag2Ignore select AsString(t)
       let oSerial =
           from o in oo.Descendants() where Tag2Ignore == null || o.Name.LocalName != Tag2Ignore select AsString(o)
       let tDiff = tSerial.Except(oSerial)
       let oDiff = oSerial.Except(tSerial)
       let tPrefix = AsString(to.Attribute("prefix"))
       let oPrefix = AsString(oo.Attribute("prefix"))
   where tDiff.Count() > 0 || oDiff.Count() > 0 || tPrefix != oPrefix
   select new {Id = to.Attribute("IdString").Value, T = tDiff.ToList(), O = oDiff.ToList(), TPrefix = tPrefix, OPrefix = oPrefix};

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

опять повторю - вики нормально расписано.

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

Радуйся, что они не открыли для себя юникод, а то ж ведь понапихают символов новых в синтаксис. Слова то новые занимать некошерно, а вот лепить разные «смайлики» это самое то :}

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

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

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

надо различать делегаты, лямбда-методы и лямбда-выражения.

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

лямбда-методы - это просто методы без имени. Даже в бедной Scheme именованые функции внутри движка превращаются в создание переменной, лямбда-функции и связывании их между собой. Язык без лямбд - это какая-то жава какое-то днище.

лямбда-выражения - это то, о чем срач

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

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

Это зависит от того, что ты называешь «лямбдой» и «обычнейшей анонимной функцией».

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

Слова то новые занимать некошерно

в C# есть такая штука, contextual keywords. Это значит, что слова, изначально НЕ зарезервированные как ключевые, могут становиться ключевыми в зависимости от контекста, способа употребления. В частности, все query keywords являются контекстными. Поэтому сильной проблемы со вводом ключевых слов у них нету -)

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

Ты опять притащил сюда это нечитаемое говнище?

Вы спросили я ответил.
Чиать мозга не хватает, так и пишите - мозгов нет. Я буду игнорировать тред.

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

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

Анонимная функция - это как sub{ ... }->() в перле, подпрограмма не имеющая идентификатора для вызова по имени, но с известным адресом в памяти.

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

Я буду игнорировать тред.

Это было бы замечательно. Если не затруднит - прошу именно так и сделать.

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

Это было бы замечательно. Если не затруднит - прошу именно так и сделать.

Не заметил ключевых слов.

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

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

С терминологией такого уровня ответить затруднительно. В вполне ООП Python функции могут возвращать функции, в Си и Паскале - тоже.

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

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

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

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

Ты опять притащил сюда это нечитаемое говнище?

Кстати, как вы собираетесь судить о возможностях лямбда-выражений в C# если вы читаь код не умеете?

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

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

«Автомобиль - это такая хрень с дверьми». Да, двери есть, но суть-то не в этом.

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

«Обычнейшие анонимные» - просто кусок кода который нельзя вызвать по имени, а только по адресу. Со всеми вытекающими. Как в перле, в C и пр.

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

F(n) = lambda (x)->(x+n)
a(x) = F(sin(1/x))
b(x) = F(tg(1/x))
В итоге получается, что если вызвать a = a(b) то выполнится a = b + sin(1/b) и т.п.

В новых языках рекламируемое - лямбды или «обычнейшие анонимные»?

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

Добавлю ещё более простой код:

int []arr = [1,2,3,4,5,6,7,56,6,7,7,8,8,8,7,6,5,4,4,32,42354,4356,546,456,45,6756,7,56];
var result = arr.Where(x => x >5 && x<100);
Проще уже сложно.

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

F(n) = lambda (x)->(x+n)
a(x) = F(sin(1/x))
если вызвать a = a(b) то выполнится a = b + sin(1/b)

Пять раз прочёл, не понял, почему. Откуда F знает что такое x?

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

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

Лямбда - это и есть генератор функций.

F(n) = lambda (x)->(x+n)
a(x) = F(sin(1/x))

Я не понимаю этого языка (и не знаю Перла). Вот пример на Питоне:

>>> f = lambda x: (x + 1) # f - это функция, сконструированная лямбда-выражением
>>> print f(2) # вызываем функцию
3
tailgunner ★★★★★
()
Ответ на: комментарий от Redrum

Ну типа

    (define (doubler f) (lambda (x) (f x x)))
    ((doubler +) 4)

8

    printf sub{ $_[0] + $_[1] }->(1,2)."\n";

3

    int x = 1;                                                                                      
    int y = 2;                                                                                      
    printf("%d\n", ({ int z = x + y; z; }) );                                                       

3

Ну и так далее. Минимальный код, чтобы пояснить суть фишки.

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