Здравствуйте, alex_public, Вы писали:
_>Это полная ерунда. Я бы разделил изменения в стандарте C++11 (а C++14 — это всего лишь работа над ошибками в C++11) на следующие пункты:
На самом деле все далеко не так здорово, особенно если сравнивать с шарпом.
_>1. Замыкания/лямбды. Очень важный пункт, позволяющий элементарно реализовывать потрясающие вещи (причём не только из мира ФП). Хотя естественно нечто подобное можно было делать и раньше (см. Boost), но ценой ужасающе кривого кода.
Из тройки C++/Java/C# замыкания/лямбды первыми появились в последнем. И то, что сделали с ними в C++ вызывает.. смешанные чувства. С одной стороны конечно вписали в старый язык, вроде ничего серьезно не поломав. А с другой стороны выглядит вырви глаз и после C# пользоваться таким вообще не хочется. Хотя конечно фломастеры разные.
_>2. Семантика перемещения. Вообще потрясающая вещь, не имеющая прямых аналогов в других языках. Как раз она эффективно решает известную проблему с использованием замыканий без сборщика мусора. Но полезно оно не только для замыканий — с данной техникой производительность приложений на C++ уходит вообще в недостижимый отрыв. Причём что самое интересное, многие старые приложения могут ускориться даже без правки их кода — достаточно их перекомпилировать под новый стандарт.
Скорее просто исправили старый косяк с ссылками, которые были слишком сильно завязаны на семантику указателей. Ну и немного повыносили мозг тем кто стандарт читает.
_>3. Улучшения метапрограммирования (variadic template, constexpr, decltype и т.п.). Это отдельное направление в мире C++, очень активно развивающееся. И кстати говоря не имеющее аналогов в других мейнстрим языках. Правда во многом до сих пор кривое (т.к. изначально шаблоны не для этого придумывались), но работа идёт...
Как минимум C# вполне себе работает с метапрограммированием. Я правда им пользуюсь умеренно, в основном базовые вещи, но по ним вроде одинаково у обоих. Только в шарпе листинги ошибок попроще)) Я не настолько хорошо знаком с Java, но подозреваю, что там тоже может что-то найтись (лямбды же они к себе перетянули).
Здравствуйте, D. Mon, Вы писали:
DM>Здравствуйте, 11molniev, Вы писали:
1>>Как минимум C# вполне себе работает с метапрограммированием.
DM>В каком виде? Кажется, вы с Алексом тут несколько разные вещи себе представляете.
В виде компилятор как сервис. С++ тут нервно курит в сторонке.
Здравствуйте, D. Mon, Вы писали:
1>>Как минимум C# вполне себе работает с метапрограммированием.
DM>В каком виде? Кажется, вы с Алексом тут несколько разные вещи себе представляете.
Здравствуйте, 11molniev, Вы писали:
_>>1. Замыкания/лямбды. Очень важный пункт, позволяющий элементарно реализовывать потрясающие вещи (причём не только из мира ФП). Хотя естественно нечто подобное можно было делать и раньше (см. Boost), но ценой ужасающе кривого кода. 1>Из тройки C++/Java/C# замыкания/лямбды первыми появились в последнем. И то, что сделали с ними в C++ вызывает.. смешанные чувства. С одной стороны конечно вписали в старый язык, вроде ничего серьезно не поломав. А с другой стороны выглядит вырви глаз и после C# пользоваться таким вообще не хочется. Хотя конечно фломастеры разные.
Начинать сравнивать синтаксис можно после проверки приблизительного равенства функциональности. Можно увидеть аналог на C# для данного http://coliru.stacked-crooked.com/a/ce0de866fa9e05bc простейшего кода с полиморфными лямбдами? ) Как только увижу его, можно будет начать разговор об удобстве синтаксиса...
_>>2. Семантика перемещения. Вообще потрясающая вещь, не имеющая прямых аналогов в других языках. Как раз она эффективно решает известную проблему с использованием замыканий без сборщика мусора. Но полезно оно не только для замыканий — с данной техникой производительность приложений на C++ уходит вообще в недостижимый отрыв. Причём что самое интересное, многие старые приложения могут ускориться даже без правки их кода — достаточно их перекомпилировать под новый стандарт. 1>Скорее просто исправили старый косяк с ссылками, которые были слишком сильно завязаны на семантику указателей. Ну и немного повыносили мозг тем кто стандарт читает.
Фраза "исправили старый косяк" подразумевает, что в тоже время было известно правильное решение. Можно узнать в каком именно языке оно присутствовало? )
_>>3. Улучшения метапрограммирования (variadic template, constexpr, decltype и т.п.). Это отдельное направление в мире C++, очень активно развивающееся. И кстати говоря не имеющее аналогов в других мейнстрим языках. Правда во многом до сих пор кривое (т.к. изначально шаблоны не для этого придумывались), но работа идёт... 1>Как минимум C# вполне себе работает с метапрограммированием. Я правда им пользуюсь умеренно, в основном базовые вещи, но по ним вроде одинаково у обоих. Только в шарпе листинги ошибок попроще)) Я не настолько хорошо знаком с Java, но подозреваю, что там тоже может что-то найтись (лямбды же они к себе перетянули).
Я так понял, под метапрограммированием здесь подразумевалось это?
Так вот не стоит путать метапрограммирование и обобщённое программирование — это абсолютно разные парадигмы, предназначенные для решения совершенно разных задач. И да, обобщённое программирование в C# и C++ не сильно отличается. Но здесь то речь не о нём. Хотя возможно кого-то путает тот факт, что для метапрограммирования в C++ в основном используются те же самые шаблоны, что и для обобщённого (и как раз поэтому МП в C++ достаточно кривое, т.к. изначально шаблоны разрабатывались именно для ОП), хотя и по другому. Но из этого точно невозможно сделать вывод о наличие МП в C# — там нет ничего похожего в принципе. )))
_>Начинать сравнивать синтаксис можно после проверки приблизительного равенства функциональности. Можно увидеть аналог на C# для данного http://coliru.stacked-crooked.com/a/ce0de866fa9e05bc простейшего кода с полиморфными лямбдами? ) Как только увижу его, можно будет начать разговор об удобстве синтаксиса...
Мне одному кажется, что по ссылке написан какой-то нечитаемый ад?
Здравствуйте, alex_public, Вы писали:
_>Начинать сравнивать синтаксис можно после проверки приблизительного равенства функциональности. Можно увидеть аналог на C# для данного http://coliru.stacked-crooked.com/a/ce0de866fa9e05bc простейшего кода с полиморфными лямбдами? ) Как только увижу его, можно будет начать разговор об удобстве синтаксиса...
Чудный образчик:
g++ --version && g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
g++ (GCC) 5.2.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8 7 6 5 4 3 2 1
error : "auto" is not allowed here
1> auto tuple = [](auto... args)
error : identifier "args" is undefined
1> return [=](auto f){ return f(args...); };
: error : expected a ")"
1> auto map = [](auto... args)
И т.д., 46 ошибок. VS 2013 тоже не осилила, 15 не держу.
Как работать то должно? Какую задачу (кроме демонстрации лямбд) этот код должен решить, что на входе, что на выходе?
Ну и как выше подметили, не хотелось бы видеть такое в реальных проектах.
_>Фраза "исправили старый косяк" подразумевает, что в тоже время было известно правильное решение. Можно узнать в каком именно языке оно присутствовало? )
Ха! Нужно поискать язык где бы оно отсутствовало. Сам факт лишних копирований был вызван таким подходом к семантике ссылок и увлечением абстракциями ООП. За абстракции всегдла надо платить.
_>Так вот не стоит путать метапрограммирование и обобщённое программирование — это абсолютно разные парадигмы, предназначенные для решения совершенно разных задач. И да, обобщённое программирование в C# и C++ не сильно отличается. Но здесь то речь не о нём. Хотя возможно кого-то путает тот факт, что для метапрограммирования в C++ в основном используются те же самые шаблоны, что и для обобщённого (и как раз поэтому МП в C++ достаточно кривое, т.к. изначально шаблоны разрабатывались именно для ОП), хотя и по другому. Но из этого точно невозможно сделать вывод о наличие МП в C# — там нет ничего похожего в принципе. )))
Технически метапрограммирование есть и в чистом С, через препроцессор. Что ты подразумеваешь под метапрограммированием. Особенно интересно в плане метапрограммирование vs кодогенерация (T4), метапрограммирование vs препроцессор и метапрограммирование vs метаморфизм в реалтайме.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Poopy Joe, Вы писали:
PJ>>В виде компилятор как сервис. С++ тут нервно курит в сторонке.
_>Тогда конечно же можно увидеть какую-нибудь известную библиотеку, реализующую Embedded DSL на базе этой технологии? )
Библиотеками не интересовался, но вот пример. http://alemiralles.blogspot.be/2012/11/roslyn-shopping-cart-part-1.html
Попытки сделать из с++ какой-то метаязык порождают только нечитаемый кошмар, я уж молчу про сообщения об ошибках и при этом все равно крайне ограниченные возможности.
Здравствуйте, 11molniev, Вы писали:
1>Здравствуйте, D. Mon, Вы писали:
1>>>Как минимум C# вполне себе работает с метапрограммированием.
DM>>В каком виде? Кажется, вы с Алексом тут несколько разные вещи себе представляете.
1>Ну как то так: 1>Differences Between C++ Templates and C# Generics (C# Programming Guide) 1>https://msdn.microsoft.com/en-us/library/c6cyy67b.aspx
Это никакого отношения к метапрограммированию не имеет.
Здравствуйте, Poopy Joe, Вы писали:
1>>Ну как то так: 1>>Differences Between C++ Templates and C# Generics (C# Programming Guide) 1>>https://msdn.microsoft.com/en-us/library/c6cyy67b.aspx
PJ>Это никакого отношения к метапрограммированию не имеет.
ОК. А что имеет отношение? В каких языках есть? И чего позволяет достичь, недостижимого в языках с отсутствием этого?
Здравствуйте, 11molniev, Вы писали:
1>Здравствуйте, Poopy Joe, Вы писали:
1>>>Ну как то так: 1>>>Differences Between C++ Templates and C# Generics (C# Programming Guide) 1>>>https://msdn.microsoft.com/en-us/library/c6cyy67b.aspx
PJ>>Это никакого отношения к метапрограммированию не имеет.
1>ОК. А что имеет отношение? В каких языках есть? И чего позволяет достичь, недостижимого в языках с отсутствием этого?
Все что позволяет создавать программы как результат работы программы. До рослина в c# в каком-то виде это было доступно только через рефлексию и expression trees. Есть во многих языках, с++ тут как раз пример где это сделано наиболее убого.
Здравствуйте, Mamut, Вы писали:
_>>Начинать сравнивать синтаксис можно после проверки приблизительного равенства функциональности. Можно увидеть аналог на C# для данного http://coliru.stacked-crooked.com/a/ce0de866fa9e05bc простейшего кода с полиморфными лямбдами? ) Как только увижу его, можно будет начать разговор об удобстве синтаксиса... M>Мне одному кажется, что по ссылке написан какой-то нечитаемый ад?
Это специфичный код, для его понимания нужно понять используемую там конвенцию о кортежах. Вот
Здравствуйте, Poopy Joe, Вы писали:
1>>>Как минимум C# вполне себе работает с метапрограммированием. DM>>В каком виде? Кажется, вы с Алексом тут несколько разные вещи себе представляете. PJ>В виде компилятор как сервис. С++ тут нервно курит в сторонке.
Удобный Clang появился раньше Roslyn'а, не говоря уже об менее удобном GCC.
Здравствуйте, Mamut, Вы писали:
_>>Начинать сравнивать синтаксис можно после проверки приблизительного равенства функциональности. Можно увидеть аналог на C# для данного http://coliru.stacked-crooked.com/a/ce0de866fa9e05bc простейшего кода с полиморфными лямбдами? ) Как только увижу его, можно будет начать разговор об удобстве синтаксиса... M>Мне одному кажется, что по ссылке написан какой-то нечитаемый ад?
Там используется абсолютно стандартная для ФП техника возврата одной лямбды (а точнее замыкания) в качестве результата вычисления другой лямбды. Она используется во многих местах и языках для разных целей. Например с помощью неё можно реализовать альтернативное ООП. ))) Единственно что в данном примере эта техника усилена возможностью лямбд из C++ принимать произвольное число произвольных параметров. Да, так уж вышло, что C++, долго отстававший в данной области, одним прыжком догнал и перегнал другие языки. )))
M>Кстати, что такое [=]?
В квадратных скобках указываются способы захвата переменных в замыкание. "=" — это самый простейший вид, означающий "всё по значению". Но вместо него там может быть что угодно. Например [x=y+z, new_v=move(v)] и т.п. )))
Здравствуйте, 11molniev, Вы писали:
1>Как работать то должно? Какую задачу (кроме демонстрации лямбд) этот код должен решить, что на входе, что на выходе? 1>Ну и как выше подметили, не хотелось бы видеть такое в реальных проектах.
Ну то, что компилятор C++ от MS давно отстал от конкурентов и превратился в убогое недоразумение, ни для кого не новость. А вот для компилятора от Intel похоже кто-то забыл включить поддержку C++14... )
Что касается самого кода, то он демонстрирует альтернативную (т.к. в C++ и так есть std::tuple) реализацию кортежей, на замыканиях. А так же работу с ними (слияние, применение функции). Кстати, этот пример должен быть весьма актуален как раз для C# — там же стандартные кортежи очень забавные, кажется максимум на 8 элементов, да? )))
_>>Фраза "исправили старый косяк" подразумевает, что в тоже время было известно правильное решение. Можно узнать в каком именно языке оно присутствовало? ) 1>Ха! Нужно поискать язык где бы оно отсутствовало. Сам факт лишних копирований был вызван таким подходом к семантике ссылок и увлечением абстракциями ООП. За абстракции всегдла надо платить.
Т.е. снова сравниваем разную функциональность? ) Естественно, что если делать убогую реализацию без RAII и со сборщиком мусора, то нет проблем. Два простейших примера:
1. У нас есть отдельные строки (по гигабайту каждая, для остроты ощущений) и пустой массив строк. Мы хотим положить одну строку в массив. Но чтобы при этом естественно не происходило копирования гигабайта. Ну и само собой при удаление массива все строки в нём должны удаляться.
— C: можно наколбасить руками эффективную реализацию
— Java/C#: работает автоматически, но не эффективно (сборщик мусора со всеми печальными последствиями из этого)
— C++: работает автоматически и эффективно
— так какой там язык давно имел эффективное автоматическое решение данной проблемы?
2. У нас есть объект, инкапсулирующий в себе некое соединение по сети и пустой массив такого же типа. Мы хотим положить этот объект в массив. Естественно мы хотим, чтобы при удаление массива все соединения закрывались.
— C: можно наколбасить руками эффективную реализацию
— Java/C#: можно наколбасить руками эффективную реализацию
— C++: работает автоматически и эффективно
— так какой там язык давно имел эффективное автоматическое решение данной проблемы?
_>>Так вот не стоит путать метапрограммирование и обобщённое программирование — это абсолютно разные парадигмы, предназначенные для решения совершенно разных задач. И да, обобщённое программирование в C# и C++ не сильно отличается. Но здесь то речь не о нём. Хотя возможно кого-то путает тот факт, что для метапрограммирования в C++ в основном используются те же самые шаблоны, что и для обобщённого (и как раз поэтому МП в C++ достаточно кривое, т.к. изначально шаблоны разрабатывались именно для ОП), хотя и по другому. Но из этого точно невозможно сделать вывод о наличие МП в C# — там нет ничего похожего в принципе. ))) 1>Технически метапрограммирование есть и в чистом С, через препроцессор. Что ты подразумеваешь под метапрограммированием. Особенно интересно в плане метапрограммирование vs кодогенерация (T4), метапрограммирование vs препроцессор и метапрограммирование vs метаморфизм в реалтайме.
Да, препроцессор в C тоже является метапрограммированием. Но безусловно на порядок более убогим) Как собственно и все препроцессоры, которые не умеют работать в терминах языка. Это так сказать МП прошлого века)
Любую внешнюю кодогенерацию вообще не имеет смысла упоминать при сравнение языков, т.к. она не имеет никого отношения к данному вопросу. А то такими темпами можно будет включить например пакет Mathematica в C++ (а что, оно же умеет генерировать соответствующий код?). )))
МП в реалтайме является стандартным инструментом (хотя частенько его рекомендуют избегать, т.к. слишком опасная штука) динамических языков. Использовать подобное в статическом языке можно только от жесткой безысходности. )))
В общем, если подвести итог, то можно сказать, что МП:
— в Java/C# просто нет
— в C++ есть, криво-косое
— в D, Nemerle и т.п. есть, нормальное.
Но есть один нюанс: мейнстрим языками тут являются только первые три... )
. Только вместо собственного лексера и парсера на flex+bizon используется готовое решение на базе компилятора C#. Можно пообсуждать плюсы и минусы подобного решения, но к нашей теме дискуссии это пример явно не относится.
PJ>Попытки сделать из с++ какой-то метаязык порождают только нечитаемый кошмар, я уж молчу про сообщения об ошибках и при этом все равно крайне ограниченные возможности.
Да, т.к. изначально шаблоны не были предназначены для МП, то оно получилось в C++ весьма кривым. Но при этом есть существенный нюанс: вся сложность проявляется при создание соответствующего МП кода (т.е. лежит на авторах библиотек), а вот использование его обычно не существенно сложнее (вот разве что сообщения об ошибках бывают печальные, и то если авторы библиотеки не озаботились этим вопросом). Ну и в любом случае даже кривой инструмент лучше никакого (как у остальных мейнстрим языков). )))
Здравствуйте, 11molniev, Вы писали:
PJ>>Это никакого отношения к метапрограммированию не имеет. 1>ОК. А что имеет отношение? В каких языках есть? И чего позволяет достичь, недостижимого в языках с отсутствием этого?
В C# ничего. )))
По нормальному есть скажем в D, Rust, Nim, Scala (кажется — слышал от кого-то, но сам не разбирался), Nemerle. По кривому в C++. )))
Позволяет делать такие вещи как Boost.Spirit или sqlpp11 даже с помощью кривого инструмента. А с помощью прямого можно получать уже что-то вроде шаблонизатора в vibe.d (позволяющего вставки нативного кода прямо на странице, причём с полной дальнейшей оптимизацией (инлайнами и т.п.)).
C# generics do not provide...
C# does not allow...
C# does not support...
C# does not support...
C# does not allow...
C# does not allow...
In C#, a generic type parameter cannot itself...