Признаю, был несколько неправ - казалось, что твоё восприятие скалы более негативное.
С другой стороны, мне кажется, что вопросы сложности вполне решаемы чисто административными методами. Можно как ограничить список используемых фич, причём это справедливо для обоих языков: как С++ полезно использоваться хотя бы ради деструкторов, так и на скале можно писать «почти как на джаве». Так и спрятать сложности в библиотеки. В обоих случаях, уровень команды можно подтягивать.
При наличии ревью это не видится мне проблемой. Наверное, хватает проектов где этого нет, но от них я предпочёл бы держаться подальше.
Даже с лямбдами имхо побольше закорючек бы было. Ну не буду спорить.
Получается как-то так:
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
template< typename C, typename F >
auto sum_if( C const & v, F f )
{
using R = typename std::decay< decltype(*begin(v)) >::type;
R r{};
for( auto const & x : v )
if( f(x) ) r += x;
return r;
}
int main()
{
vector< double > a = { 1.0, 2.0, 0.0, -2.0, -3.0, 4.0, 1.0 };
cout << sum_if( a, []( auto x ) { return x > 0; } ) << endl;
}
Если заложиться на то, что типом контейнера всегда будет vector, то можно еще проще сделать, без вывода типа R внутри sum_if. А эта реализация может принять не только vector, но и list, deque и т.д.
Код примера LMS делает совсем другое. Там смысл в том, чтобы получить на выходе дерево выражений, которое можно потом обрабатывать различными способами. Например, оптимизировать, сгенерировать код на C или Scala, или интерпретировать.
Если заложиться на то, что типом контейнера всегда будет vector, то можно еще проще сделать, без вывода типа R внутри sum_if. А эта реализация может принять не только vector, но и list, deque и т.д.
Для всех стандартных типов (плюс boost) можно написать просто:
ну, я лично не фанат ООП. но для моих задач оно и не нужно, в 99% случаев. у меня всегда стоит главная задача - оптимизация по скорости. так что развесистую клюкву без особой необходимости я не использую. а вот студенты, только выпустившиеся из ВУЗов, страдают ООП головного мозга. видимо, им там очень долго втирают идею о ценности ООП. я как-то переписывала код, в котором нанятый на работу программист-неофит для реализации обычного массива фиксированной длины для хранения структур создал иерархию аж из четырёх классов, с наследованием, наворотил какие-то итераторы, классы-абстракции и поверх этого всего какую-то аццкую нелинейную логику. и там ещё и ошибся в паре мест, в этом своём густом лесу. в итоге, я это всё выпилила и сделала простой malloc на нужный размер и по смещениям обращения. работать всё стало в сто раз быстрее :) обычно после двух-трёх лет работы с реальными проектами фанатичное пристрастие к ООП проходит. пожалуй, остаётся оно только в Qt-образных проектах, во всякой графической гуйне, и то пока графика не серьёзная. где серьёзная - там OpenGL во все поля и особо густой фигни не понаделаешь.
ну, реализация математики на микроконтроллерах - задача очень даже нужная, временами. и иногда довольно нетривиальная. что касается оптимизации, то математические библиотеки как раз больше всего оптимизируют.
Кстати, упоминая OpenGL, то нынче геометрия подготавливается в буферы видеопамяти и оттуда обрабатывается шейдерами. Язык и рантайм на CPU перестают занимать хоть какое-то время исполнения. Мы успешно писали OpenGL приложения на Java и процессор был почти незанят, да и основная память тоже
Речь не о том, что делает LMS.
Речь о том, что код на Scala некоторыми людьми воспринимается как сложный. Аналогично, некоторый код с шаблонами на C++ некоторыми людьми воспринимается как сложный.
Хотя все это очень относительно.
Ну, а раз речь пошла про LMS, то пример на стартовой странице может заинтересовать тех, кому по неволе приходится разгонять тормозной код на JVM. В C++ показанный мной вариант без каких-либо усилий со стороны программиста самим компилятором развернется в то, что показано в LMS-ном примере в качестве демонстрационного результата.
Т.е., наверное, LMS может гораздо более крутые вещи. Наверное. Но показали на стартовой странице какую-то фигню, которую в языках, заточенных под производительность, ни во что преобразовывать не нужно.
Пример неоптимальный, т.к. написан сходу, но позволяет использовать как обычные лямбды, так и короткую запись.
Макросы зло. Уж лучше поколдовать с placeholders вида _1, _2 и т.д.
Тогда выражение _1 > 0 будет автоматически преобразовываться в функтор, который пойдет на вход sum_if как и лямбда-функция.
Не освоил еще C++14 в должной степени, можно короче:
template< typename C, typename F >
auto sum_if( C const & v, F f )
{
std::decay_t< decltype(*begin(v)) > r{};
for( auto const & x : v )
if( f(x) ) r += x;
return r;
}
Если я правильно помню, то запись T v; приводит к созданию переменной v типа T с неинициализированным значением, если T является элементарным типом (вроде int, double или указатель на что-то). Тогда как запись T v{}; (или T v(()); в C++03) для примитивного типа инициализирует v дефолтным значением (0 для int, 0.0 для double, nullptr для указателя). Но это если я правильно помню :)
Если я правильно помню, то запись T v; приводит к созданию переменной v типа T с неинициализированным значением, если T является элементарным типом (вроде int, double или указатель на что-то).
Блин, точно, к концу дня голова уже не варит. Пойду отдыхать.
видимо, им там очень долго втирают идею о ценности ООП.
И не только студентам. Вот цитата из учебника по с# (Фроловых):
Однако объектно-ориентированный подход, предлагаемый языком C++, значительно облегчает создание программ, в результате чего обоснованность использования классического языка С при создании новых программ представляется нам весьма сомнительной. Более того, начиная изучение программирования с процедурного, а не объектно-ориентированного языка, можно приобрести вредные привычки процедурного программирования. Эти привычки в дальнейшем затруднят изучение современных объектно-ориентированных и компонентно-ориентированных технологий.
По-идее, при обучении нужно объяснять студенту, что ооп это просто надстройка. При желании ооп можно присобачить к любому стандартному процедурному языку. Я никогда ничего не писал на ооп (потому что бейсик и потому что скрипты), но вполне себе представляю как это сделать (как присобачить ооп к не ооп).