lambda являются first class citizens?
От: Максим Рогожин Россия  
Дата: 05.05.18 17:12
Оценка:
Привет!
Скажите, пожалуйста, лямбда выражения в C++ являются first class citizens?
Re: lambda являются first class citizens?
От: Анатолий Широков СССР  
Дата: 05.05.18 17:52
Оценка: 4 (2)
Здравствуйте, Максим Рогожин, Вы писали:

МР>Привет!

МР>Скажите, пожалуйста, лямбда выражения в C++ являются first class citizens?

Да, посколько результат лямбда выражения это объект (функтор, функциональный объект) типа closure type, который может быть передан в функцию, возвращен из функции, присвоен переменной. Например, код

auto a = [](int){};
a(10);


превратится

struct __closure_unique_type {
   void operator()(int) {}
};
...
__closure_unique_type a;
a(10);
Отредактировано 05.05.2018 18:05 Анатолий Широков . Предыдущая версия . Еще …
Отредактировано 05.05.2018 17:54 Анатолий Широков . Предыдущая версия .
Re[2]: lambda являются first class citizens?
От: Максим Рогожин Россия  
Дата: 05.05.18 18:07
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Да, посколько результат лямбда выражения это объект (функтор, функциональный объект) типа closure type, который может быть передан в функцию, возвращен из функции, присвоены переменной.


Спасибо! Еще вопрос:
— указатель на функцию
— функтор
тоже являются firts class citizens?
Re[3]: lambda являются first class citizens?
От: Анатолий Широков СССР  
Дата: 05.05.18 18:18
Оценка: +1
Здравствуйте, Максим Рогожин, Вы писали:

МР>Спасибо! Еще вопрос:

МР>- указатель на функцию
МР>- функтор
МР>тоже являются firts class citizens?

Если у тебя есть определение firts class citizens, как объекта, который может быть передан в качестве аргумента в функцию, возвращен из функции, присвоен переменной, то ты без труда ответишь на свой вопрос
Отредактировано 05.05.2018 18:19 Анатолий Широков . Предыдущая версия .
Re[2]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 05.05.18 18:25
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

МР>>Скажите, пожалуйста, лямбда выражения в C++ являются first class citizens?


АШ>Да, посколько результат лямбда выражения это объект (функтор, функциональный объект) типа closure type, который может быть передан в функцию, возвращен из функции, присвоен переменной. Например, код


Если да то как массив например их 3 таких лямбд задать?
Re[3]: lambda являются first class citizens?
От: Анатолий Широков СССР  
Дата: 05.05.18 18:30
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, Анатолий Широков, Вы писали:


МР>>>Скажите, пожалуйста, лямбда выражения в C++ являются first class citizens?


АШ>>Да, посколько результат лямбда выражения это объект (функтор, функциональный объект) типа closure type, который может быть передан в функцию, возвращен из функции, присвоен переменной. Например, код


_>Если да то как массив например их 3 таких лямбд задать?


Никак, поскольку массива лямбд не существует в виду того, что объект каждого лямбда выражения является уникальным типом.
Re[3]: lambda являются first class citizens?
От: Alexander G Украина  
Дата: 05.05.18 18:31
Оценка: 3 (1) +1
Здравствуйте, kov_serg, Вы писали:

_>Если да то как массив например их 3 таких лямбд задать?


А в чём проблема?


int main(void) {
    auto x = []{ std::cout <<"hi\n"; };
    decltype(x) y[] = {x, x, x};
    y[1]();
    return 0;
}
Русский военный корабль идёт ко дну!
Re[4]: lambda являются first class citizens?
От: Максим Рогожин Россия  
Дата: 05.05.18 18:36
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Если у тебя есть определение firts class citizens, как объекта, который может быть передан в качестве аргумента в функцию, возвращен из функции, присвоен переменной, то ты без труда ответишь на свой вопрос


На википедии еще, например, такое требование предъявляется:
— может быть создан во время выполнения программы

Что здесь имеется ввиду? Создание new int(10); ? А лямбда функции мы можем создавать во время выполнения программы? Лямбда функции вроде бы на этапе компиляции уже созданы все будут.
Re[4]: lambda являются first class citizens?
От: Анатолий Широков СССР  
Дата: 05.05.18 18:37
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, kov_serg, Вы писали:


_>>Если да то как массив например их 3 таких лямбд задать?


AG>А в чём проблема?



Все же здесь есть некоторое лукавство Массив лямбд с одинаковой сигнатурой функционального оператора невозможен по определению:

assert(typeid([]{}) != typeid([]{}));


поскольку я не могу вывести общий тип для таких выражений.
Отредактировано 05.05.2018 18:41 Анатолий Широков . Предыдущая версия .
Re[5]: lambda являются first class citizens?
От: Alexander G Украина  
Дата: 05.05.18 18:44
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

AG>>А в чём проблема?


АШ>Все же здесь есть некоторое лукавство


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

АШ>Массив лямбд с одинаковой сигнатурой функционального оператора невозможен


Ну это да, разные лямбды — разные типы.
Но почему массив из одной и той же лябмды не считается?
Те же массивы объектов работают только если это один и тот же класс, т.е. нельзя:
class X{};
class Y{};

decltype(X) a[] = { X{}, Y{} };
Русский военный корабль идёт ко дну!
Отредактировано 05.05.2018 19:03 Alexander G . Предыдущая версия .
Re[4]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 06.05.18 10:33
Оценка: -1 :)
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, kov_serg, Вы писали:


_>>Если да то как массив например их 3 таких лямбд задать?


AG>А в чём проблема?

AG>
AG>int main(void) {
AG>    auto x = []{ std::cout <<"hi\n"; };
AG>    decltype(x) y[] = {x, x, x};
AG>    y[1]();
AG>    return 0;
AG>}
AG>

Проблема в том что для first class citizen такой проблемы не должно быть
auto x=[]{ std::cout<<"x\n"; };
auto y=[]{ std::cout<<"y\n"; };
auto z=[]{ std::cout<<"z\n"; };
typedef decltype(x) t;
void foo(t); foo(x); foo(y); foo(z);
t a[]={x,y,z};

В C++ стараются сделать костылями. Именно это печалит. Что указатели на члены класса что лямбды. А перегружаемые функции с лямбдами. А если вируальную функцию захочеться? В результате таких нововедений растёт только сложность и энтропия и вместо упрощения получаем новые проблемы.
Так что это не "first class citizen" это "crutch class outlander".
Отредактировано 06.05.2018 10:36 kov_serg . Предыдущая версия . Еще …
Отредактировано 06.05.2018 10:34 kov_serg . Предыдущая версия .
Re[5]: lambda являются first class citizens?
От: Анатолий Широков СССР  
Дата: 06.05.18 12:01
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Проблема в том что для first class citizen такой проблемы не должно быть

_>
_>auto x=[]{ std::cout<<"x\n"; };
_>auto y=[]{ std::cout<<"y\n"; };
_>auto z=[]{ std::cout<<"z\n"; };
_>typedef decltype(x) t;
_>void foo(t); foo(x); foo(y); foo(z);
_>t a[]={x,y,z};
_>


Я уже ответил, массив различных лямбда выражений не существует в С++, они ничем не связаны. Хочешь массив, объявляй массив указателей на функцию и приводи к ним лямбда выражения без захвата.
Re[6]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 06.05.18 12:46
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Я уже ответил, массив различных лямбда выражений не существует в С++, они ничем не связаны. Хочешь массив, объявляй массив указателей на функцию и приводи к ним лямбда выражения без захвата.

Причем тут чего я хочу. Я просто сказал, что это костыли, а не типы данных. Тем более не "first class citizen".
То что в C++ это сделано через жопу, я не виноват. А вы просто констатируете факт что для этих костылей нужны еще костыли в виде указателей на функцию (тут одельная песня).
Для "first class citizen" int и double я могу написать такое
struct A {
    enum { N=3 };
    int x[N]; double y[N];
    virtual void fn(int x) {}
    virtual void fn(double x) {}
};
А для лямд не могу. Поэтому этот тип данных убог и ущербен и никак не "first class citizen" т.к на него есть куча ограничений.
Отредактировано 06.05.2018 12:52 kov_serg . Предыдущая версия .
Re[7]: lambda являются first class citizens?
От: Анатолий Широков СССР  
Дата: 06.05.18 16:24
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, Анатолий Широков, Вы писали:


АШ>>Я уже ответил, массив различных лямбда выражений не существует в С++, они ничем не связаны. Хочешь массив, объявляй массив указателей на функцию и приводи к ним лямбда выражения без захвата.

_>Причем тут чего я хочу. Я просто сказал, что это костыли, а не типы данных. Тем более не "first class citizen".

Все норм, лямбда нормально подходит на звание first class citizen, просто с массивами напряженка в виду отсутствия базового типа, к которому может быть приведено лямбда-выражение. Но даже в этом случае у тебя есть возможность сохранить лямбду в std::function.
Re[4]: lambda являются first class citizens?
От: uzhas Ниоткуда  
Дата: 07.05.18 15:32
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Если у тебя есть определение firts class citizens, как объекта, который может быть передан в качестве аргумента в функцию, возвращен из функции, присвоен переменной, то ты без труда ответишь на свой вопрос


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

Some authors require it be possible to create new functions at runtime to call them 'first-class'. As a result, functions in C are not first-class objects; instead, they are sometimes called second-class objects, because they can still be manipulated in most of the above fashions (via function pointers).

функции в сях не являются первоклассными, хотя являются первоклассными в питоне, хаскеле и жава-скрипте
std::function является первоклассной сущностью
Re[5]: lambda являются first class citizens?
От: Максим Рогожин Россия  
Дата: 08.05.18 09:50
Оценка:
Здравствуйте, uzhas, Вы писали:

U>

U>Some authors require it be possible to create new functions at runtime to call them 'first-class'. As a result, functions in C are not first-class objects; instead, they are sometimes called second-class objects, because they can still be manipulated in most of the above fashions (via function pointers).

U>функции в сях не являются первоклассными, хотя являются первоклассными в питоне, хаскеле и жава-скрипте

Можете привести пример, того что значит создать функцию at runtime? И как это могло бы выглядеть в C++?
Re[6]: lambda являются first class citizens?
От: uzhas Ниоткуда  
Дата: 08.05.18 10:55
Оценка:
Здравствуйте, Максим Рогожин, Вы писали:

МР>Можете привести пример, того что значит создать функцию at runtime? И как это могло бы выглядеть в C++?


  1. лямбда: https://ideone.com/gxNgiM
  2. std::function: https://ideone.com/yqVRmo
Re[3]: lambda являются first class citizens?
От: jazzer Россия Skype: enerjazzer
Дата: 11.05.18 15:36
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, Анатолий Широков, Вы писали:


МР>>>Скажите, пожалуйста, лямбда выражения в C++ являются first class citizens?


АШ>>Да, посколько результат лямбда выражения это объект (функтор, функциональный объект) типа closure type, который может быть передан в функцию, возвращен из функции, присвоен переменной. Например, код


_>Если да то как массив например их 3 таких лямбд задать?


Никак, это уникальные типы.
Я правильно понимаю, что по твоей логике, уникальные типы не являются first class citizens?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 11.05.18 19:31
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Никак, это уникальные типы.

J>Я правильно понимаю, что по твоей логике, уникальные типы не являются first class citizens?
Да. Я хочу сначала объявить переменную а потом присвоить. Или присвоить в зависимости от флага одну или другую функцию.
Вернуть из функции в из разных return-ов и т.п.
Re[5]: lambda являются first class citizens?
От: YuriV  
Дата: 12.05.18 12:09
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Да. Я хочу сначала объявить переменную а потом присвоить. Или присвоить в зависимости от флага одну или другую функцию.

_>Вернуть из функции в из разных return-ов и т.п.

Только если значение флага вычисляется в компайл-тайм, т.е. объявлен флаг как constexpr.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.