LINUX.ORG.RU
ФорумTalks

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

 , ,


7

7

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

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

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

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

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

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

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

тут функция возвращает другую функцию (x+y). В сишечке так конечно нельзя, но вот вернуть указатель на функцию - можно.

Тут поинт даже не в том, что возвращается функция, а в том, что в этой функции будет доступно нелокальное значение x.

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

А почему функция должна быть обязательно вложенной?

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

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

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

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

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

какая нафиг разница? определи ptr как

typedef int (*ptr)(int);
и будет возвращать функцию от одного аргумента.в чём проблема-то?

если хочешь такую-же НЁХ как в питоне, то вот что-то типа того:

#include <stdio.h>

int plus(int x, int y)
{
	return x + y;
}

int minus(int x, int y)
{
	return x - y;
}

int (*op(char c))(int, int)
{
	switch(c)
	{
		case '+':
			return plus;
		case '-':
			return minus;
	}
	return NULL;
}

int f1(int (*f)(int, int), int x)
{
	return f(x,3);
}

int main(void)
{
	int (*f)(int, int) = op('+');//функция сложения
	int (*f2)(int (*f3)(int, int), int) = f1;//функция выполняющая другую функцию со вторым аргументом равным 3
	printf("2 + 3 = %d\n", f2(f,2));// функция выполняющая функцию сложения со вторым аргументом 3 и первым аргументом 2 записанная через ПОЛНУЮ ФУНКЦИОНАЛЬНУЮ ЖОПУ!!! (:
	return 0;
}

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

Ты в очередной раз сел в лужу, потому что CL в том числе и императивный язык.

я знаю. потому и написал - «я не в курсе, как оно в CL». и да, фашисты-ли геи? (:

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

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

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

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

Ты действительно не видишь, что это не то?

если хочешь такую-же НЁХ как в питоне, то вот что-то типа того:

Опять хрень, которая делает что-то не то.

и будет возвращать функцию от одного аргумента.в чём проблема-то?

И где оно?

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

Если считается, что вы хоть что-то понимаете в програмировании, то да, я тупой.

На этом и сойдемся, тем более это не только ваше мнение а всех оставшихся в треде.

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

если хочешь такую-же НЁХ как в питоне, то вот что-то типа того:

Этот вариант не является аналогом Питон-кода, потому что в Питоне можно сделать так:

>>> def f(x): return lambda y: x+y
>>> add3 = f(3)
>>> add4 = f(4)

а в твоем примере - нельзя.

Но длинная простыня кода вместо двух строк на Питоне - это уже намекает %) И да, необходимость модифицировать op для добавления каждой операции доставляет.

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

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

на глобальные - пожалуйста. А локальные из одной функции не видны в другой функции. Тебя устроит замыкание на параметр или на глобальную переменную? Нет? А почему нет?

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

а в твоем примере - нельзя.

можно.

Но длинная простыня кода вместо двух строк на Питоне - это уже намекает %)

уже говорил - это не баг а фича.

И да, необходимость модифицировать op для добавления каждой операции доставляет.

модификации НЕТ. Я просто явно расписал через вашу ФПшную жопу. Получилось неплохо ИМХО. Красиво... Даже работает (сам удивлён).

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

Но длинная простыня кода вместо двух строк на Питоне - это уже намекает %)

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

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

Нет? А почему нет?

Потому что это не замыкание.

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

Делегаты появились в C# 2.0, лямбды - 3.0 :)

Это у вас в эльфийски лесах они так появились.
А в реальной жизни, они появились в C# 1.0
Лямбда калкулус расширялся в последующих версиях и продолжвет расширяться.

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

Тебя устроит замыкание на параметр или на глобальную переменную? Нет? А почему нет?

Не устроит. Тебе действительно нужно объяснять, почему?

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

Я просто явно расписал через вашу ФПшную жопу

Ты так ничего и не понял.

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

На плюсах как-то так.

$ cat 14.cpp
#include <boost/function.hpp>
#include <stdio.h>

boost::function<int (int)>
func(int x) {
        return [x] (int y) {return x + y;};
}

int main()
{
        auto add3 = func(3);
        auto add4 = func(4);

        printf("%d\n", add3(1));
        printf("%d\n", add4(1));
}

$ g++ 14.cpp -std=c++0x
$ ./a.out
4
5
Reset ★★★★★
()
Ответ на: комментарий от SlothSpot

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

Хехе!
Привет эльф!

Специально для вас приведу ссылку, где я сравнил С, Perl5, Perl6, C#
лямбды в новых язычках - PR или реальные полезняшки? (комментарий)

Давайте спорить с этой позиции

Так что не стоит корчить из себя «специалиста в области», у тебя плохо получается.

Я не претендую на ваше уважение.
С меня хватает уважения моей квалификации в $/h которые мне платят.

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

можно.

Нет, у тебя аргумент на основании которого генерится функция (3) захардкожен внутрь, а не передается извне.

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

Я не силён в лямбда синтаксисе введённом в С++11
Насколько я понял, это анонимная фунция принимающая 2 аргумента и возвращающая сумму

Я говорил о C#
С ним достаточно просто и в вики нормально расписано.

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

а можно привести в пример задачу, в рамках которой такой код нужен?

Если ты о замыкании, то для итерации по списку, например. Собственно, пример на Си++ с { return x > whatever; } уже приводили - хотелось бы, чтобы это было возможно в Си. Ах да, заранее: замыкание в данном случае не является _необходимым_, но с ним удобнее.

Если ты о карринге, то вот (абстрактный) пример: есть функция f(g), которая обрабатывает последовательность объектов, возвращаемую функцией g(). Так вот, g создается при помощи карринга из другой функции, которая может иметь произвольное число аргументов.

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

В крестах нужно явно указывать переменные для замыкания?

Да, потому что тут можно захватить переменную по значению, а можно и по ссылке.

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

А можно подробнее с этого места - «но closure не работает. Т.е. лямбда выражения в Перл есть и даже с карингом но неполноценное»?

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

вас не затруднит ОБЪЯСНИТЬ ЗАЧЕМ?

Увеличение эфективности программирования.
Программы получаются проще, читабельнее и в ряде случаев быстрее.

а ваши примеры я-бы переписал короче и проще.

Это очень хорошо.
Вы о сравнении XML деревьев?
Хочется взглянуть.

Опять так, я и сам могу это перереписать, просто нужно было быстро натисать утилиту для сравнения ~100мб XML документов.
Сравниваюся за примерно 15 сек, что меня устрроило и оптимизация и наведение красоты не понадобилось.

Но если напишете, будет интересно посмотреть.

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

Ты только недавно ругал Rust.

Прикол в том, что, забредя на сайт Rust из форума по D, я обнаружил сильно другой Rust O_o (по сравнению с тем, что Хоар делал изначально). Не скажу, что я сильно тащусь от этого нового Rust, но там делаются очень интересные вещи. Собственно, после тихой кончины BitC, Rust - самый интересный проект категории «современный системный язык».

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

А можно подробнее с этого места - «но closure не работает. Т.е. лямбда выражения в Перл есть и даже с карингом но неполноценное»?

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

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

Ты только недавно ругал Rust.

Прикол в том, что, забредя на сайт Rust из форума по D, я обнаружил сильно другой Rust O_o (по сравнению с тем, что Хоар делал изначально). Не скажу, что я сильно тащусь от этого нового Rust, но там делаются очень интересные вещи. Собственно, после тихой кончины BitC, Rust - самый интересный проект категории «современный системный язык».

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

Ключевое слово «можно». _Можно_ явно указать переменные для замыкания, но не _обязательно_

theNamelessOne ★★★★★
()
Ответ на: комментарий от grim
#!/usr/bin/perl -w
use strict;

my $outer_sub=sub {
    my $const=12;
    my $inner_sub=sub
    {
        my $var=shift;
        return $var*$const;
    };
    return $inner_sub;
};

my $caller=$outer_sub->();
warn $caller->(2);

Всё верно? Пишет 24.

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

Achievement unlocked: ЧЕЛОВЕК-КОСТЫЛЬ.

Лучше и не скажешь.

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

Не устроит. Тебе действительно нужно объяснять, почему?

не нужно. Мне нужно объяснить, на кой нужны лямбды в императивных ЯП.

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

А если $outer_sub вызвать повторно и изменить $const?
Я помню у меня были проблемы но возможно все исправили. Перл5 как никак тоже развивается.

grim ★★☆☆
()
Ответ на: комментарий от grim
#!/usr/bin/perl -w
use strict;

my $outer_sub=sub
{
    my $const=shift;
    my $inner_sub=sub
    {
        my $var=shift;
        return $var*$const;
    };
    return $inner_sub;
};

my $caller=$outer_sub->(12);
warn $caller->(2);
$caller=$outer_sub->(13);
warn $caller->(3);

$ /usr/bin/perl -v

This is perl, v5.10.0 built for i486-linux-gnu-thread-multi

$ perl test2.pl 24 at test2.pl line 16. 39 at test2.pl line 18.

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

Специально для вас приведу ссылку, где я сравнил С, Perl5, Perl6, C#

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

Давайте спорить с этой позиции

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

Да и сама постановка задачи говорит о кривом и непродуманном дизайне. Не надо передавать в функцию непонятно что, что-бы потом проверять, что-же туда передали? Это говорит о быдлокодерстве.

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

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

Вот и не врите.
Я на С достаточно много написал.

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

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

нужно:
my $caller=$outer_sub->(12);
my $caller1=$outer_sub->(13);
warn $caller->(2);
warn $caller1->(3);

И да, все работает как нужно. Т.е. в Perl 5 все нормально.

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

Нет. LINQ - это анализ и трансформация AST лямбд.

Наверное по этому его запилили для Явы через чейнинг, а идея взята из Haskell/ML, где, сколь мне помнится, этой трансформации нету.

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

его запилили для Явы через чейнинг

И? Кстати, его запилили до C# или после? Ссылку.

идея взята из Haskell/ML, где, сколь мне помнится, этой трансформации

Ссылку на LINQ для ML - в студию.

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

Это у вас в эльфийски лесах они так появились.
А в реальной жизни, они появились в C# 1.0
Лямбда калкулус расширялся в последующих версиях и продолжвет расширяться.

Угу , в Канаде у «эксперта» совсем другой лес )). Я к чему, в С# 1.0 оно было костылем на тему указателя на функцию, в C# 2.0 появилась групировка, а в C# 3.0 появились лямбды. По сути, чем-то полезным оно стало как раз в районе 2.0-3.0. Про калкулус: Для такого уже вывод типов починили:

var foo = (int x) => x*x;
?

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

Специально для вас приведу ссылку, где я сравнил С, Perl5, Perl6, C#
Приведите пожалуйста код на С и давайте сравним с моим кодом, который я писал не на выставку а взял из проекта.

У тебя там в коде опечатки, что как бы говорит о какчестве проекта.

Если же забить на срач, и говорить по сути вопроса: Я не вижу в том коде никакого WOW; я не считаю что лямбды не нужны, но и называть их серебрянной пулей не стану; Если сравнить с OCaml - в коде касты, а значит не все хорошо с выводом типов. Как итог: в разных языка разные практики решения одних и тех же задач, из-за особенностей этих самых языков далеко не всегда туда можно прикрутить лямбда калкулус, говорить о том, что если нет лямбд - язык говно, тоже не стоит. И самое важное: ретроградов/лудитов на темную сторону силы ты не переведешь, так что не трать энергию, лучше поучи своих студентов, о которых писал выше.

С меня хватает уважения моей квалификации в $/h которые мне платят.

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

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

Я к чему, в С# 1.0 оно было костылем на тему указателя на функцию

Т.е. в 1.0 были, но вы ищете отмазки. Ну-ну.

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

Я вообще-то просил сделать и сделал сам средствами языка а не найти библиотеку.

Чо? «Найти»? Это getopt _НАЙТИ_? Это ж чо надо делать и насколько быть несведущим чтобы getopt ИСКАТЬ?

И эти люди мнят себя программистами? Мда.. Деградация просто поражает.

Так что ваше решение некоректно.

Некорректно ровно настолько же, насколько и ваше. И не стоит начинать вешать на уши лапшу про то, что всякие .Contains .StartsWith .Where .FirstOrDefault .Substring и прочая - это «средства языка» а не функции из библиотеки.

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

И? Кстати, его запилили до C# или после? Ссылку.

Практически уверен что под влиянием и после. тут и тут

Ссылку на LINQ для ML - в студию.

Ссылку не дам, пока уточню: LINQ по сути своей - сахар на тему map/fold/filter/sort/etc. Открытый вопрос: библиотеки для доступа к источникам данных( БД, ХМЛ, итп). Что именно хочешь увидеть ты?

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

Т.е. в 1.0 были, но вы ищете отмазки. Ну-ну.

Смотри, в 1.0 был формально указатель на функцию не имеющий плюсов над сишным, какой смысл о нем говорить как о чем-то очень важном? Речь же шла о том, что С убог и нельзя на нем в лябмда калкулус, потому давай и продолжать говорить о сильных сторонах C#, а не о тех, где паритет.

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