PVA,
Начну с последнего вопроса, ок?
PVA>В свете изложенных соображений, что мешает програмить на с++ в ФП?
В мелких дозах ничего не мешает, в крупных — 10й закон Гринспуна. Чтобы воспользоваться преимуществами функционального программирования, вам нужно будет создать строительные блоки на C++ и работать используя только эти строительные блоки. Вместе с тем у меня возникают большие сомнения в том, что некоторые строительные блоки реализуемы эффективно и удобно или вообще реализуемы. Кроме того, такой способ приведёт к тому, что вы не сможете воспользоваться большинством оптимизаций, которые делают компиляторы функциональных языков (например, уничтожение промежуточного копирования, хвостовая рекурсия и т.п.).
PVA>Параллелизм
PVA>В условиях независимости от внешнего состояния оно может быть распараллелено и в традиционных случаях. Разве нет?
Да, конечно. До тех пор, пока это будет описываться программистом _явно_.
PVA>Горячая замена кода
PVA>Сериализация не поможет?
Не поможет. Возьмём пример на Яве. Пусть у нас интерфейс CSDescriptor:
public interface CSDescriptor extends Serializable {
/**
* @return descriptor type
*/
String getDescriptorType();
}
Мы берём, и рефакторим до
public interface CSDescriptor extends Serializable {
/**
* @return descriptor type
*/
String getDescriptorType(Object param);
}
Компилируем. Меняем все зависимые от этого интерфейса классы. Компилируем. Дальше выгружаем все объекты этих классов, а также всех зависимых классов, а также всех зависимых от этих классов и т.п. на диск, пишем кастомный загрузчик (который обработает нестыковки), загружаем...

Ещё что-то нужно делать со старыми потоками, а также старыми ресурсами (например, сокетами, коннекшнами к БД). Всё это контролировать настолько тяжело, что больше напоминает закат солнечной системы вручную, причём практически не отличается от перезапуска. Ну и девять девяток при таком подходе уж точно не видать...
PVA>Функции высшего порядка
PVA>А с коленки реализация не подойдет?
PVA>struct op_t
PVA>{
PVA> virtual int operator()(int a, int b) = 0;
PVA>};
PVA>struct op_add : public op_t
PVA>{
PVA> virtual int operator()(int a, int b)
PVA> {
PVA> return a + b;
PVA> }
PVA>};
PVA>void show(int a, int b, op_t & op)
PVA>{
PVA> printf("%d\n", op(a, b));
PVA>}
PVA>int main(int argc, char* argv[])
PVA>{
PVA> op_add add;
PVA> show(4, 5, add);
PVA> return 0;
PVA>}
PVA>Аналогично для приведенного обработчика может быть реализована необходимая схема. Соответсвенно, вот это
PVA>...Мы вынуждены создать два новых типа просто для поддержки различного клиентского кода!...
PVA>и сопутствующий текст выглядит странно.
Мне бы
op_t принимающую любое количество параметров любого типа...

Причём вместо создания экземпляра типа
op_add я хочу просто писать (+).
PVA>Карринг
PVA>#define square(x) pow((x), 2)
... а вместо создания экземпляра типа op_add_xX(2) я хочу писать (+2) (ну или (_ + 2)), вместо создания экземпляра типа op_add_Xx(2) хочу писать (2+) (или (2 + _)), а вместо создания экземпляра op_add_XX(2,3) я хочу писать 2 + 3. Ну и конечно передать полученные функции куда нибудь в ФВП.
PVA>Ленивые вычисления
PVA>А разве оптимизаторы нынешние не делают то же самое?
Если могут — делают, но почти всегда не могут. А не могут, потому что когда вы пишете foo(x, y), то аргументы x и y должны быть вычислены
до того, как управление передастся в функцию foo.
PVA>Абстрагирование от управляющих структур
PVA>Аналогично функциям высшего порядка.
Возможно у вас есть свежая идея. Поделитесь?
PVA>Бесконечные структуры данных
PVA>Шаблоны с++ + метапрограммирование?
Возможно у вас есть ещё одна свежая идея. Мне будет очень интересно.
PVA>Продолжения
PVA>Аналогично функциям высшего порядка.
Здесь если покопать, то лес настолько дремучий, что связываться с этим не захочется. Есть реализация продолжений и на Яве, и на C, и на C#. Но все они неуниверсальны и интрузивны для клиентского кода. Поизвращаться над своим кодом я и так могу, без продолжений (тем более что "продолжения" на списках сделает любой нормальный студент, не слишком сложная задача), а что делать с rt.jar?
PVA>Сопоставление с образцом
PVA>Шаблоны?
Сопоставление с образцом уж точно не реализуемо на шаблонах. Максимум, что можно выжать, это boost::tie.
PVA>Замыкания
PVA>Function makePowerFn(int power)
PVA>{
PVA> int powerFn(int base)
PVA> {
PVA> return pow(base, power);
PVA> }
PVA> return powerFn;
PVA>}
PVA>Function square = makePowerFn(2);
PVA>square(3); // возвращает 9
PVA>Не совсем понятно, каким образом происходит вызов powerFn неявно, аналогично с инкрементом.
Это псевдокод. Можно было написать ещё
Function makePowerFn(int power)
{
return new Function( int powerFn(int base) { return pow (base, power); } );
}
как вариант. Но это тоже не Ява. Идея состоит в том, чтобы вернуть функцию, причём связанную с внешним параметром.
PVA>А реализовано может быть через те же функторы.
Это вы делаете вывод исходя из ошибочного предположения, что функции высшего порядка == функторы. А на самом деле функторами можно
эмулировать ФВП (так же как это делает компилятор написанный на C).
Я с удовольствием послушаю, как вы реализуете на функторах функцию
iterate:
let compose f g x = f(g x) ;;
let rec iterate n f =
if n = 0 then (function x -> x)
else compose f (iterate (n-1) f) ;;
(* использовать можно так *)
let rec power i n =
let i_times = ( * ) i in (* "i_times n" равно функции "умножить на i" n раз *)
iterate n i_times 1 ;;
power 2 8 ;; (* выдаст 256 *)
(ocaml)
Больше чем уверен, что вы вернёте разве что функтор-интерпретатор, который будет инкапсулировать АСТ.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>