LINUX.ORG.RU

50 лет языку LISP

 , mccarthy,


1

0

Сегодня знаменательная дата, старейшему после фортрана языку программирования исполнилось 50 лет. Несмотря на столь почтенный для языка программирования возраст, он до сих пор активно развивается, используется в новых проектах и десятилетиями использует концепции, которые в новых языках стали появляться только недавно. Кое-кто считает даже, что когда все остальные языки канут в небытие, LISP останется, потому что это единственный язык, про который можно сказать, что он не придуман, а математически вычислен Джоном Маккарти.

>>> Подробности

anonymous

Проверено: Shaman007 ()
Ответ на: комментарий от yyk

В-общем, контрлисперы ни лиспа на жабе не показали. (ну хоть бы размер исходников голой схемы под jvm народу представили, задача вроде бы не сложная - вместе посмеемся), ни psd/tsd на лор не представили... зато гон на езыг устроили уже практически на 6 страниц )))) Все за них надо делать :)

anonymous
()
Ответ на: комментарий от jtootf

> кстати, что вы находите в устрицах? несколько раз пробовал - ну невкусно же :( или это я чего-то не понимаю,

природный афродизиак ЕМНИП

//trying

anonymous
()

Вот конкретный пример - архиватор, использующий алгоритм LZ. На лиспе (Common Lisp) и на C. Версия на лиспе тормозит страшно и занимает больше строк кода:

(setq DICT_SIZE 1024) (setq BUFF_SIZE 64)

(setq dict (make-array DICT_SIZE :element-type 'string-char)) (setq buff (make-array BUFF_SIZE :element-type 'string-char)) ;///////////////////////////////// (defun init_lz() (setq buff_end 0) (setq dict_start DICT_SIZE) ) ;///////////////////////////////// (defun fill_buff (inp_file)

(do ((i buff_end (+ i 1))) ((= i BUFF_SIZE) t)

(setq rb (read-byte inp_file nil 256)) (if (= rb 256) (return) ) (setf (aref buff i) (int-char rb)) (incf buff_end) ) ) ;///////////////////////////////// (defun shift_buff(n)

(when (= n buff_end) (setq buff_end 0) (return-from shift_buff 0))

(do ((dst 0 (1+ dst)) (src n (1+ src))) ((= src buff_end) t) (setf (aref buff dst) (aref buff src)) )

(decf buff_end n) ) ;///////////////////////////////// (defun shift_dict(n src_buf)

(decf dict_start n) (if (< dict_start 0) (setq dict_start 0))

(do ((dst dict_start (1+ dst)) (src (+ dict_start n) (1+ src))) ((>= src DICT_SIZE) t)

(setf (aref dict dst) (aref dict src)) )

(do ((dst (- dict_size n) (1+ dst)) (src 0 (1+ src))) ((= src n) t) (setf (aref dict dst) (aref src_buf src)) ) ) ;///////////////////////////////// (defun put_code(file dict_pos len symb)

(setq put_pos (mod dict_pos 256)) (setq put_len (+ len (/ (- dict_pos put_pos) 4)))

(write-byte put_pos file) (write-byte put_len file) (write-byte (char-int symb) file) ) ;///////////////////////////////// (defun compress(in_file_name out_file_name)

(setq in_file (open in_file_name :element-type '(unsigned-byte 8))) (setq out_file (open out_file_name :direction :output :element-type '(unsigned-byte 8))) (init_lz)

(loop (setq substr_len 0) (setq dict_pos 0) (fill_buff in_file) (if (= buff_end 0) (return)) (when (= buff_end 1) (put_code out_file 0 0 (aref buff 0)) (return))

(do ((substr_end 1 (1+ substr_end)) (_srch) ) ((= substr_end (1- buff_end)) nil) (setq _srch (search (subseq buff 0 substr_end) dict :start2 dict_start)) (if (null _srch) (return)) (setq dict_pos _srch) (setq substr_len substr_end) ) (put_code out_file dict_pos substr_len (aref buff substr_len)) (shift_dict (1+ substr_len) buff) (shift_buff (1+ substr_len)) ) (close in_file) (close out_file) ) ;///////////////////////////////// (defun decompress(in_file_name out_file_name)

(setq in_file (open in_file_name :element-type '(unsigned-byte 8))) (setq out_file (open out_file_name :direction :output :element-type '(unsigned-byte 8)))

(init_lz) (loop (setq byte_1 (read-byte in_file nil 256)) (if (= byte_1 256) (return)) (setq byte_2 (read-byte in_file nil 256)) (setq symb_int (read-byte in_file nil 256)) (when (or (= byte_2 256) (= symb_int 256)) (princ "Неожиданный конец файла!") (return) )

(setq pos byte_1) (setq pos (+ pos (* (- byte_2 (mod byte_2 64)) 4))) (setq len (mod byte_2 64)) (setq symb (int-char symb_int)) (setq substr (subseq dict pos (+ pos len))) (setq substr (adjust-array substr (1+ len))) (setf (aref substr len) symb) (shift_dict (1+ len) substr) (do ((i 0 (1+ i))) ((= i (1+ len)) t) (write-byte (char-int (aref substr i)) out_file) ) ) (close in_file) (close out_file) ) ;/////////////////////////////////

anonymous
()

архиватор на С: #include <string.h> #include <stdio.h> #define BUFF_SIZE 64 #define DICT_SIZE 1024

char dict[DICT_SIZE]; char buff[BUFF_SIZE]; unsigned int buff_end=0; unsigned int dict_start=DICT_SIZE;

void fill_buf(FILE* in) { buff_end+= fread(buff+buff_end,1,BUFF_SIZE-buff_end,in); }

void shift_buff(unsigned int n) { unsigned int i; for ( i=n;i<buff_end;i++) buff[i-n]=buff[i]; buff_end-=n; }

void shift_dict(unsigned int n,char* src_buf) { unsigned int i; if (n<dict_start) dict_start-=n; else dict_start=0;

for (i=dict_start;(i+n)<DICT_SIZE;i++) dict[i]=dict[i+n];

for (i=0;i<n;i++) dict[DICT_SIZE-n+i]=src_buf[i]; }

void put_code(FILE* out,unsigned int pos,unsigned int len,char S) { char putbuf[3]; putbuf[0]=pos & 0xFF;putbuf[1]=((pos & 768)>>2)| len;putbuf[2]=S; fwrite(putbuf,1,3,out); }

int search(char* substr,unsigned int size) { unsigned int i; for (i=dict_start;i<DICT_SIZE-size+1;i++) if (memcmp(dict+i,substr,size)==0) return i; return -1; }

void compress(FILE* in,FILE* out) { unsigned int i; unsigned int pos,len; do { pos=0; len=0; fill_buf(in); if (buff_end==0) return; if (buff_end==1) { put_code(out,0,0,buff[0]); return; } for (i=1;i<buff_end;i++) { int srch_pos; if ((srch_pos=search(buff,i))>=0) { pos=srch_pos; len=i; } else break; } put_code(out,pos,len,buff[len]); shift_dict(len+1,buff); shift_buff(1+len); } while(1); }

void decompress(FILE* in,FILE* out) { unsigned int pos,len; unsigned char getcode[3]; do { if (fread(getcode,1,3,in)!=3) return;

pos=getcode[0]|((getcode[1]&192)<<2); len=getcode[1]&63;

memcpy(buff,dict+pos,len);

buff[len]=getcode[2]; shift_dict(len+1,buff); fwrite(buff,1,len+1,out); } while(1); }

int main(int argc,char** argv) { FILE *in,*out;

if (argc<4) return -1;

in=fopen(argv[2],"rb"); out=fopen(argv[3],"wb");

if (in==0 || out==0) return -1;

if (argv[1][0]=='c') compress(in,out);

if (argv[1][0]=='d') decompress(in,out);

fclose(in); fclose(out);

return 0; }

anonymous
()
Ответ на: комментарий от jtootf

>у D появился OSS-фронтенд? ссылку можно?

D compiler with front end source:
http://www.digitalmars.com/d/2.0/dmd-linux.html
"dmd/src/dmd/
D compiler front end source under dual (GPL and Artistic) license
"

оно, правда, переписывалось пару раз с D на С++ и назад:
http://www.digitalmars.com/d/2.0/faq.html#dogfood

anonymous
()
Ответ на: комментарий от anonymous

> Вот конкретный пример - архиватор, использующий алгоритм LZ. На лиспе (Common Lisp) и на C. Версия на лиспе тормозит страшно и занимает больше строк кода:

на лиспе сначала научись пейсать, умник.

// vioming

anonymous
()
Ответ на: комментарий от anonymous

>Ну и что Столман сделал для лиспа?

1. не дал опропиертарить лисп-машинам лисп. Когда начался раздрай Symbolics/LMI, он не стал корпоративным самураем, а открыл исходники Emacs.

2. Guile/Scheme, задумка была хорошая: вместо NxM скриптовых движком 1 движок + N трансляторов в схему. Странно, что "не взлетело", Guile тот ещё тормоз.

anonymous
()
Ответ на: комментарий от anonymous

странно, у меня реализация как4-то покороче будет: (compress dest destlenp src srclen) PS откуда такой ужостный премер? Одни LOOP да DO. Хоть без Goto и то хорошо.

anonymous
()
Ответ на: комментарий от anonymous

а можно код в студию? :) сравним

anonymous
()
Ответ на: комментарий от anonymous

> 1. не дал опропиертарить лисп-машинам лисп. Когда начался раздрай Symbolics/LMI, он не стал корпоративным самураем, а открыл исходники Emacs.

Это все его фанатизм etc. к теме не относящееся. Я говорю про конкретно, что он сделал для развития Common Lisp или Scheme. Guile развитием я с трудом могу назвать.

anonymous
()
Ответ на: комментарий от jtootf

полгода-год назад где-то. Исходники фронтэнда в стандартной поставке, до того было отдельно (DMDFE). На базе фронтэнда DMDFE были написаны DParser (разбор D грамматики шаблонами D, во время компиляции, код -- что-то около 700 строк), бекенд к LLVM и ещё 2-3 компилятора D (что-то вроде TinyD -- транслятор D в Cи код).
Грамматика и описание семантики D есть в спецификации (dmd_spec_XXx.pdf)

anonymous
()
Ответ на: комментарий от anonymous

>Because you code is not lispy at all. It is a crap.

+1. Он бы ещё вот так написал (реальный пример на win32 из поделия под названием Bee Lisp)
http://paste.lisp.org/display/68938

anonymous
()
Ответ на: комментарий от anonymous

yacc - dsl для парсеров. Компилятор - это не только парсер, это много чего еще.

anonymous
()
Ответ на: комментарий от yyk

Поковырялся немного в CCL, реализацию DIRECTORY мне лень осиливать, но open и probe-file получилось заставить работать с юникодными именами. Вот http://trac.clozure.com/openmcl/ticket/358#comment:1 объяснение, почему оно само не работает пока что.

anonymous
()
Ответ на: комментарий от jtootf

Нешта сyмневаюсь, что таки алгоритм: [1] Инициализация таблицы цепочек; [2] [.c.] <- пусто; [3] K <- следующий символ в потоке символов; [4] Входит ли [.c.]K в таблицу цепочек? (да: [.c.] <- [.c.]K; go to [3]; ) (нет: добавить [.c.]K в таблицу цепочек; вывести код для [.c.] в поток кодов; [.c.] <- K; go to [3]; ) так сильно и мутно кодировувается на лиспе... Даже на С

anonymous
()
Ответ на: комментарий от jtootf

> кстати, что вы находите в устрицах?

Спроси тов. Guy Steele (личность ну очень в лисперской тусовке известная), почему он среди авторов спецификации языка Java.

anonymous
()
Ответ на: комментарий от jtootf

пожалуйста
по теме: DLisp http://www.dsource.org/projects/dlisp (сыроват)
http://www.dsource.org/projects/languagemachine http://languagemachine.sourceforge.net/ http://languagemachine.sourceforge.net/guide.html (самый, пожалуй, навороченный "компилятор компиляторов" на D, в нем особо интересен пример http://languagemachine.sourceforge.net/d_to_d_translator.html http://languagemachine.sourceforge.net/j2d.html ) -- метапрограммирование на D (ещё см. библиотеку http://www.dsource.org/projects/meta )

anonymous
()
Ответ на: комментарий от anonymous

У него хорошо получается составлять спецификации. Common Lisp, Scheme, Java. Кстати, всем непременно смотреть или читать его "Growing a language".

anonymous
()
Ответ на: комментарий от anonymous

> Странно, что "не взлетело", Guile тот ещё тормоз.

Сам удивился, сам себе и ответил? Потому и не взлетело, что тормоз.

anonymous
()
Ответ на: комментарий от anonymous

> Назови любой популярный язык - и я покажу, какие фичи этого языка позаимствованы из Лиспа.

Можно назвать 2 языка? Си и Хаскел.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

>>кстати, что вы находите в устрицах?

>Спроси тов. Guy Steele (личность ну очень в лисперской тусовке известная), почему он среди авторов спецификации языка Java.

кто такой Гай Стил я знаю, но при чём тут устрицы? анонимус, ты что курил?

jtootf ★★★★★
()
Ответ на: комментарий от anonymous

>пожалуйста по теме: DLisp http://www.dsource.org/projects/dlisp (сыроват) http://www.dsource.org/projects/languagemachine http://languagemachine.sourceforge.net/ http://languagemachine.sourceforge.net/guide.html (самый, пожалуй, навороченный "компилятор компиляторов" на D, в нем особо интересен пример http://languagemachine.sourceforge.net/d_to_d_translator.html http://languagemachine.sourceforge.net/j2d.html ) -- метапрограммирование на D (ещё см. библиотеку http://www.dsource.org/projects/meta )

и ещё раз спасибо. я от D в своё время отказался именно из-за отсутствия открытого компилятора - есть повод ещё раз на него посмотреть, и повнимательней

jtootf ★★★★★
()

Товарищи, блин третий раз спрашиваю, подскажите какой из коммерческих лиспов требует процент от прибыли?

anonymous
()
Ответ на: комментарий от jtootf

А, это я такой тупой. Головой вниз в детстве падал частенько.

Подумал, что тебя удивляет, что лисперы находят в жабах и плюсплюсах.

Ты таки про настоящих устриц спрашиваешь... Ну, в общем, это на любителя. К ним привыкнуть надо. И есть их надо правильно, не абы как. Я, как большой любитель французской кухни, себя привыкнуть заставил, потом ни разу не пожалел - вкусно, блин!

anonymous
()
Ответ на: комментарий от anonymous

> Товарищи, блин третий раз спрашиваю, подскажите какой из коммерческих лиспов требует процент от прибыли?

Allegro Common Lisp.

// minlled

anonymous
()
Ответ на: комментарий от tailgunner

> Можно назвать 2 языка? Си и Хаскел.

Си - структурное программирование (это ко всем потомкам алгола относится, впервые же структурное программирование появилось именно в Лиспе).

Хаскелл - лямбда впервые была реализована в языке программирования именно в Лиспе. Можно конечно же считать, что в Хаскелле она напрямую из математики взялась, но это неверно - до Хаскелля был накоплен громадный опыт реализации функциональных языков, и основная его часть происходит именно из Лиспа. Первые эксперименты по ленивости тоже были в Лиспе.

anonymous
()
Ответ на: комментарий от anonymous

Смотри у них на сайте. Если хочешь покупать, то лучше обращайся к ним, мож договоритесь дешевле.

anonymous
()
Ответ на: комментарий от anonymous

> Смотри у них на сайте. Если хочешь покупать, то лучше обращайся к ним, мож договоритесь дешевле.

Да покупать то пока не собираюсь, так, на будущее, но лицензия что-то больно смахивает на анальное рабство, не много ли они хотят? На LispWorks надо глянуть еще.

anonymous
()
Ответ на: комментарий от anonymous

Ну не знаю, все равно же не ты будешь платить, а твои клиенты. Дороже выйдет, но если что-нибудь серьезное, то наверное и незаметно будет.

anonymous
()
Ответ на: комментарий от anonymous

> Ну не знаю, все равно же не ты будешь платить, а твои клиенты. Дороже выйдет, но если что-нибудь серьезное, то наверное и незаметно будет.

Да так-то оно так, но сама перспектива того что чужой дядя ни с того, ни с сего становится партнером, не радует, это притом что и за саму программу ему надо заплатить!

anonymous
()
Ответ на: комментарий от tailgunner

>> Назови любой популярный язык - и я покажу, какие фичи этого языка позаимствованы из Лиспа.

>Можно назвать 2 языка? Си и Хаскел.

Си под некоторой лисповской инфлюэнцией написан, об этом даже где-то его авторы говорили. Желание управляющие операторы заменить выражениями (тернарный оператор) видно точно.

Absurd ★★★
()
Ответ на: комментарий от anonymous

>На LispWorks надо глянуть еще.

В "историях успеха" LispWorks кстати есть российский проект - какая то софтина для спортивного менеджмента.

Absurd ★★★
()
Ответ на: комментарий от Absurd

> Си под некоторой лисповской инфлюэнцией написан, об этом даже где-то его авторы говорили.

я бы сказал, что нотация похожа, но Си выкручивается за счёт ABI, а лисп -- за счёт самой формы записи. Например, заменяем символы разыменованными указателями, списки -- стеком, атомы -- переменными, и добавляем к переменным типы (при этом правда ломается "полиморфность" элементов списка, но остаётся "полиморфность" указателей).

anonymous
()
Ответ на: комментарий от anonymous

> Си - структурное программирование

Вообще-то Си старше структурного программирования. Кроме того, структурное программирование вообще не фича языка. Что-нибудь еще есть?

> впервые же структурное программирование появилось именно в Лиспе

ЕМНИП, в книге Дейкстры, Хоара и Вирта, которая ввела в обиход этот термин, Лисп не упоминался вообще. Повторюсь - структурное программирование не является фичей языка, структурно можно писать хоть на ассемблере.

> Хаскелл - лямбда впервые была реализована в языке программирования именно в Лиспе.

"Я знал, что ты скажешь это" (c) Лямбда - это вообще математика. С тем же успехом можно сказать, что арифметику все языки позаимствовали из Фортрана.

> Можно конечно же считать, что в Хаскелле она напрямую из математики взялась,

Именно. Хотя бы потому, что лямбду не Маккартни изобрел.

> до Хаскелля был накоплен громадный опыт реализации функциональных языков, и основная его часть происходит именно из Лиспа.

Заимствования. Покажи заимствования.

> Первые эксперименты по ленивости тоже были в Лиспе.

ОК.

Итого: 0 фичей Си, 1 фича Хаскела. Вот это и есть место Лиспа в эволюции языков программирования.

Кстати, основная фича Хаскеля (для меня, по крайней мере) - это суровая статическая типизация. Сравним с динамическим Лиспом (я знаю о Qi)?

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

>я бы сказал, что нотация похожа, но Си выкручивается за счёт ABI, а лисп -- за счёт самой формы записи. Например, заменяем символы разыменованными указателями, списки -- стеком, атомы -- переменными, и добавляем к переменным типы (при этом правда ломается "полиморфность" элементов списка, но остаётся "полиморфность" указателей)

Если в слове "ХЛЕБ" сделать 4 ошибки, то получится слово "ПИВО"

anonymous
()
Ответ на: комментарий от tailgunner

>Кстати, основная фича Хаскеля (для меня, по крайней мере) - это суровая статическая типизация.

Чем тебе так въелась эта статическая типизация? Решает только проблему наличия самой себя. Трата времени на абсолютно ненужный кариес.

Absurd ★★★
()
Ответ на: комментарий от Absurd

>Решает только проблему наличия самой себя

она упрощает проектирование, отбивая тебе руки при попытках сделать "как-нибудь". по-моему, достаточно для занесения в плюсы

jtootf ★★★★★
()
Ответ на: комментарий от anonymous

> Да, именно это я и сказал. А теперь сравни сложность СИНТАКСИСА Лиспа и Хаскелля. В синтаксис Лиспа легко можно воткнуть очень много всякого, что Лиспом ни разу не является. В Хаскелль же - тоже можно, но это будет очень костылисто и коряво, просто от того, что синтаксис сложный.

А теперь барабанная дробь: http://haskell.org/haskellwiki/Quasiquotation

pierre
()
Ответ на: комментарий от anonymous

> Брр. Ужасно выглядит.

Почему-то я не думаю, что парсер чего-нибудь вроде xml или императивного языка (да вобще чего угодно без кучи скобок) на макросах будет выглядеть лучше.

pierre
()
Ответ на: комментарий от anonymous

> Брр. Ужасно выглядит.

Кстати, советую обратить внимание на секцию "Example", можно ли такое делать на лиспе?

> Taking advantage of our quasiquoter, we can re-write our evaluator so it uses concrete syntax:

> eval' :: Expr -> Integer

> eval' [$expr|$int:x|] = x

> eval' [$expr|$x + $y|] = eval' x + eval' y

pierre
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.