G>> Это единственный неакадемический ФЯ.
АХ>Я бы назвал Common Lisp тоже вполне практическим.
У CL есть одна проблемка — неоднозначность реализаций. То есть да, выучить, как писать макросы, например, можно в любой реализации. Но вот ни в threading ни в работу со строками уже не полезешь, потому что они для разных реализаций разные.
Тут правда, все упирается в то, что подразумевается под "выучить ФЯ".
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, <Аноним>, Вы писали:
[skip] VD>Это хорошо... что ты плоский и зеленый, тфу ты, анонимный и никому неизвестный. Ни то стройные ряды дубокодеров будут шириться до кончины рода человеческого.
Здравствуйте, Андрей Хропов, Вы писали:
АХ>Здравствуйте, Gaperton, Вы писали:
G>>Во-вторых, это, к сожалению, пока единственный ФЯ, на котором не только говорят,
G>> но и делают промышленный софт.
АХ>А как же Common Lisp? Он уж пораспространеннее Erlangа будет в коммерческих приложениях.
Ммм, а можно хоть примерный список? Про Эрланг вот видел, а про CL...
АХ>>А как же Common Lisp? Он уж пораспространеннее Erlangа будет в коммерческих приложениях.
К>Ммм, а можно хоть примерный список? Про Эрланг вот видел, а про CL...
VD>>Да и какой Паскаль? Виртовский? Еги реализацию и найти то уже не просто. А Дельфи будет мало чем отличаться от Явы/C# скажем. CS>Чистый Паскаль найти легко. Тот же FreePascal например.
Чистый??? ТАм Delphi-расширений до фига, Apple Object Pascal, GNU Pascal...
Вот уж совсем он не чистый.
Из относительно чистых — можно попробовтаь скачать Turbo Pascal 1.0 — едва ли там много чего добавить успе Кан тoгда
Аноним 320 wrote: > VD>>Да и какой Паскаль? Виртовский? Еги реализацию и найти то уже не > просто. А Дельфи будет мало чем отличаться от Явы/C# скажем. > CS>Чистый Паскаль найти легко. Тот же FreePascal например. > > Чистый??? ТАм Delphi-расширений до фига, Apple Object Pascal, GNU Pascal... > Вот уж совсем он не чистый. > > Из относительно чистых — можно попробовтаь скачать Turbo Pascal 1.0 — > едва ли там много чего добавить успе Кан тoгда
В режим турбо паскаля Free Pascal Compiler загнать можно.
>> Из относительно чистых — можно попробовтаь скачать Turbo Pascal 1.0 — >> едва ли там много чего добавить успе Кан тoгда R>В режим турбо паскаля Free Pascal Compiler загнать можно.
Опять же — какого ?
Я же первую версию TP упомянул не из-за любви к программам в 60 КБ весом.
Просто тогда среди всех TP там должно быть наименьшее количество расширений.
Еще можно попробовать найти UCSD PAscal.
А Free Pascal делался с максимальной совметсимостью и "загнать" его можно — вот только обрезать все фичи до TP 1.0 — вряд ли.
И учить программированию, когда перед паскалевским кодом будем десяток строчек обрезающих компилятору разные гланды — совсем не наглядне будет
Здравствуйте, Андрей Хропов, Вы писали:
G>> но и делают промышленный софт.
АХ>А как же Common Lisp? Он уж пораспространеннее Erlangа будет в коммерческих приложениях.
Не будет он пораспространеннее Erlang-а в коммерческих приложениях. Даже близко. На Эрланг написано в разы больше коммерческого кода, чем на любом ФЯ, тут даже сравнивать глупо. Простой тест — задайтесь вопросом, какой коммерческий софт обычно ( ) пишут на CLisp, когда думают его коммерчески применить. Для Эрланга несложно ответить на этот вопрос, Lisp же применяется эпизодически где попало. У него даже устоявшейся ниши применений нет. Массово его применяли во времена программы СОИ, в рамках заказов американского министерства обороны. В системах "военного искусственного интеллекта". Даже LISP-процессоры делали. Ушла вместе с Рейганом СОИ — и все. Да и то — коммерческим этот софт можно назвать с большой натяжкой. Он заказной.
Сейчас пытаюсь изучить схему по scip.
Видимо, моей ошибкой при разборе злых примеров и выполнении упражнений были попытки представить рекурсию в уме.
Не делайте этого без бумажки!
Или это у меня с абстрактным мышлением что-то не в порядке?
Носок исчез в гильбертовом пространстве. Туда ему и дорога.
Здравствуйте, last shinji, Вы писали:
LS>Сейчас пытаюсь изучить схему по scip. LS>Видимо, моей ошибкой при разборе злых примеров и выполнении упражнений были попытки представить рекурсию в уме. LS>Не делайте этого без бумажки!
Да на первых порах и императивную программу без бумажки трудно представить. А потом...
LS>Или это у меня с абстрактным мышлением что-то не в порядке?
Вот этого точно сказать нельзя (надеюсь, что впроядке ) . Тут нужно не абстрактное мышление (все эти ФЯ-специфические заморочки понятны любому умному человеку), нужна именно привычка думать определённым образом. Некоторые задачи потом в функциональном стиле думаются даже проще, чем в в императивном.
Здравствуйте, Mamut, Вы писали:
CC>>Что может быть проще отсутствия синтаксиса (который, соответственно, не надо изучать)?
M>Потому что надо знать, почему я обязан писать так: M>
M>(quote (1 2 3 4 5))
M>
Тут действует единственное общее правило - первый аргумент списка — это команда, все последующие — ее аргументы.
Поэтому зная, что (quote (1 2 3 4)), ты заодно знаешь, что (fib 20), (+ 1 2), (= 3 4) etc.
M>Для того, чтобы понять, например, следующее выражение, надо знать именно синтаксис и как он работает: M>
M>(let ((x 2))
M> (+ x 3))
M>
let — это макрос. Означает он вот что: ((lambda (x)(+ x 3) 2).
Синтаксис тут прежний — команда let принимает аргументы — первый(список-списков): ((x 2)) и второй(выражение): (+ x 3). Синтаксис тут совершенно прежний, а знание того, что let нужно вызывать с двумя аргументами, это не знание синтаксиса, а, скорее, знание API
Здравствуйте, konsoletyper, Вы писали:
K>Вот этого точно сказать нельзя (надеюсь, что впроядке ) . Тут нужно не абстрактное мышление (все эти ФЯ-специфические заморочки понятны любому умному человеку), нужна именно привычка думать определённым образом. Некоторые задачи потом в функциональном стиле думаются даже проще, чем в в императивном.
Вот как раз сейчас передо мной встал такой вопрос.
Нужно ли представлять рекурсию во всех деталях, или изначально нужно пытаться формулировать задачу в терминах рекурсии, не вдаваясь в детали того, как она развернется и свернется обратно?
Довольно сложно представить в уме рекурсию такого рода:
(define (permutations s) (if (null? s)
(flatmap (lambda (x)
(map (lambda (p) (cons x p))
(permutations (remove x s))))
s)))
а на бумажке лень >_<.
Второй подход выглядит более рационально, но при таком подходе осознание того, как же работает процедура не приходит.
Насколько необходимо такое осознавание?
Носок исчез в гильбертовом пространстве. Туда ему и дорога.
Здравствуйте, last shinji, Вы писали:
LS>Вот как раз сейчас передо мной встал такой вопрос. LS>Нужно ли представлять рекурсию во всех деталях, или изначально нужно пытаться формулировать задачу в терминах рекурсии, не вдаваясь в детали того, как она развернется и свернется обратно?
LS>Второй подход выглядит более рационально, но при таком подходе осознание того, как же работает процедура не приходит. LS>Насколько необходимо такое осознавание?
Смотря что понимать под "осознанием". Если имеется ввиду некоторая последовательность исполнения инструкций на уровне операций с элементами списка — то, ИМХО, это рецедив императивного мышления. Но, естественно, нужно понимать что твориться в программе: ага, вот тут map — это значит, что функция, переданная как первый аргумент, применится к каждому элементу списка и породит список результатов применений; ну и т.д.
Мне кажется, здесь лучше "думать" на уровне списков, а не их элементов: выполнили что-то над данным списком и вызвали ту же самую обработку для подсписков на 1 элемент короче, обеспечив правильную "подклейку" результатов этих новых вызовов.
(Блин, сколько в Лиспе скобок (только не бейте, дяденьки))
Почти точное повторение приведённой SICPовской реализации на Хаскелле
permutations :: Eq a => [a] -> [[a]]
permutations [] = [[]]
permutations xs = concatMap (\x -> map (\ys -> x : ys) (permutations (remove x xs))) xs
where
remove u us = filter (\x -> x /= u) us
-- concatMap это flatmap, [] это nil, : это cons (в инфиксной форме)
-- remove взят со следующий страницы SICP и хаскеллизован
Внутренние лямбды заменяем сечениями, а избыточные скобки — инфиксным оператором $ (задаёт низкий приоритет для применения функции):
permutations xs = concatMap (\x -> map (x :) $ permutations $ remove x xs) xs
where
remove u us = filter (/= u) us
Видим, что remove ни фига не сокращает запись; избавляемся от него:
Я чуствую, что Трурль бы пошёл дальше в этом, как его, рефакторинге, что ли? О, придумал: рехаскеллинге. И сделал бы permutations полную анлямбду.
Кстати, этот SICPовский permutations странненько будет работать на списке с повторяющимися элементами (из-за того, что remove убирает не 1 элемент, а все элементы с данным значением).
permutations [] = [[]]
permutations xs = concatMap (permWithFirst xs) xs
where-- возвращает все пермутации xs с отброшенным x, а затем
-- добавляет этот x в начало каждой пермутации
permWithFirst xs x = map (x:) $ permutations $ filter (/=x) xs
Ага! Чтобы получить все перестановки x:xs делаем так:
Берём все перестановки xs (это rs), нарезаем их по-всякому (splits), и засовываем x между левым и правым обрезками (ps ++ x:qs).
Класс. Компрехеншен — сила!
Класс!
Переписал на python получилось только немного длиннее:
def split(xxs):
if not xxs:
return [([], [])]
return [([], xxs)] + [([xxs[0]] + ps, qs) for ps, qs in split(xxs[1:])]
def perm(xxs):
if not xxs:
return [[]]
return [ps + [xxs[0]] + qs for rs in perm(xxs[1:]) for ps, qs in split(rs)]
А вот если попытаться работать с итераторами и генераторами, получается уже не так лаконично:
def split2(xxs):
xs, xxs = itertools.tee(iter(xxs))
try:
x = xs.next()
yield [], list(xxs)
for ps, qs in split2(xs):
yield [x] + ps, qs
except StopIteration:
yield [], []
def perm5(xs):
xs = iter(xs)
try:
x = xs.next()
for rs in perm5(xs):
for ps, qs in split2(rs):
yield ps + [x] + qs
except StopIteration:
yield []