Здравствуйте, kov_serg, Вы писали:
J>>Я правильно понимаю, что по твоей логике, уникальные типы не являются first class citizens? _>Да. Я хочу сначала объявить переменную а потом присвоить.
твои хотелки никак не связаны с понятием first class citizen, не мешай всё в кучу
лямбды в плюсах сделали очень легковесными, это жирный плюс
твои хотелки реализуются с помощью std::function, который имеет бОльший оверхед, нежели лямбды и достаточно просто создаются из лямбд
по-моему, по сравнению с теми же bind + placeholders, лямбды в язык вписались довольно гармонично (хотя, синтаксис чудноват, имхо) и любителям перформанса не очень больно
Здравствуйте, uzhas, Вы писали:
U>твои хотелки никак не связаны с понятием first class citizen, не мешай всё в кучу U>лямбды в плюсах сделали очень легковесными, это жирный плюс U>твои хотелки реализуются с помощью std::function, который имеет бОльший оверхед, нежели лямбды и достаточно просто создаются из лямбд
Это first class citizen? Это как для передачи char использовать double.
U>по-моему, по сравнению с теми же bind + placeholders, лямбды в язык вписались довольно гармонично (хотя, синтаксис чудноват, имхо) и любителям перформанса не очень больно
На вкус и цвет карандаши разные.
Здравствуйте, 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
короче, с логикой явные проблемы
Здравствуйте, 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);
Здравствуйте, 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-а ?
Где возможноть передавать назные лямды в одну виртуальную функцию?
Невижу.
Здравствуйте, 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 subroutineint main()
{
auto l = f(); // assigned into a variablereturn l();
}
Приведённые требования выполняются.
Значит по мнению Michael L. Scott лямбды first-class values
_>А виртуальную функцию как? А экспортировать эту функцию как, перегдужать как? То что вы привели шаблон, а не функция.
Тогда стоит для начала уточнить требования.
Я не знаю, что автор утверждения говорит насчёт шаблонов, виртуальных функций, экспорта (что такое экспорт ?) и перегрузки (о чём речь?).
Это всё не приводилось в качестве обязательных требований.
Если без шаблоном то очевидно никак нельзя заранее указать тип лямбды потому как он выводится из самой лямбды.
Однако мы можем указать тип после и передать лямбду в качестве параметра тем самым имея нешаблонную функцию и отвечая требованию 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, так ?
Здравствуйте, _NN_, Вы писали:
_NN>Если без шаблоном то очевидно никак нельзя заранее указать тип лямбды потому как он выводится из самой лямбды. _NN>Однако мы можем указать тип после и передать лямбду в качестве параметра тем самым имея нешаблонную функцию и отвечая требованию 1.
Вы смотрите со стороны C++. Если даже если это реализовано неудачно вы будете настаивать на обратном.
Вот представте что тип для каждого целого числа был уникален. Очень удобно да?
_NN>Во вторых оператор ?: требует одинаковые типы, а типы не одинаковые.
Дык в этом и есть претензия что работать напрямую с ними нельзя. Только через переходники и другие типы.
_NN>Тут у нас похоже разные трактования 'assigned into a variable'. _NN>Я считаю, что если можно создать объект и передать ему значение, то требование выполняется.
Посмотрите как сделано в других языках и поймёте что в C++ не лучшая реализация.
_NN>Для лямбды копирование запрещено, но есть перемещение _NN>Получается по этой логике тип с приватным конструктором либо с запретом на конструктор копирования или присваивания не является first-class, так ?
Это уже особенности развития C++(n+1).
Я вот одного не пойму почему каждый считает своим долго защищать глупости которые постоянно добавляют в стандарт.
При этом с пеной у рта доказывать что реализовать можно только так и никак иначе и ещё ссылку на стандарт кинуть.
Как-будто это доказательство, что это истина в последней инстанции. Это напоминает про милион мух которые не могут ошибаться.
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, jazzer, Вы писали:
J>>Никак, это уникальные типы. J>>Я правильно понимаю, что по твоей логике, уникальные типы не являются first class citizens? _>Да. Я хочу сначала объявить переменную а потом присвоить. Или присвоить в зависимости от флага одну или другую функцию. _>Вернуть из функции в из разных return-ов и т.п.
Жжешь
По твоей логике, объекты классов в С++ — не first class citizens, потому что у них может не оказаться оператора присваивания
Здравствуйте, jazzer, Вы писали:
J>По твоей логике, объекты классов в С++ — не first class citizens, потому что у них может не оказаться оператора присваивания
Это всего лишь классификация и она ни на что не влияет.
Если не будет оператора присвоения то соответственно это значение будет не first class.
У вас совсем определение первоклассной сущности это:
Возможность конструировать тип с конструктором без параметров.
Возможность копировать объект через присваивание.
Возможность копировать объект через конструктор копирования.
Очевидно лямбда, являющаяся типов без возможности создания пустого объекта и копирования. не подходит под это определение.
Если это и так было понятно зачем было поднимать тему ?
Могу отметить, что большинство классов не имеют возможности копирования.
Будем всех считать второклассными сущностями ?
Здравствуйте, _NN_, Вы писали:
_NN>Могу отметить, что большинство классов не имеют возможности копирования. _NN>Будем всех считать второклассными сущностями ?
Да если они попадают во второй класс.
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, jazzer, Вы писали:
J>>По твоей логике, объекты классов в С++ — не first class citizens, потому что у них может не оказаться оператора присваивания _>Это всего лишь классификация и она ни на что не влияет. _>Если не будет оператора присвоения то соответственно это значение будет не first class.
Если она ни на что не влияет, то какой в ней смысл тогда?
Вот я объявил объект типа int — и это объект первого класса.
А если я объявлю const int — в него нельзя присвоить, вообще с ним ничего нельзя сделать, кроме как инициализировать и прочитать значение — и что, это объект второго класса?
Что там такая классификация дает?
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, jazzer, Вы писали:
J>>Что там такая классификация дает? _>Она просто удобна при обучении студентов. Вам она скорее всего не понадобиться.
Она удобна в плане сравнения возможностей языков. Но при таком сравнении никто не привязывается к деталям конкретных реализаций. Просто — есть ли возможность. Если возможность предоставлена в виде std::function — этого с головой достаточно. Потому что это всего лишь означает, что в других языках std::function сидит везде и неявно, а она небесплатна, а в С++ ты не должен платить за то, что не используешь.
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, _NN_, Вы писали:
_NN>>Если без шаблоном то очевидно никак нельзя заранее указать тип лямбды потому как он выводится из самой лямбды. _NN>>Однако мы можем указать тип после и передать лямбду в качестве параметра тем самым имея нешаблонную функцию и отвечая требованию 1. _>Вы смотрите со стороны C++. Если даже если это реализовано неудачно вы будете настаивать на обратном. _>Вот представте что тип для каждого целого числа был уникален. Очень удобно да?
числа друг от друга никак не отличаются. А объекты-лямбды даже с одной сигнатурой имеют разный размер в зависимости от того, что было захвачено.
А объекты с неизвестным в рантайме размером (и, соответственно, типом) на стек (и в массив, ага) не положишь — так что остается только динамическая память, общий базовый класс и виртуальные вызовы.
Внезапно, именно это и обеспечивает std::function.
Так что ты определись, тебе шашечки или ехать.
_NN>>Тут у нас похоже разные трактования 'assigned into a variable'. _NN>>Я считаю, что если можно создать объект и передать ему значение, то требование выполняется. _>Посмотрите как сделано в других языках и поймёте что в C++ не лучшая реализация.
В других языках, скорее всего, лямбд в смысле C++ (т.е. без накладных расходов) вообще нет, только аналог std::function, со всеми сопутствующими расходами.
Причем в плюсах и писать-то надо не намного больше, чем, скажем, в JS:
Здравствуйте, kov_serg, Вы писали:
_NN>> auto l = f(); // assigned into a variable _>Не объявление константы, а присвоение переменной. _>
_> l=f(); l=f(); // не работает
_>
_NN>>Приведённые требования выполняются. _>и где они выполняются?
В функциональных языках типа семейства ML или хаскелла, например, вообще нет переменных.
Там все "переменные" — это рантаймовые константы.
А теперь давайте поговорим про непервоклассность функций в мл.