LINUX.ORG.RU

Чем сейчас лямбда выражения удобны?


3

5

Что их наличие преподносится как большой плюс?

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

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

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

.....

T result;
{
// а вот тут код, который любят в лямбда функции совать
....
result = ....;
}
....

Перемещено JB из talks

★★★★★

Последнее исправление: cvs-255 (всего исправлений: 4)

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

Например, тем, что такой код ты не передаш в (С++) алгоритмы, а лямбда функцию можно.

DarkEld3r ★★★★★
()
Ответ на: комментарий от cvs-255

Или собираешься прямо на ходу генерить их?

Товаришь PolarFox в треде про язык D приводил пример со словарями. Такое описание объктов бывает удобнее «традиционного» (java- c++ подобного) тем, что 1.) легче надстраивать абстракции 2.) легче генерить (не обязательно на ходу) 3.) См.п 1

anonymous
()

Шла третья неделя тупняка на лоре...

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

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

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

Поколение выучившихся по sicp троечников

Троечники как раз SICP не читали и тупо боятся лямбд. Но их мнение никому не интересно.

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

Все же знают что в монадах не обязательно соблюдать монадические законы :)

vertexua ★★★★★
()

Для detached тредов в спп нет ничего лучше. Что-то типа такого:

#include <thread>
#include <iostream>
#include <string>
#include <unistd.h>

void f(bool b)
{
  std::thread ([b] () {
    std::cout << [&b] () -> std::string {return b?"true":"false";}() << std::endl;
  }).detach();
}

int main()
{
  f(true);
  f(false);
  usleep(400000);
}

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

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

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

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

Fixed ☺

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

Я, к своему сожалению, не учился по SICP. Но в зрелом возрасте читал, да.

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

Во ворой таблице хранится уровень доступа.

Если вы сделаете 2 вложенных цикла это будет очень медленно.

В данной ситуации создаётся пересечение 2х таблиц.

BTW, лямбды уже есть в C++. Хотя я с ними не разбирался.

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

Нет. Можно построить деревья. То, что получается в данном случае, кстати так и назыается Expression Trees.

Не забывайте Lazy Evaluation

Например следующим шагом вы делаете join с xml докуменом по условию.

var molSpec = from p in Db.Personell
    join a in Db.Access on p.PersonellId equals a.PersonellId
    where p.Age < 30 && p.Education = High && a.Level < Manager
    select new { Id= p.PersonellId, Name = p.Name, Age = p.Age, Birthday = p.DateOfBirth };

var specs = from s in molSpec
    join x in xDoc.Element("Feed").Elements("Employee") on s.Id equals x.Attribute("id").Value
    where x.Attribute("Salary").Value > 1000
    select new { Personell = s, Xml = x };

Соответственно Expression Tree извлечет только данные нужные для результата.

Живым примером было, когда я за пару часов написал тростенькую программу сравнивающую 2 xml документа ~150мб каждый.

Коллега ненавидящий C# сказал что это херня и нужно пользовать профессиональные тулзы запустив XmlSpy.

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

Кстати, после небольшой оптимизации она стала справляться за ~20 sec.

grim ★★☆☆
()
Последнее исправление: grim (всего исправлений: 2)
Ответ на: комментарий от dzidzitop

Ну не делай inline функций.

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

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от PolarFox

Вот уж на чём, а на плюсах плюсы лямбд продемонстрировать трудно.

1) удобно вместо stateful functors; 2) просто удобно (код рядом с местом вызова)

Хотя без ніх можно код пісать.

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

Ну если хочешь производительности, тогда делай. Но тогда не передашь их никуда. На то они и inline. А lambda, сдается мне, компилируются либо в inline код либо в не-inline код. Потому что иначе фон-неймановская архитектура не умеет.

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

указатель на функцію не инлайнится никогда. функтор и лямбда инлайнятся очень часто.

+ фичи что расписали выше.

Выбор между землянкой и дворцом.

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

Сейчас всё серверное программирование идёт в асинхрон для оптимизации нагрузки

хрен отдебажишь потом эти грозьдья колбэков, и хрен остановишь процесс где-то в середине. Плавали-знаем.

dzidzitop ★★
()
Ответ на: комментарий от cvs-255

inline code - вместо вызова функции делается вставка его непосредственно в код.

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

я про то как делают stateful callbacks на C. (ТС упомінал глобальные переменные)

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

Как говорит Одерский, это - такой генерик, с двумя методами: apply и flatmap, первый конструирует монаду apply(1) => Monad(1), а второй по лямбде, возвращающей монаду, из одной монады другую строит Monad(1).flatmap(x=>apply(x+1)) => Monad(2).

И у него три правила, о которых мы и говорили.

1) ассоциативность. Monad(1).flatmap(x=>apply(x+1)).flatmap(x=>apply(x*10)) === Monad(1).flatmap(x=>apply(x+1).flatMap(x=>apply(x*10)))

2) правая единица. Monad(1).flatMap(x=>apply(x)) == Monad(1)

3) левая единица. apply(1).flatMap(x=>f(x)) == f(1) // f опять же возвращает монаду

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

Так вот, конструирование IQuareble у вас делается методом From. flatMap - это select(или нет?). Так вот тут народ вопрошал, выполняются ли три правила, или как у всех пацанов только два.

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

Что-то туго думается.

Похоже что все соблюдается.

лямбды в C# не совсем канонические, но достаточные для большинства случаев.

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

Ок, сформулирую так: указатель на функцию не инлайнится почти никогда.

Для успешного инлайна нужно чтобы был доступен весь контекст (включая реализацию самой функции и той функции куда передаётся коллбэк). На hello world работает (и то удивлён). Но стоит вынести функцию в иной .cpp - и магия исчезнет.

Для лямбды будет создан свой инстанс шаблонной функции - и там всё намного более просто.

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

Плюс нужно проверять на двух колах process(&selector1) & process(&selector2)

Возможно уже тут магия окончится и инлайнинг станет тыквой.

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

Вдобавок:

template<typename C> g(C callback)
{
    callback();
}

f()
{
    g(c);
}

Для C = function pointer инлайн может наступить только когда: f инлайнит g, а g инлайнит C.

Для C = functor (лямбда) инлайн может быть также и такой: f вызывает g<C>, а интанс g<C> инлайнит функтор c.

Как-то так.

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

Скорее всего так.
Но вообще, надежда на инлайн по указателю - это странно (я сам не ожидал, когда пробовал).

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