LINUX.ORG.RU
ФорумTalks

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

 , ,


7

7

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

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

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

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

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

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

★★★★★

Ответ на: комментарий от grim
#define CURRSUM(x,y) ( (x) + (y) )
...
int a = CURRSUM(5,6) // a == 11
...
#define PLUSADIN(x) (CURRSUM((x),1))
int b = PLUSADIN(10); // b == 11

И?

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

Но работать и выглядеть будет по-лямбдски типа.

Работать «по-лямбдски» - не будет.

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

Это да. Правда, на тебя будуь смотреть с жалостью, но вопить можно будет.

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

Эээ... Ну указатель на объект тоже как бы переменная? Значит есть ссылка и объект остается. Для ССЗБ языков типа С++ его может кто-то удалить, но это уже вопрос самого кода

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

Или даже так:

def errorHandler(error, &x)
    lambda {
        loop {
            result = x.call
            return result if result != error
        }
    }
end


ret = if type == BULK
    errorHandler(EAGAIN){usb_bulk_read(dev,ep,buf,size,1000)}
else
    errorHandler(EAGAIN){usb_interrupt_read(dev,ep,buf,size,1000)}
end

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

Отчего лямбда в вашем примере типа есть, а в сях её нету? То же самое всё, и результат, и фичи. В сях даже фич побольше будет.

Мы говорили о саринге или о лямбдах как таковых?
Мне кажется мы что-то не понимаем друг у друга.

В С - plusAdin можно тоже через дефайны определить, но их ведь не передашь к примеру, как параметр или не вернёшь как результат вызова функции.

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

Да-да, оно самое.

Но вопрос в том, насколько это отличается от #define. Можно ли написать, например (абстрактно):

usb_bulk_read_again = eagainHandler{usb_bulk_read(int,int,char*,int,int)}
usb_bulk_read_again(dev,ep,buf,size,1000);

При этом, чтобы код этой самой не существовавшей ранее функции usb_bulk_read_again возник именно в момент вызова eagainHandler, например.

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

Почти поголовно везде получается вот что (в той или иной форме, но я покажу на примере класса) в scala-like псевдокоде

val x = 10;
def f(q) = x+q;
val m = f(50)

Превращается в

val x = 10

class f_function{
   val x;
   f_function(xarg){
     x = xarg
   }

   def apply(q) = q+x
}

val f = new f_function(10)
val m = f.apply(50)
vertexua ★★★★★
()
Ответ на: комментарий от tailgunner

Работать «по-лямбдски» - не будет.

Так работать по-лямбдски - это на самом деле генерировать код функции именно при вызове функции с лямбдой или такого не бывает?

В сях конкретный и сугубый код для target процессора сгенерируется при компиляции. А по-лямбдски как будет?

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

Можно ли написать, например (абстрактно):

usb_bulk_read_again = eagainHandler{usb_bulk_read(int,int,char*,int,int)}
usb_bulk_read_again(dev,ep,buf,size,1000);

Нет. eagainHandler возвращает уже выполненое замыкание. Чтобы получить то, что ты хочешь, надо замкнуть еще раз, в правильном контексте:

usb_bulk_read_again = lambda {|a, b, c , d, e| eagainHandler{usb_bulk_read(a, b, c, d, e)}}
usb_bulk_read_again.call(dev, ep, buf, size, 1000)

При этом, чтобы код этой самой не существовавшей ранее функции usb_bulk_read_again возник именно в момент вызова eagainHandler, например.

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

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

Так работать по-лямбдски -

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

это на самом деле генерировать код функции именно при вызове функции с лямбдой или такого не бывает?

Тело генерируется при компиляции, в рантайме генрируется макисмум trampoline или даже не генерируется ничего - я не в курсе стратегий современных компиляторов.

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

Ну хоть я scala не знаю, тут понятно, при «генерации функции» класс создаётся с инициализацией x и где-то просто есть код q+x и кода q+10 не появляется.

И опять же, вариант val f = new f_function(sin(1/x)) - прокатит?

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

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

$ cat 1.pl
use strict;
use warnings;

sub {
        my ($a, $b) = @_;
        print $a, "\n";
        return sub {
                my $c = shift;
                print $b, " ", $c, "\n";
        }
}->(10, 11)->(9);

$ perl 1.pl
10
11 9

подпрограмма не имеющая идентификатора для вызова по имени, но с известным адресом в памяти.

это лишь детали реализации, которые о сути не говорят

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

что ты подразумеваешь под «сборщиком мусора»? Если просто тупой подсчетчик ссылок - то конечно не осложняет. Если движок, который в фоне сидит и думает, как бы так выкинуть из памяти побольше ненужно, чтобы всё не стало колом - помойму осложняет еще как.

Например, если мы юзаем переменные переменные, то не можем простым способом заюзать дедупликацию в случае если два объекта окажутся бинарно одинаковы (язык динамический!). Ну или в моей башке это не совместимо, а на самом деле совместимо =)

Потом представь, в качестве аргумента замыкания мы используем переменную переменную, и это замыкание запускаем работать в отдельном потоке. Если каждый раз разбирать переменную переменную тупо парсингом, то для логического уровня это будут разные перменные, и получается замыкания должны пересобираться с новой сигнатурой. Но если мы хотим заюзать какие-то оптимизации, нужно к этому реальному представлению переменной добавить метаинформацию, что она была получена как подстановка. И дальше оптимизатор должен работать уже не только со ссылками, но и со связанными подстановками.

Есть такой алгоритм (забыл как называется, там аббривиатура), когда мы делим выполнение на кейсы, зависящие от каких-то условий (этот кусок кода выглядит вот так из предположения, что A<3, а если нет - по другому ), для каждого кейса использования мы внутри движка разделяем переменную на несколько экземпляров (то что было А для случая когда A<3 переименуется в A1). На это накладываются переменные переменные, евалы, и самое главное - concurrency и ссылочная целостность. И вновь пучина ада. Выкрутиться можно, грамотно расписав абстракции, но это и есть «сложности».

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

Получается, что на самом деле никто никакую новую функцию не возвращает, а просто производятся всякие операции с указателями на куски заранее существующего кода?

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

что ты подразумеваешь под «сборщиком мусора»?

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

Есть такой алгоритм (забыл как называется, там аббривиатура), когда мы делим выполнение на кейсы, зависящие от каких-то условий (этот кусок кода выглядит вот так из предположения, что A<3, а если нет - по другому ), для каждого кейса использования мы внутри движка разделяем переменную на несколько экземпляров

Если это SSA, у тебя в голове просто образцовая каша.

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

и?

$ cat 2.pl
use strict;
use warnings;

sub doubler
{
        my $f = shift;
        return sub {
                my $x = shift;
                return $f->($x, $x);
        }
}

print doubler(sub { $_[0] + $_[1] })->(4), "\n";
$ perl 2.pl
8
Reset ★★★★★
()
Ответ на: комментарий от tailgunner

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

Я знаю что с макросами такое не прокатит, я их чисто для пущей выпуклости вопроса привёл. Но объектный подход к лямбдам тоже не «по-лямбдски» и нифига нового в этом нету. vertexua прекрасный и понятный пример привёл.

Тело генерируется при компиляции, в рантайме генрируется макисмум trampoline или даже не генерируется ничего - я не в курсе стратегий современных компиляторов.

Понятно. А вообще - есть ли хоть один язык, где лямбда может генерировать именно новый код для процессора? Именно «возвращать новую функцию».

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

«Обычнейшие анонимные» - просто кусок кода который нельзя вызвать по имени, а только по адресу. Со всеми вытекающими. Как в перле, в 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) и т.п.

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

Захотелось нервно закурить.

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

По Лямбдски:

 Func<int,int,int> add = (x,y) => x+y;
 Func<int, int, int> div = (x, y) => x / y;
 Func<Func<int, int, int>, Func<int, int, int>> curOp = x => (y, z) => x(y, z);

 var curAdd = curOp(add);
 var curDiv = curOp(div);

 System.Console.WriteLine("curAdd(10,2) {0}", curAdd(10, 2));
 System.Console.WriteLine("curDiv(10,2) {0}", curDiv(10, 2));
Можно и с делегатами такое-же делать, но делегаты это просто указатели на функции, так что не чистая лямбда получится.

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

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

Это деталь реализации, вряд ли такое специфицировано хоть где-то. Если нужна динамическая генерация кода - она делается другими средствами.

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

Понятно. А вообще - есть ли хоть один язык, где лямбда может генерировать именно новый код для процессора? Именно «возвращать новую функцию».

А зачем, если код лямбды известен на стадии компиляции?

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

если есть х, то да. Сначала вычислят выражение, потом подставят в функцию.

Не, как раз в этом и фишка. Оперировать с кодом, а не со значениями.

Понятно, что можно извратиться и написать что-то типа

class lambda_function
{
  int (x *)(int);
  lambda_function( int (init_func *)(int) ) 
  {
    x = init_func;
  }
  int add(int q) { x(q) + q }
}

init_func(x){ return sin(1/x)}

lambda_function f = new lambda_function(init_func);

int a = f.add(10)



Но это ведь никакая не фича и не продвинутость...
Stanson ★★★★★
() автор топика
Ответ на: комментарий от Stanson

Получается, что на самом деле никто никакую новую функцию не возвращает, а просто производятся всякие операции с указателями на куски заранее существующего кода?

В Ruby все объекты унаследованы от Object. В том числе и функции (Proc). Любой обьект является по сути хитрым словарём, содержащим указатели на методы, переменные и т.п. Которые сами являются объектами.

Или вот еще пример из Io:


errorHandler := method(error, x,
    method(
        loop(
            result := x()
            (result != error) ifTrue (return(result))
        )
    )
)

usb_bulk_read_again := method(a, b, c, d, e, errorHandler(EAGAIN, usb_bulk_read(a, b, c, d, e)))
usb_bulk_read_again(dev, ep, buf, size, 1000)

Суть та же. Однако в отличие от Ruby, где понятие «код метода» выходит за пределы языка, в Io код любого метода подаётся полной интроинспекции. Т.е., натурально, список (errorHandler(EAGAIN, usb_bulk_read(a, b, c, d, e))) является кодом, и в то же время — обычным списковым типом языка.

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

А зачем, если код лямбды известен на стадии компиляции?

А хрен знает. Может и незачем, и все фичи генерируемого кода можно реализовать объектно там, или ещё как. Но просто это будет повторение древних фишек, а не какой-то новый подход.

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

Неспроста всякие экспертные системы пытаются именно на тех самых лиспах с хаскелями писать.

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

Неспроста всякие экспертные системы пытаются именно на тех самых лиспах с хаскелями писать.

Экспертные системы не генерируют кода. И я что-то не слышал об ЭС на Хаскеле.

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

А зачем, если код лямбды известен на стадии компиляции?

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

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

Экспертные системы не генерируют кода. И я что-то не слышал об ЭС на Хаскеле.

Не генерируют. Зато вовсю используют возможности функционального программирования, в том числе и возможность генерации функций по ходу дела.

Насчёт хаскеля не помню. Может это не хаскель а эрланг был. Неважно, главное - функциональщина.

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

Да ты что, тут же всё просто ;):

func n = \x -> n + x
«\» — это как acii-вариант греческой буквы «лямбда» («λ»), типа похожа по написанию (это, наверное, у них юмор такой, у хаскельщиков).

То есть функции func при вызове передается аргумент n, и она возвращает лямбду (анонимную функцию), n при этом каррируется. Дальше вызываем эту лямбду (с аргументом x), получаем сумму n + x.

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

ACID же. Atomicity, consistency, isolation, durability. Можно и руками это сделать, но приятно, когда конпелятор/виртуалка делает всё автоматически.

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

А хрен знает. Может и незачем, и все фичи генерируемого кода можно реализовать объектно там, или ещё как. Но просто это будет повторение древних фишек, а не какой-то новый подход.

Тебе нужен обязательно принципиально новый подход?

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

А-а-а, какой прикольный язычок этот Io ! Блин, никогда не слышал, ща почитал - прикольно. У него сам интерпретатор какого размера примерно?

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

Тебе нужен обязательно принципиально новый подход?

Ну вообще да, это же интересно. Может и говно получится, но есть только один способ это узнать.

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

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

У него сам интерпретатор какого размера примерно?

$ pacman -Ql iolanguage-git | cut -d' ' -f 2 | egrep '(/bin/.*[^/]|\.so)$' | xargs du -h
8,0K	/usr/bin/io
972K	/usr/bin/io_static
16K	/usr/lib/io/addons/AsyncRequest/_build/dll/libIoAsyncRequest.so
28K	/usr/lib/io/addons/BigNum/_build/dll/libIoBigNum.so
8,0K	/usr/lib/io/addons/Bitly/_build/dll/libIoBitly.so
20K	/usr/lib/io/addons/Blowfish/_build/dll/libIoBlowfish.so
20K	/usr/lib/io/addons/Box/_build/dll/libIoBox.so
8,0K	/usr/lib/io/addons/CGI/_build/dll/libIoCGI.so
8,0K	/usr/lib/io/addons/ContinuedFraction/_build/dll/libIoContinuedFraction.so
8,0K	/usr/lib/io/addons/DistributedObjects/_build/dll/libIoDistributedObjects.so
12K	/usr/lib/io/addons/EditLine/_build/dll/libIoEditLine.so
8,0K	/usr/lib/io/addons/Facebook/_build/dll/libIoFacebook.so
8,0K	/usr/lib/io/addons/Flux/_build/dll/libIoFlux.so
12K	/usr/lib/io/addons/Fnmatch/_build/dll/libIoFnmatch.so
24K	/usr/lib/io/addons/Font/_build/dll/libIoFont.so
8,0K	/usr/lib/io/addons/GoogleSearch/_build/dll/libIoGoogleSearch.so
8,0K	/usr/lib/io/addons/HttpClient/_build/dll/libIoHttpClient.so
48K	/usr/lib/io/addons/Image/_build/dll/libIoImage.so
12K	/usr/lib/io/addons/LZO/_build/dll/libIoLZO.so
16K	/usr/lib/io/addons/LibSndFile/_build/dll/libIoLibSndFile.so
64K	/usr/lib/io/addons/Libxml2/_build/dll/libIoLibxml2.so
12K	/usr/lib/io/addons/Loki/_build/dll/libIoLoki.so
16K	/usr/lib/io/addons/MD5/_build/dll/libIoMD5.so
16K	/usr/lib/io/addons/MySQL/_build/dll/libIoMySQL.so
8,0K	/usr/lib/io/addons/NotificationCenter/_build/dll/libIoNotificationCenter.so
8,0K	/usr/lib/io/addons/Obsidian/_build/dll/libIoObsidian.so
20K	/usr/lib/io/addons/Ogg/_build/dll/libIoOgg.so
180K	/usr/lib/io/addons/OpenGL/_build/dll/libIoOpenGL.so
8,0K	/usr/lib/io/addons/PostgreSQL/_build/dll/libIoPostgreSQL.so
16K	/usr/lib/io/addons/Python/_build/dll/libIoPython.so
12K	/usr/lib/io/addons/Random/_build/dll/libIoRandom.so
32K	/usr/lib/io/addons/Range/_build/dll/libIoRange.so
8,0K	/usr/lib/io/addons/Rational/_build/dll/libIoRational.so
12K	/usr/lib/io/addons/ReadLine/_build/dll/libIoReadLine.so
24K	/usr/lib/io/addons/Regex/_build/dll/libIoRegex.so
48K	/usr/lib/io/addons/SGML/_build/dll/libIoSGML.so
28K	/usr/lib/io/addons/SHA1/_build/dll/libIoSHA1.so
20K	/usr/lib/io/addons/SQLite3/_build/dll/libIoSQLite3.so
72K	/usr/lib/io/addons/Socket/_build/dll/libIoSocket.so
8,0K	/usr/lib/io/addons/SqlDatabase/_build/dll/libIoSqlDatabase.so
24K	/usr/lib/io/addons/Syslog/_build/dll/libIoSyslog.so
24K	/usr/lib/io/addons/SystemCall/_build/dll/libIoSystemCall.so
20K	/usr/lib/io/addons/Theora/_build/dll/libIoTheora.so
16K	/usr/lib/io/addons/Thread/_build/dll/libIoThread.so
8,0K	/usr/lib/io/addons/Twitter/_build/dll/libIoTwitter.so
12K	/usr/lib/io/addons/UUID/_build/dll/libIoUUID.so
8,0K	/usr/lib/io/addons/User/_build/dll/libIoUser.so
8,0K	/usr/lib/io/addons/VertexDB/_build/dll/libIoVertexDB.so
28K	/usr/lib/io/addons/Volcano/_build/dll/libIoVolcano.so
20K	/usr/lib/io/addons/Vorbis/_build/dll/libIoVorbis.so
44K	/usr/lib/io/addons/Yajl/_build/dll/libIoYajl.so
16K	/usr/lib/io/addons/Zlib/_build/dll/libIoZlib.so
420K	/usr/lib/libbasekit.so
12K	/usr/lib/libcoroutine.so
20K	/usr/lib/libgarbagecollector.so
580K	/usr/lib/libiovmall.so
geekless ★★
()
Ответ на: комментарий от tailgunner

Если это SSA, у тебя в голове просто образцовая каша.

сорри, бабло за интернет закончилось, пришлось сходить до круглосуточного продуктового)

помойму SSA - это про версии одной и той же переменной, которые выстраиваются по времени присваивания, а тут нечто другое (expectations + threading).

Да, у меня в башке каша. Но и на деле каша, потому что в идеальном языке, о котором я тут ныл, намешаны между собой интерпретация, конпеляция в байткод, конпеляция в машинный код, итп. Чтобы что-то более конкретное, некая смесь PHP, JS, C++ и SQL- от PHP кодогенерация в рантайме, от JS - замыкания и ооп, от С++ - многопоточность и прямая работа с памятью, от SQL - автоматический ACID когда нужно и декларативное описание результата.

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

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

Да, у меня в башке каша. Но и на деле каша, потому что в идеальном языке, о котором я тут ныл, намешаны между собой интерпретация, конпеляция в байткод, конпеляция в машинный код, итп. Чтобы что-то более конкретное, некая смесь PHP, JS, C++ и SQL- от PHP кодогенерация в рантайме, от JS - замыкания и ооп, от С++ - многопоточность и прямая работа с памятью, от SQL - автоматический ACID когда нужно и декларативное описание результата.

По-моему, тебе пора проспаться. :}

Кстати, может он такой уже есть? )

lisp

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

контекст-то неизвестен

Про него речи и не было.

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

Ну это же фигня какая-то совершенно.

модификация кода это типа (на псевдоассемблере)

adjust:
    mov mem[10]->a
adjust1:
    inc a
    mov a->mem[10]
    return

... код "inc a" допустим 0x10 а код "dec a" допустим 0x20
    mov 0x20->mem[adjust1]
    mov 1->mem[10]
    call adjust
    mov 0x10->mem[adjust1]
    call adjust
...

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

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

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

Напомнило концовку из «Многорукого бога Далайна».

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

Вы выбрали «Быдлокод» за 500!

А что такое лямбда с use?

@ stevejobs

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

Тогда я вообще не понимат. У них чёрным по белому в мануале написано:

Anonymous functions, also known as closures

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

у это же фигня какая-то совершенно.

Это у вас в голове «фигня какая-то совершенно» если пишете не понимая что.

cecil предоставляет возможность модифицировать и добавлять новый исполняемый код.

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

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

Лямбда это анонимная функция, видящая переменные того, кто ее вызывает, обычно (но не обязательно) захватывающая их с коротким синтаксисом. Используется главным образом для функциональных манипуляций с коллекциями, например filter. Ничего нового в этом концепте нет, но в популярных языках это начало появляться недавно вместе с модой на функциональное программирование.

Legioner ★★★★★
()
Ответ на: комментарий от geekless
int sum(int x, int y) {
     return x+y;
}
const ONE = 1;

int sum(any) {
     return ONE;
}

int sum(int x, any) {
     return x++;
}

Это всё один и тот же код, но с разными предположениями. Первый - когда x!=y, второй - когда всегда x==0, третий - когда всегда x==y. У них разная стоимость (не говоря уж о том, что всякие константы и x++ можно заинлайнить). Предположения мы можем выяснить на этапе статического анализа при первоначальной конпеляции, или при подгрузке нового кода (сказали include «new_file.php», а там предположение x всегда ==0 больше не выполняется).

наверное там выше имелся в виду какой-нибудь специализированный код, типа байткода виртуальной машины, и в нем вот так просто уже не покопаешься. Чиселку типа указателя еще можно подставить, если знаешь с какого по какой байтик менять, а логику - данунафиг! Проще переконпелять блок с нуля используя новый контекст.

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

Да не в переменной суть.

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

Здесь ты пытаешься говорить о «функциях высшего порядка» (higher-order functions). А лямбда и анонимная функция - это одно и тоже. Причем термин «лямбда» возник раньше.

dave ★★★★★
()

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

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