Функциональное программирование |
Функциональное программирование всегда привлекало меня в противопоставлении к императивному.
Я очень часто обсуждаю различные аспекты функционального программирования на различных ветках на Базарной площади.
Но хотелось бы собрать всех заинтересованный этой темой в одной ветке.
Я думаю что настало время открыть такую тему. И вот почему.
Исторически функциональное программирование появилось практически вместе с императивным.
Вторым языком после фортрана был лисп.
Но увы, функциональное программирование надолго было уделом исследовательских институтов или специализированных приложений (Искусственный Интеллект)
Конечно не надо считать весь мир дураками из за того что развитие пошло по пути языков Алгол семейства.
Для этого были вполне обьективные причины. Функциональные языки слишком близки к человеку и слишком далеки от машины.
Они сьедают в десятки раз больше рессурсов чем императивные языки.
Вспомните претензии, предявляемые к java - первому императивному языку с виртуальной машиной и сборщиком мусора, толкаемому большими корпорациями в mainstream.
Жутко тормозит, и жрет всю память какая есть. А ведь функциональные языки (далее ФЯ) все без иключения имеют сборщик мусора, виртуальную машину.
Многие из них (семейство лисп) еще и динамические, что только усугубляет положение.
Вполне естественно что появившись более полусотни лет назад они надолго опередилли свое время.
Для широкого распространения ФЯ нужны гигабайты дешевой памяти и гигагерцы дешевых процессоров.
Прошло более 50 лет, прежде чем такие требования к железу стали реальностью.
Это время наступило. СЕЙЧАС.
Добро пожаловать в новую эру программирования.
Jack Of Shadows
Всего в теме 5502 сообщения
Добавить свое сообщение
Отслеживать это обсуждение
- Средства разработки. Языки программирования.
- Delphi 4 or Delphi 5
- Что приобрести в качестве средства разработки?
- Delphi6
- Delphi vs PowerBuilder
- Сравнение компиляторов
- Вот и вышла Delphi 7... Вы рады?
№ 2252 26-03-2007 17:08 | |
Ответ на »сообщение 2251« (Илья Ермаков)
___________________________
Я так понял, что Сергей задал конкретный вопрос - что требуется менять вместо "строчки исходного кода".
Ну, в статически линкуемой системе - только список линкуемых модулей.
А, дошл о!
(Смущенно.) Пардон.
Да, я имел в виду, что меняется только список модулей (дополнительных к основным).
№ 2251 26-03-2007 16:48 | |
Ответ на »сообщение 2249« (Сергей Перовский)
___________________________
Ответ на »сообщение 2248« (AVC)
___________________________
>>>Но, мне кажется, тот же самый прием "инверсия импорта" вполне пригоден для легкости (пере)конфигурирования проекта. Главное потенциальное достоинство -- при этом не требуется менять ни строчки исходного кода.
А что требуется менять?
Я так понял, что Сергей задал конкретный вопрос - что требуется менять вместо "строчки исходного кода".
Ну, в статически линкуемой системе - только список линкуемых модулей.
Например, давая команду
DevLinker.Link BlackBox.exe := Kernel CoreHost_Win_A (и еще несколько модулей) - я получаю ББ с захватом памяти у ОС мелкогранулярными блоками, что медленнее, но менее "жадно" - и соответствует режиму "ББ внутри DLL" обычного ББ,
а давая команду
DevLinker.Link BlackBox.exe := Kernel CoreHost_Win_B, я получаю ББ с политикой резервирования всего виртуального пространства и "жадного" выделения страниц у ОС по принципу "я сам себе ОС, вся память моя...", что соответствует стандартному режиму работы обычного ББ.
Ну а линкуя Kernel с CoreHost_Lin и т.п. - я получаю сборку ядра ББ под Линукс, не меняя ни одной строчки кода в самом Kernel и зависимых модулях...
№ 2250 26-03-2007 16:31 | |
Ответ на »сообщение 2249« (Сергей Перовский)
___________________________
Ответ на »сообщение 2248« (AVC)
___________________________
>>>Но, мне кажется, тот же самый прием "инверсия импорта" вполне пригоден для легкости (пере)конфигурирования проекта. Главное потенциальное достоинство -- при этом не требуется менять ни строчки исходного кода.
А что требуется менять?
Кому что. :)
Мне потребовалось в темпе менять туда-сюда всю привязку к аппаратуре (адреса, номера портов, некоторые методы работы с периферией). Причем не ошибиться, т.к. речь идет о ПЗУ.
Вам -- не знаю.
Если Вам (как убежденному прикладнику :) ) никогда не надо менять конфигурацию, хотя бы с целью экспериментального сравнения методов решения задачи, то Вам остается только позавидовать: Вы работаете в идеальных условиях. :)
№ 2249 26-03-2007 16:03 | |
Ответ на »сообщение 2248« (AVC)
___________________________
>>>Но, мне кажется, тот же самый прием "инверсия импорта" вполне пригоден для легкости (пере)конфигурирования проекта. Главное потенциальное достоинство -- при этом не требуется менять ни строчки исходного кода.
А что требуется менять?
№ 2248 26-03-2007 15:21 | |
Ответ на »сообщение 2244« (Сергей Перовский)
___________________________
Ответ на »сообщение 2241« (info21)
___________________________
>>>Вы очень редко используете дин. связывание скорее всего потому, что Ваши инструменты его по-хорошему не поддерживают
Да нет мне разницы, динамическое или статическое.
За все время было ровно 2 случая, когда НЕОБХОДИМО было использование dll.
Поэтому я понимаю полезность проверки, но сам в ней абсолютно не заинтересован. Давайте, наконец, не просто меряться инструментами, а с учетом целей.
Оставим на время в покое многострадальную динамическую загрузку. :)
Недавно Илья Ермаков рассказывал о том, что он условно обозначил как "инверсия импорта".
(Например, сообщение 3462 в обероновской ветке).
Благодаря этому трюку можно менять на лету реализацию той или иной функциональности.
Это, IMHO, позволяет несколько по-иному взглянуть на старый анекдот о споре механика и врача: "А теперь попробуй сделать то же самое при включенном двигателе." :)
Вам на лету не надо. Это ясно.
Но, мне кажется, тот же самый прием "инверсия импорта" вполне пригоден для легкости (пере)конфигурирования проекта. Главное потенциальное достоинство -- при этом не требуется менять ни строчки исходного кода.
Набрел на мысль о таком применении упомянутой "инверсии" из-за сегодняшних рабочих проблем с конфигурацией. (Проблемы-то собственно не такие большие, но всякая лишняя возня в условиях цейтнота довольно неприятна.)
№ 2247 26-03-2007 15:14 | |
Ответ на »сообщение 2246« (Сергей Перовский)
___________________________
Ответ на »сообщение 2245« (info21)
___________________________
>>>стиль и методика работы зависят от логики инструмента.
Вот тут мы принципиально расходимся.
Стиль и методика работы зависят от решаемой задачи и, соответственно, должны определять выбор инструмента.
Ей богу, рубанок не лучше и не хуже разводного ключа. Хотя стиль работы абсолютно разный :)
Мы принципиально расходимся в качестве нашей логики 8))
Вы сделали неявное предположение, что "стиль и методика... " определяется решаемой задачей однозначно.
Насчет метафор -- не сомневаюсь, что сами сообразите, подумашви пару минут, почему Ваша метафора не по делу.
№ 2246 26-03-2007 11:48 | |
Ответ на »сообщение 2245« (info21)
___________________________
>>>стиль и методика работы зависят от логики инструмента.
Вот тут мы принципиально расходимся.
Стиль и методика работы зависят от решаемой задачи и, соответственно, должны определять выбор инструмента.
Ей богу, рубанок не лучше и не хуже разводного ключа. Хотя стиль работы абсолютно разный :)
№ 2245 26-03-2007 11:21 | |
Ответ на »сообщение 2244« (Сергей Перовский)
___________________________
За все время было ровно 2 случая, когда НЕОБХОДИМО было использование dll. ... Давайте, наконец, не просто меряться инструментами, а с учетом целей.
"НЕОБХОДИМО" это, все-таки, интерпретация.
Ведь можно все, что сверх машины Тьюринга объявить не необходимым.
Дело не в меряться инструментами, а в том, что стиль и методика работы зависят от логики инструмента.
№ 2244 26-03-2007 09:09 | |
Ответ на »сообщение 2241« (info21)
___________________________
>>>Вы очень редко используете дин. связывание скорее всего потому, что Ваши инструменты его по-хорошему не поддерживают
Да нет мне разницы, динамическое или статическое.
За все время было ровно 2 случая, когда НЕОБХОДИМО было использование dll.
Поэтому я понимаю полезность проверки, но сам в ней абсолютно не заинтересован. Давайте, наконец, не просто меряться инструментами, а с учетом целей.
№ 2243 26-03-2007 06:55 | |
Ответ на »сообщение 2237« (Geniepro)
___________________________
Ответ на »сообщение 2234« (Jack Of Shadows)
___________________________
GeniePro даже пустился на героический просто поступок, потратил кучу времени и написал на хаскеле задачу с програмисткой олимпиады. С подороным разбором полетов.
Ой, Вагиф, ну прям засмущали... :о)
Не корысти ради, а токмо для пропаганды ФП в целом и Хаскелла в частности... ;о)
А задачка, кстати, ну такая простенькая, прям разминочная...
И почему дельфисты да цеплюсплюсники не могут найти на неё время, показать всю мощь их языков, не пойму... :о))
Да пожалуйста. Практически построчный перевод с Хаскеля с парой фокусов со строками
program ACM_2007_A;
uses Classes, SysUtils;
type
TPairItem = array [0..1] of string;
const
abo2alls : array [1..7] of TPairItem
= (('A', 'A'), ('A', 'O'), ('B', 'B'), ('B', 'O')
, ('AB', 'A'), ('AB', 'B'), ('O', 'O'));
alls2abo : array [1..9] of TPairItem
= (('AA', 'A'), ('AO', 'A'), ('OA', 'A')
, ('BB', 'B'), ('BO', 'B'), ('OB', 'B')
, ('AB', 'AB'), ('BA', 'AB'), ('OO', 'O'));
rh2alls : array [1..3] of TPairItem
= (('+', '+'), ('+', '-'), ('-', '-'));
alls2rh : array [1..4] of TPairItem
= (('++', '+'), ('+-', '+'), ('-+', '+'), ('--', '-'));
procedure getalls(const src : string; var grp, sgn : string);
begin
grp := copy(src, 1, length(src) - 1);
sgn := src[length(src)];
end;
function calc_child(const papa, mama : string) : string;
var
acc, pgrp, mgrp, psgn, msgn : string;
e, e1, e2, e3, e4 : TPairItem;
begin
Result := ' ';
getalls(papa, pgrp, psgn);
getalls(mama, mgrp, msgn);
for e1 in abo2alls do if e1[0] = pgrp then
for e2 in abo2alls do if e2[0] = mgrp then
for e3 in rh2alls do if e3[0] = psgn then
for e4 in rh2alls do if e4[0] = msgn then
begin
acc := ' ';
for e in alls2abo do if e1[1] + e2[1] = e[0] then acc := acc + e[1];
for e in alls2rh do if e3[1] + e4[1] = e[0] then acc := acc + e[1];
if pos(acc, Result) < 1 then Result := Result + acc;
end;
end;
function calc_parent(const parent, child : string) : string;
var
possible_parent : string;
e1, e2 : TPairItem;
begin
Result := ' ';
for e1 in abo2alls do for e2 in rh2alls do
begin
possible_parent := e1[0] + e2[0];
if (pos(child, calc_child(parent, possible_parent)) > 0) then
if (pos(' ' + possible_parent, Result) < 1) then
Result := Result + ' ' + possible_parent;
end;
end;
function calculate(ln : integer; var m, p, c, s : string) : boolean;
function prettyprinter(const txt : string) : string;
begin
Result := trim(txt);
if Result <> '' then Result := '{' + Result + '}' else Result := 'IMPOSSIBLE';
end;
begin
Result := true;
if c = '?' then c := prettyprinter(calc_child(m, p))
else if p = '?' then p := prettyprinter(calc_parent (m, ' ' + c))
else if m = '?' then m := prettyprinter(calc_parent (p, ' ' + c))
else begin
writeln('Incorrect test case in line ', ln, ':'#13#10#13#10, s);
Result := false;
end;
end;
procedure GetOneArg(var s, t : string);
var i : integer;
begin
i := pos(' ', s);
if i < 1 then i := length(s) + 1;
t := copy(s, 1, i - 1);
s := trim(copy(s, i + 1, length(s) - i));
end;
procedure main(const filename : string);
var
f : text;
i : integer;
m, p, c, s : string;
begin
AssignFile(F, filename);
Reset(F);
i := 1;
while not Eof(f) do
begin
Readln(F, s);
GetOneArg(s, m);
GetOneArg(s, p);
GetOneArg(s, c);
if m + p + c = 'END' then break;
if calculate(i, m, p, c, s) then
writeln('Case ', i, ':', m, ' ', p, ' ', c);
i := i + 1;
end;
CloseFile(F);
end;
begin
main('in.txt');
readln;
end.
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|