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[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?
От: 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[11]: lambda являются first class citizens?
От: Кодт Россия  
Дата: 16.05.18 08:22
Оценка: +1 :)
Здравствуйте, kov_serg, Вы писали:

_NN>> auto l = f(); // assigned into a variable

_>Не объявление константы, а присвоение переменной.
_>
_> l=f(); l=f(); // не работает
_>


_NN>>Приведённые требования выполняются.

_>и где они выполняются?

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

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

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

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

J>>Я правильно понимаю, что по твоей логике, уникальные типы не являются first class citizens?

_>Да. Я хочу сначала объявить переменную а потом присвоить.

твои хотелки никак не связаны с понятием first class citizen, не мешай всё в кучу
лямбды в плюсах сделали очень легковесными, это жирный плюс
твои хотелки реализуются с помощью std::function, который имеет бОльший оверхед, нежели лямбды и достаточно просто создаются из лямбд

по-моему, по сравнению с теми же bind + placeholders, лямбды в язык вписались довольно гармонично (хотя, синтаксис чудноват, имхо) и любителям перформанса не очень больно
lambda являются first class citizens?
От: Максим Рогожин Россия  
Дата: 05.05.18 17:12
Оценка:
Привет!
Скажите, пожалуйста, лямбда выражения в C++ являются first class citizens?
Re[2]: lambda являются first class citizens?
От: Максим Рогожин Россия  
Дата: 05.05.18 18:07
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

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


Спасибо! Еще вопрос:
— указатель на функцию
— функтор
тоже являются firts class citizens?
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[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[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.
Re[6]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 14.05.18 12:09
Оценка:
Здравствуйте, uzhas, Вы писали:

U>твои хотелки никак не связаны с понятием first class citizen, не мешай всё в кучу

U>лямбды в плюсах сделали очень легковесными, это жирный плюс
U>твои хотелки реализуются с помощью std::function, который имеет бОльший оверхед, нежели лямбды и достаточно просто создаются из лямбд
#include <functional>

int fn( std::function<int()> f) { return f(); }

int main(int argc,char** argv) {
    //return fn( argc ?  [=]{return argc;} : [=]{return argc;} ); // облом
    return fn( argc ?  std::function<int()>([=]{return argc;}) : std::function<int()>([=]{return argc;}) );
}

Это first class citizen? Это как для передачи char использовать double.

U>по-моему, по сравнению с теми же bind + placeholders, лямбды в язык вписались довольно гармонично (хотя, синтаксис чудноват, имхо) и любителям перформанса не очень больно

На вкус и цвет карандаши разные.
Re[7]: lambda являются first class citizens?
От: uzhas Ниоткуда  
Дата: 14.05.18 14:23
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Это first class citizen?


да: https://wandbox.org/permlink/oEFfJUfH0z0CuoBh
твой тернарный оператор не имеет никакого отношения к first-class. иди вики почитай уже или внятно объясни, где ты видишь несостыковки с понятием first-class
"мне неудобно" — это не обоснование, т.к. first-class не об удобстве, а о возможностях. плюсовые лямбды предоставляют те возможности, которые прописаны для first-class объектов (пусть даже и неудобно кому-то). если быть точнее, то лямбды соответствуют тем критериям\условиям, которые определены для всех first-class объектов

это всё равно, что заявлять, что обработка double не соответствует IEEE754. т.к. при печати 0.1 выдаётся куча девяток после запятой. ну да, кому-то неудобно, но это не значит, что double не соответствует стандарту IEEE
короче, с логикой явные проблемы
Re[8]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 14.05.18 16:10
Оценка:
Здравствуйте, uzhas, Вы писали:

U>да: https://wandbox.org/permlink/oEFfJUfH0z0CuoBh

U>твой тернарный оператор не имеет никакого отношения к first-class. иди вики почитай уже или внятно объясни, где ты видишь несостыковки с понятием first-class

Michael L. Scott, Programming Language Pragmatics, 3-rd ed., ELSEVIER 2011
ISBN 13: 978-0-12-374514-9

Page:154

3.6.2 First-Class Values and Unlimited Extent

In general, a value in a programming language is said to have
first-class status if it can be passed as a parameter, returned from a subroutine, or assigned into a variable.
Simple types such as integers and characters are first-class values in most programming languages.
By contrast, a
“second-class” value can be passed as a parameter, but not returned from a subroutine or assigned into a variable,
and a
“third-class” value cannot even be passed as a parameter.

Делаем виртуальнкю функцию, которая принимает лямду как параметр и в зависимости от того совпала она с предыдущим значением которое передавали в эту функцию
возвращает лямду 1 или лямду 2.
struct A {
  lambda prev;
  virtual lambda fn( lambda a ) {
    if (a==prev) return []{ one };
    prev=a;
    return []{ two };
  }
};

Для first class int это выглядит так:
struct A {
  int prev;
  virtual int fn(int a) {
    if (a==prev) return 1;
    prev=a;
    return 2;
  }
};


U>"мне неудобно" — это не обоснование, т.к. first-class не об удобстве, а о возможностях. плюсовые лямбды предоставляют те возможности, которые прописаны для first-class объектов (пусть даже и неудобно кому-то). если быть точнее, то лямбды соответствуют тем критериям\условиям, которые определены для всех first-class объектов


U>это всё равно, что заявлять, что обработка double не соответствует IEEE754. т.к. при печати 0.1 выдаётся куча девяток после запятой. ну да, кому-то неудобно, но это не значит, что double не соответствует стандарту IEEE

U>короче, с логикой явные проблемы
Я имел ввиду что это выглядит так как если бы для char приходилось писать
 char r = flag ? (double) char(65) : (double) char(48);
Re[9]: lambda являются first class citizens?
От: uzhas Ниоткуда  
Дата: 14.05.18 16:39
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>first-class status if it can be passed as a parameter, returned from a subroutine, or assigned into a variable.


проверяем все три пункта:
https://wandbox.org/permlink/sQ8zFvdmI61NIx6M
вот и виртуальная функция и без шаблонов: https://wandbox.org/permlink/epZyEGUG9MGcgu7y
Re[10]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 14.05.18 18:03
Оценка:
Здравствуйте, uzhas, Вы писали:

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


_>>first-class status if it can be passed as a parameter, returned from a subroutine, or assigned into a variable.


U>проверяем все три пункта:

U>https://wandbox.org/permlink/sQ8zFvdmI61NIx6M
U>вот и виртуальная функция и без шаблонов: https://wandbox.org/permlink/epZyEGUG9MGcgu7y
Где присвоение переменной? Где без кастыльная возможность вернуть лямды в разных ветках switch-а ?
Где возможноть передавать назные лямды в одну виртуальную функцию?
Невижу.
Re[9]: lambda являются first class citizens?
От: _NN_ www.nemerleweb.com
Дата: 14.05.18 19:52
Оценка:
Здравствуйте, kov_serg, Вы писали:

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


U>>да: https://wandbox.org/permlink/oEFfJUfH0z0CuoBh

U>>твой тернарный оператор не имеет никакого отношения к first-class. иди вики почитай уже или внятно объясни, где ты видишь несостыковки с понятием first-class
_>

_>Michael L. Scott, Programming Language Pragmatics, 3-rd ed., ELSEVIER 2011
_>ISBN 13: 978-0-12-374514-9

_>Page:154

_>3.6.2 First-Class Values and Unlimited Extent

_>In general, a value in a programming language is said to have
_>first-class status if it can be passed as a parameter, returned from a subroutine, or assigned into a variable.
_>Simple types such as integers and characters are first-class values in most programming languages.
_>By contrast, a
_>“second-class” value can be passed as a parameter, but not returned from a subroutine or assigned into a variable,
_>and a
_>“third-class” value cannot even be passed as a parameter.


Попробуем по порядку.

first-class status if it can be passed as a parameter,


#include <iostream>
#include <memory>
using namespace std;

void f(auto) {}

int main()
{
    f([]{});
}


returned from a subroutine, or assigned into a variable

#include <iostream>
#include <memory>
using namespace std;

auto f() { return []{return 1;}; } // returned from a subroutine

int main()
{
    auto l = f(); // assigned into a variable
    return l();
}


Приведённые требования выполняются.
Значит по мнению Michael L. Scott лямбды first-class values
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[10]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 14.05.18 20:10
Оценка:
Здравствуйте, _NN_, Вы писали:


_NN>Попробуем по порядку.

_NN>

first-class status if it can be passed as a parameter,


_NN>
_NN>#include <iostream>
_NN>#include <memory>
_NN>using namespace std;

_NN>void f(auto) {}

_NN>int main()
_NN>{
_NN>    f([]{});
_NN>}
_NN>

А виртуальную функцию как? А экспортировать эту функцию как, перегружать как? То что вы привели шаблон, а не функция.

_NN>

returned from a subroutine, or assigned into a variable

_NN>
_NN>#include <iostream>
_NN>#include <memory>
_NN>using namespace std;

_NN>auto f() { return []{return 1;}; } // returned from a subroutine

auto f(int f) { if (f) return [=]{return f;}; return [=]{return f-1;}; }

И где?



_NN> auto l = f(); // assigned into a variable

Не объявление константы, а присвоение переменной.
 l=f(); l=f(); // не работает


_NN>Приведённые требования выполняются.

и где они выполняются?
Отредактировано 14.05.2018 20:12 kov_serg . Предыдущая версия .
Re[11]: lambda являются first class citizens?
От: _NN_ www.nemerleweb.com
Дата: 14.05.18 20:30
Оценка:
Здравствуйте, kov_serg, Вы писали:

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



_NN>>Попробуем по порядку.

_NN>>

first-class status if it can be passed as a parameter,


_NN>>
_NN>>#include <iostream>
_NN>>#include <memory>
_NN>>using namespace std;

_NN>>void f(auto) {}

_NN>>int main()
_NN>>{
_NN>>    f([]{});
_NN>>}
_NN>>

_>А виртуальную функцию как? А экспортировать эту функцию как, перегдужать как? То что вы привели шаблон, а не функция.

Тогда стоит для начала уточнить требования.
Я не знаю, что автор утверждения говорит насчёт шаблонов, виртуальных функций, экспорта (что такое экспорт ?) и перегрузки (о чём речь?).
Это всё не приводилось в качестве обязательных требований.

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

int main()
{
    auto x = []{};
    
    auto f = [](decltype(x)) {};
    f(x);
}


Собственно виртуальность не проблема:
class A
{public:
     static constexpr auto x = []{};

     virtual void f(decltype(x)) {} // Объявляем
};

class B:public A
{
  void callf()
  {
    f(x); // Вызываем
  }

  virtual void f(decltype(A::x)) override {}  
};


_NN>>

returned from a subroutine, or assigned into a variable

_NN>>
_NN>>#include <iostream>
_NN>>#include <memory>
_NN>>using namespace std;

_NN>>auto f() { return []{return 1;}; } // returned from a subroutine
_>[c]
_>auto f(int f) { if (f) return [=]{return f;}; return [=]{return f-1;}; }
_>

_>И где?
Где что ?
Во первых это не относится к требования first-class из цитаты.
Во вторых оператор ?: требует одинаковые типы, а типы не одинаковые.
Этот код аналогичен
struct A{};
struct B{};

A x(int f)
{
 if (f) return A();
 return B();
}


_NN>>int main()

_NN>>{
_NN>> auto l = f(); // assigned into a variable
_NN>> return l();
_NN>>}
_NN>>[/c]
_>Assigned into variable
_>
_> l=f(); l=f(); // не работает
_>


_NN>>Приведённые требования выполняются.

_>и где они выполняются?
Тут у нас похоже разные трактования 'assigned into a variable'.
Я считаю, что если можно создать объект и передать ему значение, то требование выполняется.
С вашей стороны есть дополнительное требование, которое мне неясно имел ввиду автор или нет, а именно создание пустого значения переменной этого типа и последующее присовение.

Для лямбды копирование запрещено , но есть перемещение
Получается по этой логике тип с приватным конструктором либо с запретом на конструктор копирования или присваивания не является first-class, так ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[12]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 14.05.18 21:01
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Если без шаблоном то очевидно никак нельзя заранее указать тип лямбды потому как он выводится из самой лямбды.

_NN>Однако мы можем указать тип после и передать лямбду в качестве параметра тем самым имея нешаблонную функцию и отвечая требованию 1.
Вы смотрите со стороны C++. Если даже если это реализовано неудачно вы будете настаивать на обратном.
Вот представте что тип для каждого целого числа был уникален. Очень удобно да?

_NN>Во вторых оператор ?: требует одинаковые типы, а типы не одинаковые.

Дык в этом и есть претензия что работать напрямую с ними нельзя. Только через переходники и другие типы.

_NN>Тут у нас похоже разные трактования 'assigned into a variable'.

_NN>Я считаю, что если можно создать объект и передать ему значение, то требование выполняется.
Посмотрите как сделано в других языках и поймёте что в C++ не лучшая реализация.

_NN>Для лямбды копирование запрещено, но есть перемещение

_NN>Получается по этой логике тип с приватным конструктором либо с запретом на конструктор копирования или присваивания не является first-class, так ?
Это уже особенности развития C++(n+1).

Я вот одного не пойму почему каждый считает своим долго защищать глупости которые постоянно добавляют в стандарт.
При этом с пеной у рта доказывать что реализовать можно только так и никак иначе и ещё ссылку на стандарт кинуть.
Как-будто это доказательство, что это истина в последней инстанции. Это напоминает про милион мух которые не могут ошибаться.
Re[5]: lambda являются first class citizens?
От: jazzer Россия Skype: enerjazzer
Дата: 15.05.18 00:20
Оценка:
Здравствуйте, kov_serg, Вы писали:

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


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

J>>Я правильно понимаю, что по твоей логике, уникальные типы не являются first class citizens?
_>Да. Я хочу сначала объявить переменную а потом присвоить. Или присвоить в зависимости от флага одну или другую функцию.
_>Вернуть из функции в из разных return-ов и т.п.

Жжешь

По твоей логике, объекты классов в С++ — не 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[6]: lambda являются first class citizens?
От: kov_serg Россия  
Дата: 15.05.18 05:35
Оценка:
Здравствуйте, jazzer, Вы писали:

J>По твоей логике, объекты классов в С++ — не first class citizens, потому что у них может не оказаться оператора присваивания

Это всего лишь классификация и она ни на что не влияет.
Если не будет оператора присвоения то соответственно это значение будет не first class.
Re[13]: lambda являются first class citizens?
От: _NN_ www.nemerleweb.com
Дата: 15.05.18 06:49
Оценка:
Здравствуйте, kov_serg, Вы писали:

Попробуем заново.

У вас совсем определение первоклассной сущности это:
  • Возможность конструировать тип с конструктором без параметров.
  • Возможность копировать объект через присваивание.
  • Возможность копировать объект через конструктор копирования.

    Очевидно лямбда, являющаяся типов без возможности создания пустого объекта и копирования. не подходит под это определение.
    Если это и так было понятно зачем было поднимать тему ?

    Могу отметить, что большинство классов не имеют возможности копирования.
    Будем всех считать второклассными сущностями ?
  • http://rsdn.nemerleweb.com
    http://nemerleweb.com
    Re[14]: lambda являются first class citizens?
    От: kov_serg Россия  
    Дата: 15.05.18 08:23
    Оценка:
    Здравствуйте, _NN_, Вы писали:

    _NN>Могу отметить, что большинство классов не имеют возможности копирования.

    _NN>Будем всех считать второклассными сущностями ?
    Да если они попадают во второй класс.
    Re[7]: lambda являются first class citizens?
    От: jazzer Россия Skype: enerjazzer
    Дата: 15.05.18 14:35
    Оценка:
    Здравствуйте, kov_serg, Вы писали:

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


    J>>По твоей логике, объекты классов в С++ — не first class citizens, потому что у них может не оказаться оператора присваивания

    _>Это всего лишь классификация и она ни на что не влияет.
    _>Если не будет оператора присвоения то соответственно это значение будет не first class.

    Если она ни на что не влияет, то какой в ней смысл тогда?
    Вот я объявил объект типа int — и это объект первого класса.
    А если я объявлю const int — в него нельзя присвоить, вообще с ним ничего нельзя сделать, кроме как инициализировать и прочитать значение — и что, это объект второго класса?
    Что там такая классификация дает?
    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: lambda являются first class citizens?
    От: jazzer Россия Skype: enerjazzer
    Дата: 15.05.18 15:09
    Оценка:
    Здравствуйте, Максим Рогожин, Вы писали:

    МР>Привет!

    МР>Скажите, пожалуйста, лямбда выражения в C++ являются 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[8]: lambda являются first class citizens?
    От: kov_serg Россия  
    Дата: 15.05.18 15:35
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Что там такая классификация дает?

    Она просто удобна при обучении студентов. Вам она скорее всего не понадобиться.
    Re[9]: lambda являются first class citizens?
    От: jazzer Россия Skype: enerjazzer
    Дата: 15.05.18 15:59
    Оценка:
    Здравствуйте, kov_serg, Вы писали:

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


    J>>Что там такая классификация дает?

    _>Она просто удобна при обучении студентов. Вам она скорее всего не понадобиться.

    Она удобна в плане сравнения возможностей языков. Но при таком сравнении никто не привязывается к деталям конкретных реализаций. Просто — есть ли возможность. Если возможность предоставлена в виде std::function — этого с головой достаточно. Потому что это всего лишь означает, что в других языках std::function сидит везде и неявно, а она небесплатна, а в С++ ты не должен платить за то, что не используешь.
    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[13]: lambda являются first class citizens?
    От: jazzer Россия Skype: enerjazzer
    Дата: 16.05.18 01:15
    Оценка:
    Здравствуйте, kov_serg, Вы писали:

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


    _NN>>Если без шаблоном то очевидно никак нельзя заранее указать тип лямбды потому как он выводится из самой лямбды.

    _NN>>Однако мы можем указать тип после и передать лямбду в качестве параметра тем самым имея нешаблонную функцию и отвечая требованию 1.
    _>Вы смотрите со стороны C++. Если даже если это реализовано неудачно вы будете настаивать на обратном.
    _>Вот представте что тип для каждого целого числа был уникален. Очень удобно да?

    числа друг от друга никак не отличаются. А объекты-лямбды даже с одной сигнатурой имеют разный размер в зависимости от того, что было захвачено.
    А объекты с неизвестным в рантайме размером (и, соответственно, типом) на стек (и в массив, ага) не положишь — так что остается только динамическая память, общий базовый класс и виртуальные вызовы.
    Внезапно, именно это и обеспечивает std::function.
    Так что ты определись, тебе шашечки или ехать.

    _NN>>Тут у нас похоже разные трактования 'assigned into a variable'.

    _NN>>Я считаю, что если можно создать объект и передать ему значение, то требование выполняется.
    _>Посмотрите как сделано в других языках и поймёте что в C++ не лучшая реализация.

    В других языках, скорее всего, лямбд в смысле C++ (т.е. без накладных расходов) вообще нет, только аналог std::function, со всеми сопутствующими расходами.

    Причем в плюсах и писать-то надо не намного больше, чем, скажем, в JS:
    std::function f([&](int i){ return i/3.0; }); // сигнатура int->double вывелась автоматом
    std::cout << f(10) << '\n'; // напечатает 3.33333

    Ты же не будешь говорить, что в JS функции не первоклассные сущности, потому что в нем всегда надо писать function?
    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[13]: lambda являются first class citizens?
    От: _NN_ www.nemerleweb.com
    Дата: 16.05.18 08:30
    Оценка:
    Здравствуйте, kov_serg, Вы писали:

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


    _NN>>Если без шаблоном то очевидно никак нельзя заранее указать тип лямбды потому как он выводится из самой лямбды.

    _NN>>Однако мы можем указать тип после и передать лямбду в качестве параметра тем самым имея нешаблонную функцию и отвечая требованию 1.
    _>Вы смотрите со стороны C++. Если даже если это реализовано неудачно вы будете настаивать на обратном.
    _>Вот представте что тип для каждого целого числа был уникален. Очень удобно да?

    Добро пожаловать в TypeScript:

    const a = 1;
    const b = 2;
    
    if (a == b) { // Operator == cannot be applied to type '1' and '2'  
    }


    Очень удобно.
    http://rsdn.nemerleweb.com
    http://nemerleweb.com
    Re: lambda являются first class citizens?
    От: kov_serg Россия  
    Дата: 04.07.18 14:29
    Оценка:
    Здравствуйте, Максим Рогожин, Вы писали:

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

    Как-то так должны бы были бы выглядеть λ что бы быть first class
    #include <stdio.h>
    
    struct Callback {
      typedef void (*fn_t)(void *ctx); fn_t fn; void *ctx;
      Callback(fn_t fn=0,void* ctx=0) : fn(fn), ctx(ctx) {}
      operator bool () const { return !!fn; }
      void operator() () const { if (fn) fn(ctx); }
      template<class T>Callback(T t) {
        static struct L{T t;L(const T&t):t(t){}static void f(void*ctx){((L*)ctx)->t();}}c(t);
        fn=L::f;ctx=&c;
      };
    };
    
    struct A {
      void fn() { printf("A(0x%016llX).fn()\n",(long long)this); }
      Callback get_fn() {return{[&](){ fn(); }};}
    };
    
    int main(int argc,char** argv) {
      A a; Callback list[3];
    
      list[0]={[&](){ printf("argc=%d argv[0]=%s\n",argc,argv[0]);  }};
    
      list[1]={[=](){
        printf("sizeof(Callback)=%d sizeof(void*)=%d sizeof(int)=%d\n",(int)sizeof(Callback),(int)sizeof(void*),(int)sizeof(int));
      }};
    
      list[2]=a.get_fn(); // тут бы просто a.fn, но нет этож c++
    
      for(auto item:list) item();
    
      return 0;
    }
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.