LINUX.ORG.RU
Ответ на: комментарий от bugmaker

> я отрицаю. Хотя претензий болше не к самому наречию а к реализации, но всёодно это далеко нелисп.

А что не в порядке с реализацией?

Круто. Теперь пофлеймите между собой.

На самом деле все разговоры про питон были ловушкой. Я сразу понял что таких ветеранов как bugmaker и yyk перефлеймить не удасться, и искал повод чтобы стравить их между собой :-)

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

Ну вот, теперь точно флейму конец... :)

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

:D

С реализацией мнозе чё нетак. Траблы с оперативой например и легендарные тормозы. Даже несмотря на то, чё многие фрагменты нутра питона написаты на сях а cmucl (?почти?) полносью на се самом, питон намного тормознее в целом.

зачем перефлеймивать? Я-то думал мы тут обсуждаем а не флеймируем.

А стравливать ИМХО безполезно. Два умных чела всегда поймут друх друха.

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

> На самом деле все разговоры про питон были ловушкой.

Так я что, ветряной мельнице дубиной махал? 8-О

:))

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

> С реализацией мнозе чё нетак. Траблы с оперативой например и легендарные тормозы. Даже несмотря на то, чё многие фрагменты нутра питона написаты на сях а cmucl (?почти?) полносью на се самом, питон намного тормознее в целом.

Про оперативку уже разобрали. Это non-issue

Питон тормозит из-за динамической типизации. Python + psyco (JIT) может работать до ~100 раз быстрее, но основная надежда на PyPy, питон написаный на питоне и который переводится в статически типизованый код, там где код действительно типизован статически. Сейчас у них питон работает в 3.5 раза медленне чем C.

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

гы. А я сразу понял чёто нетак. Бо полюбому питон с лиспом сравнивать смехотворно.

давайте теперь про бап штоли.

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

> Про оперативку уже разобрали. Это non-issue

аха, разобрали. Я тож думаю чё это не issue а просто лажа.

> Питон тормозит из-за динамической типизации

а лисп нетормозит :P

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

>> Питон тормозит из-за динамической типизации

> а лисп нетормозит :P

Кстати, о типизации,а в Лиспе какая типизация? Именно динамическая? Тогда из-за чего он не тормозит? Или статическая но с type-inference?

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

Динамическая. И на си-подобном участке кода будет тормозить по сравнению с тем-же си. Но в _некоторых_ реализациях компилятор при указании типов данных и соответствующих опций компилятору может генерить код практически идентичный си-шному.

yyk ★★★★★
()
Ответ на: комментарий от ero-sennin

> Справедливости ради, надо сказать, что и для Питона есть Pyrex. :)

(ожидая волну народного гнева) Справедливости ради надо сказать, в cmucl/sbcl это есть "в любое время в любом месте", а для питона - кастыль! (me прячется от тухлых помидоров)

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

> файловый ввод-вывод у clisp кстати быстрее.

Угу, и с большими числами он неплохо работает (одна из "голубых мечт" - прикрутить к sbcl для больших чисел gmp+mpfr, но когда я ещё с vop-ами, оптимизацией и прочим разберусь... :( Да и нафиг это не надо - прикрутить через ffi - и всё :-Е

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

Динамическая типизация, но сильная (strong). Это важно. И компиляторы 
позволяют оптимизировать код, как хочешь. Вот SBCL. Дампы не мои.
Мне было лень самому все это делать. Каждый может сам поиграться. :)

Сначала просто без типов.

CL-USER> (defun foo (a b)
           ;; simple addition procedure; generates lots of assembly
           (+ a b))
FOO
CL-USER> (disassemble 'foo)
; 0AB63811:       8B55F4           MOV EDX, [EBP-12]          ; no-arg-parsing entry point
;       14:       8B7DF0           MOV EDI, [EBP-16]
;       17:       E81CC949F6       CALL #x1000138             ; GENERIC-+
;       1C:       8BE3             MOV ESP, EBX
;       1E:       8B4DF8           MOV ECX, [EBP-8]
;       21:       8B45FC           MOV EAX, [EBP-4]
;       24:       83C102           ADD ECX, 2
;       27:       8BE5             MOV ESP, EBP
;       29:       8BE8             MOV EBP, EAX
;       2B:       FFE1             JMP ECX
;       2D:       90               NOP
;       2E:       90               NOP
;       2F:       90               NOP
;       30:       CC0A             BREAK 10                   ; error trap
;       32:       02               BYTE #X02
;       33:       18               BYTE #X18                  ; INVALID-ARG-COUNT-ERROR
;       34:       CD               BYTE #XCD                  ; EBX
;       35:       CC0A             BREAK 10                   ; error trap
;       37:       02               BYTE #X02
;       38:       18               BYTE #X18                  ; INVALID-ARG-COUNT-ERROR
;       39:       4D               BYTE #X4D                  ; ECX
;
NIL

Включаем оптимизацию. И жестко типизируем. Математика на LISP так
и пишется.

CL-USER> (defun foo (a b)
           ;; optimized addition procedure; much leaner assembly
           (declare (optimize (speed 3) (safety 0) (debug 0)))
           (declare (type fixnum a b))
           (the fixnum (+ a b)))
FOO
CL-USER> (disassemble 'foo)
; 0C267EDE:       01FA             ADD EDX, EDI               ; no-arg-parsing entry point
;       E0:       8D65F8           LEA ESP, [EBP-8]
;       E3:       F8               CLC
;       E4:       8B6DFC           MOV EBP, [EBP-4]
;       E7:       C20400           RET 4
;       EA:       90               NOP
;       EB:       90               NOP
;       EC:       90               NOP
;       ED:       90               NOP
;       EE:       90               NOP
;       EF:       90               NOP
;       F0:       CC0A             BREAK 10                   ; error trap
;       F2:       02               BYTE #X02
;       F3:       18               BYTE #X18                  ; INVALID-ARG-COUNT-ERROR
;       F4:       4D               BYTE #X4D                  ; ECX
;
NIL
CL-USER>

А вот Allegro генерит
^^^^^^^^^^^^^^^^^^^^^

(defun add (x y)
  (declare (optimize (speed 3) (safety 0)))
  (declare (fixnum x y))
  (the fixnum (+ x y)))

CL-USER> (disassemble 'add)
;; disassembly of #<Function ADD>
;; formals: X Y

;; code start: #x7374dc34:
   0: 03 c2    addl        eax,edx
   2: f8         clc
   3: 8b 75 fc movl        esi,[ebp-4]
   6: c3         ret
   7: 90         nop
; No value

;; the function is essentially just an ADD instruction!

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

Может быть, ламерский вопрос, но всё же...

Как соотносится

> жестко типизируем

и

> (safety 0)

?

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

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

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


По идее -- да. Я практически с этой стороной не возился плотно. На 
уровне игрушки потыркал -- смотрел, как он с FPU работает и пр.  
Однако сейчас проверил кое-что:


* (defun foo (a b)
           ;; optimized addition procedure; much leaner assembly
           (declare (optimize (speed 3) (safety 0) (debug 0)))
           (declare (type fixnum a b))
           (the fixnum (+ a b)))

FOO


* (foo 3 5)

8

* (foo "d" "f")
#<unknown immediate object, lowtag=#b110, widetag=#xC6 {14FE6CC6}>

*

Ругается. Так что, возможно, если при пользовании функциями 
неправильный тип нарисовался, то сообщит что-то.

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

> Ругается. Так что, возможно, если при пользовании функциями неправильный тип нарисовался, то сообщит что-то.

Тогда это не может компилироваться в одну инструкцию "add" %)

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

Функция - может, а вот её вызов... ;)

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

Причем в Си/Си++ она _реально_ в одну инструкцию компилируется ;) А в Lisp там еще и ret есть :-P

Но в Си/Си++ компилятор типы проверяет, так что мусора на входе не будет, если ты сам не захочешь ;)

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

>Тогда это не может компилироваться в одну инструкцию "add" %)

Ну если подумать, то, скорее всего, он ругается на более раннем этапе. Ведь еще же есть цепочка событий, которая идет от REPL. :) Как только я в REPL написал (foo "2" "3"), он пытается засунуть эти вещи в регистры, которые в сложении учавствуют. Видит, что тип не тот (неупаковываемый в понятие fixnum), и раппортует. Я попробовал не REPL, а вызов foo из другой функции. При указании чисел с плавающей точкой SBCL также ругнулся. Так что думаю, ругается он еще до вызова функции, а в самой функции проверок нет, как видишь. Ничего более точного сказать не могу. Этой стороной я плотно не занимался пока.

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

> Причем в Си/Си++ она _реально_ в одну инструкцию компилируется ;) А в Lisp там еще и ret есть :-P

Это если инлайн. А инлайн там из-за скудности макросов :P

> Но в Си/Си++ компилятор типы проверяет,

Дык в лиспе тоже может проверить при желании

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

>> Причем в Си/Си++ она _реально_ в одну инструкцию компилируется ;) А в Lisp там еще и ret есть :-P

> Это если инлайн. А инлайн там из-за скудности макросов :P

Скудости, щедрости - не важно. Главное, что в реально одну инструкцию :)

>> Но в Си/Си++ компилятор типы проверяет,

>Дык в лиспе тоже может проверить при желании

В каком из Лиспов? Что-то я не помню в Scheme объявления типов аргументов. Или глобальный type inference? Тоже что-то не слышал о таком в Лиспе.

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

> Скудости, щедрости - не важно. Главное, что в реально одну инструкцию :)

Дык запихай в макрос вместо, будет и в лиспе.

> В каком из Лиспов?

А про какой мы теперь обсуждаем где (declare (type fixnum a b))

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

>> Скудости, щедрости - не важно. Главное, что в реально одну инструкцию :)

>Дык запихай в макрос вместо, будет и в лиспе.

Как насчет проверки типов параметров макроса?

>> В каком из Лиспов?

>А про какой мы теперь обсуждаем где (declare (type fixnum a b))

Ну ни слова в простоте... :( Речь шла о Steel Bank CL, но является ли это фишкой _всех_ CL?

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

> Речь шла о Steel Bank CL, но является ли это фишкой _всех_ CL?

Это является "фишкой" CL (стандарта), но некоторые реализации (cLisp например) на многие объявления "кладут"

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

> Как насчет проверки типов параметров макроса?

не трабла, хоть одново, хоть половины хоть всех скопом

[1]> (defmacro tst (a b) `(format t "~S ~S~%" (the fixnum ,a) ,b))
TST
[2]> (tst 1 2)
1 2
NIL
[3]> (tst 1 "2")
1 "2"
NIL
[4]> (tst "1" "2")

*** - THE: "1" при вычислении возвратила следующие значения ("1"), не принадлежащие типу FIXNUM
Break 1 [5]> 


> но является ли это фишкой _всех_ CL?

не.

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

>> Как насчет проверки типов параметров макроса?

> не трабла

Хм... а то, что все проверяемые значения - литералы, это, конечно, чистая случайность? ;)

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

> Хм... а то, что все проверяемые значения - литералы, это, конечно, чистая случайность? ;)

не понел, а кем оне должны быть?

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

как ты представляеш себе макрос с переменными? их же значение может быть неопределено на момент компиляции ну ваще. Макросы код на лиспе генерят есличё...

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

> Макросы код на лиспе генерят есличё...

Это понятно

> как ты представляеш себе макрос с переменными?

ХЗ. Я вообще Лисп плохо знаю. Твоими руками я пытаюсь решить такую задачу: обернуть некую функцию в макрос, который выдавал бы ошибку (на этапе трансляции!), если аргумент функции имеет не тот тип. Понятно, что аргумент может быть как аргументом, так и литералом. Можно ли такое сделать?

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

> Твоими руками я пытаюсь решить такую задачу: обернуть некую функцию в макрос, который выдавал бы ошибку (на этапе трансляции!), если аргумент функции имеет не тот тип.

Ох уж эта динамическая типизация... Статическая типизация и ocaml рулят.

PS. Ну надо же развивать флейм...

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

> Ох уж эта динамическая типизация...

Аминь, брат.

> Статическая типизация и ocaml рулят.

Насчет статической типизации - аминь, а Ocaml - он еще маргинальнее Лиспа.

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

> PS. Ну надо же развивать флейм...

Да мы и так уже гордимся своими успехами во флеймостроении 8)

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

> Понятно, что аргумент может быть как аргументом, так и литералом.

Во время выполнения макры некоторую обработку параметров можно вести, но, как правило, это касается только значений или списков. С литералами хуже: текущее пространство имен и т.п. Не видел. Попробуйте... :)

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

Кстати о статической типизации, недавно нашёл один интересный лисп: http://lush.sourceforge.net/. В нём есть офигенно эффективный компилятор для статически типизированного кода. Если быть точным, генерируется код на C, и код получается обычно такой же, как я бы руками написал. Ну и что меня вообще добило, в программу на лиспе можно запросто делать вставки на С. :) Кто там хотел лисп с ассемблерными вставками? Да лехко! :D

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

такое будет ругацо на этапе компиляции

(defun foo (a b) (declare (optimize (speed 3) (safety 0) (debug 0))) (declare (type fixnum a b)) (+ a b))

(defmacro bar (x y) `(foo ,x ,y))

(format t "~D~%" (bar "a" "b"))

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

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

Если уайтспейсом ты называешь Питон, то по сравнению с Лиспом он мэйнстрим. По сравнению с VB - не очень распространенный язык (но уже не маргинальный, как лет 8-10 назад).

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

> (defun foo (a b) (declare (optimize (speed 3) (safety 0) (debug 0))) (declare (type fixnum a b)) (+ a b))

> (defmacro bar (x y) `(foo ,x ,y))

> (format t "~D~%" (bar "a" "b"))

Сложновато для меня (а CL под рукой нет). В любом случаее - я не вижу проверки типов x и y в defmacro.

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

Ничего вы не понимаете, это эзотерический яп. Это для тех, чей воспаленный мозг уже не будоражат ни лисп, ни с, ни тупые флеймы на лоре, вроде этого.

stassats ★★★★
()
Ответ на: комментарий от ero-sennin

> Кстати о статической типизации, недавно нашёл один интересный лисп: http://lush.sourceforge.net/. В нём есть офигенно эффективный компилятор для статически типизированного кода. Если быть точным, генерируется код на C, и код получается обычно такой же, как я бы руками написал. Ну и что меня вообще добило, в программу на лиспе можно запросто делать вставки на С. :) Кто там хотел лисп с ассемблерными вставками? Да лехко! :D

Не, нам такого не надо. Макр нет, объектная система - хуже чем у тикля. А код на си генерируют gcl и ecl - почти полноценные CL-и :)

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

> Макр нет

Всё там есть, только называется ни defmacro, а dm почему-то. :)

> А код на си генерируют gcl и ecl - почти полноценные CL-и. :)

Знаем мы, какой они код генерируют, это убиться проще! :D Ну и сишные вставки им и не снились, понятно.

Короче, lush - это такой лисп для задач с элементами числодробления. :) Там в комплекте и привязки к соответствующим библиотекам есть: GSL, FFTW, BLAS, LAPACK, MPI и т. д. По количеству баратеек для околонаучных расчётов он явно рулит.

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

> Всё там есть, только называется ни defmacro, а dm почему-то. :)

Упс, прогнал... :) Но без `, :(

Да, наваяли не мало... Но и получили ещё один ни с чем не совместимый... Нет в жизни счастья :)

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

> Да, наваяли не мало... Но и получили ещё один ни с чем не совместимый... Нет в жизни счастья :)

И ещё он скорее Lisp-1 нежели Lisp-2 (хотя, похоже, от обоих ещё дальше чем NewLisp).

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

> И ещё он скорее Lisp-1 нежели Lisp-2 (хотя, похоже, от обоих ещё дальше чем NewLisp).

И они сами себя позиционируют как замену ... в том числе и схемы. CL в спсике нету (гы-гы, питон есть :)

yyk ★★★★★
()
Ответ на: комментарий от ero-sennin

> Кто-нибудь, пофлеймите немного про Lisp-1 vs Lisp-2

Или хоть скажите, что это такое, и чем один от другого отличается

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

> Или хоть скажите, что это такое, и чем один от другого отличается

Основное отличие - в Лиспе-2 два отдельных пространства имён для функций и переменных, остальное всё так или иначе из этого вытекает.

http://www.dreamsongs.com/Separation.html

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

>> Ох уж эта динамическая типизация...

> Аминь, брат.

>> Статическая типизация и ocaml рулят.

> Насчет статической типизации - аминь, а Ocaml - он еще маргинальнее Лиспа.

Tailgunner, никак не могу понять как ты можешь совмещать в себе любовь к статической типизации и Питону одновременно? Для меня это загадка посильнее будет чем лисперы :-)

Если тебе _так_ нужна статичемкая типизация и ты прёшься от Питона, то тебе сюда: http://boo.codehaus.org/

Хелло ворлд на Boo:

print 'Hello, world!'

На нём можно написать достаточно большую программу и на первый взгляд может показаться что это Питон, но на самом деле это язык с сильной статической типизацией для .NET. Пашет на Mono, в портаже есть.

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

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

Я люблю Питон не за его динамизм (который иногда очень полезен), а за мощные, но при этом удобные средства работы с данными - списки, итерацию. Вообще, Питон - это уникальная комбинация мощности и простоты использования. Но, ИМХО, динамическая типизация здесь большой роли не играет.

Вот вопрос: как ты проведешь рефакторинг большой проги на Питоне? Переименованы классы, добавлены/удалены поля, измемены сигнатуры методов. На Си/Си++ делается рекомпиляция, и компилятор сам показывает, где несовпадения. На Питоне придется искать самому, и не факт, что всё найдешь. Остается полагаться на тесты, но 100% test coverage не бывает.

Кстати, здесь проскакивали интересные ссылки на работу по type inference для Питона: Starkiller и Aggressive Type Inference.

http://www.python.org/pycon/dc2004/papers/1/paper.pdf http://www.python.org/workshops/2000-01/proceedings/papers/aycock/aycock.html

> и ты прёшься от Питона

Я бы не сказал, что я прусь. Некоторые вещи в нем меня сильно раздражают - например, отсуствие try-except-finally (наконец-то добавили в 2.5, знаю), отсуствие многострочной лямюды, или то, что неотделим от огромной библиотеки ("поставляется с батарейками" - а они не всегда нужны). Но по совокупности возможностей Питон - лучшее в своем классе.

> тебе сюда: http://boo.codehaus.org/

Ты уже гооврил :) Я зашел по ссылке - совершенно не впечатлился. Это на Питон похоже только отдаленно, пользует .NET, и, похоже, оффтопик-ориентироано. А мне нужно "real thing", под линух, и легкая интеграция с native-кодом (да, и заверните мне Numeric Python и Matplotlib). Boo - игрушка для энтузиастов (так же, как Лиспы ;)). Если я захочу поиграть в такие игры, буду играть с PyPy, или Haskell/Ocaml.

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

> Насчет статической типизации - аминь, а Ocaml - он еще маргинальнее Лиспа.

Фигасе. Язык, позволяющий быструю и эффективную разработку и результат сравнимый по скорости исполнения с хорошо написанным руками С, называется маргинальным?

А если речь о распространенности, что гроша выеденного не стоит шкала "маргинальный" -- "немаргинальный".

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

> А если речь о распространенности

Именно о ней

> гроша выеденного не стоит шкала "маргинальный" -- "немаргинальный".

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

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

> Вот вопрос: как ты проведешь рефакторинг большой проги на Питоне? Переименованы классы, добавлены/удалены поля, измемены сигнатуры методов. Остается полагаться на тесты, но 100% test coverage не бывает.

Ты прав, это проблема. Это надо делать аккуратнее чем на языке со статической типизацией. Но это вообще проблема не только динамической типизации но и позднего связывания, даже в зяыках со статической типизацией.

Ещё pychecker / pylint могут помочь. И стремиться к 100% test coverage

>> тебе сюда: http://boo.codehaus.org/

> Ты уже гооврил :) Я зашел по ссылке

Ну ещё могу посоветовать Dylan, но штука тоже маргинальная.

> Если я захочу поиграть в такие игры, буду играть с PyPy, или Haskell/Ocaml.

Да Haskell это круто, а он динамически библиотеки загружать научился? Вроде 21 век уже, а они это вот вот собираются доделать :-)

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

> Но это вообще проблема не только динамической типизации но и позднего связывания, даже в зяыках со статической типизацией.

Там она стоит отнюдь не так остро - поэтому я бы убил ради статически типизированного Питона :)

> Ещё pychecker / pylint могут помочь.

pylint - вещь, ИМХО, бесполезная. pychecker - да, помогает, но мало.

> Dylan

В отличие от Boo, Dylan мне активно не понравился. Вообще, такое впечатление, что значительная часть language designer'ов просто недовыпендривались в детстве, и компенсируют это в разрабатываемых языках.

>> Если я захочу поиграть в такие игры, буду играть с PyPy, или Haskell/Ocaml.

> Да Haskell это круто, а он динамически библиотеки загружать научился?

Ты как будто писать на нем собрался ;) Если "на поиграть" - то пох динамические библиотеки :)

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

> Язык, позволяющий быструю и эффективную разработку и результат сравнимый по скорости исполнения с хорошо написанным руками С, называется маргинальным?

а только такой и называецо. Понятие "маргинальный язык" вообще появилось одновременно с недоацтоем вроде делфей и висуалвасика, потому что это понятие срочно понадобилось для пересадки разработчиков на недоацтои, а размных аргументов никаки не нашлось.

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

> закон Райзера

это чево такое?

> в случае проблем - спросить не у кого (потому что почти все - хоббисты), нет литературы/документации в Сети...

В случае с лиспом всево этово ну просто завались. Во всяком случае больше чем с например тем же питоном. Да и самостоятельно разобраться проще, ибо всё не такое извращённое.

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

> Да Haskell это круто, а он динамически библиотеки загружать научился? Вроде 21 век уже, а они это вот вот собираются доделать :-)

+1, заели бинари по писятмех. Доделают - буду размышлять о хаскеле. Окамль чёто пока не впечятлил, но я ево совсем мало трогал.

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

>Понятие "маргинальный язык" вообще появилось одновременно с недоацтоем вроде делфей и висуалвасика

Ты определись - с Делфями и Визивасиком? Они в разное время появились. Впрочем, ты этого не помнишь.

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

"Пересадки", я плакал. Марш историю учить! 1) И Дельфи, и Визивасик были существенным шагом вперед по сравнению с предшественниками - TurboPascal и QuickBasic 2) лисперы и прочие знатоки "неацтойных" языков были в дефиците, и высокомерно плевали на рынок PC.

Delphi - достойная и удачная система. То, что ее использовали стада быдлокодеров - это не ее вина.

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

>> закон Райзера

> это чево такое?

Это закон такой. Программисты знают, а остальным не нужно.

>> в случае проблем - спросить не у кого (потому что почти все - хоббисты), нет литературы/документации в Сети...

> В случае с лиспом всево этово ну просто завались.

Чего "этого"? Литературы - да, за 50 лет накопилось. Спросить? Ни фига, все либо хоббисты, либо с таким самомнением, что лучше бы и не отвечали. Мои слова о распространенности ты просто проигнорировал - а ведь из этого почти всё остальное и вытекает.

> Да и самостоятельно разобраться проще, ибо всё не такое извращённое.

Если спросить 10 случайно выбранных программистов, не знакомых ни с Лиспом, ни с Питоном, что им понятнее - текст на Лиспе или на Питоне, все 10 скажут - на Питоне. Но ты-то знаешь, что они все извращенцы...

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

> Delphi - достойная и удачная система. То, что ее использовали стада быдлокодеров - это не ее вина.

Быдлокодер пишуший на delphi останется быдлокодером. В отличие от. Уже за это создателей делфи должно судить в Нюрнберге за преступления против человечества.

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

> Быдлокодер пишуший на delphi останется быдлокодером. В отличие от. Уже за это создателей делфи должно

За то, что он не делает из быдлокодера - суперкодера? За это же нужно судить создателей Си, Паскаля, SQL и т.д. Да и создателей Лиспа - тоже. В общем, "всех убью - один останусь".

Или быдлкодер, вынужденный писать на Лисп, волшебным образом совершенствуется? "Не верю" (C) Станиславский.

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

> Ты определись - с Делфями и Визивасиком? Они в разное время появились. Впрочем, ты этого не помнишь.

Да примерно в одинаковое, в конце 9х дето. Действительно худо помню, не особо мя этот вопрос волнует.

> "Пересадки", я плакал. Марш историю учить! 1) И Дельфи, и Визивасик были существенным шагом вперед по сравнению с предшественниками - TurboPascal и QuickBasic 2) лисперы и прочие знатоки "неацтойных" языков были в дефиците, и высокомерно плевали на рынок PC.

вобщето тогда можно было свободно на сях работат, чё я и делал. По сравнению с сями эти во всех отношениях, как в быдлопесне поёцо "Стоша Говнозад тихо на пальцах...". А для лиспа и прочих аппаратура писихек слабовата была и тормоза немеряные, отчево и плювали, всёодно бесполезно.

> Delphi - достойная и удачная система. То, что ее использовали стада быдлокодеров - это не ее вина.

бугога. Чё же в ей удачново?

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

> Это закон такой. Программисты знают, а остальным не нужно.

чё тада умоминаеш если те всёодно ненужный?

> Спросить? Ни фига, все либо хоббисты, либо с таким самомнением, что лучше бы и не отвечали

давай ссылу в студию, де ты спрашивал а там лучебы не отвечяли

> распространенности

пох распространёнось. Пять годов тому про дотнениненадо никто и не знал, а щяс если не распространёный, то по крайней мере многие знают чё такое бывает хотябы. Хотя он во всех отношениях хуже не то што лиспа но даже висуалвасика.

> Если спросить 10 случайно выбранных программистов, не знакомых ни с Лиспом, ни с Питоном, что им понятнее - текст на Лиспе или на Питоне, все 10 скажут - на Питоне. Но ты-то знаешь, что они все извращенцы...

А если просить 10 случяйно выбратых бомжей, не знакомых ни с лиспом ни с питоном, все 10 скажут - нам пох. Ичё?

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

> быдлкодер, вынужденный писать на Лисп

дык нету никакой надобности, чёбы быдлокодер писал на лиспе. Там для этово макросы есь, они гораздо лучше быдлокодера код генерят, виш как оно...

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

> За то, что он не делает из быдлокодера - суперкодера?

Да.

> Или быдлкодер, вынужденный писать на Лисп, волшебным образом совершенствуется?

Да.

> Не верю" (C) Станиславский.

А ты попробуй. Вдруг у тебя получится?

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

> В отличие от Boo, Dylan мне активно не понравился. Вообще, такое впечатление, что значительная часть language designer'ов просто недовыпендривались в детстве, и компенсируют это в разрабатываемых языках.

У Грэма об этом хорошо сказано. Смысл в том что учёным надо писать статьи, а ситема типов языка программирования, это благодатная область.

Соответственно про язык с динамической типизацией, столько статей не напишешь, вот и плодятся всякие академические языки со статической типизацией, вместо того чтобы доделать один до юзабельного состояния или заниматься JIT в динамических языках.

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

Что для тебя важно? Программист 1С может поднимать неплохие деньги. Сравнимые, видимо, с получаемыми мной. Но это не делает 1С пристойным занятием с моей точки зрения.

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

> А ты попробуй. Вдруг у тебя получится?

Один раз попробовал - не получилось. Чтобы попробовать второй раз, мне нужны веские причины. Я работаю над их сбором (в том числе - в этом треде), но пока не густо...

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

> Что для тебя важно?

Получать удовольствие от работы, обеспечивающей приемлемый уровень жизни.

> Программист 1С может поднимать неплохие деньги. Сравнимые, видимо, с получаемыми мной. Но это не делает 1С пристойным занятием с моей точки зрения.

Аминь, брат. Пока не стану дохнуть с голоду - не стану связываться.

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

> вот и плодятся всякие академические языки со статической типизацией

Пусть плодятся. Это же исследования - они не обязаны приносить немедленную практическую пользу. Вдруг додумаются, как доказывать правильность хоть умеренно сложных фрагментов программ - уже большое подспорье.

> вместо того чтобы доделать один до юзабельного состояния

Это не задача исследователей

> или заниматься JIT в динамических языках.

Тоже не их задача. И вообще - JIT в принципе менее мощен, чем статическая компиляция. Не зря разработчик Psyco сейчас в команде PyPy.

А JIT'ы плодят как раз корпорации и вольные прогеры - Java (несколько вариантов), .NET (и Mono), Psyco, Parrot.

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

> Один раз попробовал - не получилось. Чтобы попробовать второй раз, мне нужны веские причины. Я работаю над их сбором (в том числе - в этом треде), но пока не густо...

Зыть: вспомнил дурацкое определние рекурсии: "чтобы понять рекурсию нужно понять рекурсию" :) Так вот, чтобы понять, зачем тебе изучать лисп, нужно понять, что это такое. Для этого надо изучить лисп :)

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

> Тоже не их задача. И вообще - JIT в принципе менее мощен, чем статическая компиляция. Не зря разработчик Psyco сейчас в команде PyPy.

А нифига, JIT может давать больше ускорения чем статическая компиляция, т.к. во время рантайма есть больше информации о программе чем во время компиляции. И в доке к psyco примерно такая телега и прогоняется.

Это конечно, не снимает проблемы со статической проверкой типов, но тоже юмор.

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

> Я работаю над их сбором (в том числе - в этом треде)

Судя по явно предвзятым и неверным твоим высказываниям, больше похоже чё ты ищещ всяческой отмазки чтобы этого не делать, но пока плохо получяецо :D

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

>> Ты определись - с Делфями и Визивасиком? Они в разное время появились. Впрочем, ты этого не помнишь.

>Да примерно в одинаковое, в конце 9х дето.

Ага, 31-го декабря 1999 года 8/ Для справки: VB 1.0 - 1991, VB 2.0 - 1992, Delphi - 1994.

> вобщето тогда можно было свободно на сях работат, чё я и делал.

Естественным путем миграции с TurboPascal был Delphi, с QuickBasic и dBASE-клонов - VB. Кроме того, ни в одном из Си не было такого мощного и удобного в использовании инструментария работы с компонентами, как в Delphi и VB.

> По сравнению с сями эти во всех отношениях, как в быдлопесне поёцо

Быдлопесен не слушаю, поэтому твою мысль не понял

> А для лиспа и прочих аппаратура писихек слабовата была и тормоза немеряные, отчево и плювали, всёодно бесполезно.

Какая чушь. 486-е, появившиеся в 1989, и Пентиумы, появившиеся в 1992, были всяко мощнее процессоров VAX и 680[023]0 рабочих станций, на которых разрабатывался Common Lisp. Так что - не надо о слабости аппаратуры. Рынок _просрали_. Конечно, не рядовые лисперы в этом виноваты, но это не меняет факта.

>> Delphi - достойная и удачная система. То, что ее использовали стада быдлокодеров - это не ее вина.

> бугога. Чё же в ей удачново?

Мощный и простой в использовании конструктор интерфейсов. Неплохой язык программирования.

>> Спросить? Ни фига, все либо хоббисты, либо с таким самомнением, что лучше бы и не отвечали

>давай ссылу в студию, де ты спрашивал а там лучебы не отвечяли

Ты хоббист ;) (не хотел тебя задеть, извини). Но "всё-таки нужно но сложно переучивацо с алгоритмического стиля мышления на более абстрактный" звучит высокомерно, нет?

>> распространенности

> пох распространёнось. Пять годов тому про дотнениненадо никто и не знал, а щяс если не распространёный, то по крайней мере многие знают чё такое бывает хотябы. Хотя он во всех отношениях хуже не то што лиспа но даже висуалвасика.

И что? Для него уже до чертиков инструментов. Кроме того, я имел в виду системы с открытыми исходниками.

Кстати, какой именно из уймы языков .NET хуже Визивасика? F# ? 8)

> А если просить 10 случяйно выбратых бомжей, не знакомых ни с лиспом ни с питоном, все 10 скажут - нам пох.

Что-то тебя в сторону уносит - Whitespace, бомжи...

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

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

Ну, ХЗ. Может, со стороны виднее.

> но пока плохо получяецо :D

Нормально получается ;). Ни один CL пока не инсталлирован.

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

> VB 1.0 - 1991, VB 2.0 - 1992, Delphi - 1994.

Ну фих их знаит, я имел в виду более-менее извесны стали к концу 90х.

> Естественным путем миграции с TurboPascal был Delphi

ну хтож вас туды загнал, в трупопаскаль-то? Я на 286х на ём работал потомушто компилер намного более производительный был. Ифсио. На 386х уже смысла не было с им связывацо, там и ся были и ся++.

> Какая чушь. 486-е, появившиеся в 1989, и Пентиумы, появившиеся в 1992, были всяко мощнее процессоров VAX и 680[023]0 рабочих станций, на которых разрабатывался Common Lisp.

вот только вах тянул кучю юзверей, а 286 макимум как печятная машинка годилась. При появлении 486х и пентиумов туда резво перескочили недоподелия с доса, а полноценных систем и средств, соотвецтвующих моще просто не успели сготовить - место ужо занято. И это тянецо ещё до сих пор: хотя виндовсь ниасиливает всех возможностей сёдняшнего железа, выгонять ево ещё долго будут.

> Рынок _просрали_

аха :( Вот только не из-за конкурентоспособного, а как раз методами давления на моск, как я и говорил о появлении типо понятия "маргинальный"

> Мощный и простой в использовании конструктор интерфейсов.

чем лучше того же борландовского owl?

> Неплохой язык программирования.

Чем лучше тех же сей с плюсами?

>>> Спросить? Ни фига, все либо хоббисты, либо с таким самомнением, что лучше бы и не отвечали

>> давай ссылу в студию, де ты спрашивал а там лучебы не отвечяли

> Ты хоббист ;) (не хотел тебя задеть, извини). Но "всё-таки нужно но сложно переучивацо с алгоритмического стиля мышления на более абстрактный" звучит высокомерно, нет?

ИМХО нет. Это - факт. Я сам много труда на это затратил. Мои первые проги на лиспе были длинны, карявы и весьма уродливы ибо составлялись более алгоритмически. По мере обучения я их переписывал, отчего они вконце стали вдвое-втрое короче первоначяльных и вдесятеро более понятными. Также "обычного" чела достаточно трудно обучить алгоритмическому.

> И что? Для него уже до чертиков инструментов. Кроме того, я имел в виду системы с открытыми исходниками.

ивот. Несмотря на множественные недостатки.

> Кстати, какой именно из уймы языков .NET хуже Визивасика? F# ? 8)

сама концепция хуже. а уж про с# и слов нету.

>> А если просить 10 случяйно выбратых бомжей, не знакомых ни с лиспом ни с питоном, все 10 скажут - нам пох.

> Что-то тебя в сторону уносит - Whitespace, бомжи...

ну меня твоя фраза о том, что десятеро программистов на схеме единодушно сочтут питоний код более понятным чем лисповый, тоже здорово рассмешила.

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

> Ни один CL пока не инсталлирован.

хм, ты уверен? ИМХО clisp в большинстве дистров бай дефолт присуцтвует.

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

FC4 - из всего Лиспа только emacs-{el,leim}

Да и те не нужны 8)

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

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

> нo пoкa нe гycтo...

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

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

>> VB 1.0 - 1991, VB 2.0 - 1992, Delphi - 1994.

>Ну фих их знаит, я имел в виду более-менее извесны стали к концу 90х.

Тоже нет. VB мгновенно стал хитом, Delphi тоже быстро набрал популярность.

>> Естественным путем миграции с TurboPascal был Delphi

> ну хтож вас туды загнал, в трупопаскаль-то?

Нас - никто, я юзал {Turbo,Borland} C++. Но TurboPascal был популярен, и с пришествием Windows народу надо было на что-то мигрировать.

> вот только вах тянул кучю юзверей

аха, MicroVAX в рабочей станции 8)

> а 286 макимум как печятная машинка годилась.

аха, но я-то говорил о 486+. Кстати, времена 386-х были, пожалуй, даже лучше для вторжения "взрослых" технологий.

> полноценных систем и средств, соотвецтвующих моще просто не успели сготовить - место ужо занято.

>> Рынок _просрали_

>аха :( Вот только не из-за конкурентоспособного, а как раз методами давления на моск, как я и говорил о появлении типо понятия "маргинальный"

Вот - ключевой момент. Если Лисп настолько лучше, чем всё остальное, пригоден для использования быдлокодерами и даже (по мнению некоторых) превращает быдлокодеров в суперкодеров - почему мощный десант CommonLisp'ов не смел все быдлоподелия? Мир стал бы куда лучше.

>> Мощный и простой в использовании конструктор интерфейсов.

>чем лучше того же борландовского owl?

OWL - это библиотека, а не конструктор интерфейсов.

>> Неплохой язык программирования.

>Чем лучше тех же сей с плюсами?

Не лучше, но гораздо проще. Мало кому нужна вся моща Си++

>> Кстати, какой именно из уймы языков .NET хуже Визивасика? F# ? 8)

>сама концепция хуже

Хуже чем что? Чем хуже? Мне вообще-то нравится концепция .NET - многоязыковая среда, позволяющая легкую интероперабельность между языками, managed code с возможностью прямого преобразования в "родной".

> а уж про с# и слов нету.

Не очень язычок, конечно. И развивается в какого-то монстра.

> ну меня твоя фраза о том, что десятеро программистов на схеме

На какой схеме? Где ты там это увидел? =8-0 Я сказал - "не знающих ни Питона, ни Лиспа"

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

> Значит неправильно пробовал.

Пробовал на своих практических задачах.

> Потом попробуй решить на лиспе какую-нибудь большую задачу.

А вот на это уже нет времени :/

> Думаю, дело в том преимущества лиспа проявляются во всей красе на больших задачах.

Мне просто страшно браться за большую практическую задачу на Лиспе. Только инкрементальный подход.

Хотя насчет того, чтобы _прорешать_ SICP - интересная мысль 8)

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

>> Только инкрементальный подход.

> А это тебя каким боком волнует?

Не уверен, что понял тебя правильно, но - меня волнует, чтобы программы, за которые я отвечаю, работали. Поэтому я опробую новые технологии с осторожностью - сначала на относительно небольших подзадачах. Поэтому "написание больших программ на Лисп" откладывется, пока он не зарекомендует себя на маленьких и средних.

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

> Тоже нет. VB мгновенно стал хитом, Delphi тоже быстро набрал популярность.

Я говорю чё сам видел. До виндовся 95 юзали lattice c, watcom, борландовский с/с++, ещё какуюто хрень. мсявый компилер был вроде анегдода, все над им смяялись и никто не юзал. До года примерно 98 тырфейсы под виндовсь делалисть восновном на борландовом с++ с овл, кроме прямово винапи, м которым было хоть сложнее, но проще. Потом эта нечисть попёрла, делфи и прочее, причём по снгам токо. В буржуинстве делфи досих пор сравнительно раритет.

> TurboPascal был популярен

восновном скубенты на ём лабы кропали. Эх, знать бы чем всё кончицо, луче бы поотчисляли всехнахъ.

> мощный десант CommonLisp'ов

Как ты се это представляеш? лисперы работают, а мси с борландом пеаряцо, это их заработок. Благо в компах мало кто шарил, им массовый дурятник и лохотрон сходил с рук. До сих пор сходит, но щяс ситуяйца уже выправляцо начяло.

> OWL - это библиотека, а не конструктор интерфейсов.

какая на йух разницо, если ей прользовацо проще а результат луче?

> Не лучше, но гораздо проще. Мало кому нужна вся моща Си++

Чем же оно проще? {} на begin end заменеты и... всё вроде? Откуда кстати в с++ моща?

> Хуже чем что? Чем хуже? Мне вообще-то нравится концепция .NET - многоязыковая среда, позволяющая легкую интероперабельность между языками, managed code с возможностью прямого преобразования в "родной".

Там, где можно просто скомпилить - выросла вм на пустом месте. В жабе есть хоть какая-то причина для вм, может быть даже не совсем оправданная, а тут... Всё предоставляемое дотнетиненадом намного лучше и проще решается традиционными средствами. Вобщем, достаточно посмотреть как оно работает.

>> ну меня твоя фраза о том, что десятеро программистов на схеме

> На какой схеме? Где ты там это увидел? =8-0 Я сказал - "не знающих ни Питона, ни Лиспа"

Почему программер на схеме не может попадать под это определение?

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

> Не уверен, что понял тебя правильно, но - меня волнует, чтобы программы, за которые я отвечаю, работали. Поэтому я опробую новые технологии с осторожностью - сначала на относительно небольших подзадачах. Поэтому "написание больших программ на Лисп" откладывется, пока он не зарекомендует себя на маленьких и средних.

Тогда тебя скорее волнует конкретная реализация CL, а не технология инкрементальной компиляции, которой "сто лет в обед" и которая сама по себе скорее всего не принесёт тебе никаких неудобств :)

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

>> OWL - это библиотека, а не конструктор интерфейсов.

>какая на йух разницо, если ей прользовацо проще а результат луче?

Речь не о тебе, а о среднем программисте (типа меня). Мне - удобнее пользоваться конструктором интерфейсов, чем набирать код руками (я считаю недостойным делать руками то, что автоматизировано ;) ). Насчет "результат лучше" - мне работать с OWL (на OS/2) никогда не нравилось.

>> Не лучше, но гораздо проще. Мало кому нужна вся моща Си++

>Чем же оно проще? {} на begin end заменеты и... всё вроде?

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

> Откуда кстати в с++ моща?

Всё, что есть в Си + см. выше. Хотя если моща - в крутых макрах, тогда ой.

>> мощный десант CommonLisp'ов

>Как ты се это представляеш? лисперы работают, а мси с борландом пеаряцо, это их заработок. Благо в компах мало кто шарил, им массовый дурятник и лохотрон сходил с рук.

А Лиспом коммерческие компании не знаимались, нет? Еще раз - если они считали, что у них на руках продукт, который превосходит всё имеющееся на порядок - почему они не ломанулись на завоевание? Я так думаю, они не считали Лисп настолько лучшим решением, чтобы хоть попробовать. Ты читал "Good news, bad news, how to win big"? Специально для тебя нарыл ссылку: http://www.shootybangbang.com/weenix/good-news-bad-news.txt

>> На какой схеме? Где ты там это увидел? =8-0 Я сказал - "не знающих ни Питона, ни Лиспа"

>Почему программер на схеме не может попадать под это определение?

Потому что Scheme - это такой Лисп.

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

>Получать удовольствие от работы, обеспечивающей приемлемый уровень жизни.

Я тоже. Эта работа не связана практически с программированием, разве что в крайних точках. Но вот чтоб мозг не заплывал жиром, попрограммливаю по-мелочи. Так сказать, ради академической красоты. И вот ее в ocaml в N раз больше чем в delphi и vb, вместе взятых.

PS. Лисп мне не нравится. Чисто синтаксисом. Все эти скобочки.... Вон в ocaml скобочек нет почти.

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

> а не технология инкрементальной компиляции

Я ни слова не сказал о компиляции. Насчет реализаций - тоже пока не важно. К тому времени, когда у меня появится второй шанс попробовать Лисп в деле, многое может быть иначе.

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

> работа не связана практически с программированием, разве что в крайних точках. Но вот чтоб мозг не заплывал жиром, попрограммливаю по-мелочи. Так сказать, ради академической красоты.

А моя работа - сплошное программирование, и мозги не то, чтобы жиром не заплывают, а выгорают потихоньку. И, хоть я и ценю академическую красоту, наличие библиотек, инструментальных средств, отлаженность и интегрируемость в существующие программы, легкость освоения командой - всё это более важно.

> PS. Лисп мне не нравится. Чисто синтаксисом. Все эти скобочки...

Да, ряды скобочек не рулят :(

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

> я считаю недостойным делать руками то, что автоматизировано

А тот факт, чё в делфях _до_сих_пор_ нету layout manager и приходицо вручную делать обработчики ресайзов, тя не смущяет? К концу 90х в других тулах оно вроде было ужо? (могу ашыбацо)

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

сборщика помойки ни там ни сям небыло, а остальное в с++ такое же только лучше.

> Всё, что есть в Си + см. выше. Хотя если моща - в крутых макрах, тогда ой.

Ну, такая моща, от которой больше траблеф...

> почему они не ломанулись на завоевание?

Потому что на раскрутку лохотрона денюх больше нужно чем на разработку полезной тулзы. Одновременно и то и сё тянуть сложно. LispWorks вроде неплохо жывёт... Виш, я думаю даже чё у них прибыли с солидных клеентов не меньше, чем у борланда от прыщявых скубентов, которые щитают нарисовать мышом кнопку в формочьке верхом крутизны. Вендовые платные лиспы жывы до сих пор, а борланд, виш, скопытилсо.

>>> На какой схеме? Где ты там это увидел? =8-0 Я сказал - "не знающих ни Питона, ни Лиспа"

>>Почему программер на схеме не может попадать под это определение?

>Потому что Scheme - это такой Лисп.

аха, а питон это такой уайтспейс. Только чёто называюцо поразному, к чему бы это?

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

> Да, ряды скобочек не рулят :(

Непривычно просто. Зато удобно. Если с сями сравнивать, скопки заменяют всякие {},; и остаюцо в таком же количестве при вызовах функций. Так что у лиспа фактически служебных символов числом меньше.

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

>> я считаю недостойным делать руками то, что автоматизировано

>А тот факт, чё в делфях _до_сих_пор_ нету layout manager и приходицо вручную делать обработчики ресайзов, тя не смущяет?

[Сразу скажу - сам в Delphi не работал, хотя поработал в C++Builder.]

Отсуствие layout cмущает, хотя и не сильно. И в Delphi есть anchors, которые выполняют похожую на layout функцию. Вообще, layout - штука полезная и обычно удобная, но... без нее вполне можно обойтись.

> Вендовые платные лиспы

То есть Лиспы для Винды были, но никакого распространения не получили? И виноват в этом пеар от M$? А по-моему, все причины хорошо описаны в "Good news, bad news". И основная из них - Лисп не настолько лучше, чем всё остальное.

>>Потому что Scheme - это такой Лисп.

>аха, а питон это такой уайтспейс

Это твое личное мнение?

> Только чёто называюцо поразному, к чему бы это?

Ты лиспер. тебе виднее. Цитата из Габриэля (знаешь такого? ;): "Among these Lisps were Scheme, Interlisp, Franz Lisp ..."

Так что, Scheme - это такой Лисп :-P

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

> вполне можно обойтись

ктож спорит, без всево можно обойтись и в бочке жыть, и на делфях чёто полезное сделать. Вот только стОит ли оно тово?

> То есть Лиспы для Винды были, но никакого распространения не получили?

лиспы для венды были, есь и будут есь, и распространение у их нормальное, токо не среди скубентов, которые скубенты на пеар ведуцо.

> И основная из них - Лисп не настолько лучше, чем всё остальное.

бугога. а васик с дельфями, не настолько хуже, чё прям такой распространёный?

> Это твое личное мнение?

Ну фих ево знаит, если схема это лисп, то чёрное это белое, а кактусы - это такие сосны. Почему бы и нет?

> Ты лиспер

я не лиспер а глюкотворец.

> Цитата из Габриэля (знаешь такого? ;): "Among these Lisps were Scheme, Interlisp, Franz Lisp ..."

не знаю, но хочю познакомицо с ево драгдилером.

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

>> И основная из них - Лисп не настолько лучше, чем всё остальное.

>бугога. а васик с дельфями, не настолько хуже, чё прям такой распространёный?

Как ни странно - да. У Real World (R) (TM) другие критерии оценки языков программирования, чем у тебя (и даже меня).

>> Цитата из Габриэля (знаешь такого? ;): "Among these Lisps were Scheme, Interlisp, Franz Lisp ..."

>не знаю, но хочю познакомицо с ево драгдилером.

Приехали... новое поколение лисперов не знает Габриэля. Ты хоть в целях самообразования почитай по ссылке, которую я прислал.

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

> Как ни странно - да. У Real World (R) (TM) другие критерии оценки языков программирования, чем у тебя (и даже меня).

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

> Приехали... новое поколение лисперов не знает Габриэля. Ты хоть в целях самообразования почитай по ссылке, которую я прислал.

Ладно, посмотрю как-нибудь. Раз уж он называет схему лиспом, там наверное ещё много забавново. Еличё, у них даже парадигмы разные.

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

> пpигoдeн для иcпoльзoвaния быдлoкoдepaми

Нет, не пригоден. Человек либо научится программировать, либо не будет использовать лисп. Так или иначе но быдлокодер не будет программировать на лиспе.

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

на, покури. Смотри цены, почитай истории. Сравни с делфём потома.

http://www.lispworks.com/success-stories/index.html (сайтик имхо приятный кстати)

http://www.franz.com/success/ (а тут ужоснахъ. ИМХО)

http://www.cormanlisp.com/index.html

http://www.digitool.com/

http://www.goldhill-inc.com/

http://www.webweasel.com/lisp/lisp.htm

http://www.scieneer.com/scl/index.html

http://www.symbolics.com/

http://www.ufasoft.com/lisp/

http://top2bottom.net/venue.html

учти чё дельф/васик/... в единственном экземпляре а лиспмашин кучя, платных и безплатных.

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

> Нет, не пригоден. Человек либо научится программировать, либо не будет использовать лисп. Так или иначе но быдлокодер не будет программировать на лиспе.

Почему нет? Не вижу никаких причин, почему бы у быдлокодера это невышло. Правда и причин, по которым понадобилось бы быдлокодеру работать на лиспет - тоже.

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

>Пpoбoвaл нa cвoиx пpaктичecкиx зaдaчax.

На каких, если не секрет?

>Xoтя нacчeт тoгo, чтoбы _пpopeшaть_ SICP - интepecнaя мыcль 8)

Лично у меня после этого башню сорвало и я понял, что до sicp'а совершенно не умел программировать.

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

>Пoтoмy чтo Scheme - этo тaкoй Лиcп.

Знаешь сколько копий было сломано во время обсуждения этого вопроса?

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

> He вижy никaкиx пpичин, пoчeмy бы y быдлoкoдepa этo нeвышлo.

Да язык предплоагает к работе с высокими уровнями абстракции. Человек это либо может, либо нет.

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

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

> А тот факт, чё в делфях _до_сих_пор_ нету layout manager и приходицо вручную делать обработчики ресайзов, тя не смущяет? К концу 90х в других тулах оно вроде было ужо? (могу ашыбацо)

+1

GUI без layout manager это полный отстой

> аха, а питон это такой уайтспейс. Только чёто называюцо поразному, к чему бы это?

-1

Или ты в самом деле не можешь отличить вайтспейс от питона?

Итого:

--------------

0

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

> Но это уже клиника.

Типо делфи неклиника. Будет такая же на лиспе, только работать будет чуток получше. Вобщем, быдлокодер на лиспе - вполне реализуемо, хоть и страшно.

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

> Или ты в самом деле не можешь отличить вайтспейс от питона?

Могу, почти так же уверенно, как и схему от лиспа.

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

>Tипo дeлфи нeклиникa.

Клиника. Сам на делфятину год убил и ничему не научился. Но это будет _привычная_ клиника. Тогда как только префикскная нотация сама по себе убъёт мозг быдлокодера.

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

> GUI без layout manager это полный отстой

Что - вот прям-таки полный, GUI просто использовать нельзя, да? По-моему, layout manager просто облегчает обработку resize. И _всё_.

Кроме того - ну почему вы так уверены, что в Delphi нет layout manager? У вас большой опыт разработки GUI с использованием Delphi? Может, они там есть, но называются по-другому.

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

> на, покури. Смотри цены, почитай истории. Сравни с делфём потома.

Что это должно доказать? Что CL жив? Так я и не спорю, и не сомневаюсь. Или что Лисп - это выгодно коммерчески? Об этом там данных вроде нет, но я уверен, что Borland принес своим основателям/акционерам куда больше денег.

Хе-хе: Copyright © Gold Hill Co. 2000 All rights reserved.

http://www.digitool.com/; What's New? May 2005

Не так уж круто у них дела...

Но всё равно - ОК, существует куча Лиспов и Лисп-машин. Но все вместе они даже и не претендуют на мэйнстрим (уже 20 лет). Как это согласуется со всеми заявлениями о подавляющем превосходстве Лиспа?

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

>>Пpoбoвaл нa cвoиx пpaктичecкиx зaдaчax.

>На каких, если не секрет?

Не секрет, я даже уже писал об этом 8) - надо было сделать набор тестов и прочих отладочных инструментов.

>>Xoтя нacчeт тoгo, чтoбы _пpopeшaть_ SICP - интepecнaя мыcль 8)

>Лично у меня после этого башню сорвало и я понял, что до sicp'а совершенно не умел программировать.

Я уже почти 16 лет (круглая цифра, хе-хе) работаю программистом, мою башню так легко не сорвать! 8) Я прочитал первые главы SICP - осталось чувство легкого разочаровния: "и это то, о чем столько говорят?". Может, если бы на 2/3-м курсе...

>> Пoтoмy чтo Scheme - этo тaкoй Лиcп.

> Знаешь сколько копий было сломано во время обсуждения этого вопроса?

Честно говоря, нет. Эту страницу истории я как-то упустил. А кто с кем спорил? Нигде в литературе я не встречал, что Scheme - это не труЪ, наоборот - все пишут, что Scheme - это диалект Лиспа. И чем Scheme не Лисп?

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

> Что - вот прям-таки полный, GUI просто использовать нельзя, да? По-моему, layout manager просто облегчает обработку resize. И _всё_.

Я бы сравнил разработку GUI c layout manager (LM) против разработки без них как LaTeX и Ворд. Ну типа в ворде можно (в принципе) получить всё тоже самое, но только ты загребёшься, и если надо будет что-то переделать, то в ворде надо исправлять съехавшую нумерацию и т.д. а с латехом только внести нужные изменения и заново прогнать латех.

Так и гуями, с LM тебе надо чуть-чуть поправить и всё остальное подстроиться само, а без LM надо опять вручную всё переставлять, выделять элементы, работать алайнмент-палитрой...брр...не могу вспоминать без содрогания.

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

И это даже не говоря о том, что бинарные файлы формочек, натасканных мышкой плохо поддаются системам контроля версий, а если писать в ручную с LM, то всё ништякъ

> Кроме того - ну почему вы так уверены, что в Delphi нет layout manager? У вас большой опыт разработки GUI с использованием Delphi? Может, они там есть, но называются по-другому.

C++ Builder. До питона +wxPython я писал на билдере (а делфи и билдер это, имхо, близнецы братья), и отлично понимаю почему окна во многих программах, написанных на билдере/делфи не ресайзятся. Это просто тяжело, нудно и долго, проще запретить ресайз окна.

С LM это просто небо и земля.

P.S. Можно и на ты :-)

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

> убъёт мозг быдлокодера

было бы там чему убивацо - он бы и сам апстену убился, от осознания. А так, ничё, выжывет.

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

> Лично у меня после этого башню сорвало и я понял, что до sicp'а совершенно не умел программировать.

А есть sicp в PDF-нике? А то нашёл только html

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

> просто облегчает

аха. Теперь пощитай 1) скоко нужно строк кода чёбы вручную понаписать код, производящий виндов с кучей виджетов, если есь лайаут манагер 2) скоко нужно понаписать строк кода чёбы обработать ресайз для виндова с стмя виджетами, понарисоваными мышом. Сравни. Осознай разницу меж сложностью кода этих вариантов.

> Кроме того - ну почему вы так уверены, что в Delphi нет layout manager?

В начяле 2000х абсолютно точно небыло.

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

> принес своим основателям/акционерам куда больше денег.

если бы продолжал приносить, фих бы обанкрутили наверное?

> даже и не претендуют на мэйнстрим

если под мейнстримом подразумевать прщявых скубентов, дружно кропающих хеловорды, то ЗАЧЕМ ЛИСП В МЕЙНСТРИМЕ? в смысле, кто станет тратить денюх чёбы туда ево запихать? Для работы, да, вещ незаменимая. Я сам это прочувствовал, весьма мнозе времени и сил экономит. А скубенты хай возяцо с делфами/дотнетиненадом/питоном/прочим, им это всё равно.

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

> И чем Scheme не Лисп?

я ужо отметился тут, у их даже парадигмы разные вот. Схема - это чисто функциональное, с гигиеническими тампаксами^Wмакросами, ещё всяким, короче мало чё общево.

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

умя есь в постскрипте и пдфе. Ужо непомню где брал. Хош, выкладу где.

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

> Я бы сравнил разработку GUI c layout manager (LM) против разработки без них как LaTeX и Ворд.

С Вордом знаком поверхностно, с Латехом - не знаком совсем. У _меня_ разработка с layout manager занимает больше времени, чем без него. Ибо с ним - надо думать, без - просто класть контролы на форму. Правда, с ним результат лучше.

> даже банальное изменение надписи на кнопки

Да, в этом случае тоже полезно.

> бинарные файлы формочек, натасканных мышкой плохо поддаются системам контроля версий

Серьезный недостаток, да. Но они же не обязаны быть бинарными - это артефакт реализации.

>> Может, они там есть, но называются по-другому.

>C++ Builder.

Отлично. Если ты хорошо знаешь Билдер - что там за хрень, называемая anchor? Вроде как ее можно использовать для задания взаимного расположения контролов. Типа layout manager. А?

> Можно и на ты :-)

Дык всегда :) Под "вы" я имел в виду тебя и глюкодела ;)

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

>> принес своим основателям/акционерам куда больше денег.

> если бы продолжал приносить, фих бы обанкрутили наверное?

Я говорю о доходах, которые он _успел принести_. И разве его обанкротили? Мне казалось, они просто продают свое подразделение по разработке софта, переориентируясь на консалтинг или что-то такое.

>> даже и не претендуют на мэйнстрим

> если под мейнстримом подразумевать прщявых скубентов, дружно кропающих хеловорды

По мэйнстримом подразумеваем массовое программирование. Что тебя так на студентах переклинило? Причем обязательно прыщавых.

> Для работы, да, вещ незаменимая.

Стоп, стоп. Ты вроде говорил, что не используешь Лисп для работы?

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

> A ктo c кeм cпopил?

Лисперы промеж собой.

> И чeм Scheme нe Лиcп?

Ну, например в схеме одно пространство имён для функций и переменных, а в лиспе --- два. Причём и те, и другие считают, что это фича.

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

В чём то ты прав. Если показать быдло кодеру лисп и больше ничего не показывать, то он будет кодить на нём, также как сейчас кодит на бэйсике. И если ему покажут альтернативу он также будет говорить о её неудобности/нелогичности/страшности синтаксиса/etc, как сейчас он говорит это о лиспе.

Но ведь скорее всего лисп не будет его первым языком. Опять же отсутствие литературы типа lisp за 24 часа для анацефалов ....

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

> Я говорю о доходах, которые он _успел принести_

фих ево знаит. Ты не ведаеш и я не ведаю. Вполне может быть чё принёс, но лохотрон вещ рискованая, вот и накрылся бедолаго

> разве его обанкротили? Мне казалось, они просто продают свое подразделение по разработке софта, переориентируясь на консалтинг или что-то такое.

да, оный прошёл чз процедуру банкрутства.

> Стоп, стоп. Ты вроде говорил, что не используешь Лисп для работы?

щё как юзаю. Я тамо выше код сервяка приводил, самый чё нинаесь рабочий. Готовые проги клиентам отдаю, те на сях, да. Но лисп весьма помогает сделать их быстрея и качественнея.

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

> Отлично. Если ты хорошо знаешь Билдер - что там за хрень, называемая anchor? Вроде как ее можно использовать для задания взаимного расположения контролов. Типа layout manager. А?

Эта хрень может привязать позицию элемента к какой-либо границе родителя (TOP, LEFT, BOTTOM, RIGHT), т.е. это абстракция очень низкого уровня ;-)

Anchor заботится о положении индивидуального элемента, а не группы элементов, как LM. С LM ты задаёшь логическую структуру интерфейса, а он сам делают визуальную раскладку индивидуальных виджетов.

Даже MS признал необходимость LM в новой версии LM, хотя ещё недавно в MSDN можно было найти статью о том что LM у нас нет, и нам это не надо, т.к. мы не тупые линупсоиды и нам нет неоходимости затачивать интерфейс под переводы.

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

> хрень может привязать позицию элемента к какой-либо границе родителя

Согласись, что проблему с удлинением строки при переводе это решило бы ;) Вообще, похоже на слегка недоделанный layout.

> LM ты задаёшь логическую структуру интерфейса, а он сам делают визуальную раскладку

Красиво излагаешь... 8) Если бы я сам не пользовался, бегом побежал бы пробовать.

> Даже MS признал необходимость LM

Ну, если даже M$ признал - это точно труЪ

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

> Как ни странно - да. У Real World (R) (TM) другие критерии оценки языков программирования, чем у тебя (и даже меня).

Тогда жабка - самый крутой язык? Нам с вами не по пути... :)

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

> Тогда жабка - самый крутой язык? Нам с вами не по пути... :)

Не со мной, а с Real World (R) (TM).

По мне, Java не самый плохой язык. Средненький такой.

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

> Но всё равно - ОК, существует куча Лиспов и Лисп-машин. Но все вместе они даже и не претендуют на мэйнстрим (уже 20 лет). Как это согласуется со всеми заявлениями о подавляющем превосходстве Лиспа?

Алё, ну может хоть здесь не будем гнать пену про крутость мэйнстрима и ущербность всего остального, а? :-Е

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

> Не со мной, а с Real World (R) (TM).

Каждый имеет право на свою точку зрения (и даже ошибочную) - что с того?

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

> Алё, ну может хоть здесь не будем гнать пену про крутость мэйнстрима

Алё, меня хорошо слышно? Я не говорю, что мэйнстрим - это круто. Мэйнстрим выбирает то, что оправдано экономикой и массовой психологией. И я спрашиваю (подчеркиваю - не гоню пену, а спрашиваю): если Лисп столь очевидно и намного превосходит все существующие ЯП, и, следовательно, выгоден экономически и психологически, почему он не используется в мэйнстриме?

Заметь слова "очевидно" и "намного". Если Лисп превосходит другие языки _в чем-то_ и/или _не намного_, я понимаю почему он остается (и, очевидно, всегда останется) маргинальным.

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

> Алё, меня хорошо слышно? Я не говорю, что мэйнстрим - это круто. Мэйнстрим выбирает то, что оправдано экономикой и массовой психологией. И я спрашиваю (подчеркиваю - не гоню пену, а спрашиваю): если Лисп столь очевидно и намного превосходит все существующие ЯП, и, следовательно, выгоден экономически и психологически, почему он не используется в мэйнстриме?

Пилят, ну что за!...

"превосходит все существующие ЯП, и, следовательно, выгоден экономически и психологически" - с какого такого... бугра всё, что лучше, выгодно экономически? Большинство питается экологически чистыми продуктами, а не сидит в тошниловках типа MD?

Для того, чтобы хорошо писать на лиспе, надо (опять пойдут банальности) "уметь думать абстракциями высоких порядков", проще - просто придётся чаще думать, чем долбить по клаве или елозить мышью. Многих от этого тошнит, у других случаются колики в животе, третьи просто впадают в депрессию... Так вот кое-кто решил таких вместо того, чтобы отправить красить коровники или писать женские романы, обозвать "программистами", продать им лажу, а продуктами их "жизнедеятельности" восхищаться как венцом творения человеческого... Тьфу, паскудство!..

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

> Пилят, ну что за!...

Успокойся.

> какого такого... бугра всё, что лучше, выгодно экономически

Я этого (что _всё_ что лучше, выгодно экономически) не утверждал. Специально просил заметить слова "очевидно" и "намного" - видно, ты их не заметил.

> Для того, чтобы ... Тьфу, паскудство!..

<мутный поток сознания поскипан>

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

> Мэйнстрим выбирает то, что оправдано экономикой и массовой психологией

"мейнстрим" не может выбирать, это слишком неопределённое. Ктото выбирает чё ему выгодно, ктото ведёцо на пиар, ктото пристраиваецо к общему потоку, ктото... Компы и ПО появились слишком недавно, и обществом ещё не "переработаны", наиболее эффективные модели пока не выработаны. И ещё не будут выработаны десятилетия как минимум. Знаеш сколько было разновидностей велосипеда сразу после изобретения? Хотя казалось бы вещ незамысловатая - два колеса и руль. И пришли к практически одной форме, на это понадобилось время. А с компами сложнее гораздо, это ведь целая зарождающяяся индустрия.

> если Лисп столь очевидно и намного превосходит все существующие ЯП, и, следовательно, выгоден экономически и психологически, почему он не используется в мэйнстриме?

Да потому чё рынок ПО далеко не уравновешен. Определённым кругам безусловно невыгодно если будут использовацо более эффективные средства, и на теперешном этапе развития рынка ПО именно оне рулят пока, ужель неочевидно?

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

tailgunner, я, например, знаю кучу групп которые наголову превосходит то убожество, которое крутят по радио/тель-авизору. Причём их превосходство очевидно любому человеку обладающему слухом и вкусом. Но их почему-то ни в быдлоящике, ни на радио нет. Почему?

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

> Я этого (что _всё_ что лучше, выгодно экономически) не утверждал. Специально просил заметить слова "очевидно" и "намного" - видно, ты их не заметил.

Вот упёртый попался... :)

"если Лисп столь очевидно и намного превосходит все существующие ЯП" ну не все, но ладно - превосходит, но только КАК ИЗ ЭТОГО СЛЕДУЕТ, что "выгоден экономически и психологически"?

Что в вопросе не понятно?!!!! Никак из первой части вторая не следует по той простой причине, что само человечество не совершенно.

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

> Дa пoтoмy чё pынoк ПO дaлeкo нe ypaвнoвeшeн.

Угодай в последнее время убеждается, что рынок вообще весьма далёк от равновесия. Причём это началось где-то с 70-ых годов позапрошлого века. А рыночная экономика хорошо работает только в равновесных системах. И вследствие этого человечество тратит уйму усилий крайне неэффективно.

P.S. Это я к тому, что полемическую базу флейма нужно расширить. А то мы русских физиков никогда не догоним.

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

> P.S. Это я к тому, что полемическую базу флейма нужно расширить. А то мы русских физиков никогда не догоним.

Да ну, запросто - достаточно tailgunner ещё 1000 раз спрсить, чем лисп лучше других языков :)

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

> Не человечество, а капиталистическое общество.

А так как человечество - "общность" более высокого порядка и на данный момент включает в себя и капитализм - то и оно не совершенно :)

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

> Вот упёртый попался... :)

Кто бы говорил...

> "если Лисп столь очевидно и намного превосходит все существующие ЯП" ну не все, но ладно - превосходит

Если не все - то вопрос снимается, всё ясно. Если не намного - тоже снимается по тем же причинам.

> КАК ИЗ ЭТОГО СЛЕДУЕТ, что "выгоден экономически и психологически"?

Как следует, что выгоден экономически: ты делаешь намного больше (он же намного превосходит!) за то же время; исследования показывают, что переход на новый инструмент происходит, когда он дает 37% выгоды. При этом ему особо не нужна реклама - он уже сам себя продает, все остальные ему не конкуренты.

Как следует, что выгоден психологически - всем хочется иметь мощную и быструю тачку/мотоцикл/комп/дельтаплан, так вот это - из той же серии.

И меня интересует ответ - почему этого не происходит с Лиспом? Это объективные законы.

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

Ну раз 5-6 он ещё спросит. А вот дальше ему надоест. Вот если бы можно было вызвать дух Антихриста, это оживило бы обсуждение.

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

>> А то мы русских физиков никогда не догоним.

> Да ну, запросто - достаточно tailgunner ещё 1000 раз спрсить, чем лисп лучше других языков :)

Я уже понял, что не получу ответа на _этот_ вопрос ;( Кроме того - я не стану спрашивать 1000 раз, мне скучно будет. Давайте так - я 500 раз спрашиваю, вы 500 раз отвечаете, и мы навсегда в Top 10? 8)

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

Человечество конечно несовершенно конечно, но не безнадёжно. Есть пути введения лисп в мейнстрим не уничтожая человечество.

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

Слишком сложно. Слишком похоже на "доказательство по аналогии".

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

> Kaк cлeдyeт, чтo выгoдeн экoнoмичecки: ты дeлaeшь нaмнoгo бoльшe (oн жe нaмнoгo пpeвocxoдит!) зa тo жe вpeмя; иccлeдoвaния пoкaзывaют, чтo пepexoд нa нoвый инcтpyмeнт пpoиcxoдит, кoгдa oн дaeт 37% выгoды. Пpи этoм eмy ocoбo нe нyжнa peклaмa - oн yжe caм ceбя пpoдaeт, вce ocтaльныe eмy нe кoнкypeнты.

tailgunner, ты неисправимый идеалист и романтик. Твоя схема работает только в случае маленьких улучшений, когда новым станком/автомобилем/яп можно легко овладеть не ломая груз старых знаний. В случае революционно лучших технологий всё иначе.

Ещё пример: электронный документооборот на два-три порядка (а не на несчастные 37%) быстрее и удобнее бумажного. Однако поди ж ты, все официальные документы распечатаны и снабжены подписями и печатями. Отчего такое?

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

Национал-социалистическая революция с последующей принудительной переквалификацией программистов/распространением лиспа в школах/ПТУ/институтах.

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

> я, например, знаю кучу групп которые наголову превосходит то убожество, которое крутят по радио/тель-авизору. Причём их превосходство очевидно любому человеку обладающему слухом и вкусом

Вкус - это сильно неформальная категория. Я вот - старый фанат "Ласкового мая", а ты наверняка его не любишь. И кто из нас прав? Я к тому, что производительность труда прогаммиста - это более-менее объективная категория, и не надо таких сравнений с попсой.

P.S. Насчет "Ласкового мая" - это шутка.

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

> Твоя схема работает только в случае маленьких улучшений, когда новым станком/автомобилем/яп можно легко овладеть не ломая груз старых знаний

Ну, она не моя... Кроме того, в 37% учитывается и затраты на ломку старых знаний. Я имею в виду - если Лисп на порядок лучше, то он всё окупит. Освоить новый ЯП (пусть даже Лисп) - не так уж сложно, даже если перейти на "более высокий уровень абстрактного мышления". Другое дело, что (ИМХО) даже такие затраты не будут оправданы, потому что Лисп не _настолько_ лучше.

> электронный документооборот ... Отчего такое?

Опять аналогии... Может, дело в многовековой инерции, которой в программировании просто нет?

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

> Национал-социалистическая революция

Предыдущая такая революция стоила жизни моему деду, и чуть не стоила жизни другому деду, обоим бабушкам и отцу с матерью. Нет, слишком высокая цена за Лисп.

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

> пpoизвoдитeльнocть тpyдa пpoгaммиcтa - этo бoлee-мeнee oбъeктивнaя кaтeгopия,

И какими объективными критериями ты пользуешься для оценки производительности программистов?

А музыкальный слух является абсолютно формализуемым понятием.

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

> И какими объективными критериями ты пользуешься для оценки производительности программистов?

Время, за которое он выполняет задание

> музыкальный слух является абсолютно формализуемым понятием.

Знаю. Поэтому и говорил о вкусе (художественном ;)), а не о слухе.

Кстати, с точки зрения музыкального слуха всякие там Высоцкие, Бернстайны, Диланы, Шевчуки и прочие Хетфилды с Янками и Летовыми - они же ацтой полный?

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

> Kpoмe тoгo, в 37% yчитывaeтcя и зaтpaты нa лoмкy cтapыx знaний.

Очень стрёмная фраза. Непонятно как это затраты на ломку привычек учли с точностью до процента.

> Ocвoить нoвый ЯП (пycть дaжe Лиcп) - нe тaк yж cлoжнo,

Для многих (похоже и для тебя тоже) это совершенно непосильная задача.

> Oпять aнaлoгии...

А вот ещё одна аналогия. В морских сражениях пароходы гораздо сильнее чем парусные суда. Ты думаешь, что как только научились создавать достаточно хорошие пароходы началось повальное перевооружение? Наивный.

> Moжeт, дeлo в мнoгoвeкoвoй инepции, кoтopoй в пpoгpaммиpoвaнии пpocтo нeт?

Ага, в программисты идут особые люди с безынерционным мышлением.

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

Это уже нацпол пошёл. Придут модеры всё потрут нахрен. Хочешь обсудить эту тему, стукнись на ugoday@jabber.org

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

> Непонятно как это затраты на ломку привычек учли с точностью до процента.

Ну, умеют они как-то... И не затраты на ломку, а общую прибыль от мероприятия.

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

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

>> Moжeт, дeлo в мнoгoвeкoвoй инepции, кoтopoй в пpoгpaммиpoвaнии пpocтo нeт?

> Ага, в программисты идут особые люди с безынерционным мышлением.

Во-первых, ты удобно проигнорировал слово "многовековой". Во-вторых, преучивание - это часть профессии программиста. Я работал в 7-8 операционках, с кучей инструментальных пакетов. Я привык переучиваться. Конечно, хотелось бы, чтобы следующая осваиваемая технология была более интересной.

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

> Bpeмя, зa кoтopoe oн выпoлняeт зaдaниe

Т.е. в вашей конторе все программисты выполняют одну и ту же работу, а в конце месяца смотрят кто кого обогнал и в зависимости от этого выплачивают зарплату? Жёстко.

> Знaю. Пoэтoмy и гoвopил o вкyce (xyдoжecтвeннoм ;)), a нe o cлyxe.

Женская красота является ещё менее формализуемом понятием, однако мужчины легко делят женщин на красавиц и крокодилов. (0.0001% геронтофилов, некрофилов, педофилов и прочих уродов роли не играют)

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

> Kcтaти, c тoчки зpeния мyзыкaльнoгo cлyxa вcякиe тaм Bыcoцкиe, Бepнcтaйны, Дилaны, Шeвчyки и пpoчиe Xeтфилды c Янкaми и Лeтoвыми - oни жe aцтoй пoлный?

Да.

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

> Т.е. в вашей конторе все программисты выполняют одну и ту же работу, а в конце месяца смотрят кто кого обогнал и в зависимости от этого выплачивают зарплату? Жёстко.

Нет. Не приписывай мне того, чего я не говорил.

>> Знaю. Пoэтoмy и гoвopил o вкyce (xyдoжecтвeннoм ;)), a нe o cлyxe.

> Женская красота является ещё менее формализуемом понятием

Бог ты мой... ну кто тебе сказал такое? Женская красота довольно хорошо формализуется. Прочитай лекцию Гирина из Ефремовского "Лезвия бритвы", она в начале книги. Женская привлекательность - формализуется совсем плохо, потому что тут замешана индивидуальная психология. Но красота в понимании "сосуд она, в котором пустота" - всем ясна уж тысячи лет.

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

>> Kcтaти, c тoчки зpeния мyзыкaльнoгo cлyxa вcякиe тaм Bыcoцкиe, Бepнcтaйны, Дилaны, Шeвчyки и пpoчиe Xeтфилды c Янкaми и Лeтoвыми - oни жe aцтoй пoлный?

> Да.

С тобой не согласится куча умных людей. Раз пошла такая пьянка - кто _не ацтой_? Те самые группы, которые "наголову превосходят" ?

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

> Hy, yмeют oни кaк-тo...

Похоже на развод лохов на бабки. Типа после применения нашей туши объём ресниц увеличиваются на 68%.

> Hacкoлькo я пoмню иcтopию opyжия, пoвaльнoe пepeвoopyжeниe нaчaлocь пocлe тoгo, кaк в бoeвыx cтoлкнoвeнияx пapoxoды yбeдитeльнo yдeлaли пapycники.

Не совсем так. В николаевской России продолжали строить парусники вплоть до Крымской войны. (Да и после нее от них отказались не сразу и не полностью) Хотя до этого пароходы уже показывали в мелких войнах своё превосходство.

> Bo-пepвыx, ты yдoбнo пpoигнopиpoвaл cлoвo "мнoгoвeкoвoй".

А оно тут не главное. Главное что есть привычка и её фиг поменяешь.

> Bo-втopыx, пpeyчивaниe - этo чacть пpoфeccии пpoгpaммиcтa.

Быдлокодеры это не понимают. Они предпочитают затратить 50 эргов, доказывая что новая технология им не нужна, чем 100 эргов на изучение.

>Я пpивык пepeyчивaтьcя.

А давай ты на лиспера переучишься. Чисто по привычке. Просто пока ты этого не сделаешь ты не поймёшь зачем нужен лисп.

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

> Heт. He пpипиcывaй мнe тoгo, чeгo я нe гoвopил.

Хорошо. Есть проект, в котором заняты человек 10-15 народа. Каждый делает свою часть. Как вы их отсортируете по пользе, которые они приносят?

> Пpoчитaй лeкцию Гиpинa из Eфpeмoвcкoгo "Лeзвия бpитвы"

Это формализация? Это очень нестрогия рассуждения на тему. Формализация это когда можно будет написать программу, скормить её картинки и она рассортирует женщин.

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

>> Hy, yмeют oни кaк-тo...

> Похоже на развод лохов на бабки.

Я думаю, это из Бома, который уж точно не кидала. Хотя этот курс нам читали очень давно, и на прктике это не пригодилось.

> В николаевской России продолжали строить парусники вплоть до Крымской войны.

Ну ты и пример привел.

>> Bo-пepвыx, ты yдoбнo пpoигнopиpoвaл cлoвo "мнoгoвeкoвoй".

> А оно тут не главное. Главное что есть привычка и её фиг поменяешь.

Здесь бессмысленно спорить: если тебя не убедили революции, которые ты видел, то куда уж мне. "Пути меняются, Стилгар. Ты и сам их менял." -- Ф.Херберт, "Дюна"

>>Я пpивык пepeyчивaтьcя.

>А давай ты на лиспера переучишься.

Я один раз попробовал - не получилось. Пока не соберу достаточно информации - пробовать больше не буду, да и времени нет сейчас. А если соберу положительную информацию и будет шанс - попробую еще раз.

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

> Kcтaти, c тoчки зpeния мyзыкaльнoгo cлyxa

> Дa.

> C тoбoй нe coглacитcя кyчa yмныx людeй.

Дорогая редакция, вот пишу я вам и очень удивляюсь.

Ты жёсто задал критерий отбора --- умение попадать в разные высокие и низкие ноты.

Я ответил на твой вопрос. ---- Высоцкий в этом деле далеко не самый лучший.

А ты из этого сделал вывод, будто я сказал, что Высоцкий кретин, тексты у него тупые и слушать его невозможно.

Ну куда это годится?

> Paз пoшлa тaкaя пьянкa

Я в последнее время очень люблю группу "Полынья". Поют девчёнки изумительно, музыка хорошая и тексты очень не плохи.

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

> Есть проект, в котором заняты человек 10-15 народа. Каждый делает свою часть.

Я - скорее всего по сложности работы, которую они выполняют (ты сейчас спросишь, как определить сложность работы? 8)). А вообще - это работа начальника отдела. Сотни тысяч людей ее делают. "Тоже мне, бином Ньютона." -- (C) Кот Бегемот

>> Пpoчитaй лeкцию Гиpинa из Eфpeмoвcкoгo "Лeзвия бpитвы"

> Это формализация? Это очень нестрогия рассуждения на тему. Формализация это когда можно будет написать программу

И это придет. Может, это и сейчас возможно - но никому не нужно (люди вполне справляются сами ;)). И даже если это сейчас не запрограммируешь - и что с того? Машины пока не понимают текстов и не умеют их переводить, не видят нормально, да мало ли чего еще.

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

> (ты ceйчac cпpocишь, кaк oпpeдeлить cлoжнocть paбoты? 8))

Ты знал, я именно это и делаю.

> И этo пpидeт.

Как придёт, тогда и поговорим. Пока что красоту формализировать никто не в силах.

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

> жёсто задал критерий отбора --- умение попадать в разные высокие и низкие ноты.

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

> Я ответил на твой вопрос. ---- Высоцкий в этом деле далеко не самый лучший.

Не-а, ты сказал "ацтой полный" ;) Точнее, сказал я, а ты согласился.

> А ты из этого сделал вывод, будто я сказал, что Высоцкий кретин, тексты у него тупые и слушать его невозможно.

_Я_ сделал вывод только о том, что слушать невозможно. Остальное ты мне снова приписал :( Кстати, в списке было много народа - и есть люди, которые считают, что у Леонарда Бернстайна хороший голос (уж никак не "ацтой полный").

> Ну куда это годится?

Непонимание и ошибки - неизбежны. Надо просто находить их и устранять.

> в последнее время очень люблю группу "Полынья"

Запомню группу

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

>> ecли тeбя нe yбeдили peвoлюции,

> Все революции в ПО закончились в начале 80-ых.

Я не говорю о "революциях в ПО" (их было 1-2 за всё время вообще), я говорю о революциях в производстве/потреблении ПО. Я видел их 2 - переход на ПК и переход на Windows. Возможно, и третью вижу - переход на FOSS.

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

>> LM ты задаёшь логическую структуру интерфейса, а он сам делают визуальную раскладку

> Красиво излагаешь... 8) Если бы я сам не пользовался, бегом побежал бы пробовать.

А ты какой GUI/дезайнер интерфейсов используешь?

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

>> Даже MS признал необходимость LM

> Ну, если даже M$ признал - это точно труЪ

Погуглил, в delphi 2006 появились TFlowLayout и TGridLayout. О чём это говорит?

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

> проще - просто придётся чаще думать, чем долбить по клаве или елозить мышью

Пральна, а по времени то на то и выйдет.

Мнэ, и эти люди еще рассказывают мне про мое ИМХО ;-).

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

> Я к тому, что производительность труда прогаммиста - это более-менее объективная категория

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

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

> Я один раз попробовал - не получилось.

Хм, судя по некоторым вопросам ты задавал здесь, ты не уверен даже чё лисп вообще бывает. Без обид, но действительно, прежде чем пытаться переучиваться, нужно хотя бы иметь представление, на што переучиваешся. Ато дествительно неполучицо.

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

> Погуглил, в delphi 2006 появились TFlowLayout и TGridLayout. О чём это говорит?

ИМХО о том чё ЛАЖА начинает проходить всё реже и поставщики традиционно отсталых и убогих технологий, пропихивемых только за щёт пиара, хотябы в мелочях начяли задумываться о качестве.

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

> А ты какой GUI/дезайнер интерфейсов используешь?

Glade. Кстати, недавно прочитал, что наконец-то вышел Glade3. Появилась возможность создавать custom widgets. Через 12 лет после Delphi %)

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

> производительность труда программисат никому неинтересна (кроме крайне редких исключений когда она интересна самому программисту).

Ты это серьезно? Тогда позволь спросить - ты с какой планеты?

> Ещё одна аналогия фкопилку

Ещё раз повторю: доказательство по аналогии - мошенничество

> рабовладение существовало тысячелетия, если не десятки тысячелетий, хотя оно экономически невыгодно для общества.

Ну а эта фраза выдает всего лишь невежество^Wнезнание истории. Рабство появилось всего несколько тысяч лет назад, и появилось именно потому, что было _экономически_ выгодно.

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

>> производительность труда программисат никому неинтересна (кроме крайне редких исключений когда она интересна самому программисту).

> Ты это серьезно? Тогда позволь спросить - ты с какой планеты?

тутошние мы :( а на вашей прогесс дальше зашёл?

> Ещё раз повторю: доказательство по аналогии - мошенничество

ну как хош

> невежество^Wнезнание истории

интересно, чьё? тысячелетия ?= нескко тыщ лет? did you know what паровой движок был изобретён вон когда а начял использовацо вон когда? Впрочем, это простительно незнать тем, кто утверждает чё он уроженец иных планет.

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

> а на вашей прогесс дальше зашёл?

На нашей работу надо делать в срок

>> невежество^Wнезнание истории

> интересно, чьё?

Твое. Ты говорил об экономической невыгодности рабства и том, что оно существует десятки тысяч лет. Оба твоих утверждения ошибочны.

> did you know what паровой движок был изобретён

А это здесь причем? [кстати - "did you know that", не "what"]

> это простительно незнать тем, кто утверждает чё он уроженец иных планет.

Перестань принимать наркотики - это не доведет до добра.

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

>> а на вашей прогесс дальше зашёл?

> На нашей работу надо делать в срок

а срок ращитан из тово чё ея будут делать на делфях или на лиспе?

> Твое. Ты говорил об экономической невыгодности рабства и том, что оно существует десятки тысяч лет. Оба твоих утверждения ошибочны.

Я говорил чё (если не десятки ты лет). утя есь докозательство чё оно не существовало стоко? Исторически достоверные сведения отсосоцтвуют.

А нащёт невыгодности - см в том числе войну севера и юга как пример. Она была за отмену рабовладения но обусловлена чисто економическими.

> [кстати - "did you know that", не "what"]

мне без разницы, я перепечятал из борландовской вроде проги. Или мсявой? Полюбому, отправляй им багрепорт, не мне.

> А это здесь причем?

ну прецтафь чё лисп - это такой паровой движёк а ты - enterprise slave. Про остальное сам догодайся.

> Перестань принимать наркотики - это не доведет до добра.

звучит убедительно, особенно из твоих уст.

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

>> Перестань принимать наркотики - это не доведет до добра.

>звучит убедительно, особенно из твоих уст.

То есть перестанешь? Ну и хорошо.

А вообще, пора завязывать, обсуждение исчерпало себя. Оно было интересным и полезным (для меня), спасибо всем участникам.

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

>>> Перестань принимать наркотики - это не доведет до добра.

>> звучит убедительно, особенно из твоих уст.

> То есть перестанешь? Ну и хорошо.

да, даже и начинать не буду

> А вообще, пора завязывать, обсуждение исчерпало себя. Оно было интересным и полезным (для меня), спасибо всем участникам.

наздоровье.

/me раскланиваецо.

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

> ну прецтафь чё лисп - это такой паровой движёк а ты - enterprise slave. Про остальное сам догодайся.

Как говорится, "два солдата из стройбата заменяют экскаватор". У нас тут недавно тестеров тока-тока перевели на автоматическое тестирование гуевины посредством соответствующих роботов. Аха. Тестеры роботов днем ваяют, а те ночью, пока тихо и спокойно -- тестят. И то было на три месяца споров на предмет "а нафига нам это?". И главный аргумент начальства был на тему: "Если мы научим девочек-тестеров писать роботов, то они возомнят себя крутыми программерами. И платить им придется, как программерам. И станет их дом -- полная чаша. И станут они жить не нашей жизнью".

А Вы говорите -- программисты...

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

> Если не все - то вопрос снимается, всё ясно.

Это было ясно любому здравомыслящему _всегда_, ибо нет и не может быть серебрянной пули. Лиспом не заменишь узко-специализированные языки (скажет так - заменить можно, но нерационально): тот-же SQL, си как портабельный ассемблер тоже заменить трудновато будет, всякие перлы с шеллами скорее всего тоже не надо (пока :) на лисп переводить прямо сейчас - тяжеловат он для этого. Нормальных vm на лиспе на данный момент я не знаю :(

> Если не намного - тоже снимается по тем же причинам.

По тем же самым причинам специализированным языкам лисп может проигрывать по тем или иным характеристикам. Сводную объективную оценку получить трудно :)

> Как следует, что выгоден экономически: ты делаешь намного больше (он же намного превосходит!) за то же время...

Если рабы-кодеры практически бесплатны и легко возобновляемы, то комбайнам-лисперам трудно получить превосходство на полях софтостроения :)

> Как следует, что выгоден психологически - всем хочется иметь мощную и быструю тачку/мотоцикл/комп/дельтаплан, так вот это - из той же серии.

А ещё дешёвую, экономичную и легкоуправляемую, а то все бы ездили на болидах ф1 и летали на стелсах или чём там ещё... :)

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

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

> Я уже понял, что не получу ответа на _этот_ вопрос ;(

_Здесь_ - не получишь. По многочисленным ссылкам при наличии желания - запросто :)

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

> Человечество конечно несовершенно конечно, но не безнадёжно. Есть пути введения лисп в мейнстрим не уничтожая человечество.

Очень на это надеюсь... ;)

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

> > рабовладение существовало тысячелетия, если не десятки тысячелетий, хотя оно экономически невыгодно для общества.

> Ну а эта фраза выдает всего лишь невежество^Wнезнание истории. Рабство появилось всего несколько тысяч лет назад, и появилось именно потому, что было _экономически_ выгодно.

Это зависит от того, включать или нет рабов в понятие "общества", ибо речь шла о "невыгодно для общества" :)

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

> _Здесь_ - не получишь. По многочисленным ссылкам при наличии желания - запросто :)

Диалога ничем не заменишь

>> Если не все - то вопрос снимается, всё ясно.

>Это было ясно любому здравомыслящему _всегда_, ибо нет и не может быть серебрянной пули.

"Серебряная пуля" - это совсем из другой оперы. Языки, которые были некоторое время стандартами разработки _во всей отрасли_ - были (Си, Си++, Java). И мой вопрос был - если Лисп _настолько_ хорош, то почему он не стал таким стандартом?

>> Рабство появилось всего несколько тысяч лет назад, и появилось именно потому, что было _экономически_ выгодно.

> Это зависит от того, включать или нет рабов в понятие "общества", ибо речь шла о "невыгодно для общества" :)

Демагогия. Существует определение рабства, и определены довольно точные сроки его возникновения. Спорить не о чем.

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

> Демагогия.

Не согласен.

> Существует определение рабства, и определены довольно точные сроки его возникновения. Спорить не о чем.

С этим согласен. Но вопрос был - "выгодно для общества", а не для государства, страны, хрена лысого. Для вас это одно и то же? Так вот, с выгодой "для общества" возникают сложности :)

> И мой вопрос был - если Лисп _настолько_ хорош, то почему он не стал таким стандартом?

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

Почему не все остальные языки из вашего списка? Так по той-же причине, что и фаст-фуда и женских романов продаётся больше, чем нормальной еды и литературы :) Нужна аналогия с производством, а не потреблением? Ну, паровые двигатели тоже очень долго в промышленность прорывались ;) А мы всё ещё на стадии кустарных ремесленников находимся...

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

> Так вот, с выгодой "для общества" возникают сложности :)

Не возникает никаких сложностей. Рабство тогда способствовало прогрессу _общества_ (благодаря которому оно потом было проклято и запрещено - но потом, гораздо потом).

>> И мой вопрос был - если Лисп _настолько_ хорош, то почему он не стал таким стандартом?

> Почему не лисп, а си - потому что лисп вопреки вашему утверждению не является портабельным ассемблером

Это не я утверждал, а юджин_косенко 8)

> Нужна аналогия с производством, а не потреблением? Ну, паровые двигатели тоже очень долго в промышленность прорывались

Я не припомню каких-то сильных препон на пути прорыва паровых машин - как они стали приемлемо эффективными, так и стали применяться в промышленности. Кроме того - _такие_ аналогии с промышленностью в компьютерной области не катят - на одном и том же компе одинаково хорошо (и одновременно!) могут работать Си, Лисп и Жаба. И, наконец, у Лиспа было 40 лет на то, чтобы прорваться. Огромный срок по меркам нашей отрасли.

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

> Не возникает никаких сложностей. Рабство тогда способствовало прогрессу _общества_ (благодаря которому оно потом было проклято и запрещено - но потом, гораздо потом).

Только при условии _невключения_ рабов в определение этого самого общества. Рабам прогресс принесла только отмена этого самого рабства.

> Это не я утверждал, а юджин_косенко 8)

Принимается... :)

> Я не припомню каких-то сильных препон на пути прорыва паровых машин - как они стали приемлемо эффективными, так и стали применяться в промышленности.

Достаточно. Во-первых, препоны были (бунты, если не восстания цеховиков против "фабрикантов"). Во-вторых, не "приемлемо эффективными", а эффективнее одиночных ткачей с ручными станками/на ослиной тяге :). Пока "софтопряды" считают, что толпа легкозаменяемых кодеров - выгоднее, чем небольшое количество долгоподготавливаемых профессиналов высокого уровня (речь уже даже не о языке). Но это "пока" длится ровно до того момента, пока на первый план не выступит требование _качества_ кода. А там уже всё должно будет поменяться. Правда ,что там будет - я не знаю :)

> Кроме того - _такие_ аналогии с промышленностью в компьютерной области не катят - на одном и том же компе одинаково хорошо (и одновременно!) могут работать Си, Лисп и Жаба.

А вот здесь вы уже говорите о "потреблении", а не о "производстве" :)

> И, наконец, у Лиспа было 40 лет на то, чтобы прорваться. Огромный срок по меркам нашей отрасли.

У лиспа было 40 лет для того, чтобы обкатать большинство технологий, которые только сейчас (или недавно) стали внедряться в другие языки. А для прорыва не хватило желающих сделать из него "мэйнстрим" любой ценой :)

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

>> Почему не лисп, а си - потому что лисп вопреки вашему утверждению не является портабельным ассемблером

> Это не я утверждал, а юджин_косенко 8)

Видимо, они нас в одну команду записали :-)).

А если серьезно, то хотелось бы поконкретнее узнать, в чем именно заключается непортабельность Лиспа?

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

>> _Здесь_ - не получишь. По многочисленным ссылкам при наличии желания - запросто :)

> Диалога ничем не заменишь

ну тогда просто непонятно, какой бы ты хотел ответ. Можно было бы просто ответить "патамушта!" и это было бы правильно. Остальные аргументы, навроде того, что лисп позволяет описывать более абстрактные вещи ибо обладает наиболее богатым набором средств и самой простой и удобной семантикой, тебя ведь не впечатлили. Какого рода аргументация тебя бы устроила?

>> Это зависит от того, включать или нет рабов в понятие "общества", ибо речь шла о "невыгодно для общества" :)

> Демагогия. Существует определение рабства, и определены довольно точные сроки его возникновения. Спорить не о чем.

Это какие же сроки? Наиболее ранние официальныо признанные источники относяцо если не ашыбаюсь, к VII-V вв. до н.э., зарождению древнево египта. Достоверных более ранних просто нету.

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

> А если серьезно, то хотелось бы поконкретнее узнать, в чем именно заключается непортабельность Лиспа?

Иными словами, почему он не является "портабельным ассемблером"? Потому что изначально он был нацелен на работу с символами, а не адресами. Да, в его синтаксис можно загнать и работу с сылками, но в итоге вы не получите конечной гибкости. А работа с символами - некоторый "оверхед".

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

> Рабство тогда способствовало прогрессу

хм. did you know what рабство жестоко ограничивало применение разного рода механизмов? Или ты будеш утверждать, что механизмы нейдут на пользу прогресса?

> как они стали приемлемо эффективными, так и стали применяться в промышленности.

наоборот, они стали эффективными как только понадобились. До этого просто никто (со времён Нерона!) не работал над их эффективностью.

> И, наконец, у Лиспа было 40 лет на то, чтобы прорваться.

Прорваться куды? Я приводил кучю ссылок только на коммерческие реализации, стоимостью до нескко килобаксев. А сколько ты можеш назвать разных компилеров сей, с++ и жабы? Это приблизительно всёодно чё говорить "самолёты и вертолёты маргинальны и не получили распространения потому что по гаражам у всех лисапеды и жигулёнки"

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

> Только при условии _невключения_ рабов в определение этого самого общества. Рабам прогресс принесла только отмена этого самого рабства.

ИМХО спорное. Отмена рабства сопряжена с переходом на более продуктивную экономическую модель, и повышает уровень жизни всех, поголовно.

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

> А если серьезно, то хотелось бы поконкретнее узнать, в чем именно заключается непортабельность Лиспа?

http://www.cons.org/cmucl/FAQ.html 8й вопрос. ИМХО главным образом из-за того, что высокоуровневые абстракции нужно привязывать к конкретной модели жылеза и оси. Для портабельного макроассемблера навроде сей это намного проще, потому что в неоптимизированной форме ево операторы более-менее однозначно соответствуют группе асмовых комманд.

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

> требование _качества_ кода

уточню, требование _огромного_количества_пресложново_высококачественново_кода_ . Ибо на мелких задачах даже большой в процентах выйгрыш сравнительно невелик по сравнению с накладными расходами.

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

> ИМХО спорное. Отмена рабства сопряжена с переходом на более продуктивную экономическую модель, и повышает уровень жизни всех, поголовно.

Зыть, я же о том, что рабство самим рабам никакого прогресса не принесло

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

> уточню, требование _огромного_количества_пресложново_высококачественново_кода_ .

Спасибо за уточнение :) (Я думал, что это и так понятно... и не ошибся ;)

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

> Зыть, я же о том, что рабство самим рабам никакого прогресса не принесло

А я о том, что и остальным тоже сравнительно никаково.

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

> > Зыть, я же о том, что рабство самим рабам никакого прогресса не принесло

> А я о том, что и остальным тоже сравнительно никаково.

Опять на радость оппонентам поспорить не удалось... ;)

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

> Какого рода аргументация тебя бы устроила?

Что-нибудь вроде: "Лисп не получил распространения, это факт. Потому что его огромные и несомненные были скомпенсированы следующими недостатками: <здесь перечень недостатков>"

> Наиболее ранние официальныо признанные источники относяцо если не ашыбаюсь, к VII-V вв. до н.э., зарождению древнево египта.

Я люблю ЛОР, блин! Куда нас занесло, а? 8) VII-V вв. до н.э. - это период распада и упадка Египетского царства. Зарождение, IIRC - это примерно 3-4 тысячелетие до н.э. Официально зафиксированное рабство - примерно 5 тысячелетие до н.э. Правда, это курс истории 5-го класса, могу немного ошибаться (на тысячу лет :))

> Достоверных более ранних просто нету.

Есть в изобилии. К тому времени, что ты упоминаешь, были давно (тысячи лет назад) построены битком набитые папирусами пирамиды, доживало свое Новое Царство. А до него были еще Древнее и Среднее.

>> Зыть, я же о том, что рабство самим рабам никакого прогресса не принесло

>А я о том, что и остальным тоже сравнительно никаково.

Да ты что! До 500 г.н.э (примем, что именно тогда рабство стало невыгодным) не было никакого прогресса? Древние Египет, Ассирия, Персия, Греция, Рим - это нифига не прогресс? "Водопровод, сработанный еще рабами Рима" - не прогресс?

8))) Отличный, отличный топик

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

> Рабство тогда способствовало прогрессу

хм. did you know what рабство жестоко ограничивало применение разного рода механизмов? Или ты будеш утверждать, что механизмы нейдут на пользу прогресса?

Это где такое было? Это больше похоже на городские цеха веках так в 8..13-ом. > наоборот, они стали эффективными как только понадобились. До этого просто никто (со времён Нерона!) не работал над их эффективностью.

Не было у паровых машин непрерывной истории от Нерона до этого, как его (смотрит в яндекс), Ватта, да. В Риме это была игрушка, и на тех задачах, которые решались тогда (сельское хозяйство+ремесло), она была сильно хуже, чем рабы/тягловые животные. А потом ее переизобрели заново в 18-м веке. И когда Ватт приделал к ней автоматический регулятор - тут же завоевала практически всю энергетику (ж/д и морской транспорт, фабричные и рудничные приводы - а больше тогда ничего и не было).

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

>http://www.cons.org/cmucl/FAQ.html 8й вопрос.

А это уже половые проблемы CMUCL. :) Поэтому и сделали от него fork под названием SBCL, чтобы перестроить по-нормальному код, который портируется куда веселее, чем CMU. Думаю, что скоро планомерно возьмутся все высоты. Это и было основной целью проекта SBCL, который теперь своей жизнью зажил.

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

>> Рабство тогда способствовало прогрессу

>хм. did you know what рабство жестоко ограничивало применение разного рода механизмов?

Ключевое слово - "тогда" (речь, напомню, о Древнем Египте). И, естественно, со временем рабство превратилось в тормоз прогресса, и в основном исчезло, а потом вообще было объявлено вне закона.

И еще: по-моему, в таких случаях нужно писать "did you know THAT", не "what". Нет?

<невнятное про паровые машины поскипано>

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

> Лисп не получил распространения, это факт

какой же се факт? 8()

> Потому что его огромные и несомненные были скомпенсированы следующими недостатками: <здесь перечень недостатков>"

У всех есь недостатки. С недостатками мы боремсо.

> Куда нас занесло, а?

ёпт! мя глюкнуло. Я имел введу 5-7 тыс лет до н.э. вместо 5-7 века :( нуфсё, я аблажался и теперя мне никто не поверитнахъ :'(

> Да ты что! До 500 г.н.э (примем, что именно тогда рабство стало невыгодным) не было никакого прогресса? Древние Египет, Ассирия, Персия, Греция, Рим - это нифига не прогресс? "Водопровод, сработанный еще рабами Рима" - не прогресс?

А какой там прогресс? Ну строили чёто, выращивали, киляли друх друха. Или ты знаеш там были НТР про котороя я не ведаю?

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

> До 500 г.н.э (примем, что именно тогда рабство стало невыгодным)

Ну это неправда же ни разу, это еще даже не расцвет средиземноморских рабовладельческих империй. В 500-м году еще ни Александр Македонский, ни Пунические войны даже в планах не значились (правда, Золотой Век Афин уже наступал потихоньку).

Рабство стало невыгодным эдак чуть позже Цезаря (Гая Юлия), да и то больше из-за истощения африканских земель.

А в Конфедерации оно оставалось выгодным до середины 19-го века, и сохранилось бы и дольше - но северяне не позволили.

И, кстати, выгодность политического строя для общества имеет смысл мерить по высшим достижениям этого общества - нет никаких сомнений, что Египет и Микены, Рим и Карфаген были большим шагом вперед по сравнению с племенными кланами пастухов...

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

> речь, напомню, о Древнем Египте

паровой движок был изобретён в древней греции. А вот паровоз - нет. Потому что использование механизмов невыгодно людишкам при рабовладении. Это ведь не означяет чё их использование невыходно опчеству?

> И еще: по-моему, в таких случаях нужно писать "did you know THAT", не "what". Нет?

Я ужо говорил, чё перепечятал это из толи борландовской толи мсявой проги и чё багрепорты луче направлять к им.

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

>> Лисп не получил распространения, это факт

> какой же се факт? 8()

Голый!

> > Куда нас занесло, а?

> ёпт! мя глюкнуло. ... я аблажался и теперя мне никто не поверитнахъ :'(

Ни за чьто!

> А какой там прогресс? Ну строили чёто, выращивали, киляли друх друха.

Да, Вавилон, Персеполис, Афины, Александрия, Рим - это так, "чёто". Мореплавание - какя мелочь. Ирригационные системы - тоже фигня. То, что "киляли друх друха" с ипользованием всё более совершенного оружиея и тактики - тоже ни разу не прогресс.

Ну а греческие театр и изобразительное исскуство, греческая и римская философия - они даже упоминания не стоят - это же не НТР. Только НТР стоит нашего просвещенного внимания!

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

> А если серьезно, то хотелось бы поконкретнее узнать, в чем именно заключается непортабельность Лиспа?

Не непортабельность, а более сложный процесс. Если взять CLISP, то у него с платформами все просто, так как он есть байт-код интерпретатор, написанный на C. Где скомпилится, там и пойдет. А вот с компиляторами LISP сложнее, так как поимио обеспечения нативной кодогенерации, надо еще иметь привзяку к операционной системе.

Если ты внимательно посомтришь на исходник SBCL в разделе runtime, то там все увидишь. Большой набор C-файлов, зависящих от ОС (в названиях) и архитектуры. Они там так и встречаются: alpha-osf1-os.c, alpha-linux-os.c, и т. д. :

http://sbcl.cvs.sourceforge.net/sbcl/sbcl/src/runtime/

А если ты о непортабельности кода на CL в разных реализациях, то и такое случается. Если взглянешь на серьезный проект, то увидишь там условные дела: #+sbcl #+allegro, #+openmcl и т. д. Это от того, что когда речь заходит о вещах, не описаных в стандарте, то у многих реализаций развязаны руки. Делают свое. А ты должен иметь в виду, что если ты используешь библиотеку sb-posix в SBCL, например, то ее не будет в другой реализации или она совсем другая. Или sb-bsd-sockets, например.

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

>>> Лисп не получил распространения, это факт

>> какой же се факт? 8()

> Голый!

в бане вместе парились, да?

> Да, Вавилон, Персеполис, Афины, Александрия, Рим - это так, "чёто". Мореплавание - какя мелочь. Ирригационные системы - тоже фигня. То, что "киляли друх друха" с ипользованием всё более совершенного оружиея и тактики - тоже ни разу не прогресс.

ну сравни с 19-20 веками.

> Только НТР стоит нашего просвещенного внимания!

в рамках данново топика, да. Ибо в противном случяе придёцо всякое типо методики ХР за прогесс признать.

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

> Что-нибудь вроде: "Лисп не получил распространения, это факт. Потому что его огромные и несомненные были скомпенсированы следующими недостатками: <здесь перечень недостатков>"

Ни кто не говорит, что у лиспа (CL?) нет недостатков _как у ЯП_. (И когда-то он таки был довольно распространён в процентном соотношении). Но он не получил массового распространения в большей степени не из-за своих недостатков. Лисп тоже не сразу стал CL-м. И макры в нём появились не сразу. И CLOS. И т.д., и т.д. С учётом оверхеда на "символьные вычисления" и ограниченности ресурсов можно было найти/создать более эффективный (в машинном плане) язык для конкретной области (си, кобол и т.д.). А с появлением писишек на рынок вылезли совсем другие "правила игры". К моменту появления железа, на котором на оверхед лиспа можно было не смотреть, у него была куча "конкурентов", которые имели уже довольно "широкие слои комьюнити", через которые не так-то легко пробиться, учитывая, что очень многие стали руководствоваться личными предпочтениями/привязанностями, а не строгой оценкой и прочее. Опять же мифы и предвзятое отношение...

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

>> До 500 г.н.э (примем, что именно тогда рабство стало невыгодным)

> Ну это неправда же ни разу, это еще даже не расцвет средиземноморских рабовладельческих империй. В 500-м году еще ни Александр Македонский, ни Пунические войны даже в планах не значились (правда, Золотой Век Афин уже наступал потихоньку).

У тебя проблемы с датами или чтением? А.Ф.Македонский умер в 325 г до н.э, Пунические войны закончились (IIRC) к 210 г. до н.э. А к 500 г н.э. готы уже 4 года как взяли Рим.

> Египет и Микены, Рим и Карфаген были большим шагом вперед по сравнению с племенными кланами пастухов

При этом зижделись на использовании рабского труда.

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

>> Да, Вавилон, Персеполис, Афины, Александрия, Рим - это так, "чёто". Мореплавание - какя мелочь. Ирригационные системы - тоже фигня. То, что "киляли друх друха" с ипользованием всё более совершенного оружиея и тактики - тоже ни разу не прогресс.

> ну сравни с 19-20 веками.

Ну заметь разницу в 3-4 тысячи лет.

Или сравни 20-й век с 50-м :-P

>> Только НТР стоит нашего просвещенного внимания!

>в рамках данново топика, да

Кстати, о топике... уже анонимные братья подтягиваться начали. Нехороший знак.

> Ибо в противном случяе придёцо всякое типо методики ХР за прогесс признать.

Лет через 10 увидим, что это было.

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

>А если серьезно, то хотелось бы поконкретнее узнать, в чем именно 
заключается непортабельность Лиспа?

Проще приведу пример из произвольного кода:

#+lispworks
(eval-when (:compile-toplevel :load-toplevel :execute)
  (require "comm"))

#+sbcl
(eval-when (:compile-toplevel :load-toplevel :execute)
  (require :sb-bsd-sockets))

;; managing processes

(defun current-process ()
  "Return the object representing the current process"
  #+lispworks mp:*current-process* 
  #+abcl (ext:current-thread)
  #+openmcl ccl:*current-process*
  #+sb-thread sb-thread:*current-thread*
  #+allegro sys:*current-process*
  #-(or lispworks abcl openmcl sb-thread allegro) nil)

(defun kill-process (process)
  "Kill the process represented by the object process"
  #+lispworks (mp:process-kill process)
  #+abcl (ext:destroy-thread process)
  #+openmcl (ccl:process-kill process)
  #+sb-thread (sb-thread:terminate-thread process)
  #+allegro (mp:process-kill process)
  #-(or lispworks abcl openmcl sb-thread allegro) process)

Тут видно, что тредные библиотеки в разных реализациях разные. Это не 
оговорено стандартом и очень зависит от реализации, поэтому 
не взаимозаменяемо.

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

>> ну сравни с 19-20 веками.

> Ну заметь разницу в 3-4 тысячи лет.

> Или сравни 20-й век с 50-м :-P

Дык и я про чё. За 2-3 века было прогрессу больше чем за тыщелетия.

> Кстати, о топике... уже анонимные братья подтягиваться начали. Нехороший знак.

Почему? Замечятельный. Главное чёбы модераторы не подтянулись, не к нощи будут упомянуты. А так, мож РФВС догоним если уж до форматоф недотянем.

>> Ибо в противном случяе придёцо всякое типо методики ХР за прогесс признать.

> Лет через 10 увидим, что это было.

Я предпочитаю сам создавать то, чё лет чз 10 смотреть будут.

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

>> И еще: по-моему, в таких случаях нужно писать "did you know THAT", не "what". Нет?

>Я ужо говорил, чё перепечятал это из толи борландовской толи мсявой проги

Не узнал тебя под анонимусом

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

> За 2-3 века было прогрессу больше чем за тыщелетия.

Не в том дело, когда развитие было быстрее (я бы не взялся оценивать). Главное - развитие было всегда, и некоторое время рабовладение было его двигателем.

> Я предпочитаю сам создавать то, чё лет чз 10 смотреть будут.

Доведешь до юзабельного состояния - запости ссылку

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

> Главное - развитие было всегда, и некоторое время рабовладение было его двигателем.

Не, я думаю, с "двигателем" ты перебрал... Ну ещё "используя эффективность" или что-то в этом роде... Но двигателем... ;)

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

>> Главное - развитие было всегда, и некоторое время рабовладение было его двигателем.

>Не, я думаю, с "двигателем" ты перебрал... Ну ещё "используя эффективность" или что-то в этом роде

ОК, "и некоторое время рабовладение способствовало прогрессу".

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

> У тебя проблемы с датами или чтением?

С чтением. Прочитал, что рабство стало невыгодным к "500 г. до н.э.".

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

> > Египет и Микены, Рим и Карфаген были большим шагом вперед по сравнению с племенными кланами пастухов

> При этом зижделись на использовании рабского труда.

Ну дык и я о том же. Впрочем, это уже совсем жесточайший оффтопик.

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

> Не узнал тебя под анонимусом

Это не я под ононимусом, это просто так неудачно процитировали.

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

> Не в том дело, когда развитие было быстрее

почему? как раз в этом дело. Иначе, почему ты думаеш европейцы открыли америку а не наоборот? Потому что у тех даже колеса неиспользовались в хозяйстве, хотя были изобретены.

> Главное - развитие было всегда,

ну, совсем ево не может не быть, полюбому.

> и некоторое время рабовладение было его двигателем.

Всё правильно, вопрос только в мощности двигателя. Автоматизация например на период рабства недоступна и невозможна, сам понимаеш почему. А между применением техники и толпой рабов разница принципиальная, многое, что недоступно толпе рабов, техникой делаецо.

> Доведешь до юзабельного состояния - запости ссылку

Ладно. А как доказать, что это именно то, на что будут смотреть?

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

> у тех даже колеса неиспользовались в хозяйстве, хотя были изобретены.

Да? Школьный курс истории утверждал, что "индейцы не знали колеса".

> А как доказать, что это именно то, на что будут смотреть?

Мне без разницы - будут, не будут. Мне _самому_ взглянуть любопытно.

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

> Да? Школьный курс истории утверждал, что "индейцы не знали колеса".

Не совсем так. Они отлично знали колесов, но не использовали их в практической деетельности, в т.ч. по религиозным соображениям, подобно тому как современное програмисты неюзают лиспа.

> Мне без разницы - будут, не будут. Мне _самому_ взглянуть любопытно.

ну на лисп глянь сперва, там многое на ево основе.

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

>> подобно тому как современное програмисты неюзают лиспа.

> Я знал, что ты это скажешь 8)

Хшё когда меж собеседниками взаимопонимание.

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

> Потому что изначально он был нацелен на работу с символами, а не адресами. Да, в его синтаксис можно загнать и работу с сылками, но в итоге вы не получите конечной гибкости. А работа с символами - некоторый "оверхед".

Это все лехко решается на уровне виртуальной машины. Я больше поверю аргументам о том, что оно непортабельно из-за слишком малого ядра языка. Дыкть, С с библиотеками тоже не совсем портабелен. Речь ведь шла о языках, а не о библиотеках.

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

>Лисп тоже не сразу стал CL-м.

Совершенно верно. Стандартом ANSI он стал только в 1994 году. Вся история LISP -- это борьба реализаций и подходов. То есть настоящий эволюционный процесс. И CLOS в одночасье не появился. До этого были абсолютно разные реализации: LOOPS от Xerox, FLAVORS от симболикса и др. AFAIK, именно версия от Xerox легла в основу стандарта. Ну или по большей части.

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

>>Лисп тоже не сразу стал CL-м.

>Совершенно верно. Стандартом ANSI он стал только в 1994 году.

Не знаю насчет стандарта ANSI, но "Common Lisp was defined and a book published in 1984 called 'Common Lisp: the Language'". Так что сам язык - ровесник Си++.

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

> Это все лехко решается на уровне виртуальной машины. Я больше поверю аргументам о том, что оно непортабельно из-за слишком малого ядра языка.

На сколько легко? И как давно? Вы про сегодняшний день, или про всю историю лиспа?

"непортабельно из-за слишком малого ядра языка" - расшифруйте пожалуйста :) И опять же, мы о лиспе "CAR-CDR" или о CL? В CL-е ядро маленьким никак не назовёшь. А со всеми необходимыми типами и т.п. - это уже почти CL получится. Вывести всю систему типов из списка можно, но это будет очень неэффективно (если вы только не предложите спец. процессор :)

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

Немецкие нацисты показали, что рабовладельчество может быть очень даже эффективно и в наше время.

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

>Не знаю насчет стандарта ANSI, но "Common Lisp was defined and a book published in 1984 called 'Common Lisp: the Language'". Так что сам язык - ровесник Си++.

Ну я сейчас не готов говорить, почему у этих языков в результате такая разная судьба. Этот период надо пережить. Я могу только говорить за себя. Когда я учился в бауманке, то моей тематикой были около-ИИ-шные темы. Ну и первое, что попадалось на глаза были LISP и Пролог. В результате в качестве среды для реализации был выбран Пролог. Инфраструктура была более развитая. Он чаще попадался на глаза. А еще интернета толком не было тогда. Только некоторые счастливчики на работе имели. Поэтому узнать более подробно, а тем более получить что-то подобное на руки для LISP было нереально. А вот с Прологом было все гораздо лучше (всюду был как минимум компилятор Borland Turbo Prolog). А как появился Интернет, то средство было выбрано. Потом был голландский SWI Prolog (его я использовал наиболее активно), Quintus Prolog и т. д. Считаю, что я много потерял, не имев возможности обратить внимание на LISP тогда. C++ был сразу подхвачен индустрией для массового внедрения. А LISP большей частью был в университетской среде. Кто первый встал, того и тапки. Вот и все мысли неглубокие. Говорить о том, что не произошло, не имеет смысла. Говорить уместно о том, что произойдет :)

P.S. А эффективные реализации Пролога есть и на LISP. :)

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

> Кто первый встал, того и тапки.

Первым-то встал как раз Лисп. Почему же раз за разом тапки доставались не ему?

> Говорить уместно о том, что произойдет :)

И что же произойдет?

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

>Первым-то встал как раз Лисп. Почему же раз за разом тапки доставались не ему?

В тапки индустрии. Крутился вокруг исследовательских проектов относительно небольшого количества людей (типа посвященных). Ну еще внутри корпораций для своих нужд использовался и до тех пор, пока были люди, его знающие. И главное -- не было тмогущественных компаний, которые его продвигали и совершенствовали. Был симболикс, были подразделения в Texas Instruments (CLX там и был написал в 1987 году, LISP-машины делали), была LMI, для которой старался RMS. Но это не тот масштаб. И слава богу, что так. Мне не хочется, чтобы Lisp стал мэйнстримом. Поэтому и убеждать не хочу никого. :)

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

> Первым-то встал как раз Лисп. Почему же раз за разом тапки доставались не ему?

Опять про море? ;)

Где ему тапки не достались? На писишках? Так он там первым и не был (если не считать лисп-машины, но те по цене... кусались слегка ;) да и к писишкам те компьютеры никакого отношения, разве что кроме габаритов, не имеют), а посему и тапки не его.

Ещё вопросы есть?

P.S. Не устали нам доказывать, что лисп вам незачем? :)Ь

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

>> Первым-то встал как раз Лисп. Почему же раз за разом тапки доставались не ему?

>Опять про море? ;)

А у него я еще не спрашивал ;)

> Где ему тапки не достались? На писишках? Так он там первым и не был

Да нигде - ни на мини-машинах, ни на рабочих станциях. "Встал первым" == "первым ассимилировал в себя кучу передовых идей".

> Ещё вопросы есть?

А ответы?

> P.S. Не устали нам доказывать, что лисп вам незачем? :)Ь

??? "Доказывать" ? Я сказал в самом начале - _сейчас_ Лисп мне не нужен, что тут доказывать? А мнения лисперов о том, почему их язык при всех достоинствах остался уделом немногих - мне интересны. "Мне не хочется, чтобы Lisp стал мэйнстримом." - это интересное мнение. Еще бы услышать обоснование :)

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

> Первым-то встал как раз Лисп. Почему же раз за разом тапки доставались не ему?

За песюки война токо-токо начинается. Ну ненужно было раньше на писишках таково рода наречий. И двух-трёхкратный проигрыш в производительности жалко было отдавать, и задачи сравнительно простые и прог мало делалось => можно было нанять нужное число человек и всё на с/с++ сделают. Именно в последнее время проснулся интерес к интерпретируемым/байткодным. Начяли появляцо всякие руби с питонами. А подход к программированию пока старый остался, с/с++-образный. Нового не выработали ещё. Скоро случицо кризис в айти, потом ужо всё по своим местам расползёцо.

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

> Да нигде - ни на мини-машинах, ни на рабочих станциях.

Хм, биологи давно вовсю юзают. Остальным пока не припёрло.

> "Встал первым" == "первым ассимилировал в себя кучу передовых идей"

Бывают _ненужные_пока_ идеи, хоть они правильные и передовые.

> почему их язык при всех достоинствах остался уделом немногих

Как раз достаточно многих. Из более чем 2000 языков и наречий много ли сможеш назвать? А сколько из них юзаецо больше лиспа?

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

> "Встал первым" == "первым ассимилировал в себя кучу передовых идей".

Ну и? На тот момент эти идеи нафиг никому не упёрлись - вот и тапок нет. Что поделаешь, если до людей сразу не доходит, а только после нескольких десятков лет хождения по граблям... Так что вы это у себя спросите - почему же у лиспа до сих пор тапок нет ;)

> А ответы?

А-а-а-а.... чукча не читатель... Понятно ;)

> А мнения лисперов о том, почему их язык при всех достоинствах остался уделом немногих - мне интересны.

Потому что он многим и не нужен. На постсоветском пространстве вообще натуральное хозяйство ещё очень даже в ходу... и это в 21-м веке. Что уж удивляться, что лисп многим не нужен... Мотыгой сподручнее ;)

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

> Именно в последнее время проснулся интерес к интерпретируемым/байткодным.

Мне всегда казалось ошибкой на грани слабоумия то, что в них выделяют именно эту черту. По мне, так это лишь деталь реализации. Были байткодные интерпретаторы Си - и кому они интересны? То же и с Фортом - байткодный (ну ладно, косвенно-шито-кодный), интерпретируемый.

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

> Мне всегда казалось ошибкой на грани слабоумия то, что в них выделяют именно эту черту.

Вот тут с тобой совершенно согласен. CMUCL и SBCL генерят "натив", при этом "впереди планеты всей" ;)

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

> Мне всегда казалось ошибкой на грани слабоумия то, что в них выделяют именно эту черту.

Ну выделяют ведь, и этому есть причины, и есь следствия.

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

> Вот тут с тобой совершенно согласен. CMUCL и SBCL генерят "натив", при этом "впереди планеты всей" ;)

Выполнябельник всё-таки удобнее ИМХО. А ево-то и негенерят :(

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

> Я тут начял лисп ругать. Присоединяйся!

Чтобы _так_ ругать Лисп, надо его хорошо знать, а я его не знаю.

Но присоединюсь, конечно: СКОБАЧКИ САСУТ!!!!

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

> Но присоединюсь, конечно: СКОБАЧКИ САСУТ!!!!

Замените их на то, что у вас не сосёт... А то того... последствия могут быть ;)

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

> Но присоединюсь, конечно: СКОБАЧКИ САСУТ!!!!

Ну чё делать, да, сасут. И макры тоже. Подождём, когда в питоне такое появицо. Тогда в лиспе сразу сасать перестанут. А так - пока будем получять удовольствие.

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

> небось бинарь получицо как в хаскеле, писятмех?

Пустой - почти в два раза меньше (вроде) ~ 26 мег :)

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

>> Но присоединюсь, конечно: СКОБАЧКИ САСУТ!!!!

> Замените их на то, что у вас не сосёт... А то того... последствия могут быть ;)

Какие? Делись опытом!

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

> Какие? Делись опытом!

Опыта нет. Есть информация из малой медицинской энциклопедии :)

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

Есь мнение, что у юзающево то, чё сасьйот, высасывает моск в конце концов. Это мнение иногда подтверждаецо, например в случяе с юзверями венды и питона, а иногда нет, как в случяе с скопками. Хотя, возможно, скопки всё-таки не...

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

>> Хотя, возможно, скопки всё-таки не...

> Фраза внезапно обрывается... Ты там в порядке?

Я тут нормально. А у тя как?

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

ладно, только с условием чё ты оставшиеся до нево ты тож сам забивать будеш.

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

>Если спросить 10 случайно выбранных программистов, не знакомых ни с >Лиспом, ни с Питоном, что им понятнее - текст на Лиспе или на >Питоне, все 10 скажут - на Питоне. Но ты-то знаешь, что они все >извращенцы...

А что это:

def permutations(e):
    if not e:
        yield []
    else:
        for p in permutations(e[1:]):
            for i in xrange(len(e)):
                new = list(p)
                new.insert(i, e[0])
                yield new

читается намого лучше, чем:

(defun permutations-my (x)
  (if (null x)
    (loop for e in x append
       (loop for p in (permutations-my (remove e x :count 1 :test 'eq))
                 collect (cons e p)))
      '(nil)))

Пример на Лиспе IMHO больше смахивает на английский язык.

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

> То же и с Фортом - байткодный (ну ладно, косвенно-шито-кодный), интерпретируемый.

Ну не совсем; многие Форты вполне способны разворачивать шитый код в машинный и пробегаться по нему оптимизатором. Тот же SP-Forth, например.

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

Был уже апдейт:

def permutations(e):
    if not e:
        yield []
    else:
        for p in permutations(e[1:]):
            for i in xrange(len(e)):
                yield p[:i] + [e[0]] + p[i:]

А по поводу похожести на английский:

1. Не припомню в английском слова "cons"

2. Слова в лиспе английские, но вот предложений как-то не образуется.
   Или Йода мастер лиспе сказал это на?

3. Надо поменять опрос, сменить его на: "какая из этих программ более
   читаемая?"

4. COBOL ваще от английского не отличить. И что?

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

> А по поводу похожести на английский:

Сейчас опять чукчу вспоминать буду... ;)

"Пример на Лиспе IMHO больше смахивает на английский язык."

Ты слово _больше_ видишь? А смысл понимаешь? Он в том, что "код на лиспе больше смахивает на английский язык чем код на питоне". Или ты будешь доказывать, что код на питоне похож на английский больше?

А о том, что лисп таки отличается от английского - так это ты пальцем в небо ;)

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

> Сейчас опять чукчу вспоминать буду... ;)

Шутка, повторенная дважды, причем неуместно... причем очень старая шутка

> Или ты будешь доказывать, что код на питоне похож на английский больше?

Вообще-то это не надо доказывать - это очевидно. По крайней мере в обновленной Питоньей версии меньше не-слов (это "def" и "xrange"), не говоря уже о том, что синтаксис ближе к естественному языку.

> А о том, что лисп таки отличается от английского - так это ты пальцем в небо ;)

ЕМНИП, "попасть пальцем в небо" - это значит "сильно ошиьится". Ты хочешь сказать, что лисп _не_ отличается от английского? :-O

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

> Вообще-то это не надо доказывать - это очевидно.

:-Е Дальше можно не читать...

> ЕМНИП, "попасть пальцем в небо" - это значит "сильно ошиьится".

Ок, тогда это я "попал пальцем в небо" :)

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

> > Именно в последнее время проснулся интерес к интерпретируемым/байткодным.

> Мне всегда казалось ошибкой на грани слабоумия то, что в них выделяют именно эту черту.

Ну, собственно, фишка с ними, имхо, в "запускаемом исходнике". Т.е. нету выделенного (интерфейсно) этапа компиляции => упрощается цикл разработки. И с поддержкой/внедрением проще - можно "править по живому", если надо, не парясь со сборкой. И переносимость, все же, выше - я одну и ту же перловую программу пускаю линуксе/amd64 и freebsd/x86, и даже могу делать вещи типа

open F, '| ssh runner\@other_os perl > local_result.txt');

print F $generated_source_code;

что на си довольно затруднительно.

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

>> > Именно в последнее время проснулся интерес к интерпретируемым/байткодным.

>> Мне всегда казалось ошибкой на грани слабоумия то, что в них выделяют именно эту черту.

>Ну, собственно, фишка с ними, имхо, в "запускаемом исходнике". Т.е. нету выделенного (интерфейсно) этапа компиляции

Ты сказал "интерпретируемый" другими словами :-P

По-моему, фишка именно в более высоком уровне при больше простоте использования - там, где на Си++ (тем более Java) нужна нудная писанина, на Питон/Ruby всего пара строк

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

> Ты сказал "интерпретируемый" другими словами :-P

Отсутствие _выделенного (интерфейсно) этапа компиляции_ не означает отсутствие компиляции (в натив) вообще. А это уже к интерпретируемым не относиться (имхо)

> По-моему, фишка именно в более высоком уровне при больше простоте использования - там, где на Си++ (тем более Java) нужна нудная писанина, на Питон/Ruby всего пара строк

Так было уже - с лиспом имеем и простоту использования, и компиляцию в натив (инкрементальную), да - в некоторых реализациях.

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

> Так было уже - с лиспом имеем и простоту использования, и компиляцию в натив

Воот, но волну интереса к динамическим и функциональным языкам подняли Python и Ruby :-P

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

> Воот, но волну интереса к динамическим и функциональным языкам подняли Python и Ruby :-P

Угу, это сродни "научно-популярной литературе" :)

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

> > Воот, но волну интереса к динамическим и функциональным языкам подняли Python и Ruby :-P

> Угу, это сродни "научно-популярной литературе" :)

Хотя нисколько не умаляю их вклада в это дело - сам пришёл к лиспу "через"питон :) Надо лишь отдать себе отчёт, что это не "венец творения", а робкая попытка приблизиться ;)Ь

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

> Угу, это сродни "научно-популярной литературе" :)

> сам пришёл к лиспу "через"питон :) Надо лишь отдать себе отчёт, что это не "венец творения", а робкая попытка приблизиться ;)Ь

Это сродни применению наработок кабинетных ученых на практике.

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

> Это сродни применению наработок кабинетных ученых на практике.

Ну, можно и так, только очень хочется спросить: "Если вы спёрли^Wскопировали форму конфетки - почему рецептом самой конфетки не воспользовались?" :)

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

>> Это сродни применению наработок кабинетных ученых на практике.

> Ну, можно и так, только очень хочется спросить: "Если вы спёрли^Wскопировали форму конфетки - почему рецептом самой конфетки не воспользовались?" :)

Ох уж мне эти аналогии... "Всякое сравнение хромает" -- (С) Немецкий народ. А у этого твоего сравнения - вообще ДЦП. Ни форму, ни обертку, ни рецепт ни Руби, ни Питон не копировали. Взяли то, что практично.

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

> Ох уж мне эти аналогии...

А они не "доказательство", а наживка - думать и оценивать всё равно самому надо ;)

> Ни форму, ни обертку, ни рецепт ни Руби, ни Питон не копировали. Взяли то, что практично.

Взяли технологии, с успехом применяемые в языке вот уже более ... лет, некоторые из которых из этого языка и выросли.

А по поводу "практично" - взяли то, что смогли "практично" внедрить, ибо если бы взяли то, с чем "практично" работать - лисп получился бы :)

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

Да и японцы тоже активно применяли труд заключённых наверное ради денег, а не из-за бескорыстного желания облагородить других людей.

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

> но волну интереса к динамическим и функциональным языкам подняли Python и Ruby

не путай причины и следствия. Появился интерес - появился и питон и раби и ещё другое.

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

> Появился интерес - появился и питон и раби и ещё другое.

Три раза "ха". Питон появился году в 1991-1992, Руби - в 1995. Может, они и не причина, но появились намного раньше, чем нынешняя волна интереса.

(мы уверенно движемся в Top 1 8))

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

> Три раза "ха". Питон появился году в 1991-1992, Руби - в 1995. Может, они и не причина, но появились намного раньше, чем нынешняя волна интереса.

(занудно так) А Perl - ажно в 1987-ом... Вместе с Tcl.

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

>> Питон появился году в 1991-1992, Руби - в 1995. Может, они и не причина, но появились намного раньше, чем нынешняя волна интереса.

> (занудно так) А Perl - ажно в 1987-ом... Вместе с Tcl.

Знаю. И всё же волна интереса связана именно с Python/Ruby. Не с Lisp/Tcl/Perl.

Вспомнилась прикольная цитата: "TCL is Lisp on drugs".

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

> Ни форму, ни обертку, ни рецепт ни Руби, ни Питон не копировали. Взяли то, что практично.

Вот именно, что взяли. Изначально, был фортран для числовых ращётов, а затем подтянулся лисп, для символьных. И задачи и средства и форма их отличялись. Фортран улучшали и на ево основе были изготовлены бейсик и другие в соответствии с задачями, а на основе лиспа - коммон лисп и схемы. Первые более приспособлены для работы с числами, и крайне скудно, со строками: традиционная математическая запись с зверинцем из функций, префиксных и инфиксных операторов. Вторые изначяльно ращщитаны на абстракции более высоких порядков, и соответственно у них более "общяя", подходящяя для более произвольной формы представления данных, метода. Бедолаги же пытаются использовать часть конструкций, практичных в одном окружении, и приживить в другое, чуждое им. Практичные конструкции не передохнут, потому что нужны. Что остаёцо? Либо мутировать окружение до уровня того, откуда их взяли, либо использовать готовое, уже отлаженное. Руби и лисп - это несомненно переходные от первого ко второму, и им развиваться очень долго ещё из-за фортраньего груза.

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

> Либо мутировать окружение до уровня того, откуда их взяли, либо использовать готовое, уже отлаженное

Это называется "ложная альтернатива". На самом деле, остается еще до фига путей. Это как цвета и вкусы - их можно получить, комбинируя базовые, но в мире гораздо больше цветов, чем RGB, и гораздо больше вкусов, чем кислый/соленый/горький/сладкий. Может быть, что "базовых" языков программирования - 2 (Лисп и Фортран). Но мы будем использовать гораздо больше. Всегда. Так что нет никаого "перехода от первого ко второму", это путь _между_ ними.

Блин, и меня на аналогии потянуло :/

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

>Пустой - почти в два раза меньше (вроде) ~ 26 мег :)

Дык в архиве ядро SBCL ужимается до 4-5Мb, что вполне терпимо.

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

> Три раза "ха". Питон появился году в 1991-1992, Руби - в 1995. Может, они и не причина, но появились намного раньше, чем нынешняя волна интереса.

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

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

> Знаю. И всё же волна интереса связана именно с Python/Ruby. Не с Lisp/Tcl/Perl.

к лиспу волна интереса не скоро появицо, потому что нужно время понять: безсмысленно прилаживать куски концепций к основе, на которой они не очень держацо.

> Вспомнилась прикольная цитата: "TCL is Lisp on drugs".

недавно пытался работать с тиклем. Есть много оббщего с лиспом но ужоснахъ.

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

> Поправь последнее предложение ;)

чё с им нетак?

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

> На самом деле, остается еще до фига путей.

Например?

> Это как цвета и вкусы - их можно получить, комбинируя базовые, но в мире гораздо больше цветов, чем RGB, и гораздо больше вкусов, чем кислый/соленый/горький/сладкий.

Можно. Но есть цвет и есть вкус. Сколько бы ты цветов не комбинировал, новово вкуса не получиш.

> Может быть, что "базовых" языков программирования - 2 (Лисп и Фортран). Но мы будем использовать гораздо больше. Всегда.

Дело не в езыках, а в концепциях, в их закладенных. Я вижу только две - "фортрановскую": декомпозиция задачи до уровня чисел (включяя строки как наборы кодов) с последующей их обработкой алгоритмически, и "лисповую": создание базиса для абстракций, и их конкретизация в проге до соответствующево задаче уровня. Первый путь короток и пройден до упора, а второй _массово_ только-только начинаецо, хотя для рада задачь применяецо давно и успешно.

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

> Дело не в езыках, а в концепциях, в их закладенных. Я вижу только две - "фортрановскую": декомпозиция задачи до уровня чисел (включяя строки как наборы кодов) с последующей их обработкой алгоритмически, и "лисповую": создание базиса для абстракций, и их конкретизация в проге до соответствующево задаче уровня. Первый путь короток и пройден до упора, а второй _массово_ только-только начинаецо, хотя для рада задачь применяецо давно и успешно.

algol family и fortran - это совершенно разные пути развития и семейства языков (ну, второе семейство состоит из фортрана, фортрана и фортрана - но это неважно).

В основном с т.з. подхода к машине: фортран представляет ее как большой калькулятор, который умеет считать, а традиционные языки - как систему с состоянием, которой можно управлять. А лисп - вообще не представляет, что есть "машина", он оперирует сферическими лямбдами в вакууме (это не недостаток, но подход типа "нету никаких переменных, есть только значения", "все - значение", "данные и код - одно и то же" и т.д. совершенно не соответствуют тому, как работает ЭВМ).

При этом, кстати, никак нельзя доказать, что достижимый на C уровень абстракции ниже, чем лисповый.

ИМХО, лисп круче всего остального только тем, что он уже 40 лет - полигон для экспериментов в области языкостроения (и по понятным причинам - синтаксис примитивный, метапрограммирование - встроеное, базовые абстракции - простейшие), поэтому в нем есть все подряд и еще немножко.

А на практике удобнее использовать более узкозаточенные и простые инструменты. Типа C или Perl или Java.

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

> появились - я имею в виду появились в практической деятельности.

Ну, Питон в практике появился лет 10 как. Руби 0 не знаю, не следил за ним.

> Ведь есть ещё более 2000 наречий, не забывай.

Это совсем-совсем мертвые языки. Активно используемых - десятка два, от силы - три.

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

> в топ 1 более 3000 каментоф. ниасилим ИМХО :(

3000? Ааафигеть. Проклятые флудеры 8). Нам за ними не угнаться.

1024-й пост?

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

> algol family и fortran - это совершенно разные пути развития и семейства языков

семантика разная, да. Но растут они из одново корня: http://www.levenez.com/lang/ и подход одинаковый. В основу покладены разнообразные форматы чисел и некоторые примитивные операции со строками. Методы работы одинаковые: инфиксные и префиксные операторы, действующие на базовые типы и функции для работы с ними же, всё строго алогитмично. Я это уже писал ведь.

> фортран представляет ее как большой калькулятор, который умеет считать, а традиционные языки - как систему с состоянием, которой можно управлять

Ну и чем это по твоему отличяецо? Особенно в свете того, что "традиционные" языки управляют тоже по большей части или только состояниями переменных примитивных типов?

> совершенно не соответствуют тому, как работает ЭВМ

Всё правильно, лисп - это туннель с другой стороны, в противоположном направлении. Он предполагает что комп в основном сам будет занимацо декомпозицией до приемлемого ему уровня, а прогаммист - сосредоточится на самой задаче. Именно поэтому "традиционные" программисты неприемлют лисп, ибо привыкли к тому, что приходится заниматься декомпозицией и оперировать на машинном (быдло)йазыге низкоуровневыми сущностями, на которые расклали задачу "прозрачно", привычно для себя. Подобным же образом впервые попавшая в город деревенщина чувствует себя неуютно в такси и предпочитает привычным образом итти пешком.

> При этом, кстати, никак нельзя доказать, что достижимый на C уровень абстракции ниже, чем лисповый.

Никак нелзя. В конечнои итоге оно совершенно одинаково, ибо аппаратные процессы, решающие задачу, одни и те же. Разница в том, что в одном случае приходицо разбирать задачу на байты, целые, строки, итд вручную полностью, и программить операции с байтами, строками итд, а во втором - создать понятия, соответствующие задаче, и опрерировать в дальнейшем ими. Т.е. разница не в достижимом уровне абстракции как таковом, он зависит сугубо от человека, а в инструментарии, поддерживающем тот или иной уровень абстракций, степенью абстрактности применяемых терминов. Если термины самого языка просты и недостаточно абстрактны, из них приходицо группировать "сложный" термин вручную.

> ИМХО, лисп круче всего остального только тем, что он уже 40 лет

ты опать путаеш причину со следствием? Поэтому он уже 40 лет, что круче.

> А на практике удобнее использовать более узкозаточенные и простые инструменты. Типа C или Perl или Java.

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

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

> Это совсем-совсем мертвые языки. Активно используемых - десятка два, от силы - три.

Дык и питоноруби савсем-савсем мьйортвый волялсо, пока не понадобился. Ты же не будеш отрицать чё лет скажем 5-6 тому питон юзался намного реже лиспа? Я и говорю, чё давно уже поизобретено многое, и некоторое доведено до совершенства, только вот откладено в сторону за ненадобностью. А когда надобно, обычно начинают изобретать заново, косо-криво с самого начяла, вместо того чтобы поглядеть в заначке.

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

> А вот теперь - точно 1024-й. Щасс придет модер и снесет... 8)

модераторский налог? Кажный 1024й пост в пользу заведения?

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

> При этом, кстати, никак нельзя доказать, что достижимый на C уровень абстракции ниже, чем лисповый.

Нет конечно. Но аналогичный уровень будет выглядеть кошмарно. Или нужен очень навёрнутй препроцессор... gcl например ;)

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

> "традиционные" языки управляют тоже по большей части или только состояниями переменных примитивных типов

Причем здесь язык? Создай сложные объекты и управляй _их_ состоянием. Языки (Си/Си++, Питон) это позволяют и, более того, поддерживают.

Вот этим предложением:

> Разница в том, что в одном случае приходицо разбирать задачу на байты, целые, строки, итд вручную полностью, и программить операции с байтами, строками итд, а во втором - создать понятия, соответствующие задаче, и опрерировать в дальнейшем ими.

ты противоречишь этому:

> Т.е. разница не в достижимом уровне абстракции как таковом, он зависит сугубо от человека, а в инструментарии, поддерживающем тот или иной уровень абстракций, степенью абстрактности применяемых терминов. Если термины самого языка просты и недостаточно абстрактны, из них приходицо группировать "сложный" термин вручную.

Для протокола: "приходицо разбирать задачу на байты, целые, строки, итд вручную полностью, и программить операции с байтами, строками итд" - я просто плачу над этой злой судьбиной. Надо же, "приходится". Средств определения новых объектов и понятий - ну просто нет (нигде, кроме Лиспа).

"создать понятия, соответствующие задаче, и опрерировать в дальнейшем ими" - этому учит любая нормальная книга по программированию. Керниган и Плоджер, например - хотя они используют Ратфор и Паскаль.

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

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

>> Это совсем-совсем мертвые языки. Активно используемых - десятка два, от силы - три.

>Дык и питоноруби савсем-савсем мьйортвый волялсо, пока не понадобился.

Ну, если для тебя язык, который поддерживается, развивается, и пользовательское сообщество которого растет - это мертвый язык, то твоя логика достигла непонятных мне уровней абстракции.

Мертвые языки - это всякие Algol-6[08], RTL, Clu, Jovial, Chill, Self и т.д.

> Ты же не будеш отрицать чё лет скажем 5-6 тому питон юзался намного реже лиспа?

Если бы ты сказал 10 лет - я бы не стал спорить. А 5 лет назад - спорить не стану только потому, что нет цифр на руках (но Питон наверняка обошел Лисп к тому времени).

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

> > Ты же не будеш отрицать чё лет скажем 5-6 тому питон юзался намного реже лиспа?

> Если бы ты сказал 10 лет - я бы не стал спорить. А 5 лет назад - спорить не стану только потому, что нет цифр на руках (но Питон наверняка обошел Лисп к тому времени).

Ну, такое сравнение не совсем корректно. Если учесть, что лиспов, как у бобика блох...: что схема - тоже лисп, а это sicp, а это MIT со студентами, а ещё есть биглу (или бигло? :) и прочие схемы, что есть AutoLisp - а это все, кто пытался автоматизировать кады разной направленности, что это elisp со всем, кто хоть чуть-чуть разобрался в емаксе, если попытаться вспомнить все остальные ниши, куда проник лисп - я думаю только с более-мение широким распространением zope питон возможно догнал лисп. Хотя точных цифр и у меня нет :)

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

> Причем здесь язык? Создай сложные объекты и управляй _их_ состоянием. Языки (Си/Си++, Питон) это позволяют и, более того, поддерживают.

Хм. Задачя: составить структуру данных для хранения информации о том, в каких директориях находицо файл. Одинаковый файл может храницо в нескольких. Файлы щитаецо одинаковым если совпадает и имя и размер. Создать код, который 1) поштучно добавляет информацию (имя файла, размер, директория) в структуру, 2) составляет отдельно списки имён файлов, которые есть в равном N количестве, больше или меньше. Для каждово имени нужно передать также информацию о том, в каких директориях он. Возмёшся? Потом присовокуплю код на лиспе.

> Средств определения новых объектов и понятий - ну просто нет (нигде, кроме Лиспа).

См. выше. Не в том дело, что нету, а в том дело что средства езыка не позволяют потом с ними эффективно работать.

> "создать понятия, соответствующие задаче, и опрерировать в дальнейшем ими" - этому учит любая нормальная книга по программированию. Керниган и Плоджер, например - хотя они используют Ратфор и Паскаль.

Дык полвопроса в сложности этово _создать_ понятия. А вторая, большая ево половина в том, чем потом с этими работать.

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

Дык приходицо. Только обычный стиральный порошёк^W^W^Wбыдлойазыг работает с примитивными данными, и кроме группирования приходицо ещё мапить элементарные действия на ещё более элементарные операции с примитивными типами. Опять, см. выше.

> Ну, если для тебя язык, который поддерживается, развивается, и пользовательское сообщество которого

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

> Если бы ты сказал 10 лет - я бы не стал спорить. А 5 лет назад - спорить не стану только потому, что нет цифр на руках (но Питон наверняка обошел Лисп к тому времени).

Ну ладно, тогда не будем. Просто например про лисп, что такое в принципе бывает, я услыхал в конце 80х - начяле 90х впервые, а про рубипитон - всево лет пять тому. Хотя конешно, это не показатель и не доказательство.

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

2redvasily

>Был уже апдейт:

И что, скажете читабельность повысилась ?

>1. Не припомню в английском слова "cons"

construсt... Дальше лучше припоминается ? Ну можно на pair заменить, если уж так глаз режет.

>2. Слова в лиспе английские, но вот предложений как-то не >образуется. > Или Йода мастер лиспе сказал это на?

Йода мастер сказал: "Кто не может даже в таком очевидном случае увидеть предложений, те идут это на".

>3.Надо поменять опрос, сменить его на: "какая из этих программ более > читаемая?"

Это не опрос. Это риторический вопрос. IMHO не может быть чтоб код с [1:],[:i],[i:], xrange, yield читался лучше кода без этих значков человеком, который не знает оба языка.

>4.COBOL ваще от английского не отличить. И что?

Наверное поэтому он для левых людей читается получше, чем Перл ;-)

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

> Задачя: ... Возмёшся?

Вряд ли. По двум причинам: идеологической - это докажет только то, что кто-то из нас лучший программист (не интересно - я встречал спецов и гораздо лучше себя, и гораздо хуже), и практической - у нас здесь 0:40, а завтра снова тяжелый день.

[ но всё же хочется уточнить условия задачи - каталоги могут быть вложенными? и почему такое странное определение идентичности - имя и размер? давай уже введем inode number, как в приличном Unix. Или в определении равенства по 2-м атрибутам, один из которых - строка, есть какой-то сакральный смысл? ]

> в том дело что средства езыка не позволяют потом с ними эффективно работать.

Этого просто не понял. Давай конкретно о Питоне или Си++ - с какими определенными программистом понятиями они не позволяют эффективно работать, и в чем это проявляется? И как определяется "эффективность"?

>> "создать понятия, соответствующие задаче, и опрерировать в дальнейшем ими" - этому учит любая нормальная книга по программированию. Керниган и Плоджер, например - хотя они используют Ратфор и Паскаль.

>Дык полвопроса в сложности этово _создать_ понятия. А вторая, большая ево половина в том, чем потом с этими работать

Опа. Полезли идеологические разногласия. Видишь ли, я считаю, что именно _создать_ понятия гораздо сложнее и важнее, чем потом ими манипулировать. И я не стану даже спорить по этому поводу - замечу только, что в "хорошесть" созданного понятия (программной абстракции) входят такие вещи, как сопротивление ее неправильному использованию, то есть то, что ни компилятор, ни мегапродвинутая макросистема отследит не в состоянии.

> обычный стиральный порошёк^W^W^Wбыдлойазыг работает с примитивными данными

Еще раз - он работает с теми данными, которые ты определишь. Кстати, "быдлойазыг" - это что такое? У него имя есть, или он просто рекламная^Wфигура речи?

>> Ну, если для тебя язык, который поддерживается, развивается, и пользовательское сообщество которого

> а, какая йухан разницо, если к продакшну он пока близко не подошед?

Определение "живого языка" - в студию! С количественными параметрами.

> от делфей тож кучя скубентов фанатеют

Как тебя корежит от Делфи и студентов... Ты скажи прямо - Дельфи плох, потому что его студенты любят, или студенты плохи, потому что любят Дельфи?

> хотя ни один не может внятно объеснить чем оный дельфи лучше тех же сей например

А ты сам не знаешь? ObjectPascal лучше Си тем, что в нем есть ООП и обработка исключений. Дельфи лучше Си тем, что в его IDE интегрирован мощный конструктор GUI (не в каждом Си есть IDE), и эта IDE хорошо поддерживает разработку компонентов конструктора GUI (лучше, чем любая Си IDE, которые я видел). Неужели это трудно понять? Что тебя так раздражает - то, что _ты лично_, _сейчас_ не считаешь это достоинствами?

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

>>Был уже апдейт:

>И что, скажете читабельность повысилась ?

Я скажу - да, повысилась. Ясный и даже красивый код.

>>1. Не припомню в английском слова "cons"

>construсt...

Ну тогда в Питоньей программе вообще все слова английские

> Кто не может даже в таком очевидном случае увидеть предложений, те идут это на

Достойный ответ, да

> IMHO не может быть чтоб код с [1:],[:i],[i:], xrange, yield читался лучше кода без этих значков

range, yield - это слова, отражающие назначение соотетствующих конструкций. [1:] и т.д. - достаточно близки математической нотации.

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

> Методы работы одинаковые: инфиксные и префиксные операторы, действующие на базовые типы и функции для работы с ними же,

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

> всё строго алогитмично.

Т.е. лисп у нас стал вдруг логической системой вывода? С каких это пор? На нем все алгоритмично ровно настолько же. Как известно, лямбда-исчисление эквивалентно исчислению машины Тьюринга.

>> фортран представляет ее как большой калькулятор, который умеет считать, а традиционные языки - как систему с состоянием, которой можно управлять

> Ну и чем это по твоему отличяецо? Особенно в свете того, что "традиционные" языки управляют тоже по большей части или только состояниями переменных примитивных типов?

И таки что, на фортране есть указатели? Разница в целях и подходах. А то ты таким макаром и форт в одну семью с джавой засунешь. А что - язык императивный, машина стековая...

> > При этом, кстати, никак нельзя доказать, что достижимый на C уровень абстракции ниже, чем лисповый.

> Никак нелзя. В конечнои итоге оно совершенно одинаково, ибо аппаратные процессы, решающие задачу, одни и те же.

Ты, блин, отличаешь эквивалентность программы от уровня абстракции исходного кода?

> Разница в том, что в одном случае приходицо разбирать задачу на байты, целые, строки, итд вручную полностью, и программить операции с байтами, строками итд, а во втором - создать понятия, соответствующие задаче, и опрерировать в дальнейшем ими.

Т.е. стандартной библиотекой ты не пользуешься, и что такое структуры (не дай бог - классы!) не знаешь? "один случай" - это описание работы программиста, единственный инструмент которого - ассемблер без макропроцессора. А так - даже на Си (не говоря уже о более "продвинутых" алголоидах) нет никаких проблем "создать понятия, соответствующие задаче, и опрерировать в дальнейшем ими". В терминах функций и структур.

> > ИМХО, лисп круче всего остального только тем, что он уже 40 лет

> ты опать путаеш причину со следствием? Поэтому он уже 40 лет, что круче.

Нет, я уверен, что это ты путаешь ;). К Си не пытались приделать coroutines и continuation (эти слова на русский вообще переводятся) потому, что на практике системного программирования это ненужно. А к лиспу (в разных инкарнациях) приделали - поэтому теперь лисперы (ну, схемеры) могут хвалиться, что оно у них есть. И так я могу перечислить еще два десятка длинных английских слов, с ровно тем же комментарием.

> > А на практике удобнее использовать более узкозаточенные и простые инструменты. Типа C или Perl или Java.

> Дык я про чё и говорю, что удобнее. [skip] Вот в этом случяе лисп и адекватен - позволяет создать вострозаточенный и простой струмент прямо по ходу пьесы.

Имхо, он избыточен. Он, при отсутсвии собственного синтаксиса и грамматики (в широко-лингвистическом смысле, как структура уровнем выше синтаксиса, а не в смысле "формальная грамматика"),позволяет играться в этой области пользователю. А остальные языки стараются предложить достаточный минимум для решения любых мыслимых задач.

В конце концов - обходимся же мы 7-ю падежами и десятком глагольных форм, и не изобретаем грамматические конструкции по ходу разговора.

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

> а, какая йухан разницо, если к продакшну он пока близко не подошед?

Это петон-та? Ой, это ты гонишь. Нет, я понимаю, что gmail в вечной бете - но все же... ;-)

Вот рядом со мной человек пишет кусок баннерной системы на Python (у нее есть еще куски на C++, plain C, Perl и javascript) - и ниччо, работает. В "продакшне".

А перл так вообще из этого продакшна выпадает постепенно. Что печально, но естественно - мало кто может осилить строчку (написано мною сегодня, правда для отладки и навыброс:

@matches = map {substr($str, $-[$_], $+[$_]-$-[$_]} 1..$#-;

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

> Вряд ли. По

ну вот. А на лиспе каждое из этих делаецо в одну (нормальной длины) строку.

> каталоги могут быть вложенными?

конешно, это дерево каталохов обычное.

> и почему такое странное определение идентичности - имя и размер? давай уже введем inode number, как в приличном Unix. Или в определении равенства по 2-м атрибутам, один из которых - строка, есть какой-то сакральный смысл?

Да нету. Просто я свой винт заср@л и только што сделал такое прогу. Вот сразу на вум и пришло. Имя и размер - потому что в разное время приволакивал на сидюках с разных мест разные файлы. Называцо могут одинаково, вот для достоверности и размер включил. Для задачи это неважно, пускай некоторые два параметра (строка, число) или три или скокоугодно. Если инод юзать не кросплатформенно.

> Этого просто не понял. Давай конкретно о

Давай чтобы менее голословно и более очевидно было, с кодом этой задачи закончим, и на её примере (надеюсь) это будет очевидно.

> И как определяется "эффективность"?

логическим размером кода в основном. Если на одном языке например я хочу расширить набор например целых чисел их квадратами, на лиспе я пишу (отобразить множество а на множесво б функцией: (список: число, ево квадрат)) и не парюсь. А на например сях мне нужно 1) вычислить сколько места отвести под результат 2) выделить место 3) создать цикл перебора всех (причём в это входит нескко логических операций!) 4) присвоить элементу результата число 5) присвоить след. элементу результата число 6) после работы не забыть очистить выделенное. Это неэффективное использование труда программера. Хотя этой эффективности просто не замечают. По аналогии, жители высокогорного плато не замечают что жывут высоко, пока не подойдут к краю плато.

> Опа. Полезли идеологические разногласия. Видишь ли, я считаю, что именно _создать_ понятия гораздо сложнее и важнее, чем потом ими манипулировать. И я не стану даже спорить по этому поводу - замечу только, что в "хорошесть" созданного понятия (программной абстракции) входят такие вещи, как сопротивление ее неправильному использованию, то есть то, что ни компилятор, ни мегапродвинутая макросистема отследит не в состоянии.

Это характерный подход для ООП, потому что только в этом случае неправильно построенная иерархия обектов может привести к тому, что единова придёцо переписывать прогу с нуля (!). Если же иерархии обектов нету, можно довольно свободно адаптировать как структуры данных так и алгоритмы в случяе косяка в разработке или небольшово изменения задачи.

> Еще раз - он работает с теми данными, которые ты определишь.

он не будет. Потому что набор операций (арифметические, функции с рядом ограничений, и... всё?) предполагает работу с примитивными типами.

> Кстати, "быдлойазыг" - это что такое? У него имя есть, или он просто рекламная^Wфигура речи?

Ну, это в какой-то степени собирательный образ "майнстримовых" наречий.

> Определение "живого языка" - в студию!

ну лисп например

> С количественными параметрами.

адын штук

> Как тебя корежит от Делфи и студентов... Ты скажи прямо - Дельфи плох, потому что его студенты любят, или студенты плохи, потому что любят Дельфи?

Больше всево меня расстраивает "стадность" и отсутствие критического взгляда на вещи.

> А ты сам не знаешь?

не

> ObjectPascal лучше Си тем, что в нем есть ООП и обработка исключений.

ну в с++ тож есь такое. Дык скубенты и не смогут объяснить чем делви луче с++ тоже.

> Дельфи лучше Си тем, что в его IDE интегрирован мощный конструктор GUI (не в каждом Си есть IDE), и эта IDE хорошо поддерживает разработку компонентов конструктора GUI (лучше, чем любая Си IDE, которые я видел).

А он там нужен ваще, тем более такой ацтойный? Ну напишеш в строке компиляции например -lgtk и будет в сях не хуже нискоко.

> Неужели это трудно понять?

весьма

> Что тебя так раздражает - то, что _ты лично_, _сейчас_ не считаешь это достоинствами?

дык не особо раздражает. Несколько удивляет такая "динозавровось" и махровый экстремизьм. Например один скубент всерьёз предлагал зделать серверное приложение на делфях. Мой вопрос, как оно станет работать на сановском серяке с солярой, просто зямяли. Или например, быдлоподелия гуи на дельфях в одной из фирм - выгледит хуже вебовского, постоянно глючит и падает, елементарные изменения внести - кучя времени и толпа народу, особенно с учётом того чё придёцо по клиентам бегать обновлённое устанавливать кому-то, которое ещё далеко не всегда заведёцо нормально, и ещё кучя траблев. Дык нет, всё одно зделали на делфях потомушто типо "делфи все знают"... Не, быдлойазыги _обязаны_ исдохнуть.

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

> Имхо, он избыточен. Он, при отсутсвии собственного синтаксиса и грамматики (в широко-лингвистическом смысле, как структура уровнем выше синтаксиса, а не в смысле "формальная грамматика")

Ну, ээ. Эт я прогнал, что грамматика - это структура над синтаксисом. Штука просто в том, что у естественного языка на уроень больше, и то, что для С мы назовем грамматикой, для русского - морфология, а сишный синтаксис соотвествует русской грамматике, грубо говоря.

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

> Ясный и даже красивый код.

Ты читал код, который получился, когда я перевёл ЭТО 1:1 на лисп и сравнил с первоначяльно лисповым?

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

> Потому что набор операций (арифметические, функции с рядом ограничений, и... всё?) предполагает работу с примитивными типами.

Гм. Учтя, что у "протолиспа" из перечисленного есть только функции (хотя и чуть более продвинутые - потому что тпизация изначально динапическая, точнее "символьная") - то что?

И почему сишные функции "предполагают работу с примитывными типами"? Вон на gtk (хотя уродец тот еще) посмотри - какие там примитивные типы? Или ты считаешь, что если объект доступен как opaque handle, который typedef int - то он не сложнее int-а?

> А он там нужен ваще, тем более такой ацтойный? Ну напишеш в строке компиляции например -lgtk и будет в сях не хуже нискоко.

Таки VCL+борляндческий гуередактор - это хорошо (можно, кстати, и на плюсах писать, хотя исходник самой библиотеки - на паскале). Просто им, как и всем остальным, нужно уметь пользоваться, и включать мозг на этапе проектирования. А если в программе присутствует Button432, то переход на gtk таких индивидуумов не спасет.

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

> Если на одном языке например я хочу расширить набор например целых чисел их квадратами, на лиспе я пишу (отобразить множество а на множесво б функцией: (список: число, ево квадрат)) и не парюсь. А на например сях мне нужно 1) вычислить сколько места отвести под результат 2) выделить место 3) создать цикл перебора всех (причём в это входит нескко логических операций!) 4) присвоить элементу результата число 5) присвоить след. элементу результата число 6) после работы не забыть очистить выделенное. Это неэффективное использование труда программера. Хотя этой эффективности просто не замечают.

Откройте для себя Бейсик и не трахайте людям моск...

> Не, быдлойазыги _обязаны_ исдохнуть.

Бейсик что-то с 64ого года никак не издохнет... И используется он значительно шире лиспа. Потому что туда заложены вполне практически полезные идеи и фишки (как можно больше вещеё по умолчаний и простой для человека, а не для машины синтаксис), а не маразматичные рассуждения и упивание "красотой" и "правильностью" языка. Результат можете лицезреть в любой школе/инсте где преподают информатику. Там почему-то не Цэ, не фортран, не жаба, не хаскель, а именно он самый...

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

> так читабельнее и привычнее

только в случяе с числами. Поэтому я и говорю, такие наречия - это для программируемого калькулятора.

> Вполне можно переписать любую сишную прогу таким образом, чтобы операторов там не было вообще

А вместо них?

> На нем все алгоритмично ровно настолько же. Как известно, лямбда-исчисление эквивалентно исчислению машины Тьюринга.

А как с например функциями (map... ?

> И таки что, на фортране есть указатели?

А какая разница? Понадобились бы - были бы.

> Ты, блин, отличаешь эквивалентность программы от уровня абстракции исходного кода?

А ты не?

> структуры (не дай бог - классы!)

Ну разобрали чёто на байты, а потом сгруппировали опять, удобства для. Ичё?

> нет никаких проблем "создать понятия, соответствующие задаче, и опрерировать в дальнейшем ими". В терминах функций и структур.

Я там приводил задачку, запость сюды код на сях, сравним.

> Имхо, он избыточен.

От задачи зависит. Иногда как бы и недостаточен может быть.

> А остальные языки стараются предложить достаточный минимум для решения любых мыслимых задач.

Асм ево тоже вполне предоставляет. Принципиальная возможность решения != лёхкость и простота решения, так то вот.

> В конце концов - обходимся же мы 7-ю падежами и десятком глагольных форм, и не изобретаем грамматические конструкции по ходу разговора.

Вот именно. А ты утверждаеш

> нет никаких проблем "создать понятия, соответствующие задаче, и опрерировать в дальнейшем ими". В терминах функций и структур.

Это читал?

http://www.paulgraham.com/quotes.html

Это ведаеш?

> "Greenspun's Tenth Rule of Programming: any sufficiently complicated C or Fortran program contains an ad hoc informally-specified bug-ridden slow implementation of half of Common Lisp."

перевод: всякая достаточно сложная прога на сях или фортране содержит свою собственную неформальную тормозную и глякавую реализацию полкоммонлиспа.

Оно нам нужно всякий раз лисапед изобретать? Да ещё далеко не факт что самый лучший.

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

> Бейсик что-то с 64ого года никак не издохнет... И используется он значительно шире лиспа. Потому что туда заложены вполне практически полезные идеи и фишки (как можно больше вещеё по умолчаний и простой для человека, а не для машины синтаксис), а не маразматичные рассуждения и упивание "красотой" и "правильностью" языка. Результат можете лицезреть в любой школе/инсте где преподают информатику. Там почему-то не Цэ, не фортран, не жаба, не хаскель, а именно он самый...

а) троллить нехорошо, пусть даже и умело ;) Мы тут, все же, обсуждаем "промышленные" языки, т.е. предназначенные для использования профессиональными разработчиками ПО, имующими профильное (ну, более-менее) образование. А вы тут со своими красными тряпками в виде VB.

б) таки про институты - вообще неправда. Бейсик на информатике я могу себе представить разве что на плохом гуманитарном факультете. У нормальных людей это (первый ЯП, в смысле) Pascal или Java, за бугром, говорят, Python или Scheme бывает иногда.

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

> Это петон-та?

аха

> Ой, это ты гонишь.

Дану? А скопки там доделали? А макросы? А лямбды многострочные? А траблы с оперативой отрешали? А превеликие тормозы?

> и ниччо, работает. В "продакшне".

ну и виндовсь на серверах типо "впродакшне". толко луче бы ваще никак чем так вот.

> А перл так вообще из этого продакшна выпадает постепенно. Что печально, но естественно

Ну чё делать, Должен Остаться Только Один!

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

> Гм. Учтя, что у "прото

Ну на "прото" никто не заставляет. И даже немогу сходу собразить где для ево лиспмашыну взять.

> Вон на gtk (хотя уродец тот еще) посмотри - какие там примитивные типы?

gint, gpointer, gchar*, GtkWidget* ну и прочие

> Или ты считаешь, что если объект доступен как opaque handle, который typedef int - то он не сложнее int-а?

Какая разница? Это ведь средствами языка недоступно. Это же пришлось делать кому-то. А в лиспе всё готовое, стандартизованное и вышшего качества.

> А если в программе присутствует Button432, то переход на gtk таких индивидуумов не спасет.

А если на кажный чих _вручную_ писать обрабочик ресайза, предлинный, и на кажный чих ево переделывать/переотлажывать?

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

> пусть даже и умело

ИМХО неуклюже очень.

> А вы тут со своими красными тряпками в виде VB.

Типо питонобейсик луче?

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

> > так читабельнее и привычнее

> только в случяе с числами. Поэтому я и говорю, такие наречия - это для программируемого калькулятора.

Ну, ээ. В Си и Паскале операторы только для чисел и есть. А для всего остального - функции. Как и в лиспе, да, только в нем инфиксной нотации для чисел нету...

> > Вполне можно переписать любую сишную прогу таким образом, чтобы операторов там не было вообще

> А вместо них?

inline int ints_add(int a, int b) { /* inline asm goes here */ }

На плюсах можно просто sum - там перегрузка есть. И будет тебе префиксная нотация, причем более "математическая" - скобочки у функций, все же, математики не так ставят, как лисперы ;)

> На нем все алгоритмично ровно настолько же. Как известно, лямбда-исчисление эквивалентно исчислению машины Тьюринга.

> А как с например функциями (map... ?

В смысле? Ну мап и мап. На си тоже можно функции высших порядков писать - просто они типизированные, поэтому "просто" map-а там нету "из коробки". А, скажем, по массивам (или спискам) определенного типа так сделать - данивапрос, 10 строчек (для связных списков типа BSD queue - вообще в один макрос (дада, страшный и убогий cpp-шный) можно уложиться). Если мне оно больше двух раз в программе понадобится - я напишу.

На плюсах же все это есть generic в STL (map == transform, конкретно).

transform(source.begin(), source.end(), insert_iterator<target_type>(target, target.begin()), source_to_target_functor());

Ну да, многа букаф - зато typesafe.

> "Greenspun's Tenth Rule of Programming: any sufficiently complicated C or Fortran program contains an ad hoc informally-specified bug-ridden slow implementation of half of Common Lisp."

s/Common Lisp/C++ and STL/

Тогда правда. См. исходники гнома/гтк.

И да, спасибо, я понимаю по английски. Письменно - так даже весьма неплохо.

> Ну разобрали чёто на байты, а потом сгруппировали опять, удобства для. Ичё?

Блин. Давай ты не будешь передергивать. А то я сейчас заявлю, что в терминах лямбда-исчисления нельзя применять никакую арифметику, кроме чисел Пеано - поэтому в расчетных задачах лисперы "разбирают чёто на инкременты, и потом группируют опять, удобства для". И буду примерно столь же прав как ты.

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

> > Ой, это ты гонишь.

> Дану? А скопки там доделали? А макросы? А лямбды многострочные? А траблы с оперативой отрешали? А превеликие тормозы?

А теперь давай логическую цепочку от "нету многострочных лямбд" до "неприменимо в продакшене". В С вон вообще никаких лямбд нету - однако ж на нем написаны все сколько-нибудь промысшленные OS общего назначения. Не говоря уже о куче другого софта.

А питон активно применяется как язык-клей, для реализации сложной, часто изменяемой логики. Особенно удобно при этом вынести простые-но-затратные части (типа "пересортировать вон те 30 гигов по вот этому полю") в сишный код, чтобы быстро было.

> ну и виндовсь на серверах типо "впродакшне". толко луче бы ваще никак чем так вот.

Это ты тоже гонишь. Просто ее готовить надо уметь (что сложнее, чем с юниксами). Вон хотмейл пару сотем миллионов ящиков обслуживает, и ниччо. На винде. А гмейл - то же самое делает, с интерфейсом на питоне. А ЖЖ (ну, он поменьше) написан весь целиком не перле. Как и, если не ошибаюсь, Amazon (ну, так было несколько лет назад точно, сейчас не знаю).

Ну-ка, давай-ка пример мегасервиса на лиспе?

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

> А для всего остального - функции. Как и в лиспе, да, только в нем инфиксной нотации для чисел нету...

г. А щё в лиспе есь макросы, замыкания, лямбды, 1st class functions и другие страшные слова.

> На плюсах можно просто sum - там перегрузка есть. И будет тебе префиксная нотация, причем более "математическая" - скобочки у функций, все же, математики не так ставят, как лисперы ;)

а как будет пощитать например сумму квадратов произвользово числа чисел произвольново численново типа? в лиспе просто (reduce #'(lambda (x y) (+ x (* y y))) '(2 3 4) :initial-value 0), где '(2 3 4) - сами агрументы, можно туда переменную.

> На си тоже можно функции высших порядков писать - просто они

Просто они, а писать сложно, а без них скушно.

> 10 строчек (для

Вот и представь, всево десяток-другой строчек там, где одново вызова функции достаточно

> зато typesafe.

Зато для каждово типа заново. А в лиспе типасейф тоже есть, опционально.

> s/Common Lisp/C++ and STL/

> Тогда правда. См. исходники гнома/гтк.

воистину бугога. Какая разница, начём лисапед, на с++/stl или на с/фортране? Просто цытата древняя, пора обобщить на питонос++ тоже.

> И да, спасибо, я понимаю по английски. Письменно - так даже весьма неплохо.

Наздоровье, только ты не один тута

> Блин. Давай ты не будешь передергивать.

Давай. Я тамо немного повыше задачку про файлы запостил, кажи код её решения, тогда и порассуждаем.

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

> А теперь давай логическую цепочку от

(Нету базовых средств + немилосердные тормоза + непредсказуемое поведение) и сразу в продакшн?

> В С вон вообще никаких лямбд нету - однако ж на нем написаны все сколько-нибудь промысшленные OS

А на питоне?

> А питон активно применяется как язык-клей, для реализации сложной, часто изменяемой логики.

Ну и зачем сложную логику на недоделаном?

> Просто ее готовить надо уметь (что сложнее, чем с юниксами)

Она от этово луче не станет, в самом распрекрасном случае будет отравлять жысь админу а не юзверям

> Вон хотмейл пару сотем миллионов ящиков обслуживает, и ниччо. На винде.

Врут небось, нету там венды. там соляра с кумайлом.

> А гмейл - то же самое делает, с интерфейсом на питоне. А ЖЖ (ну, он поменьше) написан весь целиком не перле. Как и, если не ошибаюсь, Amazon (ну, так было несколько лет назад точно, сейчас не знаю).

дык я не отрицал, что при большом желании принципиально возможно всё заставить работать. Только вот соотношение затраты/результат у лиспа намного выше получяецо. Не в разы даже а на порядки.

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

> > s/Common Lisp/C++ and STL/

> > Тогда правда. См. исходники гнома/гтк.

> воистину бугога. Какая разница, начём лисапед, на с++/stl или на с/фортране? Просто цытата древняя, пора обобщить на питонос++ тоже.

Мы, вроде, договорились не передергивать? Или ты будешь продолжать, пока я тебе программку про файлы не напишу?

Я имел ввиду, что я готов согласиться с этой цитатой, если в ней заменить Common Lisp на "C++ and STL". Для людей с мозгом, выеденным лиспом, сообщаю, что тогда она будет звучать как "any sufficiently complicated C or Fortran program contains an ad hoc informally-specified bug-ridden slow implementation of half of C++ and STL".

А имел я ввиду то, что а) гринспун "хвалился", скорее, полнотой библиотеки, чем мощью языка, б) все это давно перенесено в "алгольный" мир, со сравнительным по отношению к лиспу качеством от "не сильно хуже" до "лучше".

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

> > В С вон вообще никаких лямбд нету - однако ж на нем написаны все сколько-нибудь промысшленные OS

> А на питоне?

На питоне написан gmail. Это из того, что на слуху (я сам перлист-сишник, за питоном не слежу особо). Рядом со мной его успешно применяют в контексте корбы, очень даже в продакшене (вебсервис на сотни тысяч хитов в день, и подготовка данных для другого - уже с десятками миллионов хитов, правда отдаваемых сишной программкой).

> > Вон хотмейл пару сотем миллионов ящиков обслуживает, и ниччо. На винде.

> Врут небось, нету там венды. там соляра с кумайлом.

Детсад, мля. Винда там. И на msn search тоже винда. То, что ты неспособен ее завести и защитить - это твои проблемы.

Кстати, обычные мейлеры на таких сервисах не живут, совсем. Там custom software. Думается мне, на C (ну, может быть с крестами).

> > А гмейл - то же самое делает, с интерфейсом на питоне. А ЖЖ (ну, он поменьше) написан весь целиком не перле. Как и, если не ошибаюсь, Amazon (ну, так было несколько лет назад точно, сейчас не знаю).

> дык я не отрицал, что при большом желании принципиально возможно всё заставить работать. Только вот соотношение затраты/результат у лиспа намного выше получяецо. Не в разы даже а на порядки.

Еще раз (да, я зануда) - пример мегасервиса (ну хотя бы рунетовского масштаба, миллион+ хитов в сутки) на лиспе. Ежели все так круто - то, видимо, 2 человека в гараже с SBCL-ем на десятке серверов - реальная угроза для гугля? Где же они?

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

> Или ты будешь продолжать, пока

буду

> А имел я ввиду то, что

Всётаки, давай вернёмся к задачке. Там вроде никакой библиотеки не нужно навороченой, всё средствами делаецо.

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

> На питоне написан

А сколько-нибудь промысшленная OS?

> Детсад, мля. Винда там. И на msn search тоже винда.

Нету тама венды, откуда?

> То, что ты неспособен ее завести и защитить - это твои проблемы.

нету венды - нету проблемов.

> пример мегасервиса

мы лисп обсуждаем или мегасервис?

> Где же они?

да фих их знает, не интересовался. Своих траблов полно.

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

> Это характерный подход для ООП, потому что только в этом случае неправильно построенная иерархия обектов может привести к тому, что единова придёцо переписывать прогу с нуля (!). Если же иерархии обектов нету, можно довольно свободно адаптировать как структуры данных так и алгоритмы в случяе косяка в разработке или небольшово изменения задачи.

Голословное утверждение. В реальности ошибка в проектироании иерархии классов приводит к рефакторингу, изменениию части классов, отношений между ними, но никак не к переписыванию с нуля.

Аналогично я могу заявить что создание DSL это характерный подход для лиспа подход. "неправильно построенный DSL может привести к тому, что единова придёцо переписывать прогу с нуля (!)"

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

+5
проблемы с DSL в проекте _значительно ужаснее_ чем проблемы в иерархии классов, фактически при изменении DSL возникают теже проблемы как при переносе приложения между двумя сильно различными платформами на другой язык, с С на паскаль например - в общем DSL- гавно

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

Bugmaker, написал тебе я прогу. Только твоё ТЗ было сформулированно 
нечётко, исходник ты не показал, так что у нас наверное получились 
несколько разные проги, нарпимер я сделал persistent storage на 
sqlite, соответственно пооиск по базе файлов работает очень шустро.

Давай ты не будешь передёргивать, говорить типа оно у меня 
нетиненадо, а приведёшь исходник с аналогичной функциональностью на 
лиспе. Чтобы там были реализованы фнкции/методы/макросы для 
добавления файла в базу, удаления, и выборки файлов по заданному 
критерию. Возможные опреаторы для выборки: >, >=, <, <=, !=. 

База данных sqlite

Моя прога работает на Win32/Linux, поддерживает unicode. Прога на 
лиспе желательно должна работать под Win32/Linux также с 
поддержкой юникода.

Вот когда напишешь такую прогу, тогда и поговорим :-)

#!/usr/bin/env python

import sys
import os.path

import sqlalchemy.mods.threadlocal
import sqlalchemy
import sqlalchemy.exceptions

class File(object):
    def __init__(self, **kwargs):
        for key, value in kwargs.iteritems():
            setattr(self, key, value)

    def __unicode__(self):
        s = [ unicode(self.__class__.__name__) + u': ' ]
        for c in self.c:
            s.append(u'%s=%s ' % (c.key, getattr(self, c.key)))
        result = u''.join(s)
        return result
    
metadata = sqlalchemy.BoundMetaData('sqlite:///files.db',
    strategy='threadlocal')

files_table = sqlalchemy.Table('files', metadata,
    sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
    sqlalchemy.Column('name', sqlalchemy.String(1000), index=True),
    sqlalchemy.Column('size', sqlalchemy.Integer, index=True),
    sqlalchemy.Column('dir', sqlalchemy.String(1000), index=True),
    sqlalchemy.Column('count', sqlalchemy.Integer, index=True))

sqlalchemy.mapper(File, files_table)

class FileDb:
    def __init__(self):
        try:
            sqlalchemy.Query(File).select(limit=1)
        except sqlalchemy.exceptions.SQLError:
            metadata.create_all()
    
    def flush(self):
        sqlalchemy.objectstore.get_session().flush()
    
    def add(self, full_name, size):
        dir, name = os.path.split(full_name)
        count = self.updateFile(name, size)
        File(name=name, dir=dir, size=size, count=count)
        self.flush()
    
    def delete(self, full_name, size):
        dir, name = os.path.split(full_name)
        count = self.updateFile(name, size, -1)
        [sqlalchemy.objectstore.delete(f) for f in 
            sqlalchemy.Query(File).select_by(name=name, dir=dir, size=size)]
        self.flush()
    
    def updateFile(self, name, size, delta=1):
        files = list(sqlalchemy.Query(File).select_by(name=name, size=size))
        count = len(files)
        for f in files:
            f.count = count + delta
        return count + delta
    
    def select(self, condition=files_table.c.count >= 0):
        return sqlalchemy.Query(File).select(condition)
    
def main():
    filedb = FileDb()
    
    if 'add' in sys.argv:
        filedb.add('/home/vasily/pic/zombieeuiip.jpg', 31558)
        filedb.add('/home/vasily/zombieeuiip.jpg', 31558)
        
        filedb.add('/home/vasily/pic/sars.jpg', 19311)
        filedb.add('/home/vasily/sars.jpg', 19311)
        filedb.add('/home/vasily/junk/sars.jpg', 19311)
        
        filedb.add('/home/vasily/pic/pic6.jpg', 29638)
        filedb.add('/home/vasily/pic/pic8.jpg', 17577)
    
    if 'delete' in sys.argv:
        filedb.delete('/home/vasily/pic/zombieeuiip.jpg', 31558)
        
    if 'select' in sys.argv:
        print 'All files:'
        for f in filedb.select():
            print u'%s' % f
            
        print
        print 'N > 2'
        for f in filedb.select(files_table.c.count > 2):
            print u'%s' % f
        
        print
        print 'N != 2'
        for f in filedb.select(files_table.c.count != 2):
            print u'%s' % f
        
        print
        print 'N < 3'
        for f in filedb.select(files_table.c.count < 3):
            print u'%s' % f
        
if __name__ == '__main__':
    main()

P.S. Прога передаётся в public domain.
Можешь её использовать для чистки своего винта :-)

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

> Мега сервис это то что Пол Грем продал яхуу на лиспе написанное?

Угу. Yahoo Store. Скромненькое такое приложеньице.

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

>> В С вон вообще никаких лямбд нету - однако ж на нем написаны все сколько-нибудь промысшленные OS

> А на питоне?

Gentoo ;-)

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

Вроде Яху его переписали? Из чистой вредности, конечно. Но всё равно, получается, что продал Грэм прототип, не для "риального прадакшена" (C) (R) (TM)

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

> Но всё равно, получается...

А кому интересно, что у Вас получается? А погуглить и кинуть урл, подтверждающий мысль, слабо? Причин может может быть вагон и маленькая тележка.

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

> проблемы с DSL в проекте _значительно ужаснее_ чем проблемы в иерархии классов, фактически при изменении DSL возникают теже проблемы как при переносе приложения между двумя сильно различными платформами на другой язык, с С на паскаль например - в общем DSL- гавно

Проблемы с DSL могут быть разные - простое расширение может практически не повлечь изменения :) Изменения в имеющемся ядре DSL - да, повлекут серьёзные изменения в проекте.

А на чём основано Ваше утверждение? Личный опыт (проект, ссылки)? Или мы "подышать" вышли? С такими голословными утверждениями вы сами лучше всего подходите под последнее слово в вашем посте (не люблю переходить на личности, но гавно не люблю ещё больше ;)

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

Гык самая быстро растущая компания была у Пола а вишь прототип оказывается.Слухи ходют что нутря на лиспе остались только часть перекатали на c.

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

>>>Был уже апдейт: >>И что, скажете читабельность повысилась ?

>Я скажу - да, повысилась. Ясный и даже красивый код.

Мне в Лиспе и с mapcar был ясный и красивый. Мы вроде говорили о читабельности для тех, кто раньше не видел ни то, ни другое. Думаю, что самое разумное будет сойтись на том, что оба варианта хорошо читаются.

>>>1. Не припомню в английском слова "cons"

>>construсt...

>Ну тогда в Питоньей программе вообще все слова английские

И как в английском звучит перевод слова "xrange" ?

>> Кто не может даже в таком очевидном случае увидеть предложений, те идут это на

>Достойный ответ, да

Какой вопрос, такой и ответ. Я что ли про учителя джидаев начал. Код на Питоне тоже не очень-то похож на готовое предложение.

>> IMHO не может быть чтоб код с [1:],[:i],[i:], xrange, yield >>читался лучше кода без этих значков

>range, yield - это слова, отражающие назначение соотетствующих >конструкций. [1:] и т.д. - достаточно близки математической нотации.

Хорошо. Грех не признать, что Питон читается довольно легко, но сказать, что Лисп читается хуже тоже будет неправдой. В ряде случаев за счет изменчивости синтаксиса Лиспа можно вообще использовать ограниченный английский (или иной естественный) язык, например в DSL для самых маленьких ;-)

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

> Хорошо. Грех не признать, что Питон читается довольно легко, но сказать, что Лисп читается хуже тоже будет неправдой. В ряде случаев за счет изменчивости синтаксиса Лиспа можно вообще использовать ограниченный английский (или иной естественный) язык, например в DSL для самых маленьких ;-)

Лично я и не считаю, что язык программирования должен походить на английский / русский / албанский. И мерится по критерию похожести на английский глупо.

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

Человек не знакомый с лиспом (или знакомый поверхностно, как я) ни фига не сможет понять что написано в лисповой программе (без дополнительных знаний про mapcar, mapcan), имея только опыт работы с алголоподобными языками.

В случае с питоном, если человек не знает что такое yield (как работает xrange() можно понять из контекста) тоже ни фига не сможет понять.

Предлагаю свернуть телегу с похожестью на английский, т.к. это

1. Субъективно

2. Не имеет никакого значения

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

>В лиспе-то указатели в принципе невозможны

Посмешил. То же самое наверное надо сказать про С++ ;-)

Во первых в реализациях Common Lisp почти всегда есть FFI, который позволяет оперировать какими угодно сишными конструкциями, выделять области памяти, объявлять структуры, ворочать указателями на функции и т.д. и т.п. Потом даже реализации Common Lisp дают различные вариант доступа к нутру, например на Corman Lisp можно запросто ассемблерные вставки делать, да и в SBCL почти то же самое. Да и кто сказал, что все Лиспы должны быть такими как Common Lisp, вон в Lush вообще можно Си перемешивать с Лиспом. Лисп это идея, а не конкретный стандарт и реализация.

Прикол в том, что в SBCL операции с указателями на задаче свертки массива например с гауссианом работают во много раз быстрее, чем родные массивы ;-) От оптимизированного GCC отстал только процентов на 20-30 (для справки: это на SBCL 0.9.16 на Pentium 4 Northwood под оффтопиком). Так что обработку изображений уже можно одним Лиспом делать без всяких сишных вкраплений.

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

> А кому интересно, что у Вас получается?

Не интересно - не читай.

> А погуглить и кинуть урл, подтверждающий мысль, слабо?

А тебе? Не говоря о том, что это цитаты из "Beating the Averages" (невнимательно читал, да?)

> Причин может может быть вагон и маленькая тележка.

Неважно, какие именно причины - они были достаточно вескими.

"Viaweb at first had two parts: the editor, written in Lisp, which people used to build their sites, and the ordering system, written in C, which handled orders. The first version was mostly Lisp, because the ordering system was small. Later we added two more modules, an image generator written in C, and a back-office manager written mostly in Perl."

Заметил, что там был отнюдь не только Лисп? И то, что Лисп использовался в _редакторе сайтов_, а не в том, что реально обслуживало заказы и было под нагрузкой?

"In January 2003, Yahoo released a new version of the editor written in C++ and Perl."

Вот об этом я говорил - Яху переписало прототип на Лиспе в практичные языки

"It's hard to say whether the program is no longer written in Lisp, though, because to translate this program into C++ they literally had to write a Lisp interpreter: the source files of all the page-generating templates are still, as far as I know, Lisp code. (See Greenspun's Tenth Rule.)"

Этот фрагмент просто восхищает. FUD, ненавязчимвый и эффективный. Итак - человек ушел из Яху в 1999, и говорит о программе, выпущенной ими в 2003: "It's hard to say the program is no longer written in Lisp", "they literally had to write a Lisp interpreter", "still, as far as I know", и, конечно, любимое всеми лисперами 10-е правило Гринспана.

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

>Предлагаю свернуть телегу с похожестью на английский, т.к. это >1. Субъективно >2. Не имеет никакого значения

Вот это уже правильный подход. Ну и с читабельностью в свою очередь предлагаю на этих двух пунктах вопрос прикрыть.

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

>"In January 2003, Yahoo released a new version of the editor >written in C++ and Perl." >Вот об этом я говорил - Яху переписало прототип на Лиспе в >практичные языки

Ну быдломанагеры видно приложили лапу со своими "100 миллионов мух..."

>Этот фрагмент просто восхищает. FUD, ненавязчимвый и эффективный. >Итак - человек ушел из Яху в 1999, и говорит о программе, >выпущенной ими в 2003: "It's hard to say the program is no longer >written in Lisp", "they literally had to write a Lisp >interpreter", "still, as far as I know", и, конечно, любимое всеми >лисперами 10-е правило Гринспана.

Дык, судя по тому что было не так давно писано про Yahoo Store на Фрешмите, они просто воспроизвели функциональность Лиспа на С++, потому что переписать на плюсы, используя чисто плюсовые идиомы, не получилось. Так что Грэм по большому счету нигде не соврал.

>"Viaweb at first had two parts: the editor, written in Lisp, which >people used to build their sites, and the ordering system, written >in C, which handled orders. The first version was mostly Lisp, >because the ordering system was small. Later we added two more >modules, an image generator written in C, and a back-office manager >written mostly in Perl."

>Заметил, что там был отнюдь не только Лисп? И то, что Лисп >использовался в _редакторе сайтов_, а не в том, что реально >обслуживало заказы и было под нагрузкой?

Нормальные люди так и делают. Если есть узкое место, то с интерпретатором на танки идти как то смешно. Лисп то был - GNU CLISP. Сегодня бы на Лиспе скорее всего вообще все было написано (на SBCL скорее всего). Успех то все равно пришел в следствие удобного редактора магазинов, остальное у конкурентов тоже было в порядке.

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

> Ну быдломанагеры видно приложили лапу со своими "100 миллионов мух..."

Ну, если тебе это _видно_ - тогда ой. А во фразе про "100 миллионов мух..." есть один дефект - там предлагается человеку действовать так, словно он - муха. Это заставляет усомниться в уме тех, кто ее придумал, и тех, кто ее повторяет. А если это шутка, то какая-то она слишком тонкая (== плоская).

> Так что Грэм по большому счету нигде не соврал.

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

> они просто воспроизвели функциональность Лиспа на С++

Ну, всегда можно сказать, что рабочая система - это воспроизведение функциональности прототипа. Это игра словами.

> Если есть узкое место, то с интерпретатором на танки идти как то смешно.

ИМХО, там дело было не в "узком месте", а в глючности редактора - для продакшена это было недопустимо :) Но это читая спекуляция.

> Сегодня бы на Лиспе скорее всего вообще все было написано

"бы", "скорее всего".

[ Глюкодел, это ты? По стилю вроде похоже, но русский язык не исковеркан ]

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

> Вот это уже правильный подход. Ну и с читабельностью в свою очередь предлагаю на этих двух пунктах вопрос прикрыть.

Мудрость Питона стих 7: Readability counts

Читабельность имеет значения, вопрос в том, в чём её измерять, а вот это уже проблема. Единственное что приходит в голову, это сменить опрос на главной странице и таким образом провести статистическое исследование о том что читается лучше питон или лисп среднестатистическим Лоровцем.

А опрос всё равно не поменяют, так что выяснить это достоверно не удастся... :-(

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

> Вот об этом я говорил - Яху переписало прототип на Лиспе в практичные языки

Когда же вы оставите при себе свои домыслы? Из текста виден только переход с одного языка на другой и _ни слова_ о причинах! Тем более ни слова про "прототипы" и "практичные языки"! Идите в сад! :)

Тем более, что переписав редактор, шаблоны генераторов они таки оставили в лисповой нотации ;)

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

> ИМХО, там дело было не в "узком месте", а в глючности редактора - для продакшена это было недопустимо :) Но это читая спекуляция.

Или урл на "глючности редактора", или останешься мудозвоном :-Е

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

> Читабельность имеет значения, вопрос в том, в чём её измерять, а вот это уже проблема. Единственное что приходит в голову, это сменить опрос на главной странице и таким образом провести статистическое исследование о том что читается лучше питон или лисп среднестатистическим Лоровцем.

Это будет "статистика для статистики". Проведите опрос среди:
1) не знающих оба языка
2) знающих только питон
3) знающих только лисп
4) знающих оба языка

Вот тогда можно будет сравнивать ;)

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

>> Вот об этом я говорил - Яху переписало прототип на Лиспе в практичные языки

>Когда же вы оставите при себе свои домыслы?

Что конретно является домыслом в процитированной фразе? Что Си++ и Perl - практичные языки?

> Идите в сад! :)

Симметрично

> шаблоны генераторов они таки оставили в лисповой нотации

Насколько знал такой объективный и незаинтересованный Пол Грэм 3 года назад, после 4-х летнего отсуствия в Яху.

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

> Что конретно является домыслом в процитированной фразе? Что Си++ и Perl - практичные языки?

"Прототип" и противопоставление в фразе лиспа "практичным языкам" - _ДВА_ домысла в одной фразе. Детский сад!

> Насколько знал такой объективный и незаинтересованный Пол Грэм 3 года назад, после 4-х летнего отсуствия в Яху.

Подайте в суд или закройте форточку!

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

>> Что конретно является домыслом в процитированной фразе? Что Си++ и Perl - практичные языки?

>"Прототип" и противопоставление в фразе лиспа "практичным языкам"

Какое еще противопоставление... И эти люди посылают меня в сад :/

<shrug> Реальность можно отрицать, но от этого она не менее реальна

>> Насколько знал такой объективный и незаинтересованный Пол Грэм 3 года назад, после 4-х летнего отсуствия в Яху.

>Подайте в суд или закройте форточку!

Успокойся

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

> Какое еще противопоставление... И эти люди посылают меня в сад :/

...неявное

> <shrug> Реальность можно отрицать, но от этого она не менее реальна

...но подтверждённое :)

> Успокойся

Да, дорогая... :)

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

> > На питоне написан > А сколько-нибудь промысшленная OS?

О, да, мсье честно выполняет обещание продолжать передёргивать.

> > Детсад, мля. Винда там. И на msn search тоже винда.

> Нету тама венды, откуда?

Ну не знаю, от windows developement team, видимо - навряд ли они ее сами у себя покупали ;).

> > пример мегасервиса

> мы лисп обсуждаем или мегасервис?

В данный конкретный момент мы обсуждаем применимость Common Lisp для создания крупных систем, эксплуатирующихся под высокой нагрузкой 24x7. На примере вебсервисов. Вот большой вебсервис на Perl+HTML::Mason я знаю - Amazon, на Python - Gmail, а на Uncommon Web?

> > Где же они?

> да фих их знает, не интересовался. Своих траблов полно.

Слив засчитан. Лисп-адвокат не может привести более одной success story в наиболее динамично развивающейся нынче (и последние 10 лет) области.

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

> Вроде Яху его переписали? Из чистой вредности, конечно. Но всё равно, получается, что продал Грэм прототип, не для "риального прадакшена" (C) (R) (TM)

Ага, то-то он на этом "не для продакшена" свою фирму долго кормил, а потом yahoo купила фирму, поскольку конкуренты отсасывали по полной. У Грема на странице это хорошо расписано: http://www.paulgraham.com/road.html

А переписали (до конца ли ?) много позже, поскольку там, как и везде, заправляют манагеры, которым проще нанять толпу быдлокодеров на плюсах, чем искать пару вменяемых лисперов.

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

>Ну, если тебе это _видно_ - тогда ой. А во фразе про "100 миллионов >мух..." есть один дефект - там предлагается человеку действовать >так, словно он - муха. Это заставляет усомниться в уме тех, кто ее >придумал, и тех, кто ее повторяет. А если это шутка, то какая-то >она слишком тонкая (== плоская).

От далеких предков нам к сожалению достался стадный инстинкт. Многим достаточно узнать, что большинство кушает гуано, и они с радостью присоединяются, мол чего там, все так делают, наверное в этом есть сакральный смысл.

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

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

>Ну, всегда можно сказать, что рабочая система - это воспроизведение >функциональности прототипа. Это игра словами.

Игра словами, это то чем Вы, уважаемый, сейчас упорно занимаетесь, делая вид, что не понимаете, что я имел в виду.

>ИМХО, там дело было не в "узком месте", а в глючности редактора - >для продакшена это было недопустимо :) Но это читая спекуляция.

Домыслы пошли ? С таким же успехом можно предположить, что переписать Yahoo Store на другие языки решили из-за внезапного острого приступа даунизма среди манагеров.

>> Сегодня бы на Лиспе скорее всего вообще все было написано

>"бы", "скорее всего".

Начем выленять отдельные слова и словосочетания из текста ?

>[ Глюкодел, это ты? По стилю вроде похоже, но русский язык не >исковеркан ]

Не он. Я так сильно коверкать русский физически не могу. ;-)

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

>>ИМХО, там дело было не в "узком месте", а в глючности редактора - для продакшена это было недопустимо :) Но это читая спекуляция.

>Домыслы пошли ?

Ну, там написано "чистая спекуляция" (с опечаткой, правда), но если вам больше нравится слово "домыслы" - пожалуйста :)

> Вы тоже, я смотрю, довольно свободно оперируете терминами в свою пользу.

Ээээ... примеры?

> Ну надо же придраться к чему-то в статье, вот и нашлось к чему.

Для протокола - мне понравилась статья, я скачал и начал читать его "On Lisp".

>>> Сегодня бы на Лиспе скорее всего вообще все было написано

>>"бы", "скорее всего".

>Начем выленять отдельные слова и словосочетания из текста ?

Отвечу более развернуто - сослагательное наклонение здесь неуместно. Если есть факты - поделитесьт

> С таким же успехом можно предположить, что переписать Yahoo Store на другие языки решили из-за внезапного острого приступа даунизма среди манагеров.

С несколько меньшим. Глючные программы я лично видел куда чаще, чем приступы даунизма у менеджеров

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

> В данный конкретный момент мы обсуждаем применимость Common Lisp для создания крупных систем, эксплуатирующихся под высокой нагрузкой 24x7. На примере вебсервисов. Вот большой вебсервис на Perl+HTML::Mason я знаю - Amazon, на Python - Gmail, а на Uncommon Web?

Вы "обсуждаете" не _применимость_ а _применяемость_, что есть совсем разные вещи... :)

А самому поискать? Или будем меряться - кто эффективнее использует google? :) Ну вот - одну нашёл :)

http://www.lispworks.com/success-stories/netfonds-primetrader.html

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

> рефакторингу, изменениию части классов, отношений между ними, но никак не к переписыванию с нуля.

типо это не одно и то же?

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

>> рефакторингу, изменениию части классов, отношений между ними, но никак не к переписыванию с нуля.

>типо это не одно и то же?

Посмотри в словаре, что такое "рефакторинг". Или ты решил окончательно перейти на троллинг?

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

> написал тебе я прогу

Вообще, трёх функций, от которых требующо описываемые мной действия, было бы достаточно

> Только твоё ТЗ было сформулированно нечётко, исходник ты не показал, так что у нас наверное получились несколько разные проги

можно было спросить уточнения, я бы необиделсо

> нарпимер я сделал persistent storage на sqlite, соответственно пооиск по базе файлов работает очень шустро.

ужос! Это даже хужее чем я предполагал. Вместо переменных питону требуецо даза банных информацию хранить :D

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

Давай. Только погодим, пока тот чел с с++/стл подтянецо. Я подозреваю он просто слил, но из вежливости погодим.

> для добавления файла в базу

сразу таки в базу? чем фс для этово не подходит?

> Прога на лиспе желательно должна работать под Win32

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

> Вот когда напишешь такую прогу, тогда и поговорим :-)

Давай тада формализуем техзадание, потомушто для моей первоначальной задачи подключение дазы банных - это ПРЕОГРОМНЫЙ оверкилл, а так - я не против. Только как быть с первоначальной задачей? Повторюсь, требуецо создать структуру данных средствами языка, и две функции для работы с этим.

> P.S. Прога передаётся в public domain. Можешь её использовать для чистки своего винта :-)

винт давно почищено, это несложно было даже срецтвами баша сделать. А твоёй прогой на практике ИМХО пока не удасца пользовацо, там даже обхода дерева каталохов на фс нету, вручную файло нужно добавляти.

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

> [ Глюкодел, это ты? По стилю вроде похоже,

мамой клянусь нея. Я под ононимусом не пишу.

> но русский язык не исковеркан ]

умя нигде несковеркан

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

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

Ага. Найти вменяемого лиспера -- задача не для слабонервных ;-).

А два вменяемых лиспера, да еще и на одном диалекте -- это вообще непосильная задача :-)).

eugine_kosenko ★★★
()
Ответ на: комментарий от ero-sennin

> Кстати, для Лиспа какие-то рефакторилки существуют?

ХЗ :) Я не по Лиспу, я больше по ассемблеру - для него нету :/ Всё вручную :(

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

Ты определись,

> трёх функций, от которых требующо описываемые мной действия, было бы достаточно

или

> требуецо создать структуру данных средствами языка, и две функции для работы с этим

сколько функций?

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

> Давай. Только погодим, пока тот чел с с++/стл подтянецо.

А что, кто-то собирался на Си++ писать? Что-то я не помню таких. Если речь обо мне, я сразу сказал, что вряд ли возьмусь (и даже объяснил, почему). Если же и возьмусь - то тоже на Питоне.

> можно было спросить уточнения, я бы необиделсо

Да, неплохо бы. Сейчас уже упоминается, что нужно обходить дерево каталогов ФС. Ты определись, что нужно - программа чистки хоума, или структура данных для такой программы?

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

> Читабельность

ясен пень, чё пипл, знакомый с програмёжем в основном по бейсику, более поймёт a=7 чем (setq a 7). Ещё более понятно, чё на задачах, отличных от примитивной калькуляции, вторая запись в общем случае более предпочтительна чем первая, как раз из-за тово, чё (сравнительно) сложные конструкции и сочинять и читать лехче. Другое дело, чё пипл, знакомый с програмёжем в основном по бейсику, не вполне представляет, чё конструкции сложнее чем а=7 бывают в принципе, из-за чего и разногласия нащёт читаемости.

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

> Лисп-адвокат

я не лисп-адвокат, я глюкодел

> не может привести более одной success story в наиболее динамично развивающейся нынче (и последние 10 лет) области.

погугли, найдёш ссыло. Или вверьх отлистай. Я там приводил кучю. Или чюкчя переквалифицируецо в читателя если я запощу по второму-третьему разу?

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

> Посмотри в словаре, что такое "рефакторинг".

Я ужо. Только не могу понять, почему же он появилсо только в ООП? Или не-ООПнутых прог сравнительной сложности не было или они таки не нуждались в "рефакторинг"?

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

> Ты определись,

>> трёх функций, от которых требующо описываемые мной действия, было бы достаточно

> или

>> требуецо создать структуру данных средствами языка, и две функции для работы с этим

> сколько функций?

Не вижу противоречия. Я предполагаю чё структура будет создаваться каким-то учястком кода, который нетрабла вткнуть вфункцию. Такчто функция-инициализатор и две для работы. Всево три.

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

> А что, кто-то собирался на Си++ писать? Что-то я не помню таких.

вчера выполз троль с c++/STL. Отлистай и прочти, иначе много потеряеш. Я очень смяялсо :D

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

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

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

> более поймёт a=7 чем (setq a 7). Ещё более понятно, чё на задачах, отличных от примитивной калькуляции, вторая запись в общем случае более предпочтительна чем первая, как раз из-за тово, чё (сравнительно) сложные конструкции и сочинять и читать лехче

Ты вообще сам хоть понял что написал? Поясни на примере, где setq будет "читабельнее" знака равенства.

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

> Ты вообще сам хоть понял что написал?

А ты, я вижу, нет :(

> Поясни на примере, где setq будет "читабельнее" знака равенства.

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

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

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

Это называется ставить "удобство" машины выше удобства человека. Точно также как все эти скобки и ";" в Цэ и прочие подобные маразмы.

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

> Вы "обсуждаете" не _применимость_ а _применяемость_, что есть совсем разные вещи... :)

Да, пожалуй соглашусь.

> А самому поискать? Или будем меряться - кто эффективнее использует google? :)

Я должен искать аргументы за своих оппонентов? Это что-то новое в искусстве ведения дискуссии...

> Ну вот - одну нашёл :)

Ну, типа да. Правда, у них web presentation layer на PHP, судя по схеме ;), и по масштабам это ни разу не гугль, но сойдет. Итак, на 1100-ом сообщении мы выяснили, что на CL таки можно писать программы ;).

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

> Давай. Только погодим, пока тот чел с с++/стл подтянецо. Я подозреваю он просто слил, но из вежливости погодим.

Давай C++ не ждать, или подожапть до середины завтра. Ничего принципиально нового по сравнению с питоном мы не увидим. То же ООП и метапрограммирование (в терминологии Страуструпа) что и в питоне, только без sqlalchemy и более многословно (но быстрее и typesafe, это чтобы не обижать фанатов C++)).

У меня такое предлодение:

1. Ты делаешь полный клон моей программы на лиспе и постишь сюда. В смысле клон по функциональности, используя макросы и прочие лисповые идиомы.

2. Ты постишь свой вариант, а я делаю его клон на питоне, т.е. таже функциональность, но с использованием ООП и т.д...

> винт давно почищено, это несложно было даже срецтвами баша сделать. А твоёй прогой на практике ИМХО пока не удасца пользовацо, там даже обхода дерева каталохов на фс нету, вручную файло нужно добавляти.

А это я Раймонда начитался. :-) Это же опенсорц. Ядро есть, осталось дописать ходилку по дереву, ГУЙ и можно зарабатвыать на саппорте...

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

>>>ИМХО, там дело было не в "узком месте", а в глючности редактора - для продакшена это было недопустимо :) Но это читая спекуляция. >>Домыслы пошли ?

>Ну, там написано "чистая спекуляция" (с опечаткой, правда), но >если вам больше нравится слово "домыслы" - пожалуйста :)

Причем тут предположения, он честно и пишет, что мол переписать на другом языке будет сложновато. Но где написано про глючность редактора ?

>> Вы тоже, я смотрю, довольно свободно оперируете терминами в свою >>пользу.

>Ээээ... примеры?

Берем фразу из статьи, добавляем домыслы и вот уже вроде на правду смахивает. Вот тут вывод просто потрясающий:

"Вроде Яху его переписали? Из чистой вредности, конечно. Но всё равно, получается, что продал Грэм прототип, не для "риального прадакшена" (C) (R) (TM)"

>Для протокола - мне понравилась статья, я скачал и начал читать >его "On Lisp".

Респект. По-моему, без всякого фанатизма будет сказано, это довольно интересная/познавательная книга и "ANSI CL" у Грэма тоже неплохая, особенно в бумажном виде. Но Practical Common Lisp Сабеля все же практичнее ;-)

>>> Сегодня бы на Лиспе скорее всего вообще все было написано

>Отвечу более развернуто - сослагательное наклонение здесь >неуместно. Если есть факты - поделитесьт

Ну производительность сегодняшних лиспов даже на бросовом железе достаточна чтобы выдержать нагрузки, которые раньше только Си выдерживал. SBCL и CMUCL имеют неплохие оптимизирующие компиляторы, поэтому препятствий писать вообще все на Лиспе теперь нет никаких. Кстати переписали они на плюсы и перл например. А завтра и мастера плюсов и перла повыведутся, будут переписывать на какую-нибудь решетку. Насколько я знаю в силу некоторой неторопливости изменения стандарта и т.д. программы на Лиспе оказываются довольно живучими, зачем так дергаться если все работает. Неужели Грэм там столько понаписал, что эти "гении" разобраться не смогли и им было проще переписать по новой. C++ в сопровождении IMHO посложнее Лиспа будет, если конечно код на Лиспе не полная лапша.

>С несколько меньшим. Глючные программы я лично видел куда чаще, чем >приступы даунизма у менеджеров

Ну не обязательно даунизма, может быть просто приступ страха, что мол все вон как делают, а я рискую, лучше сделаю как все, за это не увольняют. Это трудно отрицать.

Лисп вывел их на орбиту, обеспечил победу в гонке с конкурентами, а С++ для поддержки морально комфортнее получается, вроде как менеджменту чувства стабильности захотелось. Тогда это плюс и Лиспу и С++, каждый при деле.

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

> Давай C++ не ждать, или подожапть до середины завтра.

ладно, давай. Я тоже думаю чё это был пустой трёп и он тут непоявицо больше.

> Ничего принципиально нового по сравнению с

Зато было бы презабавно

> У меня такое предлодение:

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

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

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

Вообще, я сильно подозреваю, что было переписато исключительно в целях вытягивания бабла. Потому что я наблюдал такое явление как переписывание с одного наречия на другое без всяких причин, кроме финансовых _многократно_. Насколько я знаю, причины, по которым переписывалось, так никогда и не были указаны руководством (это говорит в пользу моей догадки ИМХО). А раз достоверно ничё неизвесно, ИМХО обсуждение этого факта не очень продуктивно, хотя и положительно сказываецо на размерах топика.

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

> пипл, знакомый с програмёжем в основном по бейсику, более поймёт a=7 чем (setq a 7)

a=7 и к математической нотации ближе, так что человек, не знакомый с Бейсиом вообще, тоже более пойме a=7

>> Посмотри в словаре, что такое "рефакторинг".

>Я ужо. Только не могу понять, почему же он появилсо только в ООП? Или не-ООПнутых прог сравнительной сложности не было или они таки не нуждались в "рефакторинг"?

Были. Нуждались. Но _термин_ "рефакторинг" появился только недавно (лет 10). Сам процесс был, наверное, начиная с самых ранних дней. Только называли его разные люди по-разному, а теперь есть один общепринятый термин (ты уж прости за это ООП вообще и доктора Д.Шмидта в частности :)).

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

> к математической нотации ближе

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

> Были. Нуждались.

хм Почему-то когда я слыхал про рефакторинг, он относился только к прогам на жабе/с++. А про проги на сях говорили (в крайне редких случяях) "этот кусок кода нужно переделать потому ево накропал муд@к какойто", и речи о затрагивании остальных учястков кода небыло. А чяще просто поправляли пару десятков строк всево делов.

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

> Хм. Задачя: составить структуру данных для хранения информации о
> том, в каких директориях находицо файл. Одинаковый файл может
> храницо в нескольких. Файлы щитаецо одинаковым если совпадает и
> имя и размер. Создать код, который 1) поштучно добавляет
> информацию (имя файла, размер, директория) в структуру, 2)
> составляет отдельно списки имён файлов, которые есть в равном N
> количестве, больше или меньше. Для каждово имени нужно передать
> также информацию о том, в каких директориях он. Возмёшся? Потом
> присовокуплю код на лиспе. 

Ну, ээ. Задачка, конечно, странная - я б такое делал на шелле
 (find -printf+sort+join+grep+awk) - было бы строчек 10 вместе с
 собственно обходом директорий. Но ты просил на плюсах? Да держи.
 Правда, здесь только про "равное N количество" - поленился я три
 (почти) одинаковых функтора рисовать.

Да, "давно не брал я в руки шашек" (отмазываюсь).

#include <string>
#include <set>
#include <map>
#include <iostream>
#include <iterator>

using namespace std;

struct FileId {
    size_t size;
    string name;

    FileId(string name_, size_t size_) : name(name_), size(size_) {};

    struct Eq {
        bool operator()(const FileId &a, const FileId &b) {
            return a.name < b.name ||  a.size < b.size;
        }
    };
};


typedef map< FileId, set<string>, FileId::Eq > FileDist;

void add_file(FileDist &files, string name, string dir, size_t size) {
    const FileId key(name, size);
    FileDist::iterator duplicate = files.find(key);
    files[key].insert(dir);
};

struct not_file_has_locations {
    size_t n;
    not_file_has_locations(size_t N) : n(N) {};
    bool operator()(pair< FileId, set<string> > p) {
        return p.second.size() != n;
    }
};

int main() {
    FileDist files;
    add_file(files, "a", "/foo", 1);
    add_file(files, "a", "/bar", 1);
    add_file(files, "b", "/foo", 1);
    add_file(files, "b", "/bar", 1);
    add_file(files, "b", "/baz", 1);
    add_file(files, "b", "/fred", 2);
    add_file(files, "c", "/foo", 3);

    FileDist files_with_2_locs;

    remove_copy_if(files.begin(), files.end(),
                    insert_iterator<FileDist>(files_with_2_locs, files_with_2_locs.begin()),
                    not_file_has_locations(2));

    for (FileDist::const_iterator i = files_with_2_locs.begin(); i != files_with_2_locs.end(); ++i) {
        cout << i->first.name << ":" << i->first.size << " in ";
        copy(i->second.begin(), i->second.end(), ostream_iterator<string>(cout, " "));
        cout << endl;
    }
}

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

>>Ну, там написано "чистая спекуляция" (с опечаткой, правда), но >если вам больше нравится слово "домыслы" - пожалуйста :)

>Причем тут предположения

Я ничуть не против слова "домысл" в данном случае - потому что мое предположение сделано в пику лисперам и не поддержано никаими фактами. Я думал, очевидно, что это ирония.

>Берем фразу из статьи, добавляем домыслы и вот уже вроде на правду смахивает. Вот тут вывод просто потрясающий:

> "Вроде Яху его переписали? Из чистой вредности, конечно. Но всё равно, получается, что продал Грэм прототип, не для "риального прадакшена" (C) (R) (TM)"

Это снова была попытка иронизировать :/ Я думал, по нарочито искаженным словам и дурацкому набору значков это видно. Если серьезно - я думаю, что Яху купила многообещеющую _технологию_, вполне агностичную по отношению к языку реализации (см. про куски на Перле и Си), а не кодовую базу на CL.

> Но Practical Common Lisp Сабеля все же практичнее

На сайте Грэма не было других :) Кроме того, как-то комфортнее читать практика, за плечами которого успешные проекты.

> Ну производительность сегодняшних лиспов даже на бросовом железе достаточна

Производительность - это отнюдь не всё. Вспомни, процесс переписывания завершился в 2003, железо того времени не сильно отличалось от сегодняшнего. К тому же на Лиспе был написан _редактор сайтов_ - не самое критичный к производительности компонент. Значит, не только (или не столько) в производительности дело. Как минимум - найти специалистов по Лиспу сложнее (значит, дольше и дороже).

> А завтра и мастера плюсов и перла повыведутся

Ну. это несерьезно.

> С++ для поддержки морально комфортнее получается, вроде как менеджменту чувства стабильности захотелось.

А вот про "моральный комфорт" и "вроде как чувства стабильности захотелось" - домыслы. У Грэма по этому поводу ничего нет, из Яху он ушел, и в каком состоянии была кодовая база, каково всё это было сопровождать - нам неведомо.

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

> вчера выполз троль с c++/STL. Отлистай и прочти, иначе много потеряеш.

Я читал, правда, не увидел там особого троллинга. Человек говорил здравые вещи. Просто не старался быть политически корректным в формулировках.

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

Вторая строчка в функции add_file лишняя, осталось от мозгового штурма (давно, да и мало, писал я на плюсах - приходилось в доку по STL подглядывать, на тему "а какая у нас семантика map::operator[]").

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

> > вчера выполз троль с c++/STL. Отлистай и прочти, иначе много потеряеш.

> Я читал, правда, не увидел там особого троллинга. Человек говорил здравые вещи. Просто не старался быть политически корректным в формулировках.

10x за понимание ;)

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

> Потому что это не "а равно семи" как в мотематике, а "присвоить значение сем к перемнной а".

В голове психически здорового человека это одно и то же. Лиспоидов это понятное дело не касается.

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

> Это называется ставить "удобство" машины выше удобства человека.

любой код рано или поздно возникает потребность обрабатывать автоматически -- и тогда занозой в яопе встает вопрос: а какого хрена в Си есть две конструкции для одного и того же: if() else; и ?:

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

> любой код рано или поздно возникает потребность обрабатывать автоматически -- и тогда занозой в яопе встает вопрос: а какого хрена в Си есть две конструкции для одного и того же: if() else; и ?:

Вообще-то, между ними существует огромная разница... Как синтаксическая, так и семантическая.

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

> Я должен искать аргументы за своих оппонентов? Это что-то новое в искусстве ведения дискуссии...

Неа, не так. Если грамотно "дискутировать", то кто-то должен подавать и "гипотезу", и доказательства. А остальные оценивать/критиковать. А "базар" типа "А на Х есть то, то и то. А что у вас есть на У?" к дискуссии никакого отношения не имеет ;)

> Итак, на 1100-ом сообщении мы выяснили, что на CL таки можно писать программы ;).

И так, на 1100-ом сообщении таки кто-то не выдержал, и превёл прямой линк на готовую прогу, а кто-то другой, кто ленился искать сам, согласился, что такие проги есть... Каюсь, больше так не буду - плохо кормить рыбой, надо учить пользоваться удочкой ;)

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

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

Но-но-но, не зарывайтесь, лейтенант! Cтандартная математическая нотация - тоже зверинец из префиксных, инфиксных операторов, функций и ещё кучи всево, не подчиняющейся одним правилам, типа дробной черты или (ужас!) знака интеграла. Это плохо? :)

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

> Cтандартная математическая нотация - тоже зверинец из префиксных, инфиксных операторов, функций и ещё кучи всево, не подчиняющейся одним правилам, типа дробной черты или (ужас!) знака интеграла. Это плохо? :)

конечно плохо. Этой нотацией пользуются только придурки физики. Реальные Математики общаются телепотичецки.

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

Просто так. Цитата из Юкихиро Матсумото (Matz) -- создателя Ruby:

Ruby is a language designed in the following steps:

* take a simple lisp language (like one prior to CL). * remove macros, s-expression. * add simple object system (much simpler than CLOS). * add blocks, inspired by higher order functions. * add methods found in Smalltalk. * add functionality found in Perl (in OO way).

So, Ruby was a Lisp originally, in theory. Let's call it MatzLisp from now on. ;-)

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

на лиспе это выгледит так:

создание структуры для хранения:

(setq hash (make-hash-table :test #'equal))

в реальных прогах правда setq практически не используецо, вместо нево
 (let ((hash (make-hash-table :test #'equal)) 
 (...остальные переменные...)) ...код...), но для проверки
 в интерпретаторе так удобнее.

добавление файлов:

(push "/foo" (gethash (list "file.txt" 777) hash))
(push "/bar" (gethash (list "file.txt" 777) hash))
(push "/foobar" (gethash (list "file.txt" 777) hash))
(push "/bar" (gethash (list "file1.txt" 888) hash))
(push "/foo" (gethash (list "file1.txt" 888) hash))
(push "/foo" (gethash (list "file2.txt" 999) hash))

поиск и чепять фаела, который бывает ?N раз, и где находицо, функция:

(defun find-and-get (h &key (count 0) (cmp #'>))
  (let ((r nil))
    (maphash (lambda (k v)
      (when (funcall cmp (length v) count)(push (list k v) r))) h)
  r))

по умолчянию вызватое (find-and-get hash) выводит большее 0.
Вызватое как (find-and-get hash :count 2) выводит большее 2.
Вызватое как (find-and-get hash :count 2 :cmp #'<) выводит меншее 2.
Вызватое как (find-and-get hash :count 2 :cmp #'=) выводит равное 2.
итд.

Комментарии?

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

Кстати, прошу извинить за напрасную худую мысль про тебя, я ашыбочьно подумал чё ты покинул нас ужо :(

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

> не увидел там особого троллинга. Человек говорил здравые вещи

ну, то, что на STL работать проще и легче чем на лиспе - вещ изумительно нездравая.

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

> Как минимум - найти специалистов по Лиспу сложнее (значит, дольше и дороже).

ИМХО плохой аргумент, очень плохой. Разница в продуктивности - на порядки, а в зарплате - в разы. Вдобаваок, быдлолиспокодер выдаст продукт намного более качественный, "в нагрузку".

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

>> Потому что это не "а равно семи" как в мотематике, а "присвоить значение сем к перемнной а".

> В голове психически здорового человека это одно и то же. Лиспоидов это понятное дело не касается.

Конешно не касаецо, иначе с каких это делов для одново и тово же в сях и большинстве других наречий есь разные операторы = и == для одново и товоже?

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

>> любой код рано или поздно возникает потребность обрабатывать автоматически -- и тогда занозой в яопе встает вопрос: а какого хрена в Си есть две конструкции для одного и того же: if() else; и ?:

> Вообще-то, между ними существует огромная разница... Как синтаксическая, так и семантическая.

а в лиспе if этих обеих заменяет, и без всяково неудобства...

bugmaker ★★★★☆
()
Ответ на: комментарий от ero-sennin

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

> Но-но-но, не зарывайтесь, лейтенант! Cтандартная математическая нотация - тоже зверинец из префиксных, инфиксных операторов, функций и ещё кучи всево, не подчиняющейся одним правилам, типа дробной черты или (ужас!) знака интеграла. Это плохо? :)

Я вобщем-то это тоже имел в виду, когда утверждал, чё плохо перетаскивать из математики. Это ужасно, когда такая нотация перетаскиваецо в области, мало связанные с вычислениями. Ибо, в математике для чисел одна нотация, для множеств - совсем другая (особенно печяльно что некоторые символы общие, но смысел совершенно разный), для векторов - третья, для... нунахъ, видиш, даже в пределах математики одна нотация неюзаецо. Если ещё учесть, что для записи формул технические возможности гораздо богаче всмысле всяких индексов и закорючек (нука, изобрази мне круговой интыграл от а до б от фи по пси в проге :P), то привлечение математической нотации в программирование - жалкие потуги. Я уж не говорю, что спектр понятий в программировании гораздо шире и не совпадает с математикой. Тово же присвоения в математике просто нету.

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

Но в математике такая запись используется не просто так. Она удобна для человека. Так уж человек устроен, что ему легче читать месиво из разных значков, чёрточек, крючочков, чем однообразные наслоения этих скобок. А лисповская запись удобна не для человека, а для машины. И не надо про макросы и метапрограммирование. В математике используются такие макросы, что закачаешься. :) И всякие DSLи там вполне используются, и никто ещё не говорил, что математическая запись для этого не подходит. :)

ero-sennin ★★
()
Ответ на: комментарий от bugmaker

#!/usr/bin/env python

class FileDb(dict):
    def push(self, name, size, dir):
        try:
            self[(name, size)].append(dir)
        except KeyError:
            self[(name, size)] = [dir]

filedb = FileDb()

# Меньше шума чем в "(push "/foo" (gethash (list "file2.txt" 999) 
# hash))". Нет таких лишних сущностей как gethash и list
filedb.push('file.txt', 777, '/foo')
filedb.push('file.txt', 777, '/foobar')
filedb.push('file1.txt', 888, '/bar')
filedb.push('file1.txt', 888, '/foo')
filedb.push('file2.txt', 999, '/foo')

def find_and_get(cond=lambda n: n > 0):
    for (f, s), dirs in filedb.iteritems():
        if cond(len(dirs)):
            for d in dirs:
                yield (f, s, d)

print list(find_and_get())
print list(find_and_get(lambda n: n > 1))
print list(find_and_get(lambda n: n != 2))

Теперь ждём лисповую версию с БД. 

А БД мне понадобилась за тем, что я точно знаю что на моём винте,
без БД не разберёшься :-)

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

>Теперь ждём лисповую версию с БД.

А где тут БД ? Лисповая версия вроде тоже самое делала, только без лишних сущностей вроде наследования FileDb от словаря.

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

> А два вменяемых лиспера, да еще и на одном диалекте -- это вообще непосильная задача :-)).

Ну я думаю, что поработать с полным набором Allegro CL никто не откажется :^)

А так - два более-менее вменяемых из свободных не так уж и сильно отличаются (я имею в виду CMUCL и SBCL).

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

> А так - два более-менее вменяемых из свободных не так уж и сильно отличаются (я имею в виду CMUCL и SBCL).

Аха, и выбор одного из этих двух может застопорить любой процесс разработки :-).

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

> Тово же присвоения в математике просто нету.

Присвоение в математике -- это преобразователь предикатов.

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

> Аха, и выбор одного из этих двух может застопорить любой процесс разработки :-).

Тут всё может зависеть от того какие библиотеки могут использоваться. Например OpenGL из cl-sdl у меня в SBCL не завёлся вообще а CMU пошёл влёт. Не сомневаюсь, что есть ситуации и наоборот - SBCL вроде Unicode лучше держит.

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

> Разница в продуктивности - на порядки,

"...но при этом такая фигня получается..." :-)

> а в зарплате - в разы.

Дело не в зряплате. Дело в том, чтобы найти адекватную замену лисперу, который, начав проект, внезапно ощутит бренность всего сущего и уйдет в тибетский монастырь. И причем, желательно еще так, чтобы новый лиспер оказался не настолько гениальным, чтобы начать переписывать все с нуля. Ибо есть подозрение, что если один лиспер не способен за один присест написать всю систему, то на лиспе эта задача вообще неразрешима.

У Хаксли как-то упоминался эксперимент по построению "общества альф". Которое просуществовало ровно неделю. О том же, кстати, пишет и Джоэль в своем "БигМаке против обнаженного повара". Так что, быдлокодеры тоже нужны. Без них пока никак.

Ну, разве что, наши гениальные лисперы таки научатся писать самопрограммирующиеся программы. Которые могут адаптироваться к предметной области, самоисправляться и самотестироваться без участия самих гениальных лисперов. Но это все пока что утопия...

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

> Например OpenGL из cl-sdl у меня в SBCL не завёлся вообще а CMU пошёл влёт.

Ну, у меня примерно те же критерии. По которым быдлоламбдагтк было выбрано в ущерб правильному целлгтк.

> Не сомневаюсь, что есть ситуации и наоборот - SBCL вроде Unicode лучше держит.

А теперь представим проект, где есть обе ситуации. Гениальные лисперы, кажется, не привыкли рутино дотачивать недостающие возможности?..

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

>>Теперь ждём лисповую версию с БД.

> А где тут БД ?

Ты с нами недавно? Почитай топик с начала - тебе понравится. А версия с БД была на пару страниц раньше.

> Лисповая версия вроде тоже самое делала, только без лишних сущностей вроде наследования FileDb от словаря.

Наследование от словаря - вопрос стиля (можно и без наследования). Насчет "лишних сущностей" - при желании таковыми можно объявить все ЯВУ. Да и ассемблеры - всё равно ЦП работает с кодами команд.

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

> Потому что это не "а равно семи" как в мотематике, а "присвоить значение сем к перемнной а"

Одно из (неформальных?) определений оператора присваивания "теперь а равно <значение>"

> Почему-то когда я слыхал про рефакторинг, он относился только к прогам на жабе/с++.

А я много раз слышал и читал в логах слово "рефакторинг" по отношению к коду на Си. И Питон, конечно.

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

> Так уж человек устроен, что ему легче читать месиво из разных значков, чёрточек, крючочков, чем однообразные наслоения этих скобок.

Яволь!

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

> А теперь представим проект, где есть обе ситуации. Гениальные лисперы, кажется, не привыкли рутино дотачивать недостающие возможности?..

Смайлик где, умник?

Таки нет, сидишь и "точишь" эти самые "недостающие возможности" :-Е

P.S. Не хотите помочь? Или гениальные кодеры на мэйнстриме привыкли всё получать из коробки, а если чего нет, то "в противогазе стоя в гамаке на лыжах"? :)

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

> > Так уж человек устроен, что ему легче читать месиво из разных значков, чёрточек, крючочков, чем однообразные наслоения этих скобок.

> Яволь!

Человек не устроен читать вообще - иначе глазики бы не портились. А если именно вам легче читать "месиво из разных значков, чёрточек, крючочков", то изучайте китайский/японский.

Я к тому, что человек "устроен" ходить на двух ногах - да. А читать ему легче то, что он понимает (т.е. во многом - дело привычки). Так что не прикидывайтесь совсем уж полными идиотами - а то жалко становится "нелисперов" ;)

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

> Человек не устроен читать вообще - иначе глазики бы не портились. А если именно вам легче читать "месиво из разных значков, чёрточек, крючочков", то изучайте китайский/японский

Уже изучаю. :)

А кроме шуток, я люблю Лисп, и сам на нём иногда пишу, и мне всегда казалось, что его синтаксис - очень небольшая плата за гибкость, но вот заявлять, что S-выражения читаются ЛЕГЧЕ, чем традиционная математическая нотация это блин уже фонатство и красноглазие. Или таки вы хотите сказать, что математическая запись - отстой, и надо её срочно привести к однородному виду: префиксная нотация, скобочки и ASCII-символы? :P

ero-sennin ★★
()
Ответ на: комментарий от yyk

>> Гениальные лисперы, кажется, не привыкли рутино дотачивать недостающие возможности?..

> Смайлик где, умник?

> Таки нет, сидишь и "точишь" эти самые "недостающие возможности" :-Е

Да не злись ты так. Мы знаем, что ты дотачиваешь.

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

> Человек не устроен читать вообще - иначе глазики бы не портились.

Если читаешь в нормальных условиях - глаза не портятся. Ты еще скажи, что человек не устроен пить воду - если выпить слишком много _чистой_ воды, можно отравиться (или просто лопнуть).

Слушай, а жить человек устроен? А то он же умирает... 8)

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

> А кроме шуток, я люблю Лисп, и сам на нём иногда пишу, и мне всегда казалось, что его синтаксис - очень небольшая плата за гибкость, но вот заявлять, что S-выражения читаются ЛЕГЧЕ, чем традиционная математическая нотация это блин уже фонатство и красноглазие. Или таки вы хотите сказать, что математическая запись - отстой, и надо её срочно привести к однородному виду: префиксная нотация, скобочки и ASCII-символы? :P

Не, ну нет конечно, записывать 3-этажные мат. формулы в лисп-нотации - лучше застрелиться сразу :) Но как вы будете в мат. нотации записывать макры? ;)

А на данный момент я не видел синтаксиса, более пригодного для "макропрограммирования", чем лисповый :)

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

> Да не злись ты так. Мы знаем, что ты дотачиваешь.

Да я не злюсь - несколько удручает количество работы впереди и недостаточно колиество активных членов "комьюнити" для решения этих задач несколько быстрее, чем ещё в течение десятков лет :( Ибо, имхо, по сравнению с тем, что есть, осталось добавить совсем не много, чтобы и я (а может и ещё кто ;) с чистой совестью смог толкать лисп в свой "продакшн" :)

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

> Если читаешь в нормальных условиях - глаза не портятся. Ты еще скажи, что человек не устроен пить воду - если выпить слишком много _чистой_ воды, можно отравиться (или просто лопнуть).

Если к условиям относятся и перерывы и гимнастика для глаз - да, не портятся :) Кто-нибудь доказал тёте Клаве (или девчёнке) за соседним компьютером, что регулярные перерывы и гимнастика сделают гораздо больше, чем крутейший монитор с таким-же фильтром? (я понимаю, что лучше - и то, и другое и третье :)

При хождении/питье человек "портится" равномерно. При неправильном чтении глаза "садятся" гораздо быстрее

> Слушай, а жить человек устроен? А то он же умирает... 8)

Человек устроен жить, чтобы умереть... :)

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

> Но как вы будете в мат. нотации записывать макры? ;)

Я, может, крамольную вещь скажу, но по-моему, само различие между функциями и макросами - костыль. Пусть компилятор во время компиляции сам сворачивает те функции, которые можно свернуть.

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

> Я, может, крамольную вещь скажу, но по-моему, само различие между функциями и макросами - костыль. Пусть компилятор во время компиляции сам сворачивает те функции, которые можно свернуть.

Неа, не догоняю... Давай по-порядку: "различие между функциями и макросами - костыль" - ты предлагаешь отказать от макр? Или где? :) "Пусть компилятор во время компиляции сам сворачивает те функции, которые можно свернуть" - или я тебя не понял, или компилятор в sbcl и так с некоторыми функциями так и поступает (набивший аскомину add).

Или ты всё-таки что-то другое имел в виду?

yyk ★★★★★
()
Ответ на: комментарий от ero-sennin

>> Но как вы будете в мат. нотации записывать макры? ;)

>Я, может, крамольную вещь скажу, но по-моему, само различие между функциями и макросами - костыль. Пусть компилятор во время компиляции сам сворачивает те функции, которые можно свернуть.

Аминь, брат. Были экспериментальные языки и компиляторы, которые _примерно_ так и делали. Там был такой тип данных "тип", и средства в языке для манипуляции значениями этого типа. Такие выражения вычислялись транслятором, и результаты вычислений им же использовались для дальнейшей обработки входной программы.

К сожалению, в практически используемые языки эти технологии не пошли, а текущий тренд - вообще делать такие вещи в динамике на runtime :(

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

> Аминь, брат. Были экспериментальные языки и компиляторы, которые _примерно_ так и делали. Там был такой тип данных "тип", и средства в языке для манипуляции значениями этого типа. Такие выражения вычислялись транслятором, и результаты вычислений им же использовались для дальнейшей обработки входной программы.

Опять боюсь показаться тупым, но это описание очень "смахивает" на форт и на инкрементальную компиляцию (если несколько абстрагироваться от "тип данных "тип"" :)

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

Кажется он хочет отказаться от функций. Типа это сильно вырожденные макры, с нулевым expand'ом.

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

Ну то есть, чтоб компилятор сам хитрым образом догадывался, когда именно вычислять аргументы функции. :) На худой конец использовать что-то вроде Hold/HoldAll из Математики. Правда это немногим лучше лисповых макр. Блин. :(

ero-sennin ★★
()
Ответ на: комментарий от yyk

> это описание очень "смахивает" на форт и на инкрементальную компиляцию

Даже и близко не похоже

> если несколько абстрагироваться от "тип данных "тип"" :)

В нем вся суть

Есть такая старая книга: А.Замулин "Языки программирования баз данных и знаний". То, о чем я говорю - это его язык Атлант.

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

> Ну то есть, чтоб компилятор сам хитрым образом догадывался, когда именно вычислять аргументы функции. :) На худой конец использовать что-то вроде Hold/HoldAll из Математики. Правда это немногим лучше лисповых макр. Блин. :(

Ну, одного времени вычисления аргументов недостаточно. Макра же сама по себе - функция, упорно ворочающая списками для постройки "выхода"... Неа, не догоняю :( Имхо - ничуть не лучше, а получится очередное ограничение...

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

> Смайлик где, умник?

==> ;-)

> Таки нет, сидишь и "точишь" эти самые "недостающие возможности"

В каком из двух правильных диалектов одного самого правильного языка?

> Не хотите помочь? Или гениальные кодеры на мэйнстриме привыкли всё получать из коробки, а если чего нет, то "в противогазе стоя в гамаке на лыжах"?

С удовольствием. Только я так думаю, что лучше таки подождать, пока лисперы не определятся, какой из лиспов самый правильный. И только после этого присоединиться к процессу доточки недоработок.

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

> Ну, одного времени вычисления аргументов недостаточно. Макра же сама по себе - функция, упорно ворочающая списками для постройки "выхода"...

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

ero-sennin ★★
()
Ответ на: комментарий от eugine_kosenko

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

Отмазки ;) Никогда они не определятся. Даже специалисты по операционкам никак не определятся - Linux или *BSD (и какая именно из них), что уж говорить о лисперах.

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

> В каком из двух правильных диалектов одного самого правильного языка?

sbcl по той простой причине, что он а) портирован под офтопик (частично); б) проще собирается (по слухам).

> Только я так думаю, что лучше таки подождать, пока лисперы не определятся, какой из лиспов самый правильный. И только после этого присоединиться к процессу доточки недоработок.

Никогда не определятся :) Что-то впоследнее время лиспы множаться как сорняки ;) В этом есть и минусы, есть и плюсы. Выбирайте тот, который вам по-душе. Или несколько. Мне ещё cLisp очень нравится :)

yyk ★★★★★
()
Ответ на: комментарий от ero-sennin

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

Не получится. Вам надо его (код, список, параметры макры - как угодно) расчленять, перемешивать, анализировать части, склеивать, и, возможно, опять по кругу, а то и не один раз ;)

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

> а) портирован под офтопик (частично);

Просил же -- дайте ссылку на скачать.

> В этом есть и минусы, есть и плюсы. Выбирайте тот, который вам по-душе.

Угу. Шоб меня потом быдлосбцлкодером назвали?

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

> Даже специалисты по операционкам никак не определятся - Linux или *BSD (и какая именно из них)

Я не занимаюсь доточкой операционок. А свой самый правильный лисп я уже выбрал :-).

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

> "...но при этом такая фигня получается..." :-)

аха, нащёт разницы в качестве результата я отметил.

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

Это несурьёзно. Много народу знает лисп, сделай поиск хотябы по резюмам на какомнть фрилансерном сайте, да и выучить ево при желании тож непроблема.

> Ибо есть подозрение, что если один лиспер не способен за один присест написать всю систему, то на лиспе эта задача вообще неразрешима.

странно, почему так? Есть ведь ужо модули кемто зделаные я юзаю, и ниразу не слыхал чёбы переписывали. Вобщем, лисопедостроение имеет место, конешно, но не больше чем в других.

> Так что, быдлокодеры тоже нужны. Без них пока никак.

нету никаких причин, по которым быдлокодер не смог бы быдлокодить на лиспе. Тут этот вопрос ужо обсуждался, да и я сам лично - жывое докозательство этому.

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

> Просил же -- дайте ссылку на скачать.

Вы таки меня удивляете... ;)

http://prdownloads.sourceforge.net/sbcl/sbcl-0.9.17-x86-windows-binary.msi?do...

Но я этой не пользуюсь - подверсий 10 назад был простой архив под офтопик - распаковал в каталог с mingw и с тех пор сам собираю из cvs.

> Угу. Шоб меня потом быдлосбцлкодером назвали?

Ну, это вряд-ли. Лисперы могут поцапаться по линии "лисп-схема", или "CL - прочее фуфло", но на конкретные реализации не переходят. Хотя... ;)

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

> Вы таки меня удивляете... ;)

А, вспомнил -- пару страниц назад пробегало. Но все-равно спасибо. За демонстрацию человеческого лица :-).

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

> Но все-равно спасибо. За демонстрацию человеческого лица :-).

Ха, а что я до этого "демонтсрировал"? 8-О

yyk ★★★★★
()
Ответ на: комментарий от ero-sennin

> Но в математике такая запись используется не просто так.

по большей чясти это исторически сложившееся. Другими словами, всякий попало добавлял символ такой, какой ево левая пятка захотит.

> Она удобна для человека.

Ты незавершил. Она удобна для человека, работающево с малым количеством понятий на бумаге, где может как угодно расположить любые символы. В текстовом редакторе есть ограничения, и попытка заюзать подобный подход привёдёт вопервых к теховскому виду формул. Ты ведь не станеш утверждать чё формулы в теховской записи преотлично читабельны? Вовторых, даже на бумаге скопище формул из разных разделов математики на одной странице будет выглядеть потрясающе и нечитабельно. А в программёже встречяются учястки кода на одном и том же наречии, выражающие разные сучности: гуй, вычисления, преобразования текста, тупое перелопачивание данных итд. И всё на одном наречии. В математике по сути этих нотаций много, какая юзаецо - зависит от контекста. Например скоко смыслев имеет математическая запис: "A x B" ? Лисп предлагает средства к решению этой проблемы.

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

> Мнэ. Хреновато он таки под офтоп собран. Не запускается...

Может быть. Не запускается msi или сам лисп после установки? Что говорит?

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

Могу закинуть архив своего на googlepages

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

> Меньше шума чем в

передёргивать изволите? :D (push...) никто не запрещает при желании разместить в функцию только вот ненужно, ибо в реальной проге вызываецо один раз, в цикле перебора файлов. А как поюзать находящееся внутре class... без образования отдельново?

> Теперь ждём лисповую версию с БД.

Дык ты определился ужо, чё она должна делать?

> А БД мне понадобилась за тем, что я точно знаю что на моём винте, без БД не разберёшься :-)

потомушто питон

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

>> А БД мне понадобилась за тем, что я точно знаю что на моём винте, без БД не разберёшься :-)

>потомушто питон

Ха! И эти люди говорят о "предергивании" 8)

Так как насчет результатов соревнования?

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

>Тут всё может зависеть от того какие библиотеки могут использоваться. Например OpenGL из cl-sdl у меня в SBCL не завёлся вообще а CMU пошёл влёт. Не сомневаюсь, что есть ситуации и наоборот - SBCL вроде Unicode лучше держит.

А-а-а, вспомнил я твой скрин! http://www.linux.org.ru/view-message.jsp?msgid=1461083

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

> Ты незавершил. Она удобна для человека, работающево с малым количеством понятий на бумаге, где может как угодно расположить любые символы. В текстовом редакторе есть ограничения, и попытка заюзать подобный подход привёдёт вопервых к теховскому виду формул.

Посмотри, как Математика разворачивает привычную математическую запись в M-выражения. :) Думаю, ты не будешь спорить, что верхняя строчка читается легче, чем нижняя. :P

http://img132.imageshack.us/img132/3600/mathematicaws7.png

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

> А я много раз слышал и читал в логах слово "рефакторинг" по отношению к коду на Си. И Питон, конечно.

хм, рефакторинг к коду не применяецо вообще, а только к помойке. По определению.

bugmaker ★★★★☆
()
Ответ на: комментарий от ero-sennin

> Или таки вы хотите сказать, что математическая запись - отстой, и надо её срочно привести к однородному виду: префиксная нотация, скобочки и ASCII-символы? :P

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

bugmaker ★★★★☆
()
Ответ на: комментарий от ero-sennin

>> Но как вы будете в мат. нотации записывать макры? ;)

> Я, может, крамольную вещь скажу, но по-моему, само различие между функциями и макросами - костыль. Пусть компилятор во время компиляции сам сворачивает те функции, которые можно свернуть.

+1, несомненно когданть так и будет. Только на современном этапе развития ни один компилер ниасиливает :(

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

>> Теперь ждём лисповую версию с БД.

> Дык ты определился ужо, чё она должна делать?

Да. В точности то же самое что и запощенная выше питоновская программа. Ждём.

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

>> Ну то есть, чтоб компилятор сам хитрым образом догадывался, когда именно вычислять аргументы функции. :) На худой конец использовать что-то вроде Hold/HoldAll из Математики. Правда это немногим лучше лисповых макр. Блин. :(

> Ну, одного времени вычисления аргументов недостаточно. Макра же сама по себе - функция, упорно ворочающая списками для постройки "выхода"... Неа, не догоняю :( Имхо - ничуть не лучше, а получится очередное ограничение...

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

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

> лучше таки подождать, пока лисперы не определятся, какой из лиспов самый правильный

а змеееды не ждут, оне свой питон всёвремя мутируют, иззачево он один но очень изменчивый

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

> Мнэ. Хреновато он таки под офтоп собран. Не запускается...

Это охтоп хреново собратый, на ём ничё не запускаецо. Я пару раз пробовал.

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

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

Рефал? (что-то у меня в последнее время навязчивое ощущение "дежавю" :)

yyk ★★★★★
()
Ответ на: комментарий от ero-sennin

>> Например скоко смыслев имеет математическая запис: "A x B"?

> Обычный перегруженный оператор. :)

и всёвремя ево прегружать перед использованием? Ведь в мотематике ево смысл понятен из контекста книшки, где он. А в коде?

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

>>> А БД мне понадобилась за тем, что я точно знаю что на моём винте, без БД не разберёшься :-)

>> потомушто питон

> Ха! И эти люди говорят о "предергивании" 8)

аха, потомушто лисп.

> Так как насчет результатов соревнования?

Ну взял бы и поанализировал коды пока я дрыхъ

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

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

> Рефал? (что-то у меня в последнее время навязчивое ощущение "дежавю" :)

Ништо не ново под луною, увы. И только наивные юношы питоноеды продолжают изобретать и изобретать...

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

>>> Теперь ждём лисповую версию с БД.

>> Дык ты определился ужо, чё она должна делать?

> Да. В точности то же самое что и запощенная выше питоновская программа. Ждём.

ладно, пожжее зделаю. Если сёдне неуспею - завтре.

bugmaker ★★★★☆
()
Ответ на: комментарий от ero-sennin

>> Ты незавершил. Она удобна для человека, работающево с малым количеством понятий на бумаге, где может как угодно расположить любые символы. В текстовом редакторе есть ограничения, и попытка заюзать подобный подход привёдёт вопервых к теховскому виду формул.

> Посмотри, как Математика разворачивает привычную математическую запись в M-выражения. :) Думаю, ты не будешь спорить, что верхняя строчка читается легче, чем нижняя. :P

В этом чёто есь, да. Но дело не в том, что лехче читаецо, а что лехче _пишецо_, ибо читать прогу всёодно по большей чясти комп будет.

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

> ибо читать прогу всёодно по большей чясти комп будет.

Ну если бы комп за меня читал все чужие проги и как надо их модифицировал по моему хотению, я б тогда на работу не ходил. :) Увы блин, такое счастье нам только снится.

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

> читал все чужие проги и как надо их модифицировал по моему хотению, я б тогда на работу не ходил. :)

Дык утя работа читать проги или модифицировать?

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

>> Так как насчет результатов соревнования?

>Ну взял бы и поанализировал коды пока я дрыхъ

Уже. Мне _твой_ анализ интересен.

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

> Ништо не ново под луною, увы. И только наивные юношы питоноеды продолжают изобретать и изобретать...

Назвать Замулина "юношей-питоноедом" - это ты мощно задвинул, внушаить 8) Аффтар, пешы исчо.

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

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

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

dilmah ★★★★★
()
Ответ на: комментарий от ero-sennin

> А ты умеешь модифицировать не читая? :P

запросто. Но такая хня получяецо. Всё-таки, какая форма записи для например "добавить в хеш х по ключю к значение а" кажецо тебе наиболее удобной? В смысле, не из существующих а вообще?

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

> итд.

> Комментарии?

1:1 то же самое, что у меня на плюсах, только без "шума" явной статической типизации. Ну, то что у вас хеш, а у меня map (который в GNU STL унутре черно-красное дерево) - это детали реализации.

Да, еще, для плёхо говорьящихь на CL - а что будет с вашей прогой, если сделать

(push "/foo" (gethash (list "file.txt" 777) hash))

раз эдак 10?

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

> > STL подглядывать, на тему "а какая у нас семантика

> а в лиспе всё одинаковое :P

Дащаз. map-ом простым по хешу разве пройти можно? Фиг, maphash. А вот в STL все алгоритмы работают по итераторам, которые очень generic - главное, чтобы "модель" совпадала, а какой там конкретно тип - пофик.

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

> В этом чёто есь, да. Но дело не в том, что лехче читаецо, а что лехче _пишецо_, ибо читать прогу всёодно по большей чясти комп будет.

Нет, нет, и нет. См. Perl (я его очень хорошо знаю, ибо это мой рабочий инструмент). Он очень выразительный и гибкий (на спор - любая программа на Perl-with-whole-CPAN короче, чем аналог на CL), но если этим злоупотребить, то будет больно - через неделю не вспомнишь, что ж ты блин такое написал.

Только поэтому питон вообще и начали использовать, в остальном он перла ничем ровно не лучше. Та ж история с C++ vs. Java, имхо.

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

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

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

Если есть границы между "чистым" и "интересным" кодом (в смысле, чисто аппликативным и имеющим сайд-эффекты) (как в Haskell, например), то, наверное, можно что-то сделать эдакое.

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

> Аффтар, пешы исчо.

спасибо, ещё много буду. До топ 1 дофига осталось :(

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

> 1:1 то же самое, что у меня на плюсах, только без "шума" явной статической типизации. Ну, то что у вас хеш, а у меня map (который в GNU STL унутре черно-красное дерево) - это детали реализации.

а тот факт, чё лисповые выражовывания в полстроки на ... нужно сочинить и потом вполэкрана запечятлеть?

> а что будет с вашей прогой, если сделать (push "/foo" (gethash (list "file.txt" 777) hash)) раз эдак 10?

Ну будет добавлено 10 значений в список с данным ключём.

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

> Дащаз. map-ом простым по хешу разве пройти можно? Фиг, maphash.

исключительно для удобства. Если ненравицо - (type-of) в зубы, делаеш макрос который с любым контейнером работаит. В макросе пара строк всево будет.

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

> (на спор - любая программа на Perl-with-whole-CPAN короче, чем аналог на CL),

По символам/строкам - возможно, но логически вряд ли. Хотя достоверно не ведаю, мне перл незнаком

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

Лисповые проги поэтому и выглядят ненамного короче питоньих например, потому что в их довольно длинные токены навроде make-hash-table, как раз чёбы легче разобраться было. Ну и незамысловатые логические конструкции, тоже способствуют.

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

> а тот факт, чё лисповые выражовывания в полстроки на ... нужно сочинить и потом вполэкрана запечятлеть?

Еще раз и по-русски, пожалуйста. Я, честно, не понял смысл этой фразы совершенно. Вы о том, что лисповая программа короче? Данивапрос, это с самого начала было ясно. А вот утверждение, что она "оперирует абстракциями более выского порядка", чем плюсовая я готов оспорить.

Да, кстати, было бы нехорошо с вашей стороны придираться к стилю - я на С++ не писатель, да и времени потратил на нее немного (минут 15, наверное, вместе чтением доков). Я даже знаю в ней одну явную глупость (FileId::Eq - на самом деле не Eq, а Less - до меня не сразу доперло, что множество, естественно, хочет оператор упорядочения, а не равнества), и одну design deficiency - add_file должен принимать на вход сразу объект FileID, а не (name, size) - так абстрактнее и правильнее.

> > а что будет с вашей прогой, если сделать (push "/foo" (gethash (list "file.txt" 777) hash)) раз эдак 10?

> Ну будет добавлено 10 значений в список с данным ключём.

Т.е. программа будет работать (in my book) некорректно. Потому как pathname у нас все же уникальный должен быть.

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

> > (на спор - любая программа на Perl-with-whole-CPAN короче, чем аналог на CL),

> По символам/строкам - возможно,

Вот тебе сравнение размеров бенчмарков:

http://shootout.alioth.debian.org/debian/benchmark.php?test=all&lang=all&...

Перл и питон ~ одинаковы, лисп вдвое более многословен (и даже "хуже" С!).

> но логически вряд ли. Хотя достоверно не ведаю, мне перл незнаком

Логически они будут одинаковы. И на C оно будет такое же, логически (ну, может будет некий кусок для "поднятия абстракции" - типа реализации абстрактных типов, которых нету в языке).

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

> Это охтоп хреново собратый, на ём ничё не запускаецо. Я пару раз пробовал.

Руби, однако, в свое время так запыхтел, шо аж свист шел. И Эйфель тоже очень неплохо завелся. С Питончиком было похуже. Но студенты тоже запустили и даже тиклевый интерфейс с биндингом к MySQL прикрутили.

Не, ну я конечно понимаю, Лисп -- особо продвинутый язык...

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

> Не запускается msi или сам лисп после установки? Что говорит?

Сам Лисп. Пишет про отвал sbcl.exe с pid таким-то, а потом заявляет, что не может найти файл /usr/local/lib/sbcl//sbcl.core. Ежу понятно, что такого пути в офтопе нет. Однако попытка скопировать sbcl.core в соответствующую папку cygwin тоже результатов не дает.

А что, под цигнусью он таки нормально собирается?

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

> А вот утверждение, что она "оперирует абстракциями более выского порядка", чем плюсовая я готов оспорить.

ладно, попробуй. Вот такая конструкция например: "a.name < b.name || a.size < b.size", почему в твоей нужно было её заводить вручную а лисповае итак справилось? Или например обращение к элементу хеша по определённому ключю _разное_ для тово чёбы добавить директорий туда и извлечь имеющиеся там? Почему утя в проге многчисленные size_t, а лисповое без них обходицо? и вконце концов ты ведь

> поленился я три (почти) одинаковых функтора рисовать.

а в лисповом однин хватило "вернуть элементы, удовлетворяющие условью:..."?

Вобщем, ИМХО никаких шансов.

> Да, кстати, было бы нехорошо с вашей стороны придираться к стилю

я разве придирался? де? 8()

>>> а что будет с вашей прогой, если сделать (push "/foo" (gethash (list "file.txt" 777) hash)) раз эдак 10?

>> Ну будет добавлено 10 значений в список с данным ключём.

> Т.е. программа будет работать (in my book) некорректно. Потому как pathname у нас все же уникальный должен быть.

программа работает просто замечятельно. Потому что добавление происходит алгоритмом обхода дерева каталохов, где повторений нету. Можно было бы организовать проверку (при желании) но я счёл в рамках этой задачи излишним.

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

> Перл и питон ~ одинаковы, лисп вдвое более многословен (и даже "хуже" С!).

Ещё раз, дело не в многословии как таковом! Зряшные сокращения, ухудшающие понимание, также вредны, как кучя безсмысленново пустово трёпа.

> Логически они будут одинаковы. И на C оно будет такое же, логически

почему же они тогда не? Готов выклать прогу, логическая длина которой такая же как лисповой, на той же задаче с файлами?

> ну, может будет некий кусок для "поднятия абстракции" - типа реализации абстрактных типов, которых нету в языке

так в этом всё и дело. Реализуеш тип специально для своей задачи => не существует достаточно абстрактново готового, который удалось бы использовать, и созданный тоже недостаточно абстрактен, ибо в другой задаче придёцо реализовать _другой_ тип.

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

ну незнаю, я несколько раз (!) пытался запустить разные проги на охтопе. Последний раз это было висуальная студия 2003, а до неё какая-то игрушка, и ниодно не заработало.

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

> гуглём же в момент ищецо

>> В гугле и не такое ищется. Беда в том, чтобы потом отобрать подходящие результаты.

я крайне редко захожу на вторую строницу поиска гугля. Если задать в строку поиска "windows sbcl" результат аппеарицо на первой же странице.

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

>> а змеееды не ждут, оне свой питон всёвремя мутируют, иззачево он один но очень изменчивый

> И это есть гут.

хорошый повод размять пальцы и взаполучить дополнительное финансирования, переделывая в очередной раз прогу под уползший питон, понимаю...

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

>Сам Лисп. Пишет про отвал sbcl.exe с pid таким-то, а потом заявляет, что не может найти файл /usr/local/lib/sbcl//sbcl.core. Ежу понятно, что такого пути в офтопе нет. Однако попытка скопировать sbcl.core в соответствующую папку cygwin тоже результатов не дает.

Рад бы помочь, но виндов уже на машине давно нет. Было предупреждение, что статус "experimental". Это означает, что жалобы пока не принимаются. Вполне возможно, что можно как-то заставить работать. Путь там в каком-нибудь sbclrc переставить или еще что. Лучше на этот счет почитать мэйлинг-листы типа sbcl-help или на gmane (gmain.lisp.steel-bank.general). Может быть, там ответы найдутся? Или гууугл. :)

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

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

Не надо грязи! Мои проги, написанные под Питон 1.5, работают без изменений на 2.4, и даже Си-шные расширения компилируются без изменений (и работают, ага).

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

> Пишет про отвал sbcl.exe с pid таким-то, а потом заявляет, что не может найти файл /usr/local/lib/sbcl//sbcl.core.

Запусти sbcl --core _полный_путь_к_sbcl.core

Или установи предварительно SBCL_HOME на каталог с sbcl.core

Под цигвиком собирается как и под mingw. Нормально.

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

> Это означает, что жалобы пока не принимаются.

Почему же, принимаются... вместе с патчами :)

> Или гууугл.

А я? А как же я? Меня спросите!.. :))

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

> Запусти sbcl --core _полный_путь_к_sbcl.core

О! поехало и даже без --core. Просто указал путь как первый параметр.

> Или установи предварительно SBCL_HOME на каталог с sbcl.core

Тоже подходит.

Спасибо!

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

> ладно, попробуй. Вот такая конструкция например: "a.name < b.name || a.size < b.size", 
> почему в твоей нужно было её заводить вручную а лисповае итак справилось? 

Ну, собственно, потому, что в C++ совершенно справедливо не определяется 
никаких отношений упорядочения для пользовательских типов. 
И не менее справедливо требуется, чтобы такое отношение было определено для типов, являющихся ключами таблицы.

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

> Или например обращение к элементу хеша по определённому ключю
> _разное_ для тово чёбы добавить директорий туда и извлечь имеющиеся там? 

Это неправда. Ты о чем вообще? И класть, и доставать можно
 operator[]. Плюс есть разные другие методы. Плюс есть итераторы.

> Почему утя в проге многчисленные size_t, а лисповое без них обходицо? 

Потому что у лиспа dynamic typing, а у C++ - static. Это не лучше и не хуже, а просто по-другому. 
Кстати, если уж быть совсем строгим, там должно быть off_t (на linux, например, они разные).

> а в лисповом однин хватило "вернуть элементы, удовлетворяющие условью:..."?

Ну если взять boost::lambda - то на C++ будет так же. Не очень красивый синтаксис у нее, да - но таки работает.

Плюс можно было сделать функтор шаблонным, типа так:

template<class TBinaryPredicate> struct test_file_locations {
    size_t n;
    TBinaryPredicate    P;
    test_file_locations(size_t N) : n(N) {};
    bool operator()(pair< FileId, set<string> > p) {
        return !P(p.second.size(), n);
    }
};

И потом использовать как:

    remove_copy_if(files.begin(), files.end(),
                    insert_iterator<FileDist>(files_with_2_locs, files_with_2_locs.begin()),
                    test_file_locations< equal_to<size_t> >(2));

где equal_to можно заменить на less, greater, <whatever>.

Да, вот то, что в STL нету copy_if - это таки баг языка, приходится лишний раз предикат инвертировать.

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

А потом мы добавим в алгоритм обхода разрешение симлинков, и кю. 

Короче, тезис о превосходстве лиспа "на порядки" лично мною отвергается. Даже не в разы.

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

> > Логически они будут одинаковы. И на C оно будет такое же, логически

> почему же они тогда не? Готов выклать прогу, логическая длина которой такая же как лисповой, на той же задаче с файлами?

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

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

(нет, я не думаю, что программа типа такой справится с 30-ти терабайтной базой Яндекса или не-знаю-уж-какого-размера базой гугля) - но общее соотношение будет типа такого.

> Реализуеш тип специально для своей задачи => не существует достаточно абстрактново готового, который удалось бы использовать, и созданный тоже недостаточно абстрактен, ибо в другой задаче придёцо реализовать _другой_ тип.

Не-а, не так. Любой хаскеллоид тебе расскажет, что много типов под разные задачи - это хорошо и правильно. Главное, чтобы алгоритмы были type-agnostic, и в моей программе это так (ну, кое-где нужно было бы шаблоны добавить - я ж это не для продакшена писали вообще не старался).

А определение типа - это еще и документация. Твоя программа как раз низкоуровневая - она ничего не знает про файлы, она оперирует "списками длиной два из числа и строки", которые непонятно чему соответствуют. А в моей прямо на C++ написано, что "мы идентифицируем файл парой <имя, размер>".

Да, кстати, в этой конкретной задаче я таки мог воспользоваться прямо готовым pair<string, off_t> - для нее все нужное уже есть (operator<, в смысле).

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

> Ну, собственно, потому, что в C++ совершенно справедливо не определяется никаких отношений упорядочения для пользовательских типов.

Какую ты видиш в этом справедливось и какой сакральный смысл отличять пользовательские типы от всех остальных?

> И не менее справедливо требуется, чтобы такое отношение было определено для типов, являющихся ключами таблицы.

Почему такое справедливо? В лиспе ключи одново и тово же хеша могут иметь какой угодно тип, независимо от тово, какой тип имеют другие ключи. Какой смысел делать такое ограничение?

> Опять же, то, что в языке нет встроенной абстракции, и то, что он не может ею оперировать - это разные вещи.

так С++ может оперировать с абстракцией? Каков будет результат операции "a != b" если a - хеш-таблица, а b - число 3? Очевидно, для достаточно абстрактной операции сравнения результат должен быть логическое 0, ибо оне неэквивалентны. А в с++ как с этим?

> А потом мы добавим в алгоритм обхода разрешение симлинков, и кю.

возможно и так. Прикинь теперь изменения, требуемые для добавления корректной работы с симлинками в лисповой и с++ проге

> Короче, тезис о превосходстве лиспа "на порядки" лично мною отвергается. Даже не в разы.

ну, твоё право. Однако почему всётаки с++ прога получилось на порядки крупнее и сложнее логически?

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

> Очевидно, для достаточно абстрактной операции сравнения результат должен быть логическое 0, ибо оне неэквивалентны.

"Неэквивалентность" - это сравнение адресов этих объектов, с этим Си++ всё нормально. А операция сравнения на равенство не имеет смысла, так что должна бы возвращать NULL (в терминах SQL).

> А в с++ как с этим?

Нормально. Хочешь сравнивать - определи алгоритм сравнения и оформи его в operator ==. Не определил - компилятор укажет тебе на ошибку.

> Однако почему всётаки с++ прога получилось на порядки крупнее и сложнее логически?

"На порядки"? Интересные у тебя "порядки".

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

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

дык добавление пимитивов удлиняет логику или не?

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

возможно так и есть. Но я вопрос типов не затрагивал. В лиспе типизация достаточно строгая. Но различия в типах значений проявляюцо _там_где_оно_нужно_ а не где вздумаецо. Например ты вынужден в с++ делать отдельные методы для типо add(int,int), add(float,fload) итд, которые делают одинаковое. В лиспе можно обойтись одним (add a b) который выругаецо либо когда операция к типам a и b не применима либо когда установиш ограничение вручную.

> А определение типа - это еще и документация. Твоя программа как раз низкоуровневая - она ничего не знает про файлы, она оперирует "списками длиной два из числа и строки", которые непонятно чему соответствуют. А в моей прямо на C++ написано, что "мы идентифицируем файл парой <имя, размер>".

бугога, посмешил. Ну назови переменные (file, size) и будет щястье. И (сюрпрайз! сюрпрайз!) в лиспе можно сделать классы и объекты 1:1 к твоим. Но как ты убедился на разнице в размере прог и читаемости, это только усугубит и запутает.

> Да, кстати, в этой конкретной задаче я таки мог воспользоваться прямо готовым pair<string, off_t> - для нее все нужное уже есть (operator<, в смысле).

И потом полностью переписывать если появяцо симлинки например? Или добвлять pair<string, off_t, ???> вручную?

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

>> Очевидно, для достаточно абстрактной операции сравнения результат должен быть логическое 0, ибо оне неэквивалентны.

> "Неэквивалентность" - это сравнение адресов этих объектов, с этим Си++ всё нормально. А операция сравнения на равенство не имеет смысла, так что должна бы возвращать NULL (в терминах SQL).

А зачем нам sql? эквивалентнось ты путаеш с "самим себе" а эквивалентнось - если применить к вдум разным любую одинаковую операцию - получиш одинаковый результат. Хм, причём тут адрес?

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

> > > STL подглядывать, на тему "а какая у нас семантика

> > а в лиспе всё одинаковое :P

>Дащаз. map-ом простым по хешу разве пройти можно? Фиг, maphash. А вот в STL все алгоритмы работают по итераторам, которые очень generic - главное, чтобы "модель" совпадала, а какой там конкретно тип - пофик.

Согласен. В lisp'е как раз не хватает порой гибкости stl. В lisp'е если я определил новый тип-контейнер, то мне придется писать все эти map, reduce, remove, ... с нуля. И имена у них будут уже другими. Это минус.

С другой стороны удобство многих stl-ных алгоритмов (вроде transform) сильно ограничивается отсутсвием в плюсах хоть сколько-нибудь адекватного аналога lambda.

Также в лиспе нельзя доопределить новый численный тип и перегрузить #'+, #'*, ... для него. К примеру, если мне нужны кватернионы, то складывать их придется уже не с помощью #'+.

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

> Согласен. В lisp'е как раз не хватает порой гибкости stl. В lisp'е если я определил новый тип-контейнер, то мне придется писать все эти map, reduce, remove, ... с нуля. И имена у них будут уже другими. Это минус.

Справедливости ради, это ("другие имена") можно излечить макросами, вроде бы. Писать алгоритмы - да, таки придется, имхо.

> С другой стороны удобство многих stl-ных алгоритмов (вроде transform) сильно ограничивается отсутсвием в плюсах хоть сколько-нибудь адекватного аналога lambda.

Угу. boost::lambda - это непонятно для кого сделано, пользоваться невозможно, и тормозит потом при компиляции со страшной силой...

Но, впрочем, ничто не мешает определять функторы с понятными именами рядом. Плюс можно делать шаблонные функторы, если часто приходиться делать "то же самое, но чуть по-другому" (напр., как я сделал в примере с поиcком файлов).

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

> В lisp'е если я определил новый тип-контейнер, то мне придется писать все эти map, reduce, remove, ... с нуля.

Можно пример, когда в лиспе понадобился бы новый тип-контейнер? А в питонос++ он нужен _всегда_,

> И имена у них будут уже другими. Это минус.

Кто запрещяет юзать старые?

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

> Bugmaker, написал тебе я прогу.
> #!/usr/bin/env python

$ python files.py add
Traceback (most recent call last):
File "files.py", line 105, in ?
main()
File "files.py", line 71, in main
filedb.add('/home/vasily/pic/zombieeuiip.jpg', 31558)
File "files.py", line 48, in add
self.flush()
File "files.py", line 42, in flush
sqlalchemy.objectstore.get_session().flush()
File "/usr/lib64/python2.4/site-packages/sqlalchemy/mods/threadlocal.py", line 29, in __getattr__
return getattr(self.context.current, name)
AttributeError: 'Session' object has no attribute 'get_session'

Что не так?

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

> Что не так?

Не знаю. Какая версия sqlachemy?

Проверял на python 2.4.3 и sqlalchemy 0.2.3 и 0.2.6

Ещё нужен pysqlite (у меня 2.1.3)

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

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

>Также в лиспе нельзя доопределить новый численный тип и перегрузить
 #'+, #'*, ... для него. К примеру, если мне нужны кватернионы, то 
складывать их придется уже не с помощью #'+.

Вообще-то можно, но крайне не рекомендуется. Я считаю, что перегрузка 
стандартных операторов -- это зло. Как-то раз svu выступал в споре C 
vs C++ насчет того, как где-то, где он работал, вставали на эти грабли
 (речь шла о большом проекте). Так, а теперь LISP.

Я точно не смотрел, разрешена ли перегрузка стандартных операторов в 
стандарте или это implementation feature. Изначально в SBCL и CLISP 
(где я попробовал) это заблокировано (что правильно), но можно 
разблокировать принудительно:

*(defun < (x y) (+ x y))

STYLE-WARNING: redefining < in DEFUN

debugger invoked on a SYMBOL-PACKAGE-LOCKED-ERROR in thread #<THREAD "initial thread" {A7BF489}>:
  Lock on package COMMON-LISP violated when setting fdefinition of <.
See also:
  The SBCL Manual, Node "Package Locks"
  The ANSI Standard, Section 11.1.2.1.2

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE      ] Ignore the package lock.
  1: [IGNORE-ALL    ] Ignore all package locks in the context of this operation.
  2: [UNLOCK-PACKAGE] Unlock the package.
  3: [ABORT         ] Exit debugger, returning to top level.

(PACKAGE-LOCK-VIOLATION #<PACKAGE "COMMON-LISP">)
0] 0

<
* (< 1 2)

3
* 

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

>Можно пример, когда в лиспе понадобился бы новый тип-контейнер?

Легко. Например, я пишу продвинутую библиотеку обработки графов. Например, мне часто надо обрабатывать множество инцидентных дуг и/или смежных узлов. Но я не хочу привязывать способ кодирования графов к какому-либо встроенному типу. Например лисповый однонаправленный список и vector меня не устраивaют из-за медленного remove. Hashtable тоже меня может не устроить из-за бОльшего оверхеда и/или если мне нужно позволять кратные дуги. Если мне важна производительность, то встроенные типы в чистом виде не подойдут.

В таком случае правильное решение: сделать абстрактный тип --- множество дуг/узлов, определить операции над ним, и иметь возможность пользовать разную реализацию (в том числе и ultimate-performance) этого абстрактного типа.

Что касается юзания map, reduce, ... для других операций, то одних лишь макросов тут недостаточно. Надо значала сделать (shadow 'map), и затем уже либо макросами (что не очень хорошо), либо своей реализацией map + define-compiler-macro для случаев, когда обрабатываем встроенные типы.

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

> Что касается юзания map, reduce, ... для других операций, то одних лишь макросов тут недостаточно. Надо значала сделать (shadow 'map), и затем уже либо макросами (что не очень хорошо), либо своей реализацией map + define-compiler-macro для случаев, когда обрабатываем встроенные типы.

Этот-же подход можно юзать и для #'+.

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

> Bugmaker, написал тебе я прогу.

Я хоть и не бугмакер и даже не лиспер, но тоже решил попробовать свои
силы. Результаты примерно следующие:

(asdf:operate 'asdf:load-op 'clsql-sqlite3)
(in-package clsql)
(locally-enable-sql-reader-syntax)

(def-view-class file () 
  ((id   :type integer 
         :db-kind :key
         :db-constraints :primary-key
         :initarg :id)
   (dir  :type (string 1000) 
         :initarg :dir)
   (name :type (string 1000) 
         :initarg :name)
   (size :type integer 
         :initarg :size))
  (:base-table files))

(setq metadata 
   (connect '("files.db") :database-type :sqlite3 :if-exists :old))

; Uncomment this to see DB transactions
; (start-sql-recording :type :both)

(if (not (table-exists-p 'files))
   (create-view-from-class 'file))

(defun make-file (full-name)
  (make-instance 'file
      :dir  (directory-namestring full-name)
      :name (file-namestring full-name)))

(defun get-file (full-name)
  (cond ((caar (select 'file
                       :where [and 
                                 [= [slot-value 'file 'dir] (directory-namestring full-name)]
                                 [= [slot-value 'file 'name] (file-namestring full-name)]
                              ])))
        (t (make-file full-name))))

(defun add-file (full-name size) 
   (update-records-from-instance (progn (setq f (get-file full-name))
                                 (setf (slot-value f 'size) size)
                                 f)))

(defun del-file (full-name)
  (delete-instance-records (get-file full-name)))

(defun del-file2 (full-name)
  (delete-records 
        :from [files] 
        :where [and 
                  [= [dir]  (directory-namestring full-name)]
                  [= [name] (file-namestring full-name)]
               ]))

(defun print-sel-files (&optional (condition [>= [N] 0]))
  (progn (print (if (string= (sql condition) (sql [>= [N] 0])) "All files" (sql condition)))
         (print-query [select [f2 dir] [f1 name] [f1 size] [f1 N] 
                         :from "(select name, size, count(*) N from files group by name, size) f1, files f2"
                         :where [and 
                                   [= [f1 name] [f2 name]] 
                                   [= [f1 size] [f2 size]]
                                   condition
                                ]
                         :order-by '(([N] :desc) ([f2 dir] :asc))
                      ]
                      :titles '("DIR" "NAME" "SIZE" "COUNT"))
         (terpri)))

(defun main (action)
  (cond ((eq action :add)
         (add-file "/home/vasily/pic/zombieeuiip.jpg" 31558)
         (add-file "/home/vasily/zombieeuiip.jpg" 31558)
        
         (add-file "/home/vasily/pic/sars.jpg" 19311)
         (add-file "/home/vasily/sars.jpg" 19311)
         (add-file "/home/vasily/junk/sars.jpg" 19311)
       
         (add-file "/home/vasily/pic/pic6.jpg" 29638)
         (add-file "/home/vasily/pic/pic8.jpg" 17577))
    
        ((eq action :delete)
         (del-file2 "/home/vasily/pic/zombieeuiip.jpg"))

        ((eq action :select)
         (print-sel-files)
         (print-sel-files [> [N] 2])
         (print-sel-files [<> [N] 2])
         (print-sel-files [< [N] 3]))))

Конечно, не шедевр, но как для начинающего, ИМХО, неплохо. Ибо
намешано в кучу и лисп, и его классы, и биндинг к clsql и sqlite (я
работал только с MySQL). Кроме того, так и не понял, как работает
sqlachemy в Питоне (тоже до сих пор с этим не работал), поэтому
постарался следовать не букве, а духу.

Увы, так и не понял, как получить значения параметров командной
строки, и как вообще вызывать . Поэтому сделал функцию main, которая
принимает один из трех символов -- :add, :delete и :select.

Кроме того, не получилось завести автоматическое удаление записей по
экземпляру, посему пришлось сделать две функции удаления записей --
правильную (del-file) и "обходняк" (del-file2). То есть, если
следовать документации, то достаточно del-file, который удаляет
запись через экземпляр. Однако, при обращении к базе clsql формирует
безусловный "DELETE FROM FILES", и таблица, понятное дело, очищается
полностью. Один или два раза мне удалось получить запрос типа "DELETE
FROM FILES WHERE FILES.ID=NULL", поэтому я решил, что это как-то
связано с формированием первичного ключа объекта, о чем в следующем
абзаце. "Обходное" решение просто строит sql-запрос и выполняет его.

Не знаю, для чего именно тут нужен суррогатный первичный ключ, но я
его тоже создал. По идее, он должен был упростить запрос к базе на
удаление записей, но это у меня не вышло. Поэтому пришлось
использовать актуальный ключ для удаления, что слегка тяжеловесно. К
сожалению, у меня также не получилось запустить автогенерацию
суррогатного ключа. Я так понял, что это фишка sqlite, потому как
если хранилище создать с помощью питоньей программы, то дальше ключи
генерируются автоматически. Но как это записать в виде sql-синтаксиса
для sqlite, а тем более, на clsql, я так и не понял. Может быть,
знающие товарищи меня просветят.

Наконец, по мере написания возникло желание упростить структуру
хранилища. Вначале мне было непонятно, почему счетчики обновляются в
цикле, если это можно было сделать простым sql-апдейтом. Потом, когда
начал писать апдейт, подумал, как счетчики в отдельных файлах
соотносятся с уникальностью имени файла. В результате счетчики были
выкинуты, а пара каталог-имя сделана актуальным первичным ключом. По
уму надо бы навесить ограничения целостности (непустота и
уникальность ключа), но я так понял, что в питоньей программе этого
тоже нет. В общем, структура хранилища стала проще, за что пришлось
расплатиться усложнением выборки. Не знаю, насколько "кошерным" будет
посчитано такое решение. Однако, задача выполняется, и я думаю, что
мелкие особенности вывода не являются проблемой.

В целом потратил на это весь день, думаю, на питоне без алхимии с
mysql получилось бы часа за 2-3. Само программирование на Лиспе
оказалось достаточно приятным, чего никак не ожидал. Попробую еще
как-нибудь разобраться с построением парсеров.

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

> Проверял на python 2.4.3 и sqlalchemy 0.2.3 и 0.2.6
> Ещё нужен pysqlite (у меня 2.1.3)

python 2.4.3-r4
sqlalchemy 0.2.8
pysqlite 2.3.1

Все на Gentoo amd64.

> Дай мыло, скину исходник

eugine dot kosenko at gmail dot com

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

> Но я не хочу привязывать способ кодирования графов к какому-либо встроенному типу.

ну ведь не хотиш, а не неможеш. А в <подставь сам> захотиш, а нету. Придёцо создавать.

> В таком случае правильное решение: сделать абстрактный тип

А зачем тебе _в_этом_ случяе абстрактный тип? Слелай конкретный тип - "супер-пупер-навороченое-граф-с-сверхбыстрым-удалением" и высокоуровневые операции с им: добавить узел, итд.

> Что касается юзания map, reduce, ... для других операций, то одних лишь макросов тут недостаточно.

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

> Надо значала сделать (shadow 'map), и затем уже либо макросами (что не очень хорошо), либо своей реализацией map + define-compiler-macro для случаев, когда обрабатываем встроенные типы.

Ну во всяком случяе такая возможность есть. шадовиш мап, и делаеш свой, который для встроенных типов вызывает встроенный мап, а для твоево - твой. Обекты наследуем значит, а функции/макросы наследовать религия не позволяет штоли?

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

Фиксед. Решил запостить сюда. Теперь работает на любой 
sqlalchemy 0.2.x

Надо было исправить sqlalchemy.objectstore.get_session().flush() на
sqlalchemy.objectstore.flush()

Что-то я протупил. 
Не знаю с какого ляда оно работало на более ранних версиях :-)

#!/usr/bin/env python

import sys
import os.path

import sqlalchemy.mods.threadlocal
import sqlalchemy
import sqlalchemy.exceptions

class File(object):
    def __init__(self, **kwargs):
        for key, value in kwargs.iteritems():
            setattr(self, key, value)

    def __unicode__(self):
        s = [ unicode(self.__class__.__name__) + u': ' ]
        for c in self.c:
            s.append(u'%s=%s ' % (c.key, getattr(self, c.key)))
        result = u''.join(s)
        return result
    
metadata = sqlalchemy.BoundMetaData('sqlite:///files.db',
    strategy='threadlocal')

files_table = sqlalchemy.Table('files', metadata,
    sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
    sqlalchemy.Column('name', sqlalchemy.String(1000), index=True),
    sqlalchemy.Column('size', sqlalchemy.Integer, index=True),
    sqlalchemy.Column('dir', sqlalchemy.String(1000), index=True),
    sqlalchemy.Column('count', sqlalchemy.Integer, index=True))

sqlalchemy.mapper(File, files_table)

class FileDb:
    def __init__(self):
        try:
            sqlalchemy.Query(File).select(limit=1)
        except sqlalchemy.exceptions.SQLError:
            metadata.create_all()
    
    def flush(self):
        sqlalchemy.objectstore.flush()
    
    def add(self, full_name, size):
        dir, name = os.path.split(full_name)
        count = self.updateFile(name, size)
        File(name=name, dir=dir, size=size, count=count)
        self.flush()
    
    def delete(self, full_name, size):
        dir, name = os.path.split(full_name)
        count = self.updateFile(name, size, -1)
        [sqlalchemy.objectstore.delete(f) for f in 
            sqlalchemy.Query(File).select_by(name=name, dir=dir, size=size)]
        self.flush()
    
    def updateFile(self, name, size, delta=1):
        files = list(sqlalchemy.Query(File).select_by(name=name, size=size))
        count = len(files)
        for f in files:
            f.count = count + delta
        return count + delta
    
    def select(self, condition=files_table.c.count >= 0):
        return sqlalchemy.Query(File).select(condition)
    
def main():
    filedb = FileDb()
    
    if 'add' in sys.argv:
        filedb.add('/home/vasily/pic/zombieeuiip.jpg', 31558)
        filedb.add('/home/vasily/zombieeuiip.jpg', 31558)
        
        filedb.add('/home/vasily/pic/sars.jpg', 19311)
        filedb.add('/home/vasily/sars.jpg', 19311)
        filedb.add('/home/vasily/junk/sars.jpg', 19311)
        
        filedb.add('/home/vasily/pic/pic6.jpg', 29638)
        filedb.add('/home/vasily/pic/pic8.jpg', 17577)
    
    if 'delete' in sys.argv:
        filedb.delete('/home/vasily/pic/zombieeuiip.jpg', 31558)
        
    if 'select' in sys.argv:
        print 'All files:'
        for f in filedb.select():
            print u'%s' % f
            
        print
        print 'N > 2'
        for f in filedb.select(files_table.c.count > 2):
            print u'%s' % f
        
        print
        print 'N != 2'
        for f in filedb.select(files_table.c.count != 2):
            print u'%s' % f
        
        print
        print 'N < 3'
        for f in filedb.select(files_table.c.count < 3):
            print u'%s' % f
        
if __name__ == '__main__':
    main()

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

>Согласен. В lisp'е как раз не хватает порой гибкости stl. В lisp'е 
если я определил новый тип-контейнер, то мне придется писать все эти 
map, reduce, remove, ... с нуля. И имена у них будут уже другими. Это 
минус.

Это не то? Стандартные макросы defgeneric/defmethod:

(defgeneric plus (obj1 obj2))

(defmethod plus ((obj1 integer) (obj2 integer)) (+ obj1 obj2))

(defmethod plus ((obj1 string) (obj2 string)) (concatenate 'string obj1 obj2))

(defmethod plus ((obj1 мой-тип-контейнер) (obj2 string)) (...павлиноуткоёж...))

*(plus 1 2)
3
*(plus "a" "df")
"adf"

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

> > В таком случае правильное решение: сделать абстрактный тип

> А зачем тебе _в_этом_ случяе абстрактный тип? Слелай конкретный тип - "супер-пупер-навороченое-граф-с-сверхбыстрым-удалением" и высокоуровневые операции с им: добавить узел, итд.

Дык я про то и говорю. Но для очевидных generic (в STL-ном смысле этого слова) операций (map, reduce, etc) мне придется писать свой код, практически полностью дублирующий стандартные map, reduce, etc. А в STL мне это не нужно было бы делать. Это минус. В плюсе то что очень полезную при обработаки графов операцию pattern matching я могу очень красиво интегрировать в lisp, а для C++ это если и возможно, то через очень черную магию template metaprogramming.

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

> Дык я про то и говорю. Но для очевидных generic (в STL-ном смысле этого слова) операций (map, reduce, etc) мне придется писать свой код, практически полностью дублирующий стандартные map, reduce, etc. А в STL мне это не нужно было бы делать. Это минус.

Т.е. если тебя не устраивают стандартные алгоритмы в лиспе, ты жалуесся чё тебе их нужно будет переписывать? А если мя не устроят STLные, их не нужно? Я прально понял?

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

>Это не то? Стандартные макросы defgeneric/defmethod:

>(defgeneric plus (obj1 obj2))

>(defmethod plus ((obj1 integer) (obj2 integer)) (+ obj1 obj2))

>(defmethod plus ((obj1 string) (obj2 string)) (concatenate 'string obj1 obj2))

>(defmethod plus ((obj1 мой-тип-контейнер) (obj2 string)) (...павлиноуткоёж...))

>*(plus 1 2)

>3

>*(plus "a" "df")

>"adf"

То. Но было, бы неплохо если бы #'+ (а не #'plus) был generic function. Мелочь конечно, но все равно минус. Именно это я и имел в виду выше по поводу невозможности перегрузки #'+.

Да, это можно исправить через (progn (shadow '+) (defgeneric + (first-arg &rest args))), но при этом, похоже, придется попотеть с define-compiler-macro, чтобы не потерять производительность.

И еще, т.к. мы определяем другую функцию и пользуем другой символ, то все в стандартной библиотеке, что пользует #'+ и что нам надо расширить придется править по такой же схеме. Пример: incf, decf.

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

> Т.е. если тебя не устраивают стандартные алгоритмы в лиспе, ты жалуесся чё тебе их нужно будет переписывать?

Меня устраивают стандартные алгоритмы. Я ворчу про то, что стандарт не позволяет мне наследоваться от sequence и применять эти алгоритмы для своих типов.

Можно глянуть, к примеру на то как это сделано в Ruby, где для своего типа мне достаточно определить метод each и включить mixin Enumerable, чтобы получить map, inject (примитивный аналог reduce) и др. полезные методы. Ruby'евский подход, правда, создает большие проблемы для эффективной оптимизации этих generic методов. Но, ИМХО, эти проблемы все таки преодолимые.

BTW, насколько я помню идеи, стоящие за STL были сперва опробованы тов. Степановым на Scheme.

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

> В lisp'е как раз не хватает порой гибкости stl.

Я что-то пропустил?

> В lisp'е если я определил новый тип-контейнер, то мне придется писать все эти map, reduce, remove, ... с нуля. И имена у них будут уже другими. Это минус.

Переопредели, потому как...

> Также в лиспе нельзя доопределить новый численный тип и перегрузить #'+, #'*, ... для него. К примеру, если мне нужны кватернионы, то складывать их придется уже не с помощью #'+.

...это наглая ложь!

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

> Справедливости ради, это ("другие имена") можно излечить макросами, вроде бы.

Справедливости ради, переопределить можно _любую_ функцию.

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

> Меня устраивают стандартные алгоритмы. Я ворчу про то, что стандарт не позволяет мне наследоваться от sequence и применять эти алгоритмы для своих типов.

дык нечему там наследовацо. Как ты можеш унаследовать с++шный массив например? Максимум чё можно сделать - поместить в нутро sequence свои типы, и использовать функции для работы с ним, стандартные, если подходят, или определить свои.

> Можно глянуть, к примеру на то как это сделано в Ruby, где для своего типа мне достаточно определить метод

В лиспе методы сугубо вторичны. Т.е. Ели желаеш юзать ооп, определяй обект с методами и наследуй ево в своё удовольствие. Получиш то же самое, что и в руби и где угодно, только не на уровне языка конешно, потому что применение ооп слишком редко оправдано, чтобы ради нево язык коверкать.

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

>Справедливости ради, переопределить можно _любую_ функцию.

Не из пакета common-lisp. Стандарт явно говорит, что последствия попытки сделать это undefined. В SBCL пакет common-lisp специальным образом заблокирован. Блокировку можно снять. Но при этом отнюдь не факт, что переопределенный common-lisp:+ или common-lisp:map будут нормально работать, т.к. компилятору разрешено (стандартом) считать что #'common-lisp:+ это всегда именно та функция, что определена стандартом.

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

> > Меня устраивают стандартные алгоритмы. Я ворчу про то, что стандарт не позволяет мне наследоваться от sequence и применять эти алгоритмы для своих типов.

> дык нечему там наследовацо. Как ты можеш унаследовать с++шный массив например? Максимум чё можно сделать - поместить в нутро sequence свои типы, и использовать функции для работы с ним, стандартные, если подходят, или определить свои.

Не надо путать sequence (абстрактный класс, или интерфейс в терминологии Java) и конкретные типы вроде list и array.

В стандарте map, reduce, etc определяются именно в терминах sequence, но при этом они не generic функции, и их невозможно применять для других подклассов sequence. Это печально.

> > Можно глянуть, к примеру на то как это сделано в Ruby, где для своего типа мне достаточно определить метод

> В лиспе методы сугубо вторичны. Т.е. Ели желаеш юзать ооп, определяй обект с методами и наследуй ево в своё удовольствие. Получиш то же самое, что и в руби и где угодно, только не на уровне языка конешно, потому что применение ооп слишком редко оправдано, чтобы ради нево язык коверкать.

Да вторичны, но соотвествующие им generic функции не отличаются по статусу от всех остальных. То как map, reduce и иже с ними расширяются на used-defined типы в Ruby это лишь один из способов. Создатели common-lisp могли бы им последовать. Они могли бы найти и более lisp-way для этого. В любом случае, возможность применять эти функции для определяемых пользователем типов была-бы полезна.

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

> Не из пакета common-lisp. Стандарт явно говорит, что последствия попытки сделать это undefined. В SBCL пакет common-lisp специальным образом заблокирован. Блокировку можно снять. Но при этом отнюдь не факт, что переопределенный common-lisp:+ или common-lisp:map будут нормально работать, т.к. компилятору разрешено (стандартом) считать что #'common-lisp:+ это всегда именно та функция, что определена стандартом.

Что вам мешает переопределить _любые_ функции _только_ для своего пакета?

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

> В стандарте map, reduce, etc определяются именно в терминах sequence, но при этом они не generic функции, и их невозможно применять для других подклассов sequence. Это печально.

А с чего вы взяли, что sequence - класс? В лиспе классы и типы - совершенно разные "вещи". И их "взаимоотношение" стандартом практически не оговаривается.

> Да вторичны, но соотвествующие им generic функции не отличаются по статусу от всех остальных. То как map, reduce и иже с ними расширяются на used-defined типы в Ruby это лишь один из способов. Создатели common-lisp могли бы им последовать. Они могли бы найти и более lisp-way для этого. В любом случае, возможность применять эти функции для определяемых пользователем типов была-бы полезна.

Есть подозрение, что возможность наследования от built-in классов негативно бы сказалась на быстродействии и возможностях оптимизации компилятора.

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

>И еще, т.к. мы определяем другую функцию и пользуем другой символ, то все в стандартной библиотеке, что пользует #'+ и что нам надо расширить придется править по такой же схеме. Пример: incf, decf.

А стандарт не раскрывает детали реализации incf и decf. В каждой отдельной реализации CL они могут быть сделаны как угодно. Это в SBCL так может быть, но совсем не значит, что также в CLISP. В C++, например, нельзя утверждать, что '-' сделан с помощью '+' (сложить с указанным числом, поменяв знак ему)? Поэтому и '-' придется заменить. А что с a++ и a--?

Я предполагаю, что вопрос о переопределении стандартных операций стоял на голосованиях комиссии. Там люди сидели с опытом. :) Я считаю, что перегрузка стандартных оперций -- это ненужный синтаксический сахар, который может привести к путаницам.

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

Я предполагаю, что если переписать _весь_ лисп на CLOS - мы получим тормза не меньше чем у питона ;) И кодеры совсем за объектами не рассмотрят лиспа.

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

>Что вам мешает переопределить _любые_ функции _только_ для своего пакета?

Технически --- ничего. Я об этом уже писал выше. Повторю, что стандартные функции и макросы при этом будут пользовать версии из common-lisp. Пример: incf и decf. Эти макросы, если их тоже не перекрыть будут использовать common-lisp:+.

Вообще я не понимаю, чего тут на меня все ополчились. Мне нравится common-lisp. Но я пока еще не встречал идеальных во всех отношениях языков программирования. Common-lisp не исключение. Те недостатки о которых я писал это мелочи, но все равно недостатки. Большую проблему с точки зрения широкого применения common-lisp представляют проблемы с реализациями этого языка (где-то есть уникод, а где-то нету или плохо реализованный, где-то есть потоки, а где-то нет) и библиотеками под него (качественных библиотек маловато).

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

> Не надо путать sequence (абстрактный класс, или интерфейс в терминологии Java) и конкретные типы вроде list и array.

воистину. Можно создать экземпляр тырфейса в терминологии жабы? sequence - запросто: http://www.lisp.org/HyperSpec/Body/sec_17-1.html

> A sequence is an ordered collection of elements, implemented as either a vector or a list.

> Sequences can be created by the function make-sequence, as well as other functions

> В стандарте map, reduce, etc определяются именно в терминах sequence, но при этом они не generic функции, и их невозможно применять для других подклассов sequence. Это печально.

> create objects of types that are subtypes of sequence (e.g., list, make-list, mapcar, and vector).

Для какого из subtypes невозможно применять reduce например?

> То как map, reduce и иже с ними расширяются на used-defined типы в Ruby это лишь один из способов. Создатели common-lisp могли бы им последовать.

для лисппрог это просто _не_нужно_ потому что нету характерных для ооп ограничений, если только не вводить их специально. STL - это ведь не свойство языка, а библиотека, прально? Вот для аналогичных дел в лиспе тож библиотеки можно сделать. Я не ведаю, есть ли такие готовые или никому не было нужно. ИМХО второе. А разные sequences, списки и прочее - это _базовые_ элементы лиспа, как и функции для работы с ими. Ты ведь не жалуесся, что для базовых типов с++ (примитивных в ево терминологии), таких как целое или массив, нельзя переопределять операторы?

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

> Мне нравится common-lisp. Но я пока еще не встречал идеальных во всех отношениях языков программирования. Common-lisp не исключение. Те недостатки о которых я писал это мелочи, но все равно недостатки. Большую проблему с точки зрения широкого применения common-lisp представляют проблемы с реализациями этого языка (где-то есть уникод, а где-то нету или плохо реализованный, где-то есть потоки, а где-то нет) и библиотеками под него (качественных библиотек маловато).

А помочь? :)

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

> Вообще я не понимаю, чего тут на меня все ополчились.

я неополчился. Просто пытаюсь обяснить чё лисп - это не "с++ только луче", он _просто_ луче. И соответственно методы работы, аналогичные методам работыв в враждебном окружении, типо с++, тут негодяцо. С одной стороны, тя непременно арестуют если ты станеш без должных оснований разгуливать по городу в костюме химзащиты с надетым противогазом, с другой стороны, делать это всёодно неудобно, даже если очень хоццо.

> Большую проблему с точки зрения широкого применения common-lisp представляют проблемы с реализациями этого языка (где-то есть уникод, а где-то нету или плохо реализованный, где-то есть потоки, а где-то нет) и библиотеками под него (качественных библиотек маловато).

+1, проблем дествительно мнозе.

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

> Я предполагаю, что если переписать _весь_ лисп на CLOS - мы получим тормза не меньше чем у питона ;) И кодеры совсем за объектами не рассмотрят лиспа.

Это не обязан быть CLOS во всех своей красе. Просто больше стандартных функций могли бы быть generic. В уже писал о том, что это безусловно добавило бы работы компиляторо-писателям. Это действительно было бы сложней реализовать эффективно. Возможно, именно поэтому стандарт именно такой какой он есть.

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

> Это не обязан быть CLOS во всех своей красе. Просто больше стандартных функций могли бы быть generic. В уже писал о том, что это безусловно добавило бы работы компиляторо-писателям. Это действительно было бы сложней реализовать эффективно. Возможно, именно поэтому стандарт именно такой какой он есть.

Зыть, ещё раз... Дженерики работают с _классами_. Классы не равны типам. Для многих стандартных типов может быть _один_ класс (built-in). Поэтому без CLOS-а "во всех своей красе" от самого дна не обойтись.

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

>Я предполагаю, что если переписать _весь_ лисп на CLOS - мы получим тормза не меньше чем у питона ;) И кодеры совсем за объектами не рассмотрят лиспа.

Этого никто не предлагает. Это CLOS *тоже* построен на базе defgeneric. а не defgeneric на базе CLOS. :)

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

> Этого никто не предлагает.

Да нет, один анонимный товарищ практически этого и желает ;)

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

> Это CLOS *тоже* построен на базе defgeneric. а не defgeneric на базе CLOS. :)

Угу. Только generic-и работают с _классами_. Так что всё это "отдаёт" триединством :)

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

> > Не надо путать sequence (абстрактный класс, или интерфейс в терминологии Java) и конкретные типы вроде list и array.

> воистину. Можно создать экземпляр тырфейса в терминологии жабы? sequence - запросто: http://www.lisp.org/HyperSpec/Body/sec_17-1.html

Система типов common-lisp безусловно гораздо богаче чем в Java или C++, но в данном случае аналогия с жабщицкими интерфейсами достаточно близкая IMO. Экземпляр интерфейса (скажем Iterable) я могу создать в яве точно так же как и экземпляр sequence --- путем создания одного из конкретных подтипов. E.g. ArrayList vs. array

Правда, в стандарте, пoхоже, ничего не противоречит следующему определению sequence:

(deftype sequence () `(or list array))

> Для какого из subtypes невозможно применять reduce например?

Только что попробовал сделать user-defined class --- наследник sequence. Не дает. Если бы я мог сделать наследника sequence, то именно для него #'reduce бы не работал.

> для лисппрог это просто _не_нужно_ Не согласен. Возможность пользовать стандартные map, reduce, etc. для user-defined типов пригодилась бы. Пример я приводил. Жить без этого можно. И это совсем на большой недостаток, но он есть.

Безусловно это можно реализовать в виде сторонней библиотеки.

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

> Зыть, ещё раз... Дженерики работают с _классами_. Классы не равны типам. Для многих стандартных типов может быть _один_ класс (built-in). Поэтому без CLOS-а "во всех своей красе" от самого дна не обойтись.

Не понимаю что вы имели в виду, но я могу специализировать любую generic функцию любым встроенным типом. Никто не мешает мне сделать:

(defmethod plus ((first-arg cons) &rest args) (some-code-here))

(defmethod plus ((first-arg null) &rest args) (some-code-here))

(defmethod plus ((first-arg integer) &rest args) (some-code-here))

(defmethod plus ((first-arg fixnum) &rest args) (some-code-here))

(defmethod plus ((first-arg bignum) &rest args) (some-code-here))

И никаких слотов (разве что в внутри defmethod для обновления метаинформации о методах).

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

>Угу. Только generic-и работают с _классами_. Так что всё это "отдаёт" триединством :)

Нет. generic работает со всем, чей тип можно узнать: listp, integerp, stringp, numberp, atom (выше показаны примеры) и классов. По ним ведется диспечеризация при выборе метода. А классы -- это частный случай типа. Так что в данном случае, generic пофиг. В CLOS не классоориентированная концепция, а genericfunction-ориентрированная. defgeneric первична. CLOS порожден от нее. Аналог дженерика -- это обычная функция defun (...) со своим условным выполнением после проверки типов.

Хотя мне было бы спокойнее использовать

(defun matrix-add ...), (defun matrix-sub ...), ...

без всяких перегрузок. Выгоды переопределение не дает никакой. Говорю -- синтаксический сахар. :)

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

> Только что попробовал сделать user-defined class --- наследник sequence. Не дает.

ещёбы! sequence это не класс. Попробуй в с++ унаследовать массив

> Возможность пользовать стандартные map, reduce, etc. для user-defined типов пригодилась бы.

дык ты покажеш как в с++ пользовать стандартные [] от массива в user-defined type не переопределяя или не?

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

> Выгоды переопределение не дает никакой.

Выгода есть, хоть и небольшая. Если вместо matrix-add можно было-бы юзать +, то могли бы работать 1+, 1-, incf, decf (и возможные расширения вида mulf, divf) для моих типов.

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

> дык ты покажеш как в с++ пользовать стандартные [] от массива в user-defined type не переопределяя или не?

Мы похоже не понимаем друг друга. С самого начала я имел в виду что в STL и в Ruby я могу для user-defined типов пользовать стандартные алгоритмы, аналогичные map, reduce, etc. И для этого мне надо сделать минимум телодвижений. В STL мне надо определить итератор для моего user-defined типа, а в Ruby мне надо определить метод each. Т.е. мне не нужно для каждого user-defined типа реализовывать аналоги map, reduce, etc.

Я сожалел о том, что в common-lisp этого нету.

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

>Выгода есть, хоть и небольшая. Если вместо matrix-add можно было-бы юзать +, то могли бы работать 1+, 1-, incf, decf (и возможные расширения вида mulf, divf) для моих типов.

См. мой пост выше про '+' и '-'. Как это будет сразу работать 1+, 1-. incf, decf, когда для твоего типа должна быть определена единица? Если ты матрицу сделал 3 на 3, то что значит -- увеличить эту матрицу на 1? Это значит прибавить в ней единичную матрицу, где все единицы по диагонали? Или прибавить матрицу, где все элемены единицы? Или попытаться прибавить к матрице скаляр, что вызовет ошибку? Все эти операции придется переопределять. Умножение/сложение матриц и умножением/сложением чисел -- совершенно разные опреции. Что такое для числа i++ -- понятно (i := i + 1), а для матрицы разве эта операция следует из того, что ты только переопределил '+'?

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

> Не понимаю что вы имели в виду, но я могу специализировать любую
generic функцию любым встроенным типом.

КЛАССОМ, не типом! То, что во многих реализациях большинству
стандартных типов определены соответсвующие классы - "доброта"
авторов. Пример с вашим же определением _типа_:

* (deftype my-type () `(or list array))

MY-TYPE
* (defgeneric g1 (x))

#<STANDARD-GENERIC-FUNCTION G1 (0)>
* (defmethod g1 ((x t)) "Not defined")

#<STANDARD-METHOD G1 (T) {AD1AFC9}>
* (g1 1)

"Not defined"
* (defmethod g1 ((x my-type)) "My type")

debugger invoked on a SIMPLE-ERROR: There is no class named MY-TYPE.

Ок?

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

> См. мой пост выше про '+' и '-'. Как это будет сразу работать 1+, 1-. incf, decf, когда для твоего типа должна быть определена единица? Если ты матрицу сделал 3 на 3, то что значит -- увеличить эту матрицу на 1? Это значит прибавить в ней единичную матрицу, где все единицы по диагонали? Или прибавить матрицу, где все элемены единицы? Или попытаться прибавить к матрице скаляр, что вызовет ошибку? Все эти операции придется переопределять. Умножение/сложение матриц и умножением/сложением чисел -- совершенно разные опреции. Что такое для числа i++ -- понятно (i := i + 1), а для матрицы разве эта операция следует из того, что ты только переопределил '+'?

Да, я об этом не подумал. Эти сложности можно преодолеть (тем более что в более простых случаях, вроде кватернионов их нет), но тогда, похоже цена решения превышает выгоду.

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

> Нет. generic работает со всем, чей тип можно узнать: listp, integerp, stringp, numberp, atom (выше показаны примеры) и классов.

Ну почитатйте HyperSpec... Или определите свой _тип_ (не _класс_), и попробуйте для него определить метод... Выше я приводил пример.

> А классы -- это частный случай типа.

Классы - это классы. И к типм имеет лишь то отношение, что при создании класса автоматически создаётся тип с таким же именем (или type-of реагирует не только на типы, но и классы?)

> Так что в данном случае, generic пофиг.

Не пофиг, я приводил пример.

> Аналог дженерика -- это обычная функция defun (...) со своим условным выполнением после проверки типов.

Не типов - классов!!!

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

> КЛАССОМ, не типом! То, что во многих реализациях большинству стандартных типов определены соответсвующие классы - "доброта" авторов. Пример с вашим же определением _типа_:

Хороший пример, однако cons, number и многие другие встроенные типы являются классами, при этом они сами не являются экземплярами standard-class. T.e. мой тезис о том что многие стандартные функции могли бы быть generic без применения "тяжелого" CLOS, этот пример не отменяет.

Впрочем это не так уж и важно, что понимать под CLOS "во всей его мощи". Главное что так или иначе это могло быть сделано, и что это очень усложнило бы оптимизацию этих функций.

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

>КЛАССОМ, не типом!

Да, тут ты прав, похоже. deftype воспринимается defgeneric, если только он порожден от классов. А базовые типы просто продублировали в CLOS, так как они там обязательно нужны.

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

> Фиксед. Решил запостить сюда.

Вроде работает. Завтра погоняю на контрпримерах.

Такой вопрос: можно ли в алхимии быстро включить трассировку sql-запросов? В Лиспе это очень помогло при отладке.

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

> Мы похоже не понимаем друг друга.

похоже :(

> С самого начала я имел в виду что в STL и в Ruby я могу для user-defined типов пользовать стандартные алгоритмы, аналогичные map, reduce, etc.

Потому что в с++ (руби не знаю совсем, неведомо как там) есть примитивное типы, включяя массивы и операции с ними. А есть STL - библиотека шаблонов, которая изготовлена _поверх_ примитивных типов. Внутри себя она юзает примитивные типы, те же самые массивы и операции с примитивными типами +-=*<> итд. user-defuned типы в с++ нагромождаются _поверх_ STL в свою очередь. Операции с примитивными типами в с++ ты не можеш переопределять или наследовать, а наоборот, пользуешся ими внутри STL. В лиспе в базовый набор входят списки и всякие секвенции, ты точно также не можеш наследовать от них а только юзать их же для своих целей. Только соответствующий им набор базовых операций богаче, чем в с++, но это всё ещё базовые операции. Поэтому переопределять их ни (нормальной) возможности нету ни необходимости, точно так же как переопределять оператор [] для void * [] в с++. Необходимости переопределять нету потому что они не завязаны на какой-то конкретный тип, как в с++. Поэтому ты или юзаеш их или определяеш свои собственные. Как например если бы тя по каким-то причинам не устаивал оператор [] для void * [], то понадобилось бы делать функцию void * get (void * a [], int idx), а переопределить ты бы не смох. Если хош "нагромождения" как в с++, те сперва нужна библиотека (макросев или классов, неважно) а потом ужо наследовать от нё и переопределять.

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

> Хороший пример, однако cons, number и многие другие встроенные типы являются классами

Встроенных типов _намного_ больше, чем им в соотвествие поставленно классов, тем более что стандартом не определены эти классы - это "добрая воля" разработчиков. Да, у основных есть свои классы, но "закладываться" на это я бы не стал :)

> T.e. мой тезис о том что многие стандартные функции могли бы быть generic без применения "тяжелого" CLOS, этот пример не отменяет.

Тогда уж не "многие стандартные функции", а "подавляющее большинство". И _только_ для "чистых компиляторов" (а-ля sbcl). И в любом случае - это уже будет не CL (хотя и лисп :).

> Главное что так или иначе это могло быть сделано, и что это очень усложнило бы оптимизацию этих функций.

Для _только компилирующего_ лиспа - не очень. Всё равно или тип задан вручную, или надо ставить проверку типов в рантайме. Для всех остальных лиспов - "смерть при взлёте" :)

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

> Впрочем это не так уж и важно, что понимать под CLOS "во всей его мощи"...

Туева хуча (перекрываемых) методов для создания, "печати", наследования, фиг знает что ещё... (руки никак не дойдут разобраться с CLOS-ом до конца :(

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

> Да, тут ты прав, похоже.

Ага. Я на эти грабли умудрился стать ДВА раза. Теперь запомнил... ;)

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

> Потому что в с++ (руби не знаю совсем, неведомо как там) есть примитивное типы, включяя массивы и операции с ними. А есть STL - библиотека шаблонов, которая изготовлена _поверх_ примитивных типов. Внутри себя она юзает примитивные типы, те же самые массивы и операции с примитивными типами +-=*<> итд. user-defuned типы в с++ нагромождаются _поверх_ STL в свою очередь.

Можно долго спорить является ли STL частью языка C++ или нет, точно также можно спорить являются ли map, reduce и функции частью языка или этот "всего лишь" часть стандартной библиотеки. Это не важно.

map и reduce как операции можно определить не опираясь на какие-либо встроенные или нет типы. Они оперирует какой-то последовательностью (не важно как представленной) значений. Им в идеале наплевать как представлена эта последовательность, в виде ли цепочки cons-cell'ов или в последовательных ячейках вектора, или как-то еще. Им нужен только определенный набор базовых операций над этими последовательносями. Для reduce, к примеру, достаточно уметь каким-то образом пробежаться по последовательнсти. В Ruby эту базовую операцию предоставляет метод each, а в STL итераторы (forward iterator concept).

Предположим у меня нету стандартной функции reduce. В этом случае мне хотелось бы реализовать эту операцию ОДИН раз для ЛЮБЫХ видов последовательности. Что именно я буду использовать в качестве базового примитива для пробегания по последовательности не так важно. Важно чтобы я не повторял этот код если мне понадобится определить новый вид последовательности. Чтобы определяя этот самый новый вид последовательности мне было достаточно только определить базовые операции над ним (пробегание по ней, если мне нужен reduce).

Кстати, более-менее хороший пример как это можно сделать в common-lisp это series. Которые даже чуть было не попали в стандарт (см. cltl второй редакции).

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

> В этом случае мне хотелось бы реализовать эту операцию ОДИН раз для ЛЮБЫХ видов последовательности.

а в лиспе нету видов последовательности в том смысле, в каком есть унаследованные от STL классы в с++. Конечно ты можеш сделать свою функцию reduce используюя например elt, но смысла в этом никаково нету, потому что где работает стандартное elt там же работает и стандартное reduce.

> если мне понадобится определить новый вид последовательности.

ну безсмысленное это занятие определять новый вид последовательности в лиспе. Потому что существующие ничем не ограничивают, это ведь базовые ссущности. Чем твой новый вид может отличяцо от существующих? Только способом хранения данных, а в этом случяе стандартные алгоритмы всёодно бесполезны, они не будут знать как достичь данных в той форме, в которой ты их храниш.

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

> они не будут знать как достичь данных в той форме, в которой ты их храниш.

Будут. Способов масса. Один из них это по аналогии с Ruby такой:

(defgeneric each (sequence function)
  (:documentation "Calls FUNCTION for each element of SEQUENCE"))

(defmethod each ((sequence list) function)
  (mapl function sequence))

(defun primitive-reduce-variant (function sequence initial-value)
  (each sequence (lambda (x)
                   (setq initial-value (funcall function initial-value x))))
  initial-value)

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

>map и reduce как операции можно определить не опираясь на какие-либо встроенные или нет типы.

Так они так и определены. Есть произвольный список, к которому map можно сделать. В списке может быть объект любого вида: цифры, строчки, круги, квадраты, сферические кони в вакууме. Никаких ограничений. Гибкость, как карма у Будды :)

Спор начался, как я помню, с maphash. По какому-то недоразумению имя этой вещи начинается на map*. Но hash в CL -- это не список, не последовательность. Это таблица! Специальный неразбираемый тип данных, для которого определили отдельную функцию maphash. Нельзя по хэшу итерации устраивать, так как нет понятия индекса или последовательной связности. Есть только понятие ключа. А как по ключу итераторы устраивать? Поэтому maphash получает в качестве аргумента целиком хэш-таблицу, а не какой-то список, состоящий из его содержимого. Это совсем другая функция не из группы map*. С названием конфуз. Хэш надо рассматривать просто, как объект другой природы.

В языках C, C++ можно залезать в хэш на уровне указателей, но это уже (тут тонкая грань) работа не с хэшем, как с типом данных, а работа с хэшем на уровне реализации, коих может быть много разных.

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

> Так они так и определены. Есть произвольный список, к которому map можно сделать. В списке может быть объект любого вида: цифры, строчки, круги, квадраты, сферические кони в вакууме. Никаких ограничений. Гибкость, как карма у Будды :)

Речь шла не о этой гибкости. А о том, что common-lisp'овские map и reduce работают только для встроенных видов последовательностей: списков и массивов. Если я задам к примеру упорядоченное (мульти)множество, представленное в виде avl-дерева, то встроенные map, reduce и многие другие я применять уже не смогу.

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

>Речь шла не о этой гибкости. А о том, что common-lisp'овские map и reduce работают только для встроенных видов последовательностей: списков и массивов. Если я задам к примеру упорядоченное (мульти)множество, представленное в виде avl-дерева, то встроенные map, reduce и многие другие я применять уже не смогу.

Ну так это к вопросу только о переименовании стандартной функции map, которое делать нельзя (не рекомендуется). А так ты спокойно можешь в LISP сделать свое дерево, написать свой map для него (который будет мэпом над стандартными мэпами и т. п.), обозвать его map-tree и вперед. Единственная проблема в твоем случае: как map-tree в map переименовать. А надо очень? Ну так сделать враппер можно. Сначала проверить аргумент на то, дерево это или нет. Если да, то выполнить map-tree, а если нет, то вызвать стандартный map. Назвать это все дело my-super-map и применять его всегда в своих программах. :)

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

> Такой вопрос: можно ли в алхимии быстро включить трассировку sql-запросов? В Лиспе это очень помогло при отладке.

metadata = sqlalchemy.BoundMetaData('sqlite:///files.db', strategy='threadlocal', echo=True)

Там есть и более навороченная система, см. доку по слову echo_uow

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

>does anybody know about CL implementations for PocketPC? that'd be great to have REPL on PocketPC.

Гугл? :)

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

> Можно пример, когда в лиспе понадобился бы новый тип-контейнер? А в питонос++ он нужен _всегда_,

Это наглое вранье, уж простите. Ассортимент контейнеров STL+Boost покрывает все необходимости "обычного" программиста. А в "необычных" случаях (очень много данных, особые требования по производительности и/или памяти, специфичные структуры) - все равно придется писать, на любом языке.

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

> дык ты покажеш как в с++ пользовать стандартные [] от массива в user-defined type не переопределяя или не?

Еще раз (десятый, примерно): _этого_никто_не_хочет_. Люди хотят, чтобы определив конечное малое количество интефрфейса для своего класса, они могли бы сделать его совместимым со стандартными алгоритмами.

В C++ для этого достатосно написать класс-итератор. Ну, чтобы прям со всеми-всеми алгоритмами работало - два класса, если не ошибаюсь (не гуру, мягко говоря, в C++): один модели forward iterator и другой - insert iterator.

Причем реализация их в большинстве случаев тривиальна.

В CL это все "наоборот", там предлагается переописывать все нужные алгоритмы для нового контейнера.

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

> Это наглое вранье, уж простите. Ассортимент контейнеров STL+Boost покрывает все необходимости "обычного" программиста.

Дык их надо наследовать или и так работают?

> А в "необычных" случаях (очень много данных, особые требования по производительности и/или памяти, специфичные структуры) - все равно придется писать, на любом языке.

Так уж и на любом! Отлистай выше, для хранения файлов и в питоне и в с++ понадобилось сочинять свой, а в лиспе - не.

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

> Еще раз (десятый, примерно): _этого_никто_не_хочет_. Люди хотят, чтобы определив конечное малое количество интефрфейса для своего класса, они могли бы сделать его совместимым со стандартными алгоритмами.

ещё раз, одиннадцатый примерно: стандартные алгоритмы _не_ работают с классами.

> В C++ для этого достатосно написать класс-итератор. Ну, чтобы прям со всеми-всеми алгоритмами работало - два класса, если не ошибаюсь (не гуру, мягко говоря, в C++): один модели forward iterator и другой - insert iterator.

потому что в с++ контейнер может полноценно хранить только один тип или классы с одним общим предком. А в лиспе внутре контейнеров может сидеть всё чё угодно. Для с++ это _костыль_ который в лиспе не нужен.

> В CL это все "наоборот", там предлагается переописывать все нужные алгоритмы для нового контейнера.

Только если следовать логике "шиворот навыворот": определять и наследовать контейнеры вместо тово, чёбы юзать их по назначению, для хранения чево-то. Лисп этому никак не препяцтвует, но и костылей на такой случай (почти) не предлагает.

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

> Потому что в с++ (руби не знаю совсем, неведомо как там) есть примитивное типы, включяя массивы и операции с ними.

Весь STL можно описать не используя встроенных массивов - примитивных типов, указателей и аллокатора достаточно впоолне.

> user-defuned типы в с++ нагромождаются _поверх_ STL в свою очередь.

Это неправда. STL ортогонален пользовательским типам совершенно. Более того, оно не требует наследования - template progamming в С++ с ним не связан совершенно.

Короче, ты просто не понимаешь, о чем говоришь.

На плюсах есть "дополнительное измерение", с помошью которого я могу сказать "эта функция работает с любым типом, который удовлетворяет используемому интерфейсу". И если этот интерфейс состоит из operator++, operator--, operator*, и operator== - то она "поймет" и встроенные массивы, и STL-ные sequence-ы.

И не надо никуда ничего наследовать.

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

> а в лиспе нету видов последовательности в том смысле, в каком есть унаследованные от STL классы в с++

итак, 11-й раз -

чтобы пользоваться STL-ными алгоритмами не нужно наследоваться от STL-ных контейнеров. Более того, стандартные алгоритмы прекрасно работают на встроенных массивах (по крайней мере, когда такой массив - источник данных, insert iteratior-а для них таки нету), хотя они никакими отношениями родства ни с чем не связаны.

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

> В языках C, C++ можно залезать в хэш на уровне указателей, но это уже (тут тонкая грань) работа не с хэшем, как с типом данных, а работа с хэшем на уровне реализации, коих может быть много разных.

По map и hash_map можно идти последовательно, получая на каждом шаге пару <ключ, значение>. На этой последовательности пар работают любые алгоритмы на последовательностях. У map даже порядок будет предсказуемый, в порядке сортировки ключей (тем отношением порядка, которое было указано при инстанциировании шаблона).

Короче, вы не владеете предметом...

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

> Так уж и на любом! Отлистай выше, для хранения файлов и в питоне и в с++ понадобилось сочинять свой, а в лиспе - не.

Ну-ка, покажи-ка мне в (_моей_ же ;) программе на С++ новый контейнер? Нету его там, не ищи. В питоньей - тоже нету.

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

А контейнеры и алгоритмы там все стандартные.

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

> потому что в с++ контейнер может полноценно хранить только один тип или классы с одним общим предком. А в лиспе внутре контейнеров может сидеть всё чё угодно. Для с++ это _костыль_ который в лиспе не нужен.

Очень хочется перейти на стиль vsl.

Врешь ты нагло, или троллишь.

Каждый экземпляр контейнера, естественно, ограничен одним типом. Но сама реализация его - да ни разу. Это называется метапрограммирование...

> Только если следовать логике "шиворот навыворот": определять и наследовать контейнеры вместо тово, чёбы юзать их по назначению, для хранения чево-то.

Никто не предлагает наследовать контейнеры. ВСего лишь - определять в своих типах стандартный интерфейс.

Например, если у тебя вдруго списки перестанут помещаться в памяти и ты сделаешь тип on-disk-list, с прозрачной подкачкой из файлов, в лисповой проге тебе придется везде поменять map на map-over-on-disk-list (аналогично с reduce и какие еще у вас там определены алгоритмы). А на плюсах все заработает "автомагически".

И для этого даже не придется наследоваться от vector/list/whatever.

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

> Ну-ка, покажи-ка мне в (_моей_ же ;) программе на С++ новый контейнер?

typedef map< FileId, set<string>, FileId::Eq > FileDist;

Оно?

Вообще, шаблонирование -- штука приятная, конечно, но скорость компиляции убивает в усмерть. А однажды даже удалось создать шедевр на Эйфеле, компиляция которого просто не завершалась -- вис компилятор. Так что, это не проблема C++, а вообще проблема шаблонирования. Кроме того, в C++ использование шаблонов приводит к чудным результатам, когда в результате ошибки в одном месте диагностика выдается совершенно в другом, причем эти два места могут быть абсолютно не связаны. Если добавить к этому прелести несовместимости шаблонов, например, в MSVS C++ и G++, то ловить блох в кроссплатформенных приложениях становится особым экстримом. Посему я так и ниасилил ни STL ни его более ранние/поздние альтернативные замены. Просто тихо сполз на Эйфель.

> В питоньей - тоже нету.

class FileDb:

А это что? Правда, в таком примере можно было бы обойтись и без дополнительного класса (хинт -- переменная self нигде в классе не используется). Так что, это уже скорее следствие тяжелого воздействия ООП на психику программеров...

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

>> Потому что в с++ (руби не знаю совсем, неведомо как там) есть примитивное типы, включяя массивы и операции с ними.

> Весь STL можно описать не используя встроенных массивов - примитивных типов, указателей и аллокатора достаточно впоолне.

какая наф разница? важно чё примитивных. Можно и на структурках список выстроить. И даже бес структурок обойтись, использовать например (int *)(a + ITEM_N) где a типо void *. Главное чё STL базируецо на примитивных типах а не наоборот.

> Это неправда. STL ортогонален пользовательским типам совершенно. Более того, оно не требует наследования - template progamming в С++ с ним не связан совершенно.

STL с точки зрения компилера такая же библиотека юзверовских типоф. Если оные юзверовские типы нагромождать не поверх STL то опять таки поверх базовых типоф. Примитивный тип ты недобавиш никаким естественным способом, равно как и дополнительные операторы для работы с им.

> Короче, ты просто не понимаешь, о чем говоришь.

это просто ты не понимаеш чё в лиспе просто не нужны костыли такие как в с++

> На плюсах есть "дополнительное измерение", с помошью которого я могу сказать "эта функция работает с любым типом, который удовлетворяет используемому интерфейсу". И если этот интерфейс состоит из operator++, operator--, operator*, и operator== - то она "поймет" и встроенные массивы, и STL-ные sequence-ы.

Аха, вот ты про чё. Да, чево нет тово нет, собственно по тем же причинам. Я даже не представляю как это могло бы пригодицо если бы было. Для приведённово тобой случяя выше, это можно было бы сделать на CLOS, либо делать собственную функцию, которая не замещает встроенную но работает параллельно и называецо подругому.

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

> > Ну-ка, покажи-ка мне в (_моей_ же ;) программе на С++ новый контейнер?

> typedef map< FileId, set<string>, FileId::Eq > FileDist;

> Оно?

Ну, если _это_ называется "новый контейнер"... ;)

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

Это ж, блин, явная типизация.

> > В питоньей - тоже нету.

> class FileDb:

> А это что? Правда, в таком примере можно было бы обойтись и без дополнительного класса (хинт -- переменная self нигде в классе не используется). Так что, это уже скорее следствие тяжелого воздействия ООП на психику программеров...

Это, если я правильно помню, издержки реализации sqlalchemy (я не знаю питона) - в смысле, оно хочет класс-наследник с определением структуры данных.

Т.е. это сущность того же порядка, что и мой плюсовый typedef. Никто не _реализует_ новых контейнеров на каждый чих, а рассказывает стандартной библиотеке, чего конкретно от нее надо.

> Вообще, шаблонирование -- штука приятная, конечно, но скорость компиляции убивает в усмерть. А однажды даже удалось создать шедевр на Эйфеле, компиляция которого просто не завершалась -- вис компилятор. Так что, это не проблема C++, а вообще проблема шаблонирования. Кроме того, в C++ использование шаблонов приводит к чудным результатам, когда в результате ошибки в одном месте диагностика выдается совершенно в другом, причем эти два места могут быть абсолютно не связаны. Если добавить к этому прелести несовместимости шаблонов, например, в MSVS C++ и G++, то ловить блох в кроссплатформенных приложениях становится особым экстримом. Посему я так и ниасилил ни STL ни его более ранние/поздние альтернативные замены. Просто тихо сполз на Эйфель.

Угу, есть такая проблема. Но в лиспе, насколько я успел понять в процессе своих попыток прорешать Practical CL, она тоже стоит - эксепшены вываливают программу в REPL с 6..12 слойным стеком, и где конкретно ты сделал что-то не так - столь же непонятно неопытному глазу.

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

> какая наф разница? важно чё примитивных. Можно и на структурках список выстроить. И даже бес структурок обойтись, использовать например (int *)(a + ITEM_N) где a типо void *. Главное чё STL базируецо на примитивных типах а не наоборот.

И что? А CLOS базируется на defgeneric, который тоже, насколько я понимаю, встроенный, и переопределить который нельзя. И уже точно оно все базируется на вызовах функций и cons cell-ах, которые зашиты в компилятор. В чем аргумент-то заключается? Что С++ - статически типизированный и это плохо? Ну, это твои заморочки, мне кажется, что это хорошо.

> STL с точки зрения компилера такая же библиотека юзверовских типоф. Если оные юзверовские типы нагромождать не поверх STL то опять таки поверх базовых типоф. Примитивный тип ты недобавиш никаким естественным способом, равно как и дополнительные операторы для работы с им.

Угу, да. А ты не сможешь изменить семантику cons cell-ов, или удалить из лисп-машины сборщик мусора. Наличие и состав базовых концепций - это ни в коем разе не аргумент в "сферически-вакуумном" сравнении языков, все равно какие-то везде есть.

> это просто ты не понимаеш чё в лиспе просто не нужны костыли такие как в с++

> Я даже не представляю как это могло бы пригодицо если бы было. Для приведённово тобой случяя выше, это можно было бы сделать на CLOS, либо делать собственную функцию, которая не замещает встроенную но работает параллельно и называецо подругому.

Я тебе привел пример. Чтобы на лиспе сделать библиотеку, которая оперирует как всроенными списками (для маленьких задач), так и самодельными списками-на-диске для больших, и предлагала пользователю сделать свой тип (скажем, подкачку данных по сети для _совсем_ больших задач), тебе придется сделать массу телодвижений, сводящихся, в основном, к повторной реализации того, что уже есть в стандартной библиотеке.

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

> Ну-ка, покажи-ка мне в (_моей_ же ;) программе на С++ новый контейнер?

typedef map< FileId, set<string>, FileId::Eq > FileDist;

оно?

> Нету его там, не ищи.

нашед, нашед! :P

> В питоньей - тоже нету.

class FileDb(dict):

а эт чево?

> достаточно будет поменять только определение этого

а в лиспе и без определения всё ладно.

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

> Очень хочется перейти на стиль vsl.

нет, только не это!!!

> Каждый экземпляр контейнера, естественно, ограничен одним типом. Но сама реализация его - да ни разу. Это называется метапрограммирование...

какая разница? тип нужен переопределять или не?

>> Только если следовать логике "шиворот навыворот": определять и наследовать контейнеры вместо тово, чёбы юзать их по назначению, для хранения чево-то.

> Никто не предлагает наследовать контейнеры. ВСего лишь - определять в своих типах стандартный интерфейс.

дык а зачечем переопределяют?

> Например, если у тебя вдруго списки перестанут помещаться в памяти и ты сделаешь тип on-disk-list, с прозрачной подкачкой из файлов, в лисповой проге тебе придется везде поменять map на map-over-on-disk-list (аналогично с reduce и какие еще у вас там определены алгоритмы). А на плюсах все заработает "автомагически".

а фих ево знает как оно в лиспе будет в таком разе, там понятия памяти ваще как такового нету.

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

>Короче, вы не владеете предметом...

Перейдем на ругань или повременим? Повторю еще раз: обход по хэш-таблице -- это деталь ее *реализации*. Хэш-таблица как тип данных -- это набор пар "ключ"-"значение". В общем случае *неупорядоченный*. Детали реализации хэш-таблицы как типа данных не определены самим понятием. Есть только понятие ключ, хэш-функция и значение. Как он там эти пары ищет -- дело реализации. Поэтому еще раз утверждаю, что хэш-таблица -- это не последовательность. Последовательностью он может быть только в смысле конкретной реализации. Вот maphash в CL и ходит в хэше на низком уровне. Индекс -- это не свойство хэш-таблицы, как у массива. Смотри реализацию chaining, например. Одному индексу может соответствовать два, три, четыре и т. д. значения. То есть нет однозначного соответствия индекс-значение в общем случае. А еще используют самобалансирующиеся деревья для реализации хэш-таблиц. А завтра я сделаю хэш-функцию, которая из ключа генерирует не индекс, а сразу указатель. Выделю память по этому указателю и запишу туда данные. Как тут обходить хэш-таблицу? Индекса же нет? Но от этого она хэш-таблицей быть не перестает! Так что общем случае хэш-таблица -- это не последовательность. Давай контраргументы.

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

> Перейдем на ругань или повременим?

Мы столько времени держались в рамках... ;)

> А завтра я сделаю хэш-функцию, которая из ключа генерирует не индекс, а сразу указатель.

Этот указатель и будет хэш-ключом.

> Так что общем случае хэш-таблица -- это не последовательность.

Это _неупорядоченная_ последовательность. И операция обхода всех ее элементов с получением ключей - хорошо определена и полезна. Только не нужно рассчитывать на упорядоченность - но никто и не рассчитывает.

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

> шаблонирование -- штука приятная, конечно, но скорость компиляции убивает в усмерть.

Просто реализации такие

> ниасилил ни STL ни его более ранние/поздние альтернативные замены.

А можно подробнее - что является "альтернативной заменой" STL?

> class FileDb:

> это уже скорее следствие тяжелого воздействия ООП на психику программеров

Считай это комментарием. Впрочем, без комментариев тоже можно обойтись :D

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

>Этот указатель и будет хэш-ключом.

Ну а я про что? Как ты обойдешь последовательно такую хэш-таблицу? Всю память будешь сканировать в поисках данных? Или генерировать все возможные ключи? :) Я соглашусь, что реализация, возможно, несколько непрактичная, но хэш-таблица работать будет нормально! Или это уже не хэш-таблица будет?

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

> реализация, возможно, несколько непрактичная, но хэш-таблица работать будет нормально! Или это уже не хэш-таблица будет?

Я не могу представить себе реализацию такой хэш-таблицы, при которой хоть где-нибудь не хранился бы список ключей. Хотя бы для того, чтобы проверять коллизии ;)

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

> А можно подробнее - что является "альтернативной заменой" STL?

В 96 году пытались использовать YACL (Yet Another Class Library). Тоже содержала комплект контейнеров и прочих вкусных абстрактных типов. Не смогли собрать. Насколько я понял, BOOST тоже позиционирует себя аналогичным образом. Но за нее я уже не брался, потому как уже имел негативный опыт.

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

>> Это _неупорядоченная_ последовательность.

>Горячий лед.

Буквоедство.

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

> В чем аргумент-то заключается?

в том чё примитивные типы используются для построения а не видоизменяюцо

> Что С++ - статически типизированный и это плохо? Ну, это твои заморочки, мне кажется, что это хорошо.

а типизация тут не причём совсем.

> Угу, да. А ты не сможешь изменить семантику cons cell-ов, или удалить из лисп-машины сборщик мусора. Наличие и состав базовых концепций - это ни в коем разе не аргумент в "сферически-вакуумном" сравнении языков, все равно какие-то везде есть.

в данном случяе мы сравниваем не языки а разницу в методах работы с ними.

> Я тебе привел пример. Чтобы на лиспе сделать библиотеку, которая оперирует как всроенными списками (для маленьких задач), так и самодельными списками-на-диске для больших, и предлагала пользователю сделать свой тип (скажем, подкачку данных по сети для _совсем_ больших задач), тебе придется сделать массу телодвижений, сводящихся, в основном, к повторной реализации того, что уже есть в стандартной библиотеке.

Вовсе нет. Я использовал бы готовые и на их основе - свои.

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

Да, ну и что касается итератора над хэшами, то и в CL есть макра (with-hash-table-iterator ...)

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

> class FileDb: 
 
> А это что? Правда, в таком примере можно было бы обойтись и без
> дополнительного класса (хинт -- переменная self нигде в классе не 
> используется). Так что, это уже скорее следствие тяжелого 
> воздействия ООП на психику программеров...

И ты, Брут? :-)

Я то думал что FUD здесь только лисперы распростаняют.

Смотрим внимательно:

class FileDb(dict):
    def push(self, name, dir, value):
        try:
            self[(name, dir)].append(value)
        except KeyError:
            self[(name, dir)] = [value]

Всё ещё не видно self?

FileDb это потомок стандартного словаря. У него определён дополнительный метод push(), принимающий аргументы в терминах задачи:
имя файла, директорию и размер файла. 

Здесь абстрактный словарь из питона преврвщается в специализированный
для данной задачи контейнер. Можно пользоваться стандартным контейнером, как это делает bugmaker, но тогда мне бы каждый раз
пришлось бы городить этот огрод как в теле метода push().

А по поводу психики покарёженной ООП, в итоге я пишу:

filedb.push('file.txt', 777, '/foo') что тебе здесь не нравится?

Абсолютно все слова здесь из предметной области задачи.

Ну можно было обойтись без класса, описать функцию, которая первым
аргументом принимала бы словарь в который надо добавить файл, и что
это было бы труъ функциональное программирование? Нахуа?

Типа так

def add_to_file_db(file_db, name, dir, value):
    try:
        file_db[(name, dir)].append(value)
    except KeyError:
        file_db[(name, dir)] = [value]

И потом вместо filedb.push('file.txt', 777, '/foo') писать
add_to_file_db(filedb, 'file.txt', 777, '/foo')

Труъ?

И лично я на этом примере вижу то что на всех трёх языках решения
одинаковы. Различия обусловлены только статической типизацией в C++
и разницей стандартных контейнеров в разных языках.

Кстати, автор С++ примера, респект. Хорошо написал.

To anonymous: в этом примере не было sqlalchemy, с sqlalchemy 
был другой пример.

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

>Я не могу представить себе реализацию такой хэш-таблицы, при которой хоть где-нибудь не хранился бы список ключей. Хотя бы для того, чтобы проверять коллизии ;)

Да в принципе любые разрозненные данные в хеш-таблице можно дополнительно связать как минимум списком направленным. От одного entry к другому. И тогда по этому списку запускается итератор. В принципе, все просто. Я здесь в споре просто прицепился к словам. То есть что хэш-таблица без итератора может быть. Главное, чтобы она свою основную функцию исполняла: связывала ключ и значение. Итерация, согласен тут, реализуется дополнительно. И тут спорить не буду. Все. Не хочу больше по хешам.

Пошел писать программы на Си. Вчера поддержка новой архитектуры 2D-акселерации (EXA) в драйвере видяхи подала признаки жизни (с забавными глюками, однако). Пошел ковыряться в исходниках xorg.

Чтобы ночью было 2048 постов! :)

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

> данные в хеш-таблице можно дополнительно связать как минимум списком

ИМХО, не "можно", а "по-любому придется". Это природа контейнера, любого. Отсюда естественно следует наличие итератора.

> хэш-таблица без итератора может быть.

Если задаться целью повредничать :)

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

> Смотрим внимательно:

Это была _другая_ программа на питоне. Я тщательно разбирался только с "алхимической" версией, а там достаточно только синглетона-алхимии, которая и так выполняет всю необходимую работу. Там FileDB и в самом деле лишний. Об что и написал.

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

> А по поводу психики покарёженной ООП, в итоге я пишу:

апять бугоганахъ. в итоге я пишу (зделать-всё-песдато) ичё?

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

В основном здесь идёт обсуждение контейнеров и версий программы 
без БД.

Но даже если рассматривать версию с БД, то self тоже используется
и в конструкторе и в __unicode__():

class File(object):
    def __init__(self, **kwargs):
        # Кстати, это итерация по словарю / хэшу :-) 
        for key, value in kwargs.iteritems():
            setattr(self, key, value)

    def __unicode__(self):
        s = [ unicode(self.__class__.__name__) + u': ' ]
        for c in self.c:
            s.append(u'%s=%s ' % (c.key, getattr(self, c.key)))
        result = u''.join(s)
        return result

Класс необходим из-за того что sqlalchemy это ORM. Т.е. это для людей
поражённых ООП до мозга костей типа меня. В простейшем случае можно
считать что таблица отображается на класс, т.е. класс необходим.

А это просто мой стандартный шаблон класса для sqlalchemy, в нём
конструктору передаётся набор keyword аргументов, которые сразу
устанавливаются на объекте и определено преобразование в строку
(вернее в юникод) для вменяемого вывода на печать.

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

> Насколько я понял, BOOST тоже позиционирует себя аналогичным образом. Но за нее я уже не брался, потому как уже имел негативный опыт.

Нет, буст позиционируется как расширение STL и полигон для обкатки того, что предлагается внести в STL в новых версиях стандарта.

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

> Но даже если рассматривать версию с БД, то self тоже используется и в конструкторе и в __unicode__():

> class File(object):

Речь идет не о File, а о FileDB. Единственная его функция -- это контейнер для целевых функций. По сути, он синглетон. Можно было бы возложить на него функции инициализации базы данных, создания таблицы и алхимического картирования (а это скорее к File, об этом дальше). Но Вы ведь этого не сделали, предпочтя выполнить все эти телодвижения за пределами класса. Собсно, я споткнулся об это, когда писал свою версию для Лиспа. Я не умею хорошо работать с классами в Лиспе, потому создание еще одного класса мне показалось нецелесообразным. У меня получилось сделать всю функциональность FileDB простыми функциями. То же самое можно было бы сделать и в Питоне. Можно, конечно, спорить о масштабировании, но ведь это явно не тот случай. А даже если и помнить о масштабировании, то Вы слишком непоследовательно к нему подготовились.

> Класс необходим из-за того что sqlalchemy это ORM. Т.е. это для людей поражённых ООП до мозга костей типа меня. В простейшем случае можно считать что таблица отображается на класс, т.е. класс необходим.

Еще раз подчеркну: это именно File, не FileDB. Так ведь, и у меня такой класс понадобился, потому как CLSQL -- это тоже ORM (ну, плюс pysqlite в том же флаконе, и это особенно воодушевляет). Посему у меня определяется класс file. Только вот закавыка, у меня на Лиспе этот класс несет серьезную смысловую нагрузку -- он определяет картирование класса в таблицу. А в питоньей проге этот файл "зависает" -- у него при определнии даже явная атрибутика не задается. Это, опять же, делается отдельным вызовом за пределами класса. То есть, опять непоследовательно.

То есть, по уму, нужно было бы инкапсулировать картирование в класс File, а от класса FileDB отказаться вообще. Не знаю, стало бы это понятно для меня без Лиспа, но подозреваю, что тут скорее общее отношение программиста к задаче (не будем говорить о квалификации). Похоже, это следствие моей дотошности -- люблю находить проблемы на ровном месте.

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

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

Тебе придётся _только_ использовать имеющиеся функции для существующих типов и написать свои для новых.

Посмотрите реализацию map-ов в различных лиспах. Там, как правило, идёт проверка типа и разделение зависимого от типа кода. Теоретически - да, два хода до дженериков. Практически - 1) нфиг не надо (разве только "си++"-нутым); 2) в случае действительной надобности - легко реализуется; 3) даёт возможность компилировать довольно быстрый код.

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

>Посмотрите реализацию map-ов в различных лиспах. Там, как правило, идёт проверка типа и разделение зависимого от типа кода. Теоретически - да, два хода до дженериков. Практически - 1) нфиг не надо (разве только "си++"-нутым); 2) в случае действительной надобности - легко реализуется; 3) даёт возможность компилировать довольно быстрый код.

Точно. Я думаю, что причина того, что не сделали один универсальный map -- это забота о производительности. В процессе выполнения откуда заранее узнаешь, какой тип будет передан в map. Соответсвенно, потребовалась бы диспечеризация по типам. А нафига мне такой празник в высокопроизводительных программах? :) Поэтому и сделали для списков map, а для хэш-таблицы maphash. И это правильно. А вот в generic уже есть диспечеризация, которая разными способами оптимизируется в реализациях, но она все-равно есть.

В C++ это можно сделать без penalty, потому что тип аргументов определяется еще до компиляции. Но только опять непонятно, радоваться или огорчаться по этому поводу. Если я увижу, например, в трех участках кода универсальный (map бла-бла var), то сразу и не пойму, какой тип у var. И это только запутает. А если я вижу maphash, то сразу знаю, что там дальше хэш-таблица. Если увижу map, то знаю, то там дальше некий список. Сделаю maptree и сразу буду знать, что там дерево. И людям, которые будут читать мой код, будет легче. Так что выгода от тотальной универсализации стандартных функций в независимости от типов -- это вопрос спорный.

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

> Речь идет не о File, а о FileDB

Всё, наконец дошло о чём идёт речь.

В первой версии (не зарелизенной) у этой программы metadata и files_table были атрибутами FileDb, мне это не понравилось и я их оттуда выкинул на верхний уровень модуля (т.к. при этом получалось) меньше буков, а мне не хотелось провоцировать дополнительный флейм по этому поводу :-)

В реальной задаче я думаю всё было бы подругому, начиная с того что я бы использовал не BoundMetaData, определённый на уровне модуля, а DynamicMetadata и т.д, и т.п.

Главным критерием при написании этой программы были минимальные затраты времени на её написание :-)

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

> я их оттуда выкинул на верхний уровень модуля (т.к. при этом получалось) меньше буков, а мне не хотелось провоцировать дополнительный флейм по этому поводу :-)

Выкинули бы класс целиком -- буков было бы еще меньше. А флейма вообще не было бы.

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

> Я точно не смотрел, разрешена ли перегрузка стандартных операторов в стандарте или это implementation feature. Изначально в SBCL и CLISP (где я попробовал) это заблокировано (что правильно), но можно разблокировать принудительно

Это стандарт, принудительно можно разблокаровать ЕМНИП (with-packge-unlock ...

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

> Я точно не смотрел, разрешена ли перегрузка стандартных операторов в стандарте или это implementation feature. Изначально в SBCL и CLISP (где я попробовал) это заблокировано (что правильно), но можно разблокировать принудительно

Это стандарт, принудительно можно разблокаровать ЕМНИП (with-packge-unlock ...

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

> В C++ это можно сделать без penalty, потому что тип аргументов определяется еще до компиляции. Но только опять непонятно, радоваться или огорчаться по этому поводу. Если я увижу, например, в трех участках кода универсальный (map бла-бла var), то сразу и не пойму, какой тип у var

Гм. А зачем это знать, если алгоритм все равно работает по последовательности? Интересно знать, скорее, тип содержимого контейнера.

И, если уж _очень_ хочется такого документирования - можно инстанциировать шаблоны явными параметрами, типа

copy< list<int>::const_iterator, ostream_iterator<int> >(ambigous_list.begin(), ambigous_list.end(), ostream_iterator<int>(cout, "-");

(Да, да, оно очень длинно и тавтологично - поэтому никто так не делает).

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

> Кстати, автор С++ примера, респект. Хорошо написал.

Спасибо. Хотя, как я сам же и говорил, можно было и лучше. Но это ж думать надо было бы.

> To anonymous: в этом примере не было sqlalchemy, с sqlalchemy был другой пример.

Ну, ээ (это был я же). Я не вчитывался, я питон не знаю толком. Перлисты мы...

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

>Гм. А зачем это знать, если алгоритм все равно работает по последовательности? Интересно знать, скорее, тип содержимого контейнера.

А компилятор CL? Массивы, списки и хэши физически по-разному организованы. И физически по ним перемещаться надо по-разному. Следовательно, на каком-то этапе все-равно необходимо перейти на реализацию map, характерную для даного типа данных. Если бы ты знал тип данных заранее, то можно было бы в зависимости от типа подставлять необходимую реализацию. А так ты напишешь (defun foo+1 (seq) (super-map #'1+ seq)), например. Ну? И какой тут тип seq? Да любой может быть. Поэтому должна будет быть введена диспечеризация, и конкретная реализация на низком уровне будет выбираться уже в рантайме. Это плохо. Если же я указываю (defun foo+1 (seq) (maphash #'(lambda...) seq)), то тут явно указано, что seq ожидается, как хэш-таблица. При компиляции сразу выбирается необходимая реализация map*

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

> А компилятор CL? Массивы, списки и хэши физически по-разному организованы. И физически по ним перемещаться надо по-разному. Следовательно, на каком-то этапе все-равно необходимо перейти на реализацию map, характерную для даного типа данных.

Угу. Поэтому в таких задачах рулит явная типизация и <перегрузка|шаблонизация>. Тогда все делается в момент компиляции.

Никто, собственно не возражает, что CL работает и имеет право на жизнь, мы пытаемся выбить из головы некоторых мысли о "превосходстве Lisp на порядок" над "императивными быдлонаречиями".

Нету такого, Lisp - просто еще один (хороший) язык, в чем-то лучше других, в чем-то хуже.

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

> мы пытаемся выбить из головы некоторых мысли о "превосходстве Lisp на порядок" над "императивными быдлонаречиями".

и как, получяецо?

> Нету такого, Lisp - просто еще один (хороший) язык, в чем-то лучше других, в чем-то хуже.

почему же тогда код на ём на порядки короче и на сотни порядков проще?

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

> мы пытаемся выбить из головы некоторых мысли о "превосходстве Lisp на порядок" над "императивными быдлонаречиями".

Бесполезняк

> Lisp - просто еще один (хороший) язык, в чем-то лучше других, в чем-то хуже.

Яволь!

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

> > мы пытаемся выбить из головы некоторых мысли о "превосходстве Lisp на порядок" над "императивными быдлонаречиями".

> и как, получяецо?

Нет, у некоторых очень твердая голова :-/

> почему же тогда код на ём на порядки короче и на сотни порядков проще?

Чётта shootout-овские программки на лиспе вдвое длиннее питоньих...

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

>>> мы пытаемся выбить из головы некоторых мысли о "превосходстве Lisp на порядок" над "императивными быдлонаречиями".

>> и как, получяецо?

> Нет, у некоторых очень твердая голова :-/

или у некоторых слишком мягкие аргументы? Тёплые, мягкие, и плохо пахнут...

>> почему же тогда код на ём на порядки короче и на сотни порядков проще?

> Чётта shootout-овские программки на лиспе вдвое длиннее питоньих...

это которые?

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

>Также в лиспе нельзя доопределить новый численный тип и перегрузить >#'+, #'*, ... для него. К примеру, если мне нужны кватернионы, то >складывать их придется уже не с помощью #'+.

Да можно всякими способами, причем перегруженный + будет действовать только в пределах нужного пакета:

(in-package :my-package)

(shadow 'cl::+)

(defun + ;; тут все что позволит фантазия)

Еще есть макросы компилятора

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

> Чётта shootout-овские программки на лиспе вдвое длиннее питоньих...

> это которые?

http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=...

Смотреть третью колонку. Во _всех_ бенчмарках питоньи программы короче.

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

>> Чётта shootout-овские программки на лиспе вдвое длиннее питоньих...

>> это которые?

> http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=...

> Смотреть третью колонку. Во _всех_ бенчмарках питоньи программы короче.

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

import sys, itertools

print sum(itertools.imap(int, sys.stdin))

Это так понимать чё питонья прого становицо короче лисповой, если все 500 с малым гаком обектов убрать из её в отдельную либу и закрыть на их глаза, подобно тому как это пытались сделать в этом топе?

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

> print sum(itertools.imap(int, sys.stdin))

> Это так понимать чё питонья прого становицо короче лисповой, если все 500 с малым гаком обектов убрать из её в отдельную либу и закрыть на их глаза, подобно тому как это пытались сделать в этом топе?

В питоне есть понятие пространства имён. itertools входит в состав стандартной библиотеки. import itertools это просто подключение части стандартных возможностей языка.

Хуже того, в данном случае, это можно написать как

import sys

sum(map(int, sys.stdin))

просто это будет жрать больше памяти.

Кстати, а в Lisp-е есть пространства имён?

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

> Это так понимать чё питонья прого становицо короче лисповой, если все 500 с малым гаком обектов убрать из её в отдельную либу и закрыть на их глаза, подобно тому как это пытались сделать в этом топе?

Так и запишем - стандартная библиотека лиспа не позволяет простым способом читать числа-в-виде-строк из файла и просуммировать их?

print map {"Бугога!!!\n"} 1..1_000_000; #yes I know this wastes memory - this is purely applicative ;-)

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

> Так и запишем - стандартная библиотека лиспа не позволяет простым способом читать числа-в-виде-строк из файла и просуммировать их?

> print map {"Бугога!!!\n"} 1..1_000_000; #yes I know this wastes memory - this is purely applicative ;-)

Позволяет. Но здесь уже не раз говорили - ввод/вывод у лиспа _медленный_. И решение в две строки (как на питоне) показало бы плохой результат.

А смех без причины... Надеюсь хоть это знаете ;)Ь

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

>> Это так понимать чё питонья прого становицо короче лисповой, если все 500 с малым гаком обектов убрать из её в отдельную либу и закрыть на их глаза, подобно тому как это пытались сделать в этом топе?

> Так и запишем - стандартная библиотека лиспа не позволяет простым способом читать числа-в-виде-строк из файла и просуммировать их?

позволяет, заросто. Давай луче запишем, чё в питоньей проге нет способа зделать этого кроме как вызвать из стандартной библиотеки специально для этово случяя написатую на сях функцию, а питоноедам нечем больше похвастацо кроме стандартной либы.

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

> Да можно всякими способами, причем перегруженный + будет действовать только в пределах нужного пакета: <skipped>

Это мы уже обсудили. Аналогично ситуацию с map, reduce. Похоже многие лисперы тут так и не догнали о чем шла речь.

Хер с ним. Мне пришел на ум более удачный пример изъяна в CL-евской стандартной библиотеке.

Допустим мне нужно положить в hashtable ключи которые являются тройками. Равенство ключей определим покомпонентно. Т.е. ключ A равен ключу B если все элементы троек равны (например, в терминах equal). Так вот CL-евские hashtable'ы не позволяют мне эффективно иметь такие ключи, т.к. make-hash-table не дает мне указать особенные реализации хеш-функции и функции сравнения (или переопределить equal и функцию получения хеш-кода (которой нет, но которая была бы нужна)).

Частично эту задачу можно выполнить указав equalp в качестве теста hashtable и применив массив или структуру для моей тройки, но тогда получаем облом со сравнением строк и символов. Т.к. при сравнении по equalp имеем case-insensitive сравнение.

Для этой задачи подойдет equal в качестве теста и представление тройки в виде списка. Но такое представление тройки не всегда годится по производительности и/или потреблению памяти.

Даже убогая во многих отношениях реализация хешей в Java 2 platform мне такие вещи позволяет.

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

А все-таки есть ли какой-нибудь способ уменьшить размер ядра sbcl? Вообще самая здравая мысль это конечно маааленькое ядро и модули

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

> позволяет, заросто.

Что-то на этом примере не заметно.

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

Ну да, питон написан на С, стандартная либа на С + питон. Тогда ты прав, питоноводам (не едам, а водам) хавстаться нечем кроме ядра питона и его стандартной библиотеки, написанных на С.

Немного выше по топику ты считал достоинством лиспа то что там есть готовый контейнер для решения задачи с файлами и что тебе не надо дотачивать контейнер как в С++ или питоне. А как питон попал в аналогичную ситуацию так это уже не достоинство, а просто "из стандартной библиотеки специально для этово случяя написатую на сях функцию". Занятная манера спора.

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

>make-hash-table не дает мне указать особенные реализации хеш->функции и функции сравнения (или переопределить equal и функцию >получения хеш-кода (которой нет, но которая была бы нужна)).

В Lispworks позволяет.

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

> Допустим мне нужно положить в hashtable ключи которые являются тройками.

С десяток страниц назад я уже описывал, где конкретно это необходимо: при реализации BDD/MDD, которые используются для компактного представления булевых выражений.

На Эйфеле пришлось написать свой собственный контейнер.

> Даже убогая во многих отношениях реализация хешей в Java 2 platform мне такие вещи позволяет.

А можно пример для иллюстрации?

И как с этим обстоят дела в том же STL?

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

> Даже убогая во многих отношениях реализация хешей в Java 2 platform мне такие вещи позволяет.

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

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

Кстати исходники хэш таблицы SBCL доступны. Если уж такой специфичный случай, когда от этого зависит производительность, то можно использовать части существующей реализации и реализовать несколько функций, чтобы можно было задавать хэш функцию и функцию сравнения, в том числе возможен шаблонный вариант как в С++, чтобы статически вкомпилировать функции, а не вызвать их посредством funcall.

Создавать таблицу потом можно будет функцией вроде make-custom-hash-table или макросом сначала определить (def hash-table myhash-table (myhashfun myequalfn)) потом для создания экземпляра вызывать make-myhash-table, а тип у нее будет тот же, остальные функции должны работать с ней как с обычной таблицей в том числе gethash, maphash, loop macro.

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

>> В Lispworks позволяет.

>Нестандарт?

Если уже пишешь под Lispworks коммерческий продукт, то пофигу, ты все равно привязан к этой реализации, ведь CAPI (библиотека для GUI)тоже не входит в стандарт. Ну и потом можно уровень совместимости добавить для других реализаций, чтобы там make-hash-table выглядела так же как в Lispworks. Потом Lispworks и CAPI есть под Linux, под оффтопик, под Mac, так что вполне можно с ним жить, если производительность устраивает.

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

> Мне пришел на ум более удачный пример изъяна в CL-евской стандартной библиотеке...

Лучше бы ты изъяны искал в своей голове! :-Е

Стандарт не ограничивает хеш-функции в hash-tables _только_ указанными eq, eql, equal, equalp, но расширение функциональности оставляет "на совести" реализаций.

SBCL - см. *hash-table-tests* и define-hash-table-test.

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

> позволяет, заросто.

Только тормозит со страшной силой?

Т.е. программы на лиспе у нас или короткие, но тормозные, или быстрые, но спагетти-кодинг-оптимизированные?

Спасибо, я уж лучше на плюсах. Или Eiffel/*ML какой освою.

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

Гм. Стандартная библиотека питона написана на плюсах, и это фича такая. И это не "функции специально для этого случая", а вполне регулярно употребляемые вещи, вроде "зачитать файл в массив построчно" и "прообразовать строковое представление числа в int (man 3 atoi, да?). Эти функции необходимы едва ли не в любой юниксовой программе...

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

> Только тормозит со страшной силой?

А ты попробуй. А то с чужих слов петь - это не есть хорошо ;)

> Т.е. программы на лиспе у нас или короткие, но тормозные, или быстрые, но спагетти-кодинг-оптимизированные?

Смотри не кончи :-Е

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

> Допустим мне нужно положить в hashtable ключи которые являются тройками.

> И как с этим обстоят дела в том же STL?

В стандарте нету хешей. В SGI-ном STL-е - есть, и в бусте есть. Чтобы иметь в них ключами тройки, достаточно определить класс тройки (увы, нету в STL-е и N-tuple готовых. В бусте, возможно, есть - мне никогда не нужно было, не смотрел), функтор hash для него (с size_t operator()(const ThreeTuple &t)), и все (ну, шаблон инстанциировать).

Т.е., с т.з. С++, нет проблем - опишите ваши типы и все поедет.

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

> Гм. Стандартная библиотека питона написана на плюсах

s/плюсах/сях/

зарапортовался...

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

> Только тормозит со страшной силой?

> А ты попробуй. А то с чужих слов петь - это не есть хорошо ;)

Гм. А с твоих - можно. Цитата, даже листать назад не нужно: "Позволяет. Но здесь уже не раз говорили - ввод/вывод у лиспа _медленный_. И решение в две строки (как на питоне) показало бы плохой результат."

> > Т.е. программы на лиспе у нас или короткие, но тормозные, или быстрые, но спагетти-кодинг-оптимизированные?

> Смотри не кончи :-Е

О, конструктив попер, я смотрю.

Не, вы все-таки ничего не понимаете.

Если бы мне показали идеальный язык программирования, на порядок превосходящий остальные (ну, хотя бы бьющий C++ _и_ Perl на их поле), с хорошей - открытой и кроссплатформенной - реализацией, богатой стандартной библиотекой и активным community - я бы пересел (для собственных разработок), и ходил бы с плакатом по офису агитируя коллег. На данный момент есть желание посмотреть на Ocaml/Eiffel в качестве замены C++ - но от них, как я понял, GC не отрывается, а это плохо. Должен быть выбор. D же не настолько лучше C++/Java, чтобы переучиваться, как мне показалось.

А мне предлагают (в лице CL-я) нечто странное пока - куча полусовместимых реализаций, (относительно) тормозное, (довольно таки, по сравнению с Python/Perl/ML/Haskell) многословное, со странным синтаксисом, не умеющее порождать unix-way программы, с кривыми отстающими от mainline биндингами... Ну да, есть там приятные возможности - но граблей таки больше.

А для "общего развития" я лучше что-нибудь модное изучу - Haskell там, или io - а не 30-тилетние консервы, из которых уже поуносили все интересное...

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

> в том чё примитивные типы используются для построения а не видоизменяюцо

А что, в LISP не так? Для реализации, например, двусвязного списка ты видоизменяешь CONS? Или таки строишь новый тип из примитивных?

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

> Если бы мне показали идеальный язык программирования, на порядок превосходящий остальные (ну, хотя бы бьющий C++ _и_ Perl на их поле), с хорошей - открытой и кроссплатформенной - реализацией, богатой стандартной библиотекой и активным community - я бы пересел (для собственных разработок), и ходил бы с плакатом по офису агитируя коллег.

+1. На такую роль CL, увы, не подходит.

> На данный момент есть желание посмотреть на Ocaml/Eiffel в качестве замены C++ - но от них, как я понял, GC не отрывается, а это плохо.

Eiffel, ИМХО, слишком "традиционен". А OCaml я ниасилил :(

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

Вы правы, Hello Worldы писать у CL преимуществ совершенно никаких.

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

> Что-то на этом примере не заметно.

Он оптимизирован по скорости, а не читабельности. Вместо самописной read-int, которая и занимает бОльшую часть, можно использовать обычный read, но это будет медленнее.

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

> от них, как я понял, GC не отрывается, а это плохо.

Джоэль как-то сравнивал GC с автоматической коробкой передач. Более того, он считает, что именно создание приемлемых GC, а совсем не внедрение ООП совершили настоящую революцию в проектировании сложных программных комплексов. И я с ним согласен.

В общем, очень странно покупать автомобиль с автоматической коробкой, а потом жаловаться, что она оттуда не выдирается. Если не нужен GC -- оставайтесь на С++. Собственно, если бы не GC, то я бы вообще с C++ никуда бы не уползал.

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

> Eiffel, ИМХО, слишком "традиционен".

И многословен. Но, в отличие от Лиспа и Питона, генерирует нормальный кроссплатформенный C-код. Для примера, мои успехи в Лиспе позволили задуматься о переносе того, что я сейчас пишу на Эйфеле, на Лисп. Однако, есть одно краевое условие: созданная утилита должна подключаться, как плагин к некому закрытому коммерческому продукту под оффтопик. Эйфель на выходе дает С-код, который несложно прикрутить, как обычную программу на С через заданный плагин интерфейс (собственно этим даже не я буду заниматься -- у нас есть специалисты по этому делу). Поэтому и не подходит Питон. По крайней мере, я не знаю, как из него сделать нечто вроде dll с заранее заданным интерфейсом на С. Более того, чтобы один и тот же код в зависимости от режима компиляции создавал или утилиту командной строки или библиотеку. Может, кто подскажет?

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

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

> Джоэль как-то сравнивал GC с автоматической коробкой передач. Более того, он считает, что именно создание приемлемых GC, а совсем не внедрение ООП совершили настоящую революцию в проектировании сложных программных комплексов. И я с ним согласен.

Я вот тут работаю с большим программным комплексом на C++ - и ниччо. И в соседнем отделе еще один есть, на C++ on CORBA. Немножко стековой дисциплины + смартпойнтеры позволяют не так уж часто делать delete вручную, чтобы не сказать "вообще никогда".

GC - штука хорошая, но в системах массового обслуживания он периодически дает странные эффекты, особенно в своей жабьей ипостаси. Опять же, стековая дисциплина с предсказуемым временем разрушения, как в C++, позволяет автоматизировать учет не только памяти, но и других ресурсов (мутексы, файлы, сокеты, соединения с БД), причем exception-safe образом. Это не очень легко (особенно с т.з. автора библиотеки), но отнюдь не невозможно.

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

> Т.е., с т.з. С++, нет проблем - опишите ваши типы и все поедет.

А средства профилирования?

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

А parse-integer тоже тормозная ?

#def main(): # count = 0 # for line in sys.stdin.xreadlines(): # count += int(line) # print count # #main()

(defun main () (print (loop for int of-type integer = (parse-integer (read-line *standard-output*)) while (integerp int) sum int)))

(main)

Я не понял, должно оно для бигнумов тоже работать ?

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

А parse-integer тоже тормозная ? 
#def main(): 
# count = 0 
# for line in sys.stdin.xreadlines(): 
# count += int(line) 
# print count 
# 
#main() 

(defun main () 
   (print 
      (loop for int of-type integer = (parse-integer (read-line *standard-output*)) 
            while (integerp int) sum int))) 

(main) 

Я не понял, должно оно для бигнумов тоже работать ? 

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

Пардон. Привычка, блин. Не тот поток получается. Вот правильно:

(defun main () 
   (print 
      (loop for int of-type integer = (parse-integer 
                                           (read-line *standard-input*)) 
            while (integerp int) sum int))) 

(main) 

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

> не подходит Питон. По крайней мере, я не знаю, как из него сделать нечто вроде dll с заранее заданным интерфейсом на С.

Конкретных деталей не подскажу (давно было - во времена 1.5), но это возможно. Более того, это одно из штатных применений Питона. Python embedding называется. Если вкратце - делашь либу, у которой снаружи - нужный тебе Сишный интерфейс, а внутри - обращение к Python C API, через который вызывается Питон-код. Может быть, такое можно сделать через SWIG (не уверен).

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

> Я вот тут работаю с большим программным комплексом на C++ - и ниччо. И в соседнем отделе еще один есть, на C++ on CORBA.

Э-э-э. Мы часом "большие" и "сложные" не путаем?

> + смартпойнтеры

В стандарте С++ есть? В свое время (лет пять назад) пришлось писать свои собственные, ибо сторонние обладали странными интересными эффектами. А чем Вы пользуетесь? И насколько оно синтаксически прозрачно?

> как в C++, позволяет автоматизировать учет не только памяти, но и других ресурсов (мутексы, файлы, сокеты, соединения с БД),

Для таких целей в Эйфеле тоже есть специальный mixin (кажется, DISPOSABLE). Подмешиваешь к любому классу, и используешь метод dispose (опять кажется, ибо ни разу не понадобилось). Ну и, понятно, что при потере ссылок будет уничтожаться без спросу, хотя объекту дается "последний шанс". Кажется, точно так же это все работает и в Питоне, недавно видел статью, где для перегрузки методов как раз используют трюк с "неуничтожимыми объектами".

ИМХО, искусственно отключать сборку приходится намного реже, чем не забывать втыкать ее там, где она нужна. Как по мне, соотношение где-то 90/10 в пользу автоматической сборки.

> причем exception-safe образом

В Эйфеле все exception являются safe. Правда, ценой потери производительности.

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

>Может быть, такое можно сделать через SWIG (не уверен).

А зачем тут SWIG ? Для вызова Лиспа из другой программы можно просто FFI использовать, закатав Лисп в DLL. По крайней мере в Corman Lisp, Lispworks и ACL с этим проблем нет. Не уверен насчет SBCL.

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

>>Может быть, такое можно сделать через SWIG (не уверен).

>А зачем тут SWIG ? Для вызова Лиспа

Потому что вопрос был про Питон

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

>Однако, есть одно краевое условие: созданная утилита должна подключаться, как плагин к некому закрытому коммерческому продукту под оффтопик.

М.б. ECL (Embeddable Common-Lisp) подойдет? Он как раз сделан для встраивания в программы на C. Вроде умеет транслирвоать в C-код.

ECL is a free Common Lisp implementation aimed at producing a small-footprint Lisp system that can be embedded into existing C-based applications. It is able to create stand-alone ELF executables from Common Lisp code and runs on most platforms that sport a C compiler.

http://ecls.sourceforge.net/

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

>А мне предлагают (в лице CL-я) нечто странное пока - куча >полусовместимых реализаций

Типа в других языках выходящее за стандарт является совместимым.

>, (относительно) тормозное

Ну это касается только самых отъявленных числодробильных задач с массивами, и то там отрыв не такой же фатальный. Питон, Перл, Haskell уж точно не смогут тягаться с SBCL, да и с некоторыми другими Лиспами (например Lush). Что касается ML и С++, то с метапрограммированием как то у них тяжко, на Лиспе все таки оно намного легковеснее получается.

>, (довольно таки, по сравнению с Python/Perl/ML/Haskell) >многословное,

Краткость наверстается на нормальных по объему задачах. Для написания заоптимизированных Hello World Лисп и правда хреново подходит. Хотя без оптимизации не видно особой многословности.

> со странным синтаксисом

А у какого из упомянутых языков синтаксис не странный ? ;-)

>, не умеющее порождать unix-way программы

Почему это ? Это про тяжеловатое ядро, неудобное для мелких задачек ? Скорость запуска ядра может быть не очень. Но в принципе, тогда и Java этим грешит. Скриптовать так на GNU CLisp вроде лучше. Если полноценное приложение, где важна производительность, то можно и ядро 25 метровое запустить. В принципе можно все приложение в fasl хранить, одно и то же ядро на все приложения запускать, fasl грузятся быстро.

>, с кривыми отстающими от mainline биндингами...

А где эта mainline сейчас проходит ? Кто мешает нагенерить баиндинги для чего надо ? Почему кривыми ?

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

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

И кстати, где аналог CL библиотеки CELLS хотя бы под один упомянутый язык ?

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

> А на Pyrex ты смотрел?

Смотрел. Только, как я понял, он работает в другую сторону. Я использовал его для оптимизации числодробилок, но хостом был таки Питон, который использовал C-модули. Тут же задача прямо противоположная.

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

>> А на Pyrex ты смотрел?

>Смотрел. Только, как я понял, он работает в другую сторону.

Я им не пользовался, но по описанию решил, что он транслирует Питон в Си. Может, ошибся :/

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

> И решение в две строки (как на питоне) показало бы плохой результат.

Плохой для sbcl. Питону - выше крыши :) Но мы же хотим с "ссями" тягаться ;) А так как там половину надо писать самому, вот и решили "поупражняться" в целях повышения быстродействия.

> Если бы мне показали идеальный язык программирования, на порядок превосходящий остальные (ну, хотя бы бьющий C++ _и_ Perl на их поле), с хорошей - открытой и кроссплатформенной - реализацией, богатой стандартной библиотекой и активным community - я бы пересел (для собственных разработок), и ходил бы с плакатом по офису агитируя коллег.

Месье желает "серебрянную пулю"? И прямо сейчас? Новую, но открытую и с "богатой стандартной библиотекой и активным community"? Фантазёр!.. ;)

> GC не отрывается, а это плохо

Всё! Достаточно! Хотите "эдакого" - возьмите форт.

> А мне предлагают (в лице CL-я) нечто странное пока - куча полусовместимых реализаций

Все реализации си совершенно совместимы? (только не говорите - в пределах стандарта - у лиспа есть CL)

> (относительно) тормозное

Относительно чего? Питона? :)

> (довольно таки, по сравнению с Python/Perl/ML/Haskell) многословное

Согласен. По мне - не недостаток. Или действительно берите Перл.

> со странным синтаксисом

В сад! (неа, не яблоневый - в детский!)

> не умеющее порождать unix-way программы

Зависит от реализации.

> с кривыми отстающими от mainline биндингами...

Вы о коммерческих версиях? :) С открытыми - да, есть проблемы. Но это следствие. Причина - относительно небольшое community.

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

Ок, вернётесь, когда поймёте, что без этих возможностей что с граблями, что без них... "Пилите гири, Шура, они золотые"

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

> +1. На такую роль CL, увы, не подходит.

На такую роль сейчас ничего не подходит. И не знаю, когда подойдёт.

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

> Более того, чтобы один и тот же код в зависимости от режима компиляции создавал или утилиту командной строки или библиотеку. Может, кто подскажет?

ECL? Но там много ещё чего "пилить" надо. Хотя может то, что надо "пилить", вам и не нужно. Смотрели?

> Но вот можно ли быстро и элегантно генерить кроссплатформенный С-код из лисповских программ?

GCC?

> А было бы вкусно.

Не было бы вкусно. Ибо потеряли бы как раз много лисповых вкусностей. (К примеру, у того-же ECL не _любой_ код, который нормально компилируется, может выполниться в REPL :( А так может когда-нибудь и будет такая возможность. Или берите коммерческие версии.

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

> GC - штука хорошая, но в системах массового обслуживания он периодически дает странные эффекты, особенно в своей жабьей ипостаси.

Т.е. вместо того, чтобы поискать "ипостась" поприличнее, или самому принять участие в данном процессе, будем оттачивать владение ручной КПП?

> Это не очень легко (особенно с т.з. автора библиотеки), но отнюдь не невозможно.

Ага, т.е. сами "на лыжах в гамаке", зато все нити управления в руках? Ну, иногда и это надо (картинг), но чаще всё что можно посчитать на машине - пусть считает сама (Ф1). Всё, с аналогиями завязал :)

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

>> На такую роль CL, увы, не подходит.

> На такую роль сейчас ничего не подходит

ИМХО (подчеркиваю красным: ИМХО) на эту роль подходит Питон. Открытая единая кроссплатформенная реализация, большое и активное сообщество (единое, а не как у Лиспов), куча библиотек, биндинги ко всему подряд. Если бы там было что-то вроде type inference, я бы даже не смотрел в сторону других языков.

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

> > Я вот тут работаю с большим программным комплексом на C++ - и ниччо. И в соседнем отделе еще один есть, на C++ on CORBA.

> Э-э-э. Мы часом "большие" и "сложные" не путаем?

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

> + смартпойнтеры

> В стандарте С++ есть? В свое время (лет пять назад) пришлось писать свои собственные, ибо сторонние обладали странными интересными эффектами. А чем Вы пользуетесь?

В STL есть auto_ptr, который убогий, но быстрый. В Boost есть shared_ptr, который надежный, но с мутексом-на-каждую-операцию. И есть свой (не мой лично, а в смысле в конторской библиотеке), который не threadsafe, но быстрый (для thread-local-storage и однопоточных программ).

> И насколько оно синтаксически прозрачно?

shared_ptr<Foo> autofoo(new Foo());

autofoo->field = 1;

autofoo->call_method();

По-моему, нормально.

> как в C++, позволяет автоматизировать учет не только памяти, но и других ресурсов (мутексы, файлы, сокеты, соединения с БД),

> Для таких целей в Эйфеле тоже есть специальный mixin (кажется, DISPOSABLE). Подмешиваешь к любому классу, и используешь метод dispose (опять кажется, ибо ни разу не понадобилось). Ну и, понятно, что при потере ссылок будет уничтожаться без спросу, хотя объекту дается "последний шанс". Кажется, точно так же это все работает и в Питоне, недавно видел статью, где для перегрузки методов как раз используют трюк с "неуничтожимыми объектами".

Мы, по-моему, чуть-чуть о разном. Я о том, что можно, скажем, завернуть мутекс в класс (lock в конструкторе, unlock в деструкторе), и потом код типа

{

Lock a(MUTEX_ID_A);

Lock b(MUTEX_ID_b);

do_smth_locked();

}

оказывается автоматически избавленным от проблем с исключениями (и большей части проблем с дедлоками, хотя и не всех). А в языках с "настоящими" GC разрушение a и b произойдет неизвестно когда, и в непонятном порядке.

Соотвественно, заявление что > " В Эйфеле все exception являются safe."

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

Т.е. я хочу не столько отключаемого GC, сколько предсказуемого времени финализации (которое, как мне кажется, возможно только при явном управлении памятью со стековой дисциплиной, или при reference counting-е, как в перле. Правда, в перле порядок не соблюдается, потому что lexical pad там - это, iirc, хэш внутри).

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

> ИМХО (подчеркиваю красным: ИМХО) на эту роль подходит Питон. Открытая единая кроссплатформенная реализация, большое и активное сообщество (единое, а не как у Лиспов), куча библиотек, биндинги ко всему подряд. Если бы там было что-то вроде type inference, я бы даже не смотрел в сторону других языков.

1) Тормоз! (когда хоть какая-нибудь "ускорялка" сможет работать с _любым_ питоньим кодом?)

2) Макропрограммирование - хрен целых фиг десятых. И не предвидется (в стандарте, не надо мне про сторонние костыли напоминать)

3) Хоть какой-то "конструктор" синтаксиса - фиг. ГВР лучше знает, на чём мы должны писать!... :\

Да, Питон замечательный язык. Замечательный тем, что у него _так мало_ недостатков :)

Ладно. "Каждому - своё". Плохие были место, время и события. Слова - хорошие.

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

>Открытая единая кроссплатформенная реализация, большое и активное >сообщество (единое, а не как у Лиспов), куча библиотек, биндинги ко >всему подряд. Если бы там было что-то вроде type inference, я бы >даже не смотрел в сторону других языков.

1) Питон тормозит. 2) Что с метапрограммированием делать ? 3) В Питоне лямбды убирать собирались. И вообще минусы получаются из плюсов - один "милосердный диктатор" говорит, что там будет и чего не будет. В Лиспе такие решения принимаются по необходимости после существенной практической обкатки (как и в С++). Но в отличии от Питона добавить новые языковые конструкции в Лисп можно в любой момент, не дожидаясь решения "сверху".

Инфиксные выражения и type inference в Лисп добавить можно (например уже есть библиотека TypeL для вывода типов по Хиндли-Милнеру как в ML). Только не уверен, что это такое уж преимущество, на 80% кода биться из-за производительности со статической типизацией, когда там тормозить можно как угодно.

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

> Инфиксные выражения и type inference в Лисп добавить можно (например уже есть библиотека TypeL для вывода типов по Хиндли-Милнеру как в ML).

ИМХО, в REPL - нафиг не нужно. А в для компилятора - задавайте типы явно. Хотя да - с выводом типов - заманчивее ;)

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

> Питон, Перл, Haskell уж точно не смогут тягаться с SBCL, да и с некоторыми другими Лиспами (например Lush).

Haskell по производительности - на уровне SBCL. Он статически типизированный и прекомпилируемый в native. Был бы быстрее, если бы у него был нормальный оптимайзер.

> Что касается ML и С++, то с метапрограммированием как то у них тяжко, на Лиспе все таки оно намного легковеснее получается.

Да, но "метапрограммирование ненужно". В том смысле, что эти проблемы решает малое количество людей один раз, и, в любом случае, проектирование DSL - сильно более сложная задача, чем его реализация (даже на С/yacc).

> А где эта mainline сейчас проходит ? Кто мешает нагенерить баиндинги для чего надо ? Почему кривыми ?

Ну, вон, гтк к sbcl у кого-то тут подцепить не получилось. А, скажем, к какому-нибудь cairo их вообще нету, небось.

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

А я и не возражаю. Я к тому, что плюсовые и перловые, по крайней мере, уже известно, где лежат. А поменять все, чтобы получить то же самое - непонятно, зачем.

Я не утверждаю, что CL _хуже_, чем связка Perl/C++. Только то, что он не настолько лучше, чтобы переход на него оправдал затраты (имхо - так вообще не лучше).

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

> 2) Макропрограммирование - хрен целых фиг десятых. И не предвидется (в стандарте, не надо мне про сторонние костыли напоминать)

Ну приведи пример, строк на 100, где действительно необходимо макропрограммирование.

Пока что во всех примерах рассмотренных в этом топике не было ни обдного примера где дествительно были необходимы макры.

Или этого нельзя понять на хелло-ворлдах, а только на больших серьёзных лисповых проектах на тысячу строк?

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

> 1) Питон тормозит.

По сравнению с компилируеммы в машинный код - да. Но есть psyco. А критическое числодробление делается во всяких Numeric Python, которые юзают жостко оптимизированный Си-код.

> 2) Что с метапрограммированием делать ?

Использовать. Начать с гугления по "Python Metaprogramming". Впрочем - по-моему, "метапрограммирование" - это еще хуже, чем "обёектно-ориентированное программирование" 15 лет назад, там хоть были общепринятые определния и эталонные реализации. А "метапрограммирование" - модный термин и повод для фаллометрии.

> 3) В Питоне лямбды убирать собирались.

Но не убрали же.

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

Какая чушь. Гвидо - это финальная инстанция при разрешении конфликтов. Он может сказать, чего не будет, но что будет - решает практика.

> Только не уверен, что это такое уж преимущество, на 80% кода биться из-за производительности со статической типизацией

Это не ради производительности ни разу.

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

> Ну приведи пример, строк на 100, где действительно необходимо макропрограммирование.

_Необходимо_ - не то слово. Можно и без них обойтись. Только... гемору слишком много.

А чтобы понять - посмотрие потроха sbcl. Да, на 3 строчках все вкусности макр не увидеть. Да и желания нет.

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

> Да, но "метапрограммирование ненужно".

1. Кому как.

2. Тебе _лично_ не надо? А чё ты тогда в этом топике делаешь? Хочешь лисперам глазики промыть? Иди в свю "ссятницу" и даже define-ом не пользуйся.

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

Не хочешь - не переходи. Тебя кто-то силой тащит?

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

> _Необходимо_ - не то слово. Можно и без них обойтись. Только... гемору слишком много.

Давай заменим "необходимо" на "нельзя обойтись без макр без большого гемору"

> А чтобы понять - посмотрие потроха sbcl.

Это сильно большой пример

> Да, на 3 строчках все вкусности макр не увидеть.

Согласен на 100. Приведи пример. Я его перепишу на питоне, и мы посмотрим действительно ли макры дают большие плюсы.

> Да и желания нет.

Или примеров? :-)

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

> По сравнению с компилируеммы в машинный код - да. Но есть psyco.

Прошу прощения за безграмотность, но psyco "съест" _любой_ питоний код?

> А критическое числодробление делается во всяких Numeric Python, которые юзают жостко оптимизированный Си-код.

Аналогично. Подключите через ffi любую оптимизированную числодробильну. Всего-то.

> Впрочем - по-моему, "метапрограммирование" - это еще хуже, чем "обёектно-ориентированное программирование"...

Это в Питоне "метапрограммирование" еще хуже, чем "обёектно-ориентированное программирование", ибо через него и делается. Ага, вы ещё форт "пошлите по азимуту", потому что там одно сплошное метапрограмирование ;) Хотя да, мы же уже пришли к консенсусу - Вам метапрограммирование не нужно. Так зачем опять повторяться? :)

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

> Давай заменим "необходимо" на "нельзя обойтись без макр без большого гемору"

Давай :)

> Это сильно большой пример

> Согласен на 100. Приведи пример. Я его перепишу на питоне, и мы посмотрим действительно ли макры дают большие плюсы.

100 тоже мало. Возьми не весь sbcl - возьми из него только loop :))

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

> psyco "съест" _любой_ питоний код?

Нет. Операции с плавающей точкой оптимизируются не в машинный код, а вызов функций; вложенные функции и yield - не оптимизируется. Работает правильно, но не ускоряется.

>> А критическое числодробление делается во всяких Numeric Python, которые юзают жостко оптимизированный Си-код.

>Аналогично. Подключите через ffi любую оптимизированную числодробильну.

Не аналогично. При использовании Numeric Python мне не надо возиться с FFI. Вы вообще видели Numeric?

> Ага, вы ещё форт "пошлите по азимуту", потому что там одно сплошное метапрограмирование

Если Форт - это метапрограммирование, то спасибо, не нужно. Его уже все давно послали.

> мы же уже пришли к консенсусу - Вам метапрограммирование не нужно.

Вы пришли к такому консенсусу с кем-то другим. Я до сих пор толком не понял, что это такое :/. Но все говорят, что это неимоверно круто.

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

>> Согласен на 100. Приведи пример. Я его перепишу на питоне, и мы посмотрим действительно ли макры дают большие плюсы.

> 100 тоже мало. Возьми не весь sbcl - возьми из него только loop :))

Блин, да я верю что в _лиспе_ нельзя обойтись без макр. Мне сомнительно что другие языки не могут без них обходиться.

Ну давай 200. Приведи пример что я не смогу эффективно заменить макры чем либо другим и всё, я буду доволен. Вопрос для меня будет закрыт.

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

>> psyco "съест" _любой_ питоний код?

> Нет. Операции с плавающей точкой оптимизируются не в машинный код, а вызов функций; вложенные функции и yield - не оптимизируется. Работает правильно, но не ускоряется.

tailgunner, ты yyk-а запутываешь. Имхо правильный ответ будет такой:

Да, psyco cъест _любой_ питоний код, не любой ускорит, но _съест_ _любой_.

Для включения pysco достаточно в одной точке программы напсать:

import psyco

psyco.full()

Я это обычно делаю либо в main() либо до его вызова

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

>tailgunner, ты yyk-а запутываешь. Имхо правильный ответ будет такой:

>Да, psyco cъест _любой_ питоний код, не любой ускорит, но _съест_ _любой_.

:/ По-моему, я сказал то же самое. "Работает правильно, но не ускоряется."

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

>>Да, psyco cъест _любой_ питоний код, не любой ускорит, но _съест_ _любой_.

> :/ По-моему, я сказал то же самое. "Работает правильно, но не ускоряется."

Согласен, ты сказал то же самое. Но акценты расставлены по другому.

В разговоре с лиспером надо быть очень аккуратным.

Я просто представил что мог бы вынести из твоего поста bugmaker... :-)

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

> (не едам, а водам)

а как же "плакали, кололись, но _ели_"?

> Немного выше по топику ты считал достоинством лиспа то что там есть готовый контейнер для решения задачи с файлами и что тебе не надо дотачивать контейнер как в С++ или питоне.

справедливости ради следует отметить, что и в лиспе и в притоне и в сях++ и в жабе и ещё много где есь контейнер с более-менее одинаковыми свойствами, в составе стандартной либы. Только вот в лиспе ево _не_надо_ дотачивать, именно из-за свойств езыка, а не либы.

> А как питон попал в аналогичную ситуацию так это уже не достоинство, а просто "из стандартной библиотеки специально для этово случяя написатую на сях функцию". Занятная манера спора.

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

Хотиш сделать это на петоне, не прибегая к стандартным?

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

>> позволяет, заросто.

> Только тормозит со страшной силой?

С нормальной силой.

> Т.е. программы на лиспе у нас или короткие, но тормозные, или быстрые, но спагетти-кодинг-оптимизированные?

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

А в питоне проги одновременно и тормозные и преогромные и нечитаемые, и выбора, оптимизировать или не, нету.

> Спасибо, я уж лучше на плюсах. Или Eiffel/*ML какой освою.

да наздоровье, хто заставляет?

> Эти функции необходимы едва ли не в любой юниксовой программе...

лисповые и без них отлично обходяцо.

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

> Если бы мне показали идеальный язык программирования, на порядок превосходящий остальные

Мож тебе сразу всё тебе потребное и накодить на ём заодно?

> А мне предлагают

дык неихто тебе не предлагает, успокойся.

> нечто странное пока - куча полусовместимых реализаций,

в питоне одна всево, зато ужасная.

> (относительно) тормозное,

относительно сей, вдвое примерно. ИМХО вполне приемлемо. Если согласен для немного большей производительности намного больше коду крапать - флаг вруки и барабан и все дела, чё разнылся то? Вон народ даже питон устраивает, куда как тормозной.

> (довольно таки, по сравнению с Python/Perl/ML/Haskell) многословное,

пока что приведённые здесь проги на питоне намного длиньше. По отзывам, которых лехко можеш найти гуглем, лиспопроги для достаточно больших проектов на порядок короче с++вых. На малых задачах выйгрыш конечно намного менше, но и тут действие из 3х строк на лиспе превратилось в многотомную сагу о файлах в питоньей реализации.

> со странным синтаксисом,

у питона ещё страньше, не говоря уж о с++. И ничё, пользуют ведь.

> не умеющее порождать unix-way программы,

не умеющее, вернее это довольно сложно. Жаба тоже не умеет. Потомушто внутри своей собственной идеологии работает. Иногда это недостаток, а иногда наоборот.

> с кривыми отстающими от mainline биндингами...

напишы прямые если которые есть ненравяцо.

> я лучше что-нибудь модное изучу - Haskell

и будеш бинарь по писятмех получять

> 30-тилетние консервы, из которых уже поуносили все интересное...

только вот ни по одному параметру к ним пока даже близко не подошли.

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

>> в том чё примитивные типы используются для построения а не видоизменяюцо

> А что, в LISP не так? Для реализации, например, двусвязного списка ты видоизменяешь CONS? Или таки строишь новый тип из примитивных?

Именно так, я это и пытаюсь обяснить челу, который хотит секвенс, такой точно как стандартный, но с перламутровыми пуговицами...

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

>> Если бы мне показали идеальный язык программирования, на порядок превосходящий остальные (ну, хотя бы бьющий C++ _и_ Perl на их поле), с хорошей - открытой и кроссплатформенной - реализацией, богатой стандартной библиотекой и активным community - я бы пересел (для собственных разработок), и ходил бы с плакатом по офису агитируя коллег.

> +1. На такую роль CL, увы, не подходит.

остальные подходят ещё меньше, и намного

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

>>> На такую роль CL, увы, не подходит.

>> На такую роль сейчас ничего не подходит

> ИМХО (подчеркиваю красным: ИМХО) на эту роль подходит Питон. Открытая единая кроссплатформенная реализация, большое и активное сообщество (единое, а не как у Лиспов), куча библиотек, биндинги ко всему подряд. Если бы там было что-то вроде type inference, я бы даже не смотрел в сторону других языков.

ну, питон ещё когда доделают... ИМХО лет десять пройдёт, не меньше. Если не забросят.

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

> Ну, вон, гтк к sbcl у кого-то тут подцепить не получилось.

у меня в своё время хеловорд на бейсике не сразу завёлся, хотя казалось бы...

> А, скажем, к какому-нибудь cairo их вообще нету, небось.

есь. Вообще, биндинги несложно самому делать, они автоматом генеряцо. Правда с лисповой точки зрения невполне полноценные, из-за разницы в типах лисповых и внешних.

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

чясть обезян думала, что жыть в пещерах не настолько луче, чем на деревьях. Тебе решать, тя нихто не заставит и неуговаривает. Только вот приписывать лиспу/питону/чемутоещё свойства, которых у их нету, ИМХО неследует.

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

> Или этого нельзя понять на хелло-ворлдах, а только на больших серьёзных лисповых проектах на тысячу строк?

ИМХО нельзя, или затруднительно. Придумай _небольшую_ задачу, для которой дсл было бы оправдано...

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

> Приведи пример что я не смогу эффективно заменить макры чем либо другим и всё, я буду доволен. Вопрос для меня будет закрыт.

Тебе ведь уже привели пример обычного кодинга, где лисповые три строки на питоне были расписаны в семи томах. Ты ведь не был доволен и не закрыл для себя вопрос? Почему ты думаеш чё макры тя убедят?

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

> Я просто представил что мог бы вынести из твоего поста bugmaker... :-)

аха, я коварный...

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

> в питоне одна всево, зато ужасная.

Врешь. Уж не хуже лиспов, которые даже не все дистростроители собрать асиливают.

> пока что приведённые здесь проги на питоне намного длиньше.

Врешь. Они функциональнее, аналогичное по "наколенности" на питоне будет короче. Прога про перестановки не перле была на 20% короче.

> не умеющее, вернее это довольно сложно. Жаба тоже не умеет. Потомушто внутри своей собственной идеологии работает. Иногда это недостаток, а иногда наоборот.

Врешь. Есть gcj. Да и с сановской явой *.jar подключаются как misc_binaries очень легко. С лисповой так не получится.

> только вот ни по одному параметру к ним пока даже близко не подошли.

Врешь. *ML уж точно во многих областях (type inference, pattern matching) лиспа опередил уже десять лет назад.

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

> > А что, в LISP не так? Для реализации, например, двусвязного списка ты видоизменяешь CONS? Или таки строишь новый тип из примитивных?

> Именно так, я это и пытаюсь обяснить челу, который хотит секвенс, такой точно как стандартный, но с перламутровыми пуговицами...

"Именно так" - это крутой ответ на "альтернативный вопрос".

Если ты "видоизменяешь CONS" - делись травой. Если "строишь новый тип из примитивных" - где тут радикальное преимущество над С?

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

>Haskell по производительности - на уровне SBCL. Он статически >типизированный и прекомпилируемый в native. Был бы быстрее, если бы >у него был нормальный оптимайзер.

Haskell лично мне нравится. Никаких предубеждений против него нет, но он "ленивый", а "энергичные" языки все таки эффективнее ленивых. Так что не верю. В Haskell как ни пытался не нашел способ как сделать быструю работу с массивами. Вот Clean - это реально эффективная вещь (есть даже array comprehension), но писать GUI приложения как пишут на нем, заталкивая все в один вытянутый блок (хоть он малость и побит логически), нет никакого желания. Даже удивительно, что с таким убойным языком как Clean нет ни одной приличной GUI библиотеки. Наверное у него все еще впереди, как и Haskell.

>Да, но "метапрограммирование ненужно". В том смысле, что эти >проблемы решает малое количество людей один раз, и, в любом случае, >проектирование DSL - сильно более сложная задача, чем его >реализация (даже на С/yacc).

Это миф. Если DSL никако не интегрируется с host language, то это трудоемко и любые ошибки проектирования стоят очень дорого (путь C/yacc) Проектирование "малых" встраиваемых DSL в Lisp, Haskell, C++ (из того что я рельно видел) действительно оправдано и значительно упрощает решаемую задачу. Пример тому loop macro в Common Lisp, синтаксис в принципе не лисповый, но интегрируется с языком настолько хорошо, что считается хорошим стилем использовать именно loop, а не do,do* и т.п.

Потом без метапрограммирования невозможно сделать нечто подобное CELLS (и чтобы этим еще можно было также легко пользоваться), или приличный (но не обязательно тяжелый) фрэймворк для веб. программирования.

>Ну, вон, гтк к sbcl у кого-то тут подцепить не получилось. А, >скажем, к какому-нибудь cairo их вообще нету, небось.

Всякое бывает. Я например активно юзаю собтвенноручно сгенеренные баиндинги к OpenCV и нарадоваться не могу, очень удобная интеграция. Еще финализацию прикрутил, чтобы объекты c foreign кучи убивались сами, когда в них больше нет необходимости. Это в Lispworks, но SBCL в этом плане вроде ничем не отличается. Какие могут быть проблемы с баиндингами ? Надо конечно, чтобы в Лисп это удобно интегрировалось, кое что и завернуть в Лисп объекты неплохо, а мелочью и так рулить замечательно можно (например IplImage из OpenCV).

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

Не получится то же самое. Например лямбда в boost совершенно не то же самое, что в Лиспе. Тексты фильтров в Перле тоже не равны Лисповым макрам. Ну нигде такого сочетания функционала как в Лиспе не найти, хотя каких-то вещей конечно не хватает, например полный type inference чтоб алгебраическими типами крутить удобнее было, но в принципе это от незнания типичных лисповых способов делать то же самое. Ну иногда хочется, чтоб код со статической типизацией и объявлением типов, выглядел также красиво как с динамической, но не терять быстродействие, за счет макр это часто удается сделать.

>Я не утверждаю, что CL _хуже_, чем связка Perl/C++. Только то, что >он не настолько лучше, чтобы переход на него оправдал затраты >(имхо - так вообще не лучше).

Что тут сказать. Думайте сами, решайте сами... Не исключено, что попробовав и как следует прочувствовав все плюсы, Вам уже не захочется покидать Лисп из-за синергетики сочетания всех его функций (как мне) как бы притягательно не выглядели отдельные аргументы сторонников других языков. На comp.lang.lisp неоднократно предупреждали, что можно легко втянуться в Лисп окончательно, что ваша карьера Java или С++ программиста накроется медным тазом ;-)

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

>Haskell по производительности - на уровне SBCL. Он статически >типизированный и прекомпилируемый в native. Был бы быстрее, если бы >у него был нормальный оптимайзер.

Haskell лично мне нравится. Никаких предубеждений против него нет, но он "ленивый", а "энергичные" языки все таки эффективнее ленивых. Так что не верю. В Haskell как ни пытался не нашел способ как сделать быструю работу с массивами. Вот Clean - это реально эффективная вещь (есть даже array comprehension), но писать GUI приложения как пишут на нем, заталкивая все в один вытянутый блок (хоть он малость и побит логически), нет никакого желания. Даже удивительно, что с таким убойным языком как Clean нет ни одной приличной GUI библиотеки. Наверное у него все еще впереди, как и Haskell.

>Да, но "метапрограммирование ненужно". В том смысле, что эти >проблемы решает малое количество людей один раз, и, в любом случае, >проектирование DSL - сильно более сложная задача, чем его >реализация (даже на С/yacc).

Это миф. Если DSL никако не интегрируется с host language, то это трудоемко и любые ошибки проектирования стоят очень дорого (путь C/yacc) Проектирование "малых" встраиваемых DSL в Lisp, Haskell, C++ (из того что я рельно видел) действительно оправдано и значительно упрощает решаемую задачу. Пример тому loop macro в Common Lisp, синтаксис в принципе не лисповый, но интегрируется с языком настолько хорошо, что считается хорошим стилем использовать именно loop, а не do,do* и т.п.

Потом без метапрограммирования невозможно сделать нечто подобное CELLS (и чтобы этим еще можно было также легко пользоваться), или приличный (но не обязательно тяжелый) фрэймворк для веб. программирования.

>Ну, вон, гтк к sbcl у кого-то тут подцепить не получилось. А, >скажем, к какому-нибудь cairo их вообще нету, небось.

Всякое бывает. Я например активно юзаю собтвенноручно сгенеренные баиндинги к OpenCV и нарадоваться не могу, очень удобная интеграция. Еще финализацию прикрутил, чтобы объекты c foreign кучи убивались сами, когда в них больше нет необходимости. Это в Lispworks, но SBCL в этом плане вроде ничем не отличается. Какие могут быть проблемы с баиндингами ? Надо конечно, чтобы в Лисп это удобно интегрировалось, кое что и завернуть в Лисп объекты неплохо, а мелочью и так рулить замечательно можно (например IplImage из OpenCV).

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

Не получится то же самое. Например лямбда в boost совершенно не то же самое, что в Лиспе. Тексты фильтров в Перле тоже не равны Лисповым макрам. Ну нигде такого сочетания функционала как в Лиспе не найти, хотя каких-то вещей конечно не хватает, например полный type inference чтоб алгебраическими типами крутить удобнее было, но в принципе это от незнания типичных лисповых способов делать то же самое. Ну иногда хочется, чтоб код со статической типизацией и объявлением типов, выглядел также красиво как с динамической, но не терять быстродействие, за счет макр это часто удается сделать.

>Я не утверждаю, что CL _хуже_, чем связка Perl/C++. Только то, что >он не настолько лучше, чтобы переход на него оправдал затраты >(имхо - так вообще не лучше).

Что тут сказать. Думайте сами, решайте сами... Не исключено, что попробовав и как следует прочувствовав все плюсы, Вам уже не захочется покидать Лисп из-за синергетики сочетания всех его функций (как мне) как бы притягательно не выглядели отдельные аргументы сторонников других языков. На comp.lang.lisp неоднократно предупреждали, что можно легко втянуться в Лисп окончательно, что ваша карьера Java или С++ программиста накроется медным тазом ;-)

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

> ИМХО нельзя, или затруднительно. Придумай _небольшую_ задачу, для которой дсл было бы оправдано...

Ну вот, например, простейшая задача:

Есть связный лабиринт из квадратных полей, с одним входом. В лабиринте разбросаны вещи.

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

Ы?

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

>> в питоне одна всево, зато ужасная.

> Врешь. Уж не хуже лиспов, которые даже не все дистростроители собрать асиливают.

дык он оперативу освобождает ужо?

>> пока что приведённые здесь проги на питоне намного длиньше.

> Врешь. Они функциональнее, аналогичное по "наколенности" на питоне будет короче. Прога про перестановки не перле была на 20% короче.

Нащёт перла не знаю. Я так и не добился ответа как ей работать с списками из элементов произвольново типа а файловая так и не была представлена. Нащёт питоньих - файловая во много раз длиньше, а перестановок - незначительно длиньше по символам но намного запутаннее. Очевидно и делалась не пять минут как лисповая.

>> не умеющее, вернее это довольно сложно. Жаба тоже не умеет. Потомушто внутри своей собственной идеологии работает. Иногда это недостаток, а иногда наоборот.

> Врешь. Есть gcj. Да и с сановской явой *.jar подключаются как misc_binaries очень легко. С лисповой так не получится.

Это ты врёш, и сильно. Есь gcl. Да и с лиспом лиспопроги подключаются как misc_binaries ещё легче. Ты просто рассуждаеш о вещах о которых не имееш ни малейшево представления.

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

> Если "строишь новый тип из примитивных" - где тут радикальное преимущество над С?

Там же где для сей примитивные это указатели и байты, а для лиспа - списки и хеши. Если для большинства лисппрог новых типов строить безсмысленно, то на с/с++/питоне для более-менее сложной задачи с этого и приходицо начинать, изобретая лисапет сново и сново.

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

Это интересно, я видимо возьмусь чють пожжее. Я только сильно недопонял задачу. Ты предлагаеш управление роботом на человекоподобном языке?

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

> Не аналогично. При использовании Numeric Python мне не надо возиться с FFI. Вы вообще видели Numeric?

А чего там возиться? И Numeric - это top в числодроблении?

> Я до сих пор толком не понял, что это такое :/.

А, ну тогда у Вас ещё всё впереди ;)

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

> Блин, да я верю что в _лиспе_ нельзя обойтись без макр. Мне сомнительно что другие языки не могут без них обходиться.

В лиспе без макр маожно обходится точно так-же, как и в других языках. Вот как другие языки без них обходятся - не знаю ;)

> Ну давай 200. Приведи пример что я не смогу эффективно заменить макры чем либо другим и всё, я буду доволен. Вопрос для меня будет закрыт.

Ну, чуть по-больше: посмотри в sbcl реализацию external-format для потоков и строк

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

> Да, psyco cъест _любой_ питоний код, не любой ускорит, но _съест_ _любой_.

О, это уже кое-что ;) И давно это он так? Ладно, на досуге гляну.

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

> Врешь. *ML уж точно во многих областях (type inference, pattern matching) лиспа опередил уже десять лет назад.

Ага. Крик "Макры!" и эхом "CLOS! CLOS. CLOS..." ;)

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

>При использовании Numeric Python мне не надо возиться с FFI. Вы >вообще видели Numeric?

Да и к тому же специально для рассчетов Lush есть, кроме того, что он вероятно самый скорострельный из Лиспов (свободно можно писать код ворочающий любые матрицы и это будет работать так же шустро как в Си), он позволяет примешивать в любой пропорции сишный код прямо в текст на Лиспе, имеет готовые баиндинги ко всяким математическим (и не только) либам. Не так толст, как реализации CL. У него есть баиндинги к GUI библиотекам и SDL.

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

> Да, но "метапрограммирование ненужно". В том смысле, что эти проблемы решает малое количество людей один раз, и, в любом случае, проектирование DSL - сильно более сложная задача, чем его реализация (даже на С/yacc).

Ну а если DSL уже спроектирован? Благодаря этому топику сейчас исследую возможности генерации парсеров. То есть, в оригинале стояла задача некого обработчика (PL/)SQL. Одна лишь пустая грамматика, реализованная только на 2/3 на Эйфеле занимает порядка 10000 строк. Причем, больше половины правил -- это стандартная обработка списков с вариациями. Имена правил тоже однотипны, например, если есть правило reference, то почти наверняка нужны правила optional_reference, list_of_references и optional_list_of_field_references, первое -- для пропуска имени поля по умолчанию, второй и третий -- для (непустого и пустого) списков полей.

Далее, примерно 10%-ное заполнение действий для грамматики уже увеличило код до 14000 строк. При этом, например, в каждом правиле необходима стандартная обвязка типа if not <options.parse_only> then <действие> end. Кроме того, например, для списков, стандартное действие -- begin $$ := $1 $$.put_last($2) end. Прибавьте к этому жесткую типизацию правил, поэтому иногда приходится тыкать что-то вроде begin $$ := compound($1) $$.put_last($2) end, где в compound обернут кастинг типов и генерация объектов по нулевым ссылкам. Аналогичная история и с лексером, где во всех случаях разбора нужно выполнить один и тот же процедурный суффикс.

Ко всему следует добавить, что в Эйфеле нет разбиения класса на файлы, да и в yacc, насколько я помню, разбиение грамматики на несколько файлов требует особого использования препроцессора. А это дополнительный геморрой при организации процедуры сборки.

В общем, есть задняя мысль, что можно реализовать некую "ядерную" часть грамматики (предполагаю, что это 10-15% всего кода), из которой потом разворачивать полную (пусть даже и с лишними правилами), а для нее по неким шаблонам генерировать основные действия. Лет 5 назад, когда первый раз решал эту задачу (тогда для VHDL/Verilog), была идея реализовать что-то вроде YAGA/YAGG (Yet Another Grammar Analyzer/Generator), но когда понял, что на lex/yacc придется писать анализатор грамматики самого lex/yacc, возникло ощущение некого онан^Wдекаданса -- написание парсера ради парсеров. Сейчас есть идея свернуть SQL-грамматику в Лисп, а с него сгенерировать Эйфель-заточенное описание на Lex/Yacc. То есть, получаем хороший пример метапрограммирования (тут, кажется, кто-то хотел?), где целевой язык -- Lex/Yac/Eiffel, а последнее уже уходит в кроссплатформенный C. Впрочем, если заведется ecl, то и Эйфель можно будет выкинуть. Возможно, это и станет ядром YAGA.

Подозреваю, что у бугмакера процесс написания прог на С примерно так и организован?

> Ну, вон, гтк к sbcl у кого-то тут подцепить не получилось.

Справедливости ради стоит сказать, что таки получилось. Хотя, конечно, пока в стиле 1:1 и после некоторых плясок с бубном. Но запустить clsql по образцу оказалось уже проще.

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

Интересно, сколько в исходниках занимает ядро алхимии? В свое время пытался читать PyGTK (чтобы понять недокументированные возможности), быстро обломался.

> А, скажем, к какому-нибудь cairo их вообще нету, небось.

http://cairographics.org/cl_2dcairo

Правда, я его и в Питоне не юзал. Бо не знаю, для чего оно...

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

> Пожалуй, самой большой проблемой будет поиск авторов для включения патча в основную ветку.

После твоих достижений в освоении лиспа это даже читать смешно ;)

http://clsql.b9.com/ далее через мэйл-лист

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

> > специально для рассчетов Lush есть

> Коммерческий?

Не мужыки, вы добиваете... Это же один запрос к гуглу

http://lush.sourceforge.net/

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

> дык он оперативу освобождает ужо?

ДА! В 99.99999% случаев. Приведи реальный пример этих 0.00001%, когда он не освобождает память и это может привести к проблемам.

Сможешь привести пример, хорошо, если нет, то завязывай с этими воплями про память.

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

> ДА! В 99.99999% случаев.

согласишся ли ты юзать бучную батарейку, которая в 99.99999% случаев работает нормально а в оставшиеся взрываецо и жжыгает тебе йайтса?

> Приведи реальный пример этих 0.00001%, когда он не освобождает память и это может привести к проблемам.

там гдето выше я ссыло давал.

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

> Любой большой программный комплекс - сложен по определению.

Не всегда. Есть большие программные комплексы с регулярной структурой. Мы примерно такими занимаемся.

> А в языках с "настоящими" GC разрушение a и b произойдет неизвестно когда, и в непонятном порядке.

Я ж так и написал: вызывайте финализатор явно и будет Вам щасте. Если имеется ввиду, что сборщик мусора без Вашего ведома соберет объекты, дыкть, не теряйте на них ссылки и всего делов. Или в С/C++ утечка памяти менее страшна, чем непредсказуемая финализация?

> Соотвественно, заявление что

>> " В Эйфеле все exception являются safe."

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

Не совсем так. В Эйфеле, в отличие от других языков (кроме Ruby, разве что) не терминирующая, а возвратная модель исключений. Подпрограмма не может завершиться успешно, не выполнив контракт, посему в случае исключения автоматического освобождения локальных переменных не произойдет, и сборка мусора выполняться не будет. Можно в rescue освободить ресурсы так, как Вам нужно (в том числе синхронно и в правильном порядке, с помощью описанных Вами функций), а затем рестартовать выполнение подпрограммы по другому пути.

Так что, все Ваши проблемы вполне решаются и в Эйфеле и в Питоне. Разница в том, что в этих языках нужно прикладывать дополнительные усилия, чтобы организовать синхронную финализацию, в то время, как в С++ приходится тратить силы, чтобы организовать асинхронную. В моем опыте случаев первого типа раз в 1000 больше, чем второго (если честно, мне ни разу не пришлось контролировать финализацию, все требуемые случаи, например, с файлами и другими объектами ОС, знаю только по учебникам). Возможно, это различие в круге решаемых задач.

Кстати, если область решаемых задач узко заточена под СМО, то почему не используется Эрланг? У самого до него руки не дошли, но судя по отзывам -- самое оно для таких систем. Не знаю, как там обстоят дела с GC. Может, Вам подойдет?

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

> ECL? Но там много ещё чего "пилить" надо. Хотя может то, что надо "пилить", вам и не нужно. Смотрели?

Буду посмотреть.

>> Но вот можно ли быстро и элегантно генерить кроссплатформенный С-код из лисповских программ?

> GCC?

А шо GCC? Умеет из лиспа на входе получить С на выходе?

>> А было бы вкусно.

> Не было бы вкусно. Ибо потеряли бы как раз много лисповых вкусностей. (К примеру, у того-же ECL не _любой_ код, который нормально компилируется, может выполниться в REPL :( А так может когда-нибудь и будет такая возможность.

И это плохо :-(. Похоже, пока потренируюсь с промежуточным решением на Эйфеле.

> Или берите коммерческие версии.

На Just for fun не хочется тратить свои кровные. Лучше новый наладонник за те же деньги куплю.

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

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

Прикольно. Только у меня предложение. Не через консоль, а через TCP/IP, т.е. есть сервер с сотоянием мира, к нему по TCP/IP цепляется клиент и получает карту мира в какой-либо форме, посылает комманду и получает в ответ новое состояние мира.

Таким образом можно будет сделать клиента просто с выводом в stdout, c curses и даже с GUI или с веб-мордой :-)

Команды это передвижение и взять / положить. Игра заканчивается когда все предметы лежат на выходе.

В зачёт идёт код сервака, человеческого клиента и код бота.

Человеческий клиент в зачёте с выводом в stdout

Lisper-ы, ну как?

Может вообще устроить LOR language shootout?

Только сразу условие, если победит не лисп, то вы прекратите распространять FUD про другие языки, OK?

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

> когда первый раз решал эту задачу (тогда для VHDL/Verilog)

А если не секрет, то что вы с VHDL делали?

> Интересно, сколько в исходниках занимает ядро алхимии?

    653 ./sqlalchemy/ansisql.py
    519 ./sqlalchemy/attributes.py
    271 ./sqlalchemy/databases/firebird.py
    183 ./sqlalchemy/databases/information_schema.py
    492 ./sqlalchemy/databases/mssql.py
    292 ./sqlalchemy/databases/mysql.py
    337 ./sqlalchemy/databases/oracle.py
    374 ./sqlalchemy/databases/postgres.py
    280 ./sqlalchemy/databases/sqlite.py
      8 ./sqlalchemy/databases/__init__.py
    878 ./sqlalchemy/engine.py
     43 ./sqlalchemy/exceptions.py
    192 ./sqlalchemy/ext/activemapper.py
    121 ./sqlalchemy/ext/proxy.py
    182 ./sqlalchemy/ext/sqlsoup.py
      1 ./sqlalchemy/ext/__init__.py
    979 ./sqlalchemy/mapping/mapper.py
    359 ./sqlalchemy/mapping/objectstore.py
    980 ./sqlalchemy/mapping/properties.py
    275 ./sqlalchemy/mapping/query.py
    129 ./sqlalchemy/mapping/sync.py
    348 ./sqlalchemy/mapping/topological.py
    857 ./sqlalchemy/mapping/unitofwork.py
     31 ./sqlalchemy/mapping/util.py
    174 ./sqlalchemy/mapping/__init__.py
     86 ./sqlalchemy/mods/selectresults.py
      6 ./sqlalchemy/mods/__init__.py
    296 ./sqlalchemy/pool.py
    644 ./sqlalchemy/schema.py
   1491 ./sqlalchemy/sql.py
    202 ./sqlalchemy/types.py
    468 ./sqlalchemy/util.py
     22 ./sqlalchemy/__init__.py
  12173 total

Но решает то она обратную задачу, не парсить SQL, а генерировать его

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

> Нет, не коммерческий и Open Source. Ссылка только что выше была.

Не нашел ссылку :-(. Можно еще раз?

Ага, наш топик, открытый целиком, уже валит CMS ЛОРа (java.lang.OutOfMemoryError). Я им отписал, так что ждите, щас модераторы заявятся. ;-)

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

> там гдето выше я ссыло давал.

Аффтар той телеги мудак. Проблема надуманная и её не существует, в кратце суть его проблемы "питон плахой бууу, сделал бобу маленькому праграмисту, ааааа"

Приведи свой пример.

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

>> Да, psyco cъест _любой_ питоний код, не любой ускорит, но _съест_ _любой_.

> О, это уже кое-что ;) И давно это он так? Ладно, на досуге гляну.

Давно. Хуже того проект полностью стабилен, т.е. у автора нет ничего в TODO и нет открытых багов.

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

> Приведи реальный пример этих 0.00001%, когда он не освобождает память и это может привести к проблемам.

Чаще, чем ожидается. Я закинул этот пример в PythAgora. Тема вызвала интерес, например,

> интересно наблюдать на примере pyGTK работу сборщика мусора, когда есть 20 TreeView в них выводится содержимое файла и память разрастается до 200мб, после чего делаем очистку послей-память ~140mb, через минуты 2-3 память = 8 мб =) интересно бы почитать о принципах работы gc в питоне.

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

Задачю я всё ещё недопонял.

> Только сразу условие, если победит не лисп, то вы прекратите распространять FUD про другие языки, OK?

не, непойдёт. питон то ужо неоднократно проигрывал, проиграет и на этот раз, я совершенно в этом уверен. Тем не менее я считаю это условие несправедливое и несоглашаюсь.

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

> А если не секрет, то что вы с VHDL делали?

Ну конкретно в тот момент это был генератор VHDL-описания аппаратных приблуд в промежуточный формат для дальнейшего синтеза/симуляции.

> Но решает то она обратную задачу, не парсить SQL, а генерировать его

Видимо, Вы тоже пропустили: CLSQL тоже предназначен для генерации. Просто у меня сейчас 2 параллельных проекта (если не сказать больше), в одном из них нужен биндинг для работы с базой, а во втором -- парсер SQL.

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

> Я например активно юзаю собтвенноручно сгенеренные баиндинги к OpenCV

Я работал с OpenCV года полтора назад и юзал питоновские байнидинги, которые шил в комплекте, но потом обнаружилось что байндинги не полные и вряд-ли когда будут полные, т.к. в C API они предлагали использовать касты и пойнтерную фрифметику, и для бедного SWIG-а это было через чур.

Ты не сталкивался с такой проблемой? И как с ней боролся?

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

> А шо GCC? Умеет из лиспа на входе получить С на выходе?

Зыть, опечатка - GCL имелся в виду

В любом случае - и ECL и GCL будут генерить код с "поправкой на ветер", т.е. с опорой на своё ядро. Делать из этого бинари - запросто, а вот использовать отдельно - врядли. Или такая задача не ставилась?

> И это плохо :-(. Похоже, пока потренируюсь с промежуточным решением на Эйфеле.

Ну, ты сам себе хозяин. Но ECL посмотри - неплох. Да, Lush я пока не ковырял - ничего сказать не могу.

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

> Прикольно. Только у меня предложение. Не через консоль, а через TCP/IP, т.е. есть сервер с сотоянием мира, к нему по TCP/IP цепляется клиент и получает карту мира в какой-либо форме, посылает комманду и получает в ответ новое состояние мира.

Угу. А если правила еще чуток усложнить, то получится Space Trek (Космический Лабиринт), в который мы баловались в пору нашей олимпиадной юности :-).

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

> На Just for fun не хочется тратить свои кровные. Лучше новый наладонник за те же деньги куплю.

А их там тем или иным способом можно использовать бесконечно. Хотя конечно - ну его... :)

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

>Lisper-ы, ну как?

А прикольная мысля. Только бот надо чтоб на сервер закачивался и задачу там автономно решал, команды бота на спец. DSL пишутся, сервер и язык наращивается прямо на ходу, т.е. перезапускать сервер нельзя. Текущие параметры бота отображаются через TCP/IP на консольном клиенте в любом удобном виде. У кого бот будет шустрее решать задачу и в языке для бота будет больше возможностей, тот победил.

>Только сразу условие, если победит не лисп, то вы прекратите >распространять FUD про другие языки, OK?

ОК. Аналогичная просьба нелюбителям Лиспа.

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

> Только сразу условие, если победит не лисп, то вы прекратите распространять FUD про другие языки, OK?

"Стоять, Зорька!" Т.е. наши ответы на ваши вопросы "А чем лисп лучше XYZ? А я могу вот так да вот так - а вы что можете? А я не знаю - нафиг мне это ннадо?" - это FUD про другие языки? Зыть, где выход - вы знаете...

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

Точнее: текущие параметры бота, лабиринта, прогресс в решении задачи выноса вещей отображаются на клиенте (сойдет и консольный, но можно и c GUI). Еще можно добавить, чтобы сервер при обновлении обновлял на клиенте представление параметров (т.е. обновлял сразу клиента до нужной версии) и чтобы документацию по текущей версии DSL с сервера можно было получить при подключении или в ходе работы.

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

> Не через консоль, а через TCP/IP, т.е. есть сервер с сотоянием мира, к нему по TCP/IP цепляется клиент и получает карту мира в какой-либо форме, посылает комманду и получает в ответ новое состояние мира.

Может достаточно "изменений в мире"? А то весь мир может быть довольно большим.

> Команды это передвижение и взять / положить. Игра заканчивается когда все предметы лежат на выходе.

Ещё: мир трёхмерен; у бота/игрока нет карты (но у бота может быть память), дальность видимости задаётся; лабиринт не идеальный - т.е. используя только правило левой/правой руки его не обойти...

> В зачёт идёт код сервака, человеческого клиента и код бота.

А ещё генерация лабиринтов и распределение вещей в (псевдо-)случайном порядке.

> Lisper-ы, ну как?

Гы-гы, только после вас ;)

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

>Ты не сталкивался с такой проблемой? И как с ней боролся?

Нет, не было никаких сложностей. Я в препроцессор Lispworks кинул его заголовки и сразу получил баиндинги практически на всю библиотеку. Правда часть функционала я все таки руками довожу, чтобы было получше с Лиспом интегрировано, всякие там финалайзеры на объекты, енумераторы удобные и т.п. в итоге получается нечто вроде спец. языка для отслеживания объектов в реальном времени:

(with-objects (x y angle size) (map-ellipses my-image) ;; делаем что-то с координатами углом наклона и размером ;; очередного эллипса t) ;; вернуть t для продолжения перечисления, nil для завершения

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

Блин про форматирование снова забыл :-(

(with-objects (x y angle size) (map-ellipses my-image) 
       ;; делаем что-то с координатами углом наклона и размером 
       ;; очередного эллипса 
t) ;; вернуть t для продолжения перечисления, nil для завершения 

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

>Ещё: мир трёхмерен; у бота/игрока нет карты (но у бота может быть >память), дальность видимости задаётся; лабиринт не идеальный - т.е. >используя только правило левой/правой руки его не обойти...

Ну это уже слишком, хотя не очень трудно с OpenGL визуализатор запузырить, но время у всех не резиновое, еще работать надо.

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

>> там гдето выше я ссыло давал.

> Аффтар той телеги мудак. Проблема надуманная и её не существует, в кратце суть его проблемы "питон плахой бууу, сделал бобу маленькому праграмисту, ааааа"

> Приведи свой пример.

небуду. Для этого сперва нужно выучить недоделатый тормозной излишне замысловатый езык с карявым синтаксисом, имеющий траблы с освобождением оперативы и сообшество которого называет мудаками тех, у кого на реальных задачях при использовании на ровном месте вылазиют траблы, которых почемуто нету у хеловордов, вместо того чтобы отрешать. А на то, что я это всё буду делать ради чтобы пофлеймить лишний раз, сам понимаеш, никаких шансов нету...

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

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

Вместо 3D к вышеперечисленным вещам лучше добавить, что язык для бота должен позволять ему генерировать программы для самого себя и исполнять, например можно эволюционно совершенствующийся бот создать или reinforcеment learning заложить. Опционально реализовать сообщества ботов, т.е. чтобы несколько штук по лабиринту ходили и помогали друг другу совершенствоваться.

Хватит пожалуй ;-)

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

Угу. Можно и без 3D. Только это - боту/игроку поступает не инфа о всём мире, а только видимая область - и передавать много не надо, и боты-ясновидящие в пролёте ;)

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

Естественно, что код для бота должен быть безопасным в смысле, что он напрочь должен быть отрезан от файловой системы, сети и т.д., должен быть только интерфейс для общения с движком лабиринта и может быть для выдачи каких-то отладочных сообщений на клиента и обратно.

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

>Угу. Можно и без 3D. Только это - боту/игроку поступает не инфа о >всём мире, а только видимая область - и передавать много не надо, и >боты-ясновидящие в пролёте ;)

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

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

Прикольно. В языке бота сразу же будут доступны все управляющие конструкции Лиспа + макросы, т.е. почти весь Лисп (даже CLOS) за исключением IO, многопоточности и т.п.

Сервер должен проверить, что код не содержит запрещенных конструкций. Если туда запузырить для интерпретации исходник, например на Перле, Питоне или PHP (про C++ страшно подумать), то возникает задача анализа кода на содержание запрещенных вызовов. Верю, что она должна иметь какое-то несложное решение на этих языках. Для примера на Лиспе это получается так - что не положишь в пакет, того и не будет в языке.

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

> Это ты врёш, и сильно. Есь gcl.

gcl уже реализовал ANSI Common Lisp?

>Да и с лиспом лиспопроги подключаются как misc_binaries ещё легче.

Это правда только для тех программ, которые можно пондять из core каким-то стандартным eval-ом с командной строки. Для Java инвокация стандартизована, для CL - нет.

> Ты просто рассуждаеш о вещах о которых не имееш ни малейшево представления.

Ну, как и ты ;)

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

> Там же где для сей примитивные это указатели и байты, а для лиспа - списки и хеши.

Врешь. Список - да, хеш - нет. И вообще, список - это не совсем уж "примитивный" тип. Примитивный - это символ и cons cell.

А если брать стандартную библиотеку - то у C++ она, как минимум, не беднее. Хешей там нету, правда - только упорядоченные ассоциативные контейнеры - но это и ни разу не "кучи байтов".

> Если для большинства лисппрог новых типов строить безсмысленно, то на с/с++/питоне для более-менее сложной задачи с этого и приходицо начинать, изобретая лисапет сново и сново.

Про то, что типы, отражающие предметную область - это плюс, а не минус, тебе рассказывали уже раз 15. Но ты этого не слышишь, а зря...

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

> Это интересно, я видимо возьмусь чють пожжее. Я только сильно недопонял задачу. > Ты предлагаеш управление роботом на человекоподобном языке?

Нет. adventure видел?

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

:nothing here :you may go south :you may go west west :you wen west :Item_A lies here :you may go east :you may go west north :you hit the wall :Item_A lies here :you may go east :you may go west take Item_A :you are full :Item_A lies here :you may go east :you may go west drop :you dropped Item_B :Item_B lies here :Item_A lies here :you may go east :you may go west pick Item_A :you picked up Item_A :Item_B lies here :you may go east :you may go west

Ну и так далее. Парсить подобный вывод - несложно, командовать такой прогой - тоже.

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

> > Врешь. *ML уж точно во многих областях (type inference, pattern matching) лиспа опередил уже десять лет назад.

> Ага. Крик "Макры!" и эхом "CLOS! CLOS. CLOS..." ;)

type inference для примитивных типов на макрах, с реализацией generic алгоритмов? Ню-ню. Это разве вообще возможно?

CLOS в качестве замены pattern matching в Haskell/OCaml? НТам можно специализировать генерик на константу? Можно сказать "для пустых списков - так, для единичной длины - сяк, для более длинных - эдак"?

А покажи, я, может, передумаю.

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

> > Да, но "метапрограммирование ненужно". В том смысле, что эти проблемы решает малое количество людей один раз, и, в любом случае, проектирование DSL - сильно более сложная задача, чем его реализация (даже на С/yacc).

> Ну а если DSL уже спроектирован? Благодаря этому топику сейчас исследую возможности генерации парсеров. То есть, в оригинале стояла задача некого обработчика (PL/)SQL.

[skip lots of handwaving]

Если я ничего не путаю, для ANTLR есть готовая грамматика SQL92. Пускай он вам parse tree сделает, и уже из него генерите, что хотите, "деревянными" трансформациями (опустились до листьев сверху, наренерили наследуемых атрибутов, поднялись обратно - собрали вычисляемые).

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

> Я ж так и написал: вызывайте финализатор явно и будет Вам щасте.

Не будет. Я не хочу "вызывать финализатор явно", я хочу стековой дисциплины. Дабы вереницу try/catch не городить (а иначе довольно трудно вызвать финализатор, словив исключение уровней так на пять выше)ю

> Если имеется ввиду, что сборщик мусора без Вашего ведома соберет объекты,

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

Поэтому финализаторы в garbage-collected языках, имхо, абсолютно бесполезны - привязывать к ним "счетно-конечные" ресурсы бесполезно по перечисленным выше причинам, а пямять - ну, она и так освободится. Разве что деаллокацию FFI-объектов можно делать - да и то только если их не конечный пул.

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

Ну вы блин демагогии развели из примитивного предложения написать кастрированный клон adventure и A* pathfinder.

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

> Прикольно. В языке бота сразу же будут доступны все управляющие конструкции Лиспа + макросы, т.е. почти весь Лисп (даже CLOS) за исключением IO, многопоточности и т.п.

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

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

>> Это ты врёш, и сильно. Есь gcl.

> gcl уже реализовал ANSI Common Lisp?

не. а gcj полностью совместимый с саньей жабой?

>> Да и с лиспом лиспопроги подключаются как misc_binaries ещё легче.

> Это правда только для тех программ, которые можно пондять из core каким-то стандартным eval-ом с командной строки. Для Java инвокация стандартизована, для CL - нет.

http://www.cons.org/cmucl/doc/executable.html

рекомендация для cmucl, но там нету ни слова ни про core ни про eval, и нету никаких причин почему бы с другими незаработало бы.

>> Ты просто рассуждаеш о вещах о которых не имееш ни малейшево представления.

> Ну, как и ты ;)

но ведь это ты неуклюже пытаесся уличить мя в вранье

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

>> Там же где для сей примитивные это указатели и байты, а для лиспа - списки и хеши.

> Врешь. Список - да, хеш - нет.

не, эт ты врёш. Смотри в стандарте чё пишут http://www.lisp.org/HyperSpec/Body/chap-18.html

> И вообще, список - это не совсем уж "примитивный" тип. Примитивный - это символ и cons cell.

ну уж какой есь. Может быть следовало сказать "встроенный" но поскольку он всёодно не построен средствами лиспа из остальных ево типов, можно сказать чё и примитивный тоже, да. А в сях полюбому ево нужно делать вручную из структурок/укозателей/массивов/всево прочево. В питонос++ тоже. Хоть там кирпичики покрупнее, но средствами языка настолько же неудобно с ними, списками, там работать ибо непредназначены.

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

>> Это интересно, я видимо возьмусь чють пожжее. Я только сильно недопонял задачу. Ты предлагаеш управление роботом на человекоподобном языке?

> Нет. adventure видел?

> в духе (строки, начинающиеся на ":" - приглашение "игры", остальное - ввод пользователя):

аха, понятно. Я какраз щяс в области примерно где MUD (для модераторов: это не птичько но всёодно не то что вы подумали), и запощеный здесь сервяк для похожей был, хоть чисто отладочный.

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

> А если брать стандартную библиотеку - то у C++ она, как минимум, не беднее. Хешей там нету, правда - только упорядоченные ассоциативные контейнеры - но это и ни разу не "кучи байтов".

Только работать с ими карявенько. Отлистай вверьх, тамо с++ прого на полверсты, а лисповая аналог три строчки. Потому что сам йазыг приспособлен с кучками байтоф работать.

>> Если для большинства лисппрог новых типов строить безсмысленно, то на с/с++/питоне для более-менее сложной задачи с этого и приходицо начинать, изобретая лисапет сново и сново.

> Про то, что типы, отражающие предметную область - это плюс, а не минус, тебе рассказывали уже раз 15. Но ты этого не слышишь, а зря...

Дык, это вроде наоборот, пипл нащёт DSL догнать неможет, где не токо типы но и йазыг предметую облась отражает. Мне то чё объяснять? Если ты щитаеш обекты "типами, отражающими предметную область" дык, бугога, в лиспе их навалом можно наворотить _при_желании_ только как оказываецо не так уж чясто с ними луче.

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

> Ну вы блин демагогии развели из примитивного предложения написать 
> кастрированный клон adventure и A* pathfinder.

Да, друзья, вы тут предложений накидали уже на убийцу CS и WoW 
одновременно, а я то и TCP/IP предложил использовать чтобы не писать \
парсер вывода лабиринта.

Какие-то боты работающие на сервре, программирование AI на DSL, вы бы 
уж сразу предложили написать интерпритатор лиспа. На лиспе это 
сделать будет явно проще чем на всём остальном, кажется в первом 
сообщении сказано что достаточно 15 строк ;-)

Предложение такое:

1. Сервер при запуске принимает имя файла с картой такого вида:

##########
#  # $ # #
#$ #     .
#     #  #
##########

# - стена
$ - предмет
. - вход

2. Сервер понимает следующие комманды

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

perform_action() - выполняет действие. Возможные действия:
  north  - перейти на одну клетку на север
  west   - перейти на одну клетку на запад
  south  - перейти на одну клетку на юг
  east   - перейти на одну клетку на восток
  pickup - поднять предмет в текущей клетке
  drop   - бросить переносимый предмет в текущей клетке

В случае если предлагают совершить невозможное действие, например
поднять предмет, если в инвенторе уже есть предмет, или встать на
клетку со стеной, то команда игнорируется.

3. Игра заканчивается если все предметы в мире лежат на клетке входа

4. Требуется написать:

  4.1. Сервер, процесс который при старте считывает карту мира и
    слушает какой-то порт по TCP/IP и обслуживает запросы приходящие
    по этому порту. Запуск: advserve world.dat 7766
 
  4.2. Клиента для человека, который цепляется к серверу,
    считвает состояние мира, отображает эту информация, ждёт ввода
    комманды и передаёт её серверу. Вывод идёт в stdout, т.е. просто
    старое состояние уползает вверх, на его место вылазит новое.

    Пример вывода:
      
    ##########
    #  # $ # #
    #$ #    @.
    #     #  #
    ########## 
    Game is in progress
    You carry an item
    Here lies 1 item(s)
    > [место для ввода комманды]
    
    @ - персонаж, если на одной клетке находится персонаж и что-то
    ещё, то отображается персонаж:

    ##########
    #  #   # #
    #  #     @
    #     #  #
    ########## 
    You won!
    Your hand are empty
    Here lies 3 item(s)
    > [место для ввода комманды]

    ##########
    #  #$  # #
    #$ #   @ .
    #    $#  #
    ########## 
    You won!
    Your hand are empty
    Here lies 0 item(s)
    > [место для ввода комманды]

    Пример запуска: hclient 127.0.0.1 7766

  4.3. Клиента робота, который должен выиграть игру. В процессе игры
    на экране отображается состояние мира как для человеческого
    клиента, только нет приглашения для ввода комманды

    Пример запуска:  roboclient 127.0.0.1 7766

5. Сравнивается краткость, компактность и концептуальность :-)
  исходных текстов всез трёх программ.

Вот такое предлоджение.

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

yyk, ну как эта задача достаточно большая чтобы макры проявили себя
во всей красе?

Ну кто-нибудь из лисперов берётся? А то получится что я напишу, а мне
потом скажут: "не, мы не написали, но если бы написали, то получилось
бы в 3, нет в 10 раз короче".

В принципе, приветствуются решения на Haskell OCaml и hq9+

На С++ можно и не писать, лично мне и так понятно что получится,
получится примерно то-же самое что и на питоне, но с учётом 
ограничений статической типизации.

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

>вовсе нет, с чево бы? При желании можно но луче не надо

Почему нет ? Прекрасная демонстрация очень полезной возмозможности.

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

> Только работать с ими карявенько. Отлистай вверьх, тамо с++ прого
> на полверсты, а лисповая аналог три строчки. Потому что сам йазыг 
> приспособлен с кучками байтоф работать.

Bugmaker, ты врёшь.

Программа c файлами без БД:

язык    не пустрых строк   непробельных символов
------------------------------------------------
Lisp       12                      434
Python     17                      420
С++        41                      863

Программа с БД, кстати, ты слил её написать, написал её таки eugene_kosenko

язык    не пустрых строк   непробельных символов
------------------------------------------------
Lisp       58                      1519
Python     52                      1612
Python(*)  52                      1408

Python (*) это версия где написано "from sqlalchemy import *"
вместо import sqlalchemy, что ближе к лисповой семантике импорта,
насколько я понимаю.

Имхо, главный размер это количество непробельных символов, т.к.
в C++ очень много строк вида "}"

На простой программе (без БД), лисп слил питону, и выиграл у C++
всего в два раза, но C++ и не претендует на
сверхкомпактность и абстракции высокого уровня.

На более сложной программе лисп слил питону и по строкам и по
символам.

На shootout-e лисп сливает С/C++ по скорости и питону по компактности.

И где здесь радикальное преимущество лиспа над "недоязыгами", о
котором ты все уши прожужжал?

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

> А зачем тут DSL ?

Дык я о том же. Нафиг тут DSL? Просто тут уже начались разговоры о DSL об AI о космических кораблях бороздящих просторы большого театра, короче о том чтобы свести эту задачу к трёпу и ничего не писать :-)

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

> На более сложной программе лисп слил питону и по строкам и по символам.

Сделайте в Лисп-программе поправку на новичка. Кроме того, там одна функция -- лишняя, плюс две строки на включение трассировки и комментарий к ним. Так что, если это учесть, то получится паритет.

Кроме того, я совершенно не ожидал, что проги будут мерять по числу символов и строк. Я бы тогда некоторые вещи записал еще компактнее, а имена сделал бы еще короче. Как говорится, нет предела совершенству.

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

>Дык я о том же. Нафиг тут DSL? Просто тут уже начались разговоры о >DSL об AI о космических кораблях бороздящих просторы большого >театра, короче о том чтобы свести эту задачу к трёпу и ничего не >писать :-)

Ну вообще-то метапрограммирование к созданию DSL не сводится. Насчет описанной задачи с закачиваемым ботом и всякими AI штуками, почему бы и нет ? Если это на Лиспе реализовать легче, то что тогда труднее ? Кодеки и драйверы ? Разница только в том, что алгоритм закачивается и работает прямо на сервере, клиентский бот не требуется, только клиент для просмотра текущего состояния и закачки ботов на сервер. А эта странная задача с каким-то человекочитаемым, но достаточно формальным языком малость скучновата. Прочем тут тогда разговоры о метапрограммировании и т.п. ?

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

> На более сложной программе лисп слил питону и по строкам и по символам.

И еще, в самом корректном случае нужно мерять не по строкам или символам, а по количеству конструкций языка. У Питона это совпадает со строками, но у С/С++ нужно мерять (если грубо) по количеству символов ';', а в Лиспе -- по количеству пар круглых скобок (можно посчитать только открывающие и только закрывающие.

Замеряем таким образом?

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

> Ну кто-нибудь из лисперов берётся?

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

В порядке уточнения: в одной клетке может лежать несколько предметов (см. п. 3)? Если может, то как это показывается на карте?

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

> Кроме того, я совершенно не ожидал, что проги будут мерять по числу символов и строк. Я бы тогда некоторые вещи записал еще компактнее, а имена сделал бы еще короче. Как говорится, нет предела совершенству.

Собственно я тоже. Писал как пишу обычно. И имена у меня нормальные (metadata, filedb) и т.д.

Собственно мне лисповая прога с БД очень даже понравилась, т.е. лисп позвоялет писать программы по компактности сравнимые с питоном, но при этом компилирующиеся в маш.код.

Чего я в упор не вижу, так это этих загадочных абстракций высокого порядка, которых нет в других языках.

И bugmaker постоянно кричит что лисповый код в десятки раз компактнее, чего ну никак не наблюдается. Вот эти замеры строк и байтов в первую очередь для него.

Тут ему уже предлагали на спор померяться по компактности с Perl-oм, он не стал. Я бы поставил на Perl :-)

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

> В порядке уточнения: в одной клетке может лежать несколько предметов (см. п. 3)? Если может, то как это показывается на карте?

Может. Не покажется никак, в начальной карте каждый предмет лежит в своей клетке, человек догадается, а робот непосредственно прочитает из структуры мира с сервера.

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

> Насчет описанной задачи с закачиваемым ботом и всякими AI штуками, почему бы и нет ? Если это на Лиспе реализовать легче, то что тогда труднее ? Кодеки и драйверы ? Разница только в том, что алгоритм закачивается и работает прямо на сервере, клиентский бот не требуется, только клиент для просмотра текущего состояния и закачки ботов на сервер

Ради бога. Хоть WoW пиши. Я реально не могу и не хочу потратить на эту прогу всю жизнь.

То вариант что предлагаю я, можно написать за день. Я готов этот день потратить на написание такой проги.

Это явно уже не hello-world, так что если лисп настолько крут, докажите.

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

Я думаю что все кто может это реально написать, работают программистами, и у всех есть что писать на работе. И время у людей вобщем-то стоит денег.

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

> (а иначе довольно трудно вызвать финализатор, словив исключение уровней так на пять выше)

В Эйфеле обработка всех исключений жестко привязана к подпрограммам: это требование контрактного проектирования. Поэтому на пять уровней выше у Вас по любому уже не будет доступа к тем переменным, о которых Вы на этом уровне даже не догадываетесь. Либо финализируйте их явно на нижних уровнях, либо положитесь на GC. Как всегда, у Вас есть выбор.

> Имеется ввиду, что между потерей последнего указателя на нечто и финализацией пройдет неопределенный промежуток времени.

Пишу по буквам: вызывайте финализатор явно _до_ потери указателя. Какое из слов непонятно? Если все слова понятны, то обратите особое внимание на подчеркивание.

> И если я в финализаторе буду, скажем, закрывать файл - то мне дадут по ушам и скажут "твоя прога дескрипторами течет".

Блин, какая религия запрещает создать объект-обертку вокруг дескриптора, который будет иметь специальный метод для закрытия файла. Вызывайте этот метод там, где у Вас на C++ полагается писать delete, а уничтожение пустой обертки оставьте сборщику мусора. Чем этот вариант не устраивает?

> Поэтому финализаторы в garbage-collected языках, имхо, абсолютно бесполезны

Кстати, еще вчера хотел добавить: ключ -no_gc при компиляции в Эйфеле никто не отменял. Ибо, как написано в самой документации, "This option is useful when one prefers to use another GC provided by an external library (such as the Boehm-Demers-Weiser conservative GC), or when no GC is needed". Как говорится, специально для Вас. Аналогично, сборщик мусора можно принудительно отключить на любом сколь угодно критическом участке программы и использовать явную деаллокацию. То же самое можно сделать в Питоне.

> привязывать к ним "счетно-конечные" ресурсы бесполезно по перечисленным выше причинам

Вообще говоря, может быть, перейдем от спора на уровне сферических коней к чему-то более конкретному? Опишите точнее ситуацию, где GC сосет (в частности, где требуется стековая дисциплина, крутые обработчики исключений и "счетно-конечные ресурсы"), а я попробую элегантно решить эту проблему на Эйфеле. Чтоб не флудить, можно поболтать на эту тему по почте. eugine dot kosenko at gmail dot com.

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

> Если я ничего не путаю, для ANTLR есть готовая грамматика SQL92.

Во-первых, для Эйфеля нет "родного" ANTLR. А сшивать их на уровне C -- занятие не для слабонервных. А во-вторых, ANTLR существенно проигрывает по скорости компиляции YACC. На объемах в 5-10 тысяч строк это хорошо заметно.

Говорю не от балды: пробовал ANTLR лет 5 назад, именно в этом контексте.

> Пускай он вам parse tree сделает, и уже из него генерите, что хотите, "деревянными" трансформациями (опустились до листьев сверху, наренерили наследуемых атрибутов, поднялись обратно - собрали вычисляемые).

Гладко было на бумаге...

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

> Я готов этот день потратить на написание такой проги.

Лично для меня проблема в поведении робота. Если бы я знал алгоритм, то, может быть, тоже смог бы написать за день. Собственно, я бы сначала посмотрел на питонью реализацию, а потом попробовал бы собезьянничать на Лиспе. С учетом специфики.

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

> type inference для примитивных типов на макрах, с реализацией generic алгоритмов? Ню-ню. Это разве вообще возможно?

Можно компилятор, работающий с макрами и "с реализацией generic алгоритмов" научить нормально работать с типами ;)

> Там можно специализировать генерик на константу?

На константу в понимании лиспа? Да.

> Можно сказать "для пустых списков - так, для единичной длины - сяк, для более длинных - эдак"?

А как ты будешь на этапе компиляции определять длинну списка из переменной? А так - как обычно - анализом внутри метода, обрабатывающего списки.

> А покажи, я, может, передумаю.

Не буду я тебе ничего показывать. Понадобится - сам найдёшь.

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

> Лично для меня проблема в поведении робота.

В детстве, когдя я шарахался по всяким олимпиадам, нас научили одному грязному трюку :-) Называется "волновой алгоритм" http://www.codenet.ru/progr/alg/way.php http://algolist.manual.ru/games/wavealg.php

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

redvasily
()
Ответ на: комментарий от redvasily

> Чего я в упор не вижу, так это этих загадочных абстракций высокого порядка, которых нет в других языках.

И не увидите, если не погрузитесь в это. Обратите внимание на использование квадратных скобок для конструирования запросов. В Питоне для этого нужно использовать форматный вывод (что можно и в Лиспе), но это примерно в 1.5 раза длиннее и не так понятно. Считайте это неким мини-DSL в виде псевдо-SQL. Со стороны это кажется тривиальным (как и все в Лиспе), но когда пишешь -- серьезно помогает.

Кроме того, похоже, что у Питона намного больше спрятано "под коврик", чем у Лиспа.

eugine_kosenko ★★★
()
Ответ на: комментарий от redvasily

> В детстве, когдя я шарахался по всяким олимпиадам, нас научили одному грязному трюку :-) Называется "волновой алгоритм"

Ну, метод "роты солдат" мы тоже на олимпиаде проходили :-). Я просто думал, что мне засчитают фол за такое использование -- ведь предполагается, что робот будет только один :-). Кроме того, я думал, что с тех пор придумали что-то более продвинутое.

Ну ладно, раз с алгоритмом определились, то можно и попытаться.

Еще вопрос: зачет личный или командный?

eugine_kosenko ★★★
()
Ответ на: комментарий от redvasily

>Чего я в упор не вижу, так это этих загадочных абстракций высокого >порядка, которых нет в других языках.

А тут ножик Окама срабатывает, нафига в трех строках лишние сущности. Ну и потом сам Лисп на Лиспе и написан, поэтому многие абстракции (не такие уж высокие) просто не видны, так как выглядят естественно.

Вот если нечто вроде CELLS взять, то преимущества этих абстракции будут видны невооруженным глазом.

anonymous
()
Ответ на: комментарий от redvasily

> yyk, ну как эта задача достаточно большая чтобы макры проявили себя во всей красе?

Если ваш код на питоне будет >200 строк - да :)

yyk ★★★★★
()
Ответ на: комментарий от redvasily

> На shootout-e лисп сливает С/C++ по скорости и питону по компактности.

Ты не с той стороны смотришь (даже если полностью согласиться с твоими выводами - но это оставим на твоей совести): лисп (почти) выразителен как питон и быстр как с++ :)) А ещё все вкусности лиспа...

Хотя лично я за такое выражение убил бы ;)

yyk ★★★★★
()
Ответ на: комментарий от eugine_kosenko

> Еще вопрос: зачет личный или командный?

Я думаю командный. Мы же не своими [CENSORED] меряемся, а у наших языков. :-)

redvasily
()
Ответ на: комментарий от redvasily

> Чего я в упор не вижу, так это этих загадочных абстракций высокого порядка, которых нет в других языках.

На таком примере?.

yyk ★★★★★
()
Ответ на: комментарий от redvasily

> Думаю будет больше. Так ты участвуешь?

А правила ведения "эксперимента" и участия в нём? :)

Если все этапы открыты и здесь-же (ну или в другом топике) - куда я денусь :) Но тлько ведомым-страхующим. На роль паровоза пусть кто-нибудь помоложе претендует :)

yyk ★★★★★
()
Ответ на: комментарий от redvasily

> На примере перестановок, файлов, файлов с БД

Это больше похоже на примеры для соревнования имеющихся либ/функций языка. "Не катит" :)

> и на примере, куда tailgunner ссылку давал.

Каюсь, не смотрел.

yyk ★★★★★
()
Ответ на: комментарий от bugmaker

> Только работать с ими карявенько. Отлистай вверьх, тамо с++ прого на полверсты, а лисповая аналог три строчки. Потому что сам йазыг приспособлен с кучками байтоф работать.

Пилять, я ее писал сам. Она семантически точно такая же, как лисповая, только strongly typed. То, что некоторые не умеют за деревьями увидеть леса - это их проблемы. И я не думаю, что у меня на ее написание ушло сильно больше времени, чем у тебя на лисповую - просто потому, что его вообще ушло мало, минут так 7 (в основном - на чтение sgi.com/tech/stl).

Давай ты в лисповый вариант везде добавишь аннотации типов, исправишь проблему с двойным внесением одинакового пути, сделаешь так, чтобы "неправильный" (в смысле, не являющийся кортежем "число, строка") идентификатор нельзя было использовать как ключ в хеше - и тогда мы поглядим, чья программа короче.

> в лиспе их навалом можно наворотить _при_желании_ только как оказываецо не так уж чясто с ними луче.

Можно. Нежелание это делать обычно отражает неумение (не в смысле неспособность, а отсутствие опыта) разрабатывать что-то большое и долгое, и большой командой.

А в хелловорлдах-то конечно, преимущества C++ (или там Haskell) не видны.

anonymous
()
Ответ на: комментарий от eugine_kosenko

> Кроме того, я совершенно не ожидал, что проги будут мерять по числу символов и строк. Я бы тогда некоторые вещи записал еще компактнее, а имена сделал бы еще короче. Как говорится, нет предела совершенству.

Поверь бывалому перлисту - я знаю язык, который всех порвет в номинации "самая короткая программа, реализующая заданый алгоритм", и это ни разу не лисп.

Вот только "совершенством" программы - победители в Perl Golf назвать язык даже у меня не поворачивается.

anonymous
()
Ответ на: комментарий от eugine_kosenko

> В Эйфеле обработка всех исключений жестко привязана к подпрограммам: это требование контрактного проектирования. Поэтому на пять уровней выше у Вас по любому уже не будет доступа к тем переменным, о которых Вы на этом уровне даже не догадываетесь. Либо финализируйте их явно на нижних уровнях, либо положитесь на GC. Как всегда, у Вас есть выбор.

Ой, блин. Это ж какой спагетти получается, наверное? Как с этим любители высоких строений (хехе ;) борются?

Это не издевка, правда - как? Мы тут выше обсуждали уже это в контексте "как правильно использовать goto".

> Пишу по буквам: вызывайте финализатор явно _до_ потери указателя. Какое из слов непонятно? Если все слова понятны, то обратите особое внимание на подчеркивание.

Это понятно - просто это ничем не лучше явного delete в C++.

А я хочу, чтобы оно "само" работало, но когда надо - позволяло руками вмешаться. Т.е., если бы можно было объявить переменную лексической, и это гарантировало бы аллокацию на стеке и финализацию по выходу из области - мне бы этого хватило.

> Вызывайте этот метод там, где у Вас на C++ полагается писать delete, а уничтожение пустой обертки оставьте сборщику мусора. Чем этот вариант не устраивает?

Явным вызовом delete. Например, если у меня функция делает return в нескольких местах - мне придетсь каждый раз писать рядом "delete filehandle;" - и если я забуду - то дескриптор утечет.

На C++ вызывать delete в таких случаях _не_ _надо_ - потому что подобную переменную я размещаю на стеке, и компилятор гарантирует вызов деструктора.

> Опишите точнее ситуацию, где GC сосет (в частности, где требуется стековая дисциплина, крутые обработчики исключений и "счетно-конечные ресурсы"), а я попробую элегантно решить эту проблему на Эйфеле.

Ну я же описывал типичную ситуацию: взять два лока, потом взять два "ресурса" (скажем, сокет и бд-хендл из соответсвующих пулов), поработать - ну там, задать запрос в базу и послать результат по сокету - и "вернуть все в зад", в правильном порядке (т.е., сначала вернуть все в пулы, потом разлочить по очереди мутексы). При этом могут возникать исключения (пустые пулы, клиент отвалился, etc).

На C++ у меня в подобном коде не будет ни одного delete, и, если мне позволено обрабатывать исключения выше, ни одного try/catch. Если не позволено - один-единственный try-block. И ни одного if-а - совершенно линейный понятный код.

anonymous
()
Ответ на: комментарий от yyk

> Не буду я тебе ничего показывать. Понадобится - сам найдёшь.

Дык я уже нашел, даже два. Ocaml и Haskell. Осталось найти время и задачу "отдельную", и написать что-нибудь на них, с параллельным изучением.

anonymous
()
Ответ на: комментарий от anonymous

> Ой, блин. Это ж какой спагетти получается, наверное? Как с этим любители высоких строений (хехе ;) борются?

Борются при помощи вдумчивого чтения "Дисциплины программирования" и применения полученных знаний на практике.

> Это не издевка, правда - как? Мы тут выше обсуждали уже это в контексте "как правильно использовать goto".

Дыкть, в Эйфеле принципиально не предусмотрен ни goto ни его заменители. Что поделать, простота языка и контрактное программирование требуют определенных ограничений.

> Это понятно - просто это ничем не лучше явного delete в C++.

Дыкть, я уже выше написал, что если для Вас явная деаллокация -- не исключение, а правило, то С++ -- это Ваш выбор.

> А я хочу, чтобы оно "само" работало, но когда надо - позволяло руками вмешаться. Т.е., если бы можно было объявить переменную лексической, и это гарантировало бы аллокацию на стеке и финализацию по выходу из области - мне бы этого хватило.

Ну, есть еще понятие "expanded class", который аллоцируется прямо в стеке. Не знаю, как там с дисциплиной, но это тоже может помочь. Правда, у экспандедов есть определенные грабли в конкретных реализациях, например, в SmartEiffel при наследовании от COMPARABLE генерируется некомпилируемый C-код. Но я думаю, для Ваших целей можно обойтись без таких извращений.

> Явным вызовом delete. Например, если у меня функция делает return в нескольких местах - мне придетсь каждый раз писать рядом "delete filehandle;" - и если я забуду - то дескриптор утечет.

Во-первых, как я уже написал, в Эйфеле нет goto-подобных операторов, поэтому выход всегда осуществляется в одной точке. А во-вторых, чтобы Вы не забыли этого сделать, напишите освобожденность дескриптора, как постусловие завершения подпрограммы (часть контракта), и система проконтролирует это условие при выходе.

> Ну я же описывал типичную ситуацию: взять два лока, потом взять два "ресурса" (скажем, сокет и бд-хендл из соответсвующих пулов), поработать - ну там, задать запрос в базу и послать результат по сокету - и "вернуть все в зад", в правильном порядке (т.е., сначала вернуть все в пулы, потом разлочить по очереди мутексы). При этом могут возникать исключения (пустые пулы, клиент отвалился, etc).

Ну, если есть задача промоделировать тот фрагмент кода, то попробую сделать. Правда, сразу предупреждаю, что освобождение будет написано явно. Я ж не знал, что Вам нужно "волшебным образом". Хотя, может быть, что вариант с экспандедами тоже прокатит.

> На C++ у меня в подобном коде не будет ни одного delete, и, если мне позволено обрабатывать исключения выше, ни одного try/catch. Если не позволено - один-единственный try-block. И ни одного if-а - совершенно линейный понятный код.

Ну, на Эйфеле тоже не будет ни одного if-а -- совершенно линейный понятный код. Более того, даже try-блока не будет -- достаточно только rescue -- аналог catch. Насчет delete -- посмотрю экспандеды, не получится -- посмотрю, что можно сделать стандартными средствами.

eugine_kosenko ★★★
()
Ответ на: комментарий от anonymous

> Поверь бывалому перлисту - я знаю язык, который всех порвет в номинации "самая короткая программа, реализующая заданый алгоритм", и это ни разу не лисп.

Мы уже об этом договорились. Речь идет о количестве лишне-привлеченных сучностей. А это не всегда хорошо измеряется.

eugine_kosenko ★★★
()
Ответ на: комментарий от anonymous

> Дык я уже нашел, даже два.

Искренне рад за Вас. Одного не пойму - что же Вы в этом топике потеряли? ;)

yyk ★★★★★
()
Ответ на: комментарий от eugine_kosenko

> Дыкть, в Эйфеле принципиально не предусмотрен ни goto ни его заменители. Что поделать, простота языка и контрактное программирование требуют определенных ограничений.

Я не предлагал для этого использовать гото (ну, в смысле предлагал - но только в plain C, где нет способов лучше).

> Во-первых, как я уже написал, в Эйфеле нет goto-подобных операторов, поэтому выход всегда осуществляется в одной точке.

Это хооршо, это правильно.

> А во-вторых, чтобы Вы не забыли этого сделать, напишите освобожденность дескриптора, как постусловие завершения подпрограммы (часть контракта), и система проконтролирует это условие при выходе.

А это можно сделать, если дескриптор не существует вне подпрограммы? Т.е. подпрограмма в духе save_text_to_file(text, filename)

Если да - то на эйффель. Хотя он, скорее, для коллективной разработки оптимизированный получается, а не для выразительности - и применять его в одиночестве будет грустно, наверное...

anonymous
()
Ответ на: комментарий от redvasily

> Bugmaker, ты врёшь.

это твоя традиция и ты её не нарушаеш

> Программа c файлами без БД:

где же ты в лисповой 12 строк нащитал? Там всево 1 - на создание хеша 1 - на добавление файла 5 - на поиск по условиям. Скоко всево? Чё за хрень непортабельные символы?

> Программа с БД, кстати, ты слил её написать

некогда пока, потом понапишу

> На простой программе (без БД), лисп слил питону, и выиграл у C++ всего в два раза, но C++ и не претендует на сверхкомпактность и абстракции высокого уровня.

Бугога? это там где в питоне понадобилось два новых типа создавать?

> На более сложной программе лисп слил питону и по строкам и по символам.

это на какой?

> И где здесь радикальное преимущество лиспа над "недоязыгами", о котором ты все уши прожужжал?

Ну хто ш тебе виноват если ты не можеш отличить надобности в создании кучи новых типов от отсутствия таковой надобности?

bugmaker ★★★★☆
()
Ответ на: комментарий от eugine_kosenko

> Кроме того, я совершенно не ожидал, что проги будут мерять по числу символов и строк.

+1, маразм конешно. Однако как ещё мерить?

bugmaker ★★★★☆
()
Ответ на: комментарий от eugine_kosenko

> по количеству конструкций языка. У Питона это совпадает со строками

у питона совпадает не со строками а хрен знает с чем. Всякие . [] 1: коротки, но тем не менее это самостоятельные конструкции, они сильно усложняют и могут находиться в строке десятками.

bugmaker ★★★★☆
()
Ответ на: комментарий от redvasily

> Чего я в упор не вижу, так это этих загадочных абстракций высокого порядка, которых нет в других языках.

А ты их и не увидиш так просто, пока для тя использование низкоуровневых конструкций кажецо естественным. А оно будет казаца естественным до тех пор пока лиспа не знаеш. Как примеры применения я приводил - смотри разницу в двух лисповых прогах перестановок или хеш от файловой проги. А чтобы разница была именно ощутимой, дык и задачя должна быть побольше и поразнообразнее.

> И bugmaker постоянно кричит что лисповый код в десятки раз компактнее, чего ну никак не наблюдается. Вот эти замеры строк и байтов в первую очередь для него.

Дык ты щитать если не умееш, хто те виноватый? Нащитал в файловой проге на лиспе вдвое больше строк чем там было :D

> Тут ему уже предлагали на спор померяться по компактности с Perl-oм, он не стал. Я бы поставил на Perl :-)

От задачи зависит. При достаточно большой можно было бы сотворить наречие у котокого все понятия по одному символу :D И на достаточно крупной и разнообразной перл таки слил бы :P только я нехочю тратить на это _столько_ своево времени. Тем более если уж народ собираецо сравнивать по длине прогу из перловых закорючек и нормально читаемую лисповую, и так очевидно чё бояцо проиграть.

bugmaker ★★★★☆
()
Ответ на: комментарий от anonymous

> А я хочу, чтобы оно "само" работало, но когда надо - позволяло руками вмешаться. Т.е., если бы можно было объявить переменную лексической, и это гарантировало бы аллокацию на стеке и финализацию по выходу из области - мне бы этого хватило.

А я хочу чтобы и вмешиватся не надо было. Этот пример как раз позволяет достаточно продвинутому компилятору делать так как надо. Если некий обьект рождается, пользуется и умирает в одном стек-фрейме, то нормальный компилятор имеет полное право выделить этот обьект на стеке или даже положить его в регистры. Для этого не нужен супер-пупер интеллектуальный анализ. Кое-где это уже реализовано, возможно даже это есть в комерческих реализациях лиспа.

anonymous
()
Ответ на: комментарий от yyk

> Ну, чуть по-больше: посмотри в sbcl реализацию external-format для потоков и строк

Это как раз пример того, как делать не стоит. У SBCL в TODO как раз стоит пункт где предлагается избавляется от макросов в пользу функций там, где это возможно. В данном случае имеем не очень красивый вариант плюсовых шаблонов на стероидах. И это стоило бы сделать по-другому.

Например: функции семейства OUTPUT-BYTES/<format> генерируются макросом, при этом в макрос передаются куски кода. Это стоит оформить как универсальный output-bytes, который вместо кусков кода принимает функции. А затем для генерации специализированного кода сделать что-то вроде.

(defun output-bytes/utf8 (stream string flush-p start end) (declare (inline output-bytes)) (output-bytes stream string flush-p start end (lambda ... кусок 1) (lambda ... кусок 2)...))

Для достаточно нормального компилятора такого было-бы достаточно, чтобы получить такой-же по производительности код, но по сравнению с херовым аналогом шаблонов, у него была-бы выше читабельность и была-бы возможность нормально отлаживаться.

anonymous
()
Ответ на: комментарий от anonymous

> А я хочу чтобы и вмешиватся не надо было. Этот пример как раз позволяет достаточно продвинутому компилятору делать так как надо. Если некий обьект рождается, пользуется и умирает в одном стек-фрейме, то нормальный компилятор имеет полное право выделить этот обьект на стеке или даже положить его в регистры. Для этого не нужен супер-пупер интеллектуальный анализ. Кое-где это уже реализовано, возможно даже это есть в комерческих реализациях лиспа.

Еще, блин, один раз: меня интересует _не_деаллокация_, а _финализация_. И не доверю я компилеру самому додумывать, когда мне файлики закрывать и мутексы анлочить.

anonymous
()
Ответ на: комментарий от anonymous

> Еще, блин, один раз: меня интересует _не_деаллокация_, а _финализация_. И не доверю я компилеру самому додумывать, когда мне файлики закрывать и мутексы анлочить.

Прости, недогнал. Эти случаи само собой особые. ИМО, ни один код не должен полагаться на финализацию из GC. Само собой такие вещи не для компилятора, но и расставлять повсюду нечто вроде .. } finally { SomeHelper.close(...); } это тоже не порядок. Правильно так: (with-mutex (lock) ...). Вот где блестят макросы.

Кстати, до недавнего времени (до 2.5) в Питоне не было адекватных языковых механизмов для удобной борьбы с такими сущностями.

anonymous
()
Ответ на: комментарий от bugmaker

>+1, маразм конешно. Однако как ещё мерить?

Посчитать примененные конструкции языка. Только в CL это сделать можно автоматизированно, так как программа на LISP -- это синтаксическое дерево. По нему можно пробежать относительно несложным алгоритмом и посчитать. А вот в случае с Питоном и др. это сделать непросто. Можно, но непросто. На небольших программах проще вручную посчитать. Вопрос, какие конструкции учитывать, обсуждаем. А то непонятно как-то: объявления переменных в (let ...) принято записывать в столбик. А в Си кто-то предпочитает int a, b, c; Вот и получается, что в LISP больше строчек. А по символам тоже глупо, так как многобуквенность идентификаторов -- вопрос личных предпочтений.

Zubok ★★★★★
()
Ответ на: комментарий от anonymous

> Еще, блин, один раз: меня интересует _не_деаллокация_, а
> _финализация_. И не доверю я компилеру самому додумывать, когда мне
> файлики закрывать и мутексы анлочить.

Не знаю, того ли анонимуса я цитирую, но вот как будет выглядеть
рассмотренный пример на Эйфеле:

class ROOT
	
inherit
   EXCEPTIONS
	
creation
   make

feature -- Root
	
   make is
      do
         do_crytical
      end
	
feature -- Implementation
	
   do_crytical is
      local
         mutex_a: MUTEX
         mutex_b: MUTEX
      do
         mutex_a.lock("A")
         mutex_b.lock("B")
	
         do_something
		
         mutex_b.unlock
         mutex_a.unlock
      rescue
         mutex_b.unlock
         mutex_a.unlock
         retry -- Until crytical section contract will be satisfied
      end
	
      do_something is
         do
            -- Doing something
         end
	
end

expanded class MUTEX

inherit
   EXCEPTIONS
	
feature -- Access
	
   resource: STRING -- I.e., system lock information
	
   is_locked: BOOLEAN is
      do
         Result := resource /= Void; -- I.e., resource is allocated
      end

feature -- Setting
	
   lock(p_resource: STRING) is
      local
         v_result: STRING
      do
         resource := p_resource -- I.e., real resource allocation
      ensure
         is_locked
      rescue
         retry -- Until finalization contract (is_locked) will be satisfied
      end
	
   unlock is
      do
         if not is_locked then
            resource := Void -- I.e., system finalization
         end
      ensure
         not is_locked
      rescue
         retry -- Until finalization contract (is_unlocked) will be satisfied
      end

end

Да, решение более многословное, зато очевидно, когда заканчивается
критическая секция. Но раз уж зашла речь о "не доверяю компилеру
самому додумывать", то Эйфель как раз и заставляет прописать это явно.

Кстати, а разве стандарт C++ оговаривает порядок вызова деструкторов
при выходе из области видимости? Мне кажется, это может зависеть от
реализации компилятора и методов оптимизации кода. Или не?

eugine_kosenko ★★★
()
Ответ на: комментарий от Zubok

> Посчитать примененные конструкции языка.

Ну я и предлагаю: у питона это число непустых строк (при отсутствии трюков с записью в одну строку), у C/C++ -- количество ';' (обычные операторы), '{' (функции и анонимные блоки, при этом для одного оператора всегда писать блок) и '#' (аналог включения модулей), а у Лиспа -- количество '('.

По-моему, справедливо. Или не?

eugine_kosenko ★★★
()
Ответ на: комментарий от anonymous

> А это можно сделать, если дескриптор не существует вне подпрограммы? Т.е. подпрограмма в духе save_text_to_file(text, filename)

Не, таки низзя, сам только что попробовал :-(.

> Хотя он, скорее, для коллективной разработки оптимизированный получается, а не для выразительности

Дыкть, он так и замышлялся: как язык, где твой товарищ не даст прострелить тебе ногу :-).

> и применять его в одиночестве будет грустно, наверное...

Ну, для меня это самое оно. Бо каждый день у меня новая личность, и вспомнить, чего я хотел в этом куске кода вчера -- задача для меня почти неразрешимая :-)).

eugine_kosenko ★★★
()
Ответ на: комментарий от anonymous

> Пилять, я ее писал сам.

ну кто же на твоё авторство претендует? пешы ешо

> Она семантически точно такая же, как лисповая, только strongly typed.

и вдесятеро длиннее

> Давай ты в лисповый вариант везде добавишь аннотации типов

зачем оне там?

> исправишь проблему с двойным внесением одинакового пути

я невижу проблемы с этим, но так и быть, добавлю проверку. Чё она должна делать, игнорить одинаковое или генерить ашыпку?

> сделаешь так, чтобы "неправильный" (в смысле, не являющийся кортежем "число, строка") идентификатор нельзя было использовать как ключ в хеше

...и ваще чёбы всё перестало работать

> - и тогда мы поглядим, чья программа короче.

и работает :D

bugmaker ★★★★☆
()
Ответ на: комментарий от anonymous

>> в лиспе их навалом можно наворотить _при_желании_ только как оказываецо не так уж чясто с ними луче.

> Можно. Нежелание это делать обычно отражает неумение (не в смысле неспособность, а отсутствие опыта) разрабатывать что-то большое и долгое, и большой командой.

это в основном верно для питонос++, асма, браинфака и других, где воротить всё одно _нужно_ и разница лиш в том оформить это как положено или итак сойдёт.

bugmaker ★★★★☆
()
Ответ на: комментарий от eugine_kosenko

> Речь идет о количестве лишне-привлеченных сучностей. А это не всегда хорошо измеряется.

Это достаточно хорошё видно если описать алгоритм человечьим языком, т.е. фактически выразить алгоритмы наиболее высокоуровневым. Но пипл на такое не ведёцо ;)

bugmaker ★★★★☆
()
Ответ на: комментарий от eugine_kosenko

Слишком упрощенный алгоритм. Может привести к неверным результатам. Например, просто if:

if (x > 1) cout << "x is positive";

(if (> x 1) (format t "x is positive"))

В первом случае 1 очко, а во втором 3. Тоже самое касается множества других операторов В С++. Например в for (int n = 1; n > 0; n--) два знака ';'. Вот я и говорю, что подсчет количества конструкций языка в C/C++ нетривиален.

Zubok ★★★★★
()
Ответ на: комментарий от eugine_kosenko

> Да, решение более многословное, зато очевидно, когда заканчивается критическая секция. Но раз уж зашла речь о "не доверяю компилеру самому додумывать", то Эйфель как раз и заставляет прописать это явно.

IMO, такие вещи лучше всего организовывать как процедуру/метод/функцию куда передается блок кода, и которая гарантирует взятие мутекся до выполнения и освобождение (в том числе и при пролете исключения) после. Так позволяют делать все функциональные языки + все наследники smalltalk'а (Ruby в том числе) и даже Java (в лице анонимных классов).

Плюсовое решение с деструкторами тоже валидное, но оно привязано к деаллокации, что не так же здорово. Кстати, AFAIR плюсы гарантируют порядок вызова деструкторов.

anonymous
()
Ответ на: комментарий от eugine_kosenko

>> Посчитать примененные конструкции языка.

> Ну я и предлагаю: у питона это число непустых строк (при отсутствии трюков с записью в одну строку), у C/C++ -- количество ';' (обычные операторы), '{' (функции и анонимные блоки, при этом для одного оператора всегда писать блок) и '#' (аналог включения модулей), а у Лиспа -- количество '('.

> По-моему, справедливо. Или не?

ИМХО кривовато. потомушто и в питоне и в с++ в строке может быть дофига лишних ссущностей таких как индексы, обращения к чьленам класса итд. а в лиспе оне все выглядят как (ыыы ...). Всётаки луче переводить в хумансовое наречие 1:1 и так сравнивать.

bugmaker ★★★★☆
()
Ответ на: комментарий от eugine_kosenko

На самом деле, надо взять для C/C++ грамматику в BNF и распарсить программу, подсчитав количество expressions по результатам работы парсера. Это есть самый правильный способ.

Zubok ★★★★★
()
Ответ на: комментарий от eugine_kosenko

> Не знаю, того ли анонимуса я цитирую, но вот как будет выглядеть рассмотренный пример на Эйфеле:

Да, спасибо. Ничего так, читабельненько.

> Кстати, а разве стандарт C++ оговаривает порядок вызова деструкторов при выходе из области видимости? Мне кажется, это может зависеть от реализации компилятора и методов оптимизации кода. Или не?

В порядке, обратном аллокации - стек ведь.

http://www.research.att.com/~bs/glossary.html#Gorder-of-destruction

anonymous
()
Ответ на: комментарий от anonymous

>Поверь бывалому перлисту - я знаю язык, который всех порвет в >номинации "самая короткая программа, реализующая заданый алгоритм", >и это ни разу не лисп.

Brainfuck ?

anonymous
()
Ответ на: комментарий от anonymous

>Пилять, я ее писал сам. Она семантически точно такая же, как >лисповая, только strongly typed. То, что некоторые не умеют за >деревьями увидеть леса - это их проблемы. И я не думаю, что у меня >на ее написание ушло сильно больше времени, чем у тебя на лисповую -> просто потому, что его вообще ушло мало, минут так 7 (в основном -> на чтение sgi.com/tech/stl).

Почему многие думают, что сильная типизация и шаблоны С++ такая уж благодать. Вот буквально сегодня разбирался с программой на С++, в которой одна только нормальная лямбда и замыкания заменили (1 строка) бы 17 строчный заголовок к С++ному шаблонному классу, которые делает то же самое, причем объявлен не по месту, а черт знает где. Когда программа становится больше, то эти шаблоны растут как на дрожжах не смотря на всякие изыски в метапрограммировании и автоматическом выводе шаблонов. В итоге по этому коду ходишь как по минному полю и внести хоть какое-то значительное изменение уже не представляется возможным.

А какой на это дежурный ответ у фанатов С++ ? Правильно: "Заранее все надо было продумывать и правильно проектировать!". Если код надо менять, а он уже задубел в шаблонах и куче всяческих вспомогательных типов, то это оказывается мир вокруг неправильный, меняется так быстро, что правильно спроектировать сразу никогда не получается.

Потом типы в С++ как бы выводятся, но посмотреть, что получилось в результате вывода очень сложно. Вручную пишется куча левого кода, который к решаемой проблемме не имеет никакого отношения.

Надо заметить, что вывод типов по Хиндли-Милнеру в Haskell и OCaml и подходы применяемые в этих языках вместо шаблонов (модули, классы типов и т.п.) является значительным улучшением по сравнению с плюсовыми заморочками.

Я изучал Haskell и OCaml - многое мне там понравилось, но все равно в итоге вернулся в Лисп. Почему ? Да потому что в то время как в других языках все делается только в рамках поддерживаемых парадигм и подходов: например С++ старается рядить все в одежды ООП, на каждую трехкопеечную функцию сооружаются классы, методы и т.д.; Haskell - чисто функциональный и никуда от этого не денешься, задачу все равно надо впихивать в то что предлагает ФП; OCaml поддерживает и ФП, и императивщину и ООП в одном флаконе, но это все что он предлагает, правда для большего есть некий замысловатый препроцессор, но это уже сравнимо по сложности с шаблонами в С++.

Лисп просто получается наименьшим общим делителем: ФП можно, императивщина - пожалуйста, ООП - какой угодно, простецкий встроенный Пролог - ~150 строк и готов, встроенный SQL - пожалуйста, встроенный constraint programming - милости просим, к тому же интегрировано с CLOS; надо инфиксные выражения - вот они. Может быть Лисп не так уж хорош во всех этих областях, как какой-то отдельный язык, но он как хамелеон быстро принимает все формы и затраты на коммуникацию столь разных языков/подходов практически отсутствуют в отличие от всяких .NET

Потом от компиляции и обновления программы на ходу без остановки откажется только законченный аскет. Юзер сможет перенастроить программу так что ее авторы не узнают ;-) сгенерить исполняемое изображение и без всякого там скриптинга тормозного. Так что это не наезд на другие языки, а просто реальное взвешивание возможностей. Вы будете правы, если скажете, что многие из этих возможностей реально не используются, а некоторые еще полноценно не реализованы. Не факт, что эпоха конвейерного подхода к созданию ПО продлится долго, сейчас всякие ограничения в языке и защита от дурака считается более полезной, чем какая-то там гибкость, трудно найти достаточно творческих личностей, но я думаю что на новом витке спираль вернется к творческому подходу и всякие там Java полетят в помойку истории.

Спасибо за внимание ;-)

anonymous
()
Ответ на: комментарий от Zubok

> На самом деле, надо взять для C/C++ грамматику в BNF и распарсить программу, подсчитав количество expressions по результатам работы парсера. Это есть самый правильный способ.

О! Пока добирался домой, придумал, похоже, самый наибольший общий знаменатель для всех языков, причем с достаточно простой реализацией. Достаточно посчитать число лексем в программе, после чего можно вычислить следующие характеристики:

Общая (информационная) длина -- количество лексем (с повторениями) в программе. Определяет абсолютную длину программы.

Лексический размер (тезаурус) -- количество разных (неповторяющихся) лексем. Этот параметр определяет приблизительное количество понятий, необходимых для понимания программы.

Лексическая насыщенность -- отношение числа разных (неповторяющихся) смысловых лексем (идентификаторов, чисел, строк, символов и т.п.) к лексическому размеру. Определяет объем полезной информации, дополнительная величина определяет степень "синтаксической засахаренности".

Общая (информационная) насыщенность -- отношение общего числа (с повторениями) смысловых лексем (идентификаторов, чисел, строк, символов и т.п.) к общей информационной длине. Похож на лексическую насыщенность, но дополнительно косвенно описывает "рутиность" кода, то есть, учитывается многократное использование понятий в тексте программы.

IMHO, получается достаточно объективно, так как не учитывается экономия "на спичках" (длина идентификаторов, ключевых слов, операторов) и различная сложность грамматических конструкций (у них может быть множество способов учета). Кроме того, не нужен сложный синтаксический анализатор, можно обойтись только лексическим.

Хотел сегодня наваять мерялку в рамках освоения cl-lexer, но не сложилось. Если кто сделает раньше субботы, будет здорово. Появится у меня время до субботы -- постараюсь написать раньше.

eugine_kosenko ★★★
()
Ответ на: комментарий от anonymous

>> Поверь бывалому перлисту - я знаю язык, который всех порвет в номинации "самая короткая программа, реализующая заданый алгоритм", и это ни разу не лисп.

> Brainfuck ?

Не, APL/J, конечно же. Там средняя длина ключевого слова около 2. Я уже писал про поиск простых чисел в 17 символов и модель ядра OS/360 в 120. Но читать это практически невозможно -- язык с очень низкой энтропией.

А вообще, если брать по абсолютной длине, то *ML, скорее всего, выиграют у Лиспа -- там не нужны скобочки :-). Правда, читать их тоже сложнее, чем Лисп.

eugine_kosenko ★★★
()
Ответ на: комментарий от bugmaker

> Это достаточно хорошё видно если описать алгоритм человечьим языком, т.е. фактически выразить алгоритмы наиболее высокоуровневым. Но пипл на такое не ведёцо ;)

Не ведется, потому что в человечьем языке одну и ту же мысль можно выразить десятком разных способов. И потом, на каком из человечьих языков предлагается записывать? А то ведь в истории есть курьез, когда исследовали перевод с человечьего языка на немецкий :-)).

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

>> Это достаточно хорошё видно если описать алгоритм человечьим языком, т.е. фактически выразить алгоритмы наиболее высокоуровневым. Но пипл на такое не ведёцо ;)

> Не ведется, потому что в человечьем языке одну и ту же мысль можно выразить десятком разных способов. И потом, на каком из человечьих языков предлагается записывать? А то ведь в истории есть курьез, когда исследовали перевод с человечьего языка на немецкий :-)).

Выразить - возможно, но описать буквально то чё делает прого всево одново хватит. Я выше по треду подобное делал ужо пару раз.

bugmaker ★★★★☆
()
Ответ на: комментарий от bugmaker

> человечьим языком

Кстати, навеяло:

LISP: Вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который...

Форт: Hога простреливать себе вы.

HyperTalk: Поместите первую пулю пистолета в ступню левой ноги вас. Сообщите результат.

Пролог: Вы сообщаете вашей программе, что вы хотите иметь простреленную ногу. Программа разрабатывает способ этого достичь, но синтаксис языка не позволяет объяснить этот способ вам.

APL: Вы простреливаете себе ногу, затем тратите весь день на то, чтобы представить себе, как это сделать с меньшим количеством символов.

java: тип "пуля" не соответствует типу "нога"

Delphi: вы лезете в гугль в поисках TGun и TLeg

C#: Вы находите System.Human.Gun и System.Human.Leg в поставке .НЕТ, выстреливаете, но пуля не долетает, будучи уничтоженной сборщиком мусора

Python: <не реализовано>

:-)))

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

с++: вы стреляеете себе в ногу и вам отрывает все, что ниже шеи

C++: Вы случайно создаете дюжину экземпляров объекта "вы" и всем им простреливаете ногу. Срочная медицинская помощь оказывается невозможной, так как вы не можете разобраться, где настоящие объекты, а где - те, которые только указывают на них и говорят: "А вот - я!".

BrainF**k : вы пытаетесь прострелить себе ногу, но в место етого запутываетесь в мега коде и простреливаете себе голову

Malbolge: для того, чтобы прострелить ногу на этом языке, вам надо написать программу на другом языке, генерирующую код на malbolge. При запуске последствия непредсказуемы, т.к. ничего сложнее hello world на malbolge не тестировалось

Eiffel: <видел, но уже не найду где>

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

Можно взять что-то типа CL-YACC, вбить BNF C++ (http://www.nongnu.org/hcb/) . По этим делам сгенерируется парсер, который выдаст результат в виде нормального синтаксического дерева, идентичного программе C++. А далее надо будет договориться, что будем считать и пробежаться по дереву.

Вот совершенно короткий мануал по CL-YACC с примерчиком:

http://www.pps.jussieu.fr/~jch/software/cl-yacc/cl-yacc.html

Аналогично этому примеру из программы на С++ можно получить синтаксическое дерево.

Однако работа по вбиванию грамматики C++ сама по себе может стать рутиной немалой. Да и грабельки могут по ходу появиться, так как все-таки язык навороченный по своему объему.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

>Однако работа по вбиванию грамматики C++ сама по себе может стать рутиной немалой. Да и грабельки могут по ходу появиться, так как все-таки язык навороченный по своему объему.

Вот чего автор написал на сайте:

While CL-Yacc has undergone no systematic testing, I use it for compiling a grammar for a superset of "C" (over 400 productions) that routinely parses thousands of lines of "C" code.

К сожалению, грамматики для С я у него не нашел в репозитории. То есть он где-то для себя написал, но не выложил. Можно выпросить. Тогда будет иметься готовый парсер. В результате задача сведется к сравнению двух синтаксических деревьев, исключив все ненужное: длины идентификаторов, количество строчек.

Zubok ★★★★★
()
Ответ на: комментарий от eugine_kosenko

> Python: <не реализовано>

4.2 :-)

Пистолет и ногу можно было скачать с незапамятных времён, а начиная с 2.5 идёт в стандартной поставке (ctypes)

redvasily
()
Ответ на: комментарий от anonymous

> Кстати, до недавнего времени (до 2.5) в Питоне не было адекватных языковых механизмов для удобной борьбы с такими сущностями.

Гмм, ну with это конечно хорошо, но по-моему во всех питонах время вызова деструктора было вполне детерминировано, правила те-же что и в C++ для объектов на стеке, это возможно из-за reference-counting GC, который конечно не труъ GC как в Ruby, но зато работает в предсказуемые моменты :-)

redvasily
()
Ответ на: комментарий от redvasily

Достала эта байка о том, что в Питоне нет труъ GC! Он там есть и включен по умолчанию, в этом легко убедиться, сделав import gc; gc.isenabled(). Другое дело, что большинство объектов удаляется при подсчёте ссылок, ну так и в Руби емнип то же самое.

ero-sennin ★★
()
Ответ на: комментарий от Zubok

> Можно взять что-то типа CL-YACC, вбить BNF C++

Горе в том, что yacc органически не переваривает труъ BNF, поэтому набор грамматики С++ может стать нетривиальной задачей. Особенно, если учесть, что грамматика С++ контекстно-зависима...

> Вот совершенно короткий мануал по CL-YACC с примерчиком:

А вот что особенно убивает в Лиспе, так это периодическая лежка его информационных ресурсов. Еще в воскресенье эту доку пришлось выдирать из гуглевского кэша :-(.

eugine_kosenko ★★★
()
Ответ на: комментарий от ero-sennin

> http://docs.python.org/lib/module-gc.html

Оно-то, конечно, написано хорошо. Да вот не работает так, как хотелось бы. Если взять ту же проблему с аллокацией диапазонов, форсирование сборки не помогает и в списке мусора их нету. И если бы дело ограничивалось только целыми...

eugine_kosenko ★★★
()
Ответ на: комментарий от ero-sennin

А в Ruby разве есть подсчёт ссылок?

Я думал что там только GC, по крайней мере из чтения всякой инфы сложилось такое впечатление...

redvasily
()
Ответ на: комментарий от eugine_kosenko

> LISP: Вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который...

Visual Basic: Hа самом деле вы будете только выглядеть, как будто ваша нога прострелена. Однако в процессе реализации вы получите столько удовольствия, что подобные мелочи вас не озаботят.

anonymous
()
Ответ на: комментарий от eugine_kosenko

>Горе в том, что yacc органически не переваривает труъ BNF, поэтому набор грамматики С++ может стать нетривиальной задачей. Особенно, если учесть, что грамматика С++ контекстно-зависима...

Вот за что я люблю LISP, так это за регулярность. :) Есть в C++ *очень* труднопроходимые моменты в парсинге. Не спорю. Задача сама по себе очень сложная. Однако результаты дали бы, на мой взгляд, представление о том, сколько выражений языка требуется для решения задачи.

P.S. Кстати распарсить Java полегче должно быть, чем C++, так как она контексно-независимая.

Zubok ★★★★★
()
Ответ на: комментарий от eugine_kosenko

> Ну я и предлагаю: у питона это число непустых строк (при отсутствии трюков с записью в одну строку), у C/C++ -- количество ';' (обычные операторы), '{' (функции и анонимные блоки, при этом для одного оператора всегда писать блок) и '#' (аналог включения модулей), а у Лиспа -- количество '('.

Сам же сказал - в питоне можно загонять операции в одну строку. У С/С++ можно объявление переменных одного типа загнать под один ';'. Ну а в лиспе один loop сэкономит далеко не одну пару скобок ;)

yyk ★★★★★
()
Ответ на: комментарий от anonymous

> Это как раз пример того, как делать не стоит.

Дредложи свой вариант, только учти, что...

> Например: функции семейства OUTPUT-BYTES/<format> генерируются макросом...

и эти же макросы генерируют из тех-же кусков кода ещё с десяток функций...

> Это стоит оформить как универсальный output-bytes, который вместо кусков кода принимает функции.

Т.е. функций у тебя станет в два раза больше, а функционал останется?

> Для достаточно нормального компилятора такого было-бы достаточно, чтобы получить такой-же по производительности код, но по сравнению с херовым аналогом шаблонов, у него была-бы выше читабельность и была-бы возможность нормально отлаживаться.

Как код отлаживал автор - фиг его знает. Читабельность - субъективный фактор. А кода в твоём варианте стало бы на много больше. Если только не завернуть его в макры :) Но что мы тогда получим? ;)

yyk ★★★★★
()
Ответ на: комментарий от ero-sennin

> Достала эта байка о том, что в Питоне нет труъ GC! Он там есть и включен по умолчанию, в этом легко убедиться, сделав import gc; gc.isenabled(). Другое дело, что большинство объектов удаляется при подсчёте ссылок, ну так и в Руби емнип то же самое.

Да в питоне есть GC. Тов. redvasily (*) (19.10.2006 9:41:34) имел в виду, что он (точнее CPyhton) в отличие от более классических реализаций GC имеет детерминированное время сборки объектов, а значит детерминированное время вызова деструкторов/финализаторов, из-за того что питоновский GC сочетает GC и reference-counting. Я не уверен так ли это, надо проверить.

В Ruby, в лиспах и практически во всех других реализациях языков с GC такого свойства нету. Т.к. reference counting, как считается, негативно влияет на производительность. Вероятно, для интерпретаторов это незначительный минус, но если в дело вступает JIT то reference counting становится тормозом.

anonymous
()
Ответ на: комментарий от redvasily

> В принципе, приветствуются решения на Haskell OCaml и hq9+

[Makefile]
adventure: advserver hclient roboclient

advserver: adv_world.cmo advserver.ml
	ocamlc unix.cma adv_world.cmo advserver.ml -o advserver
hclient: adv_world.cmo hclient.ml
	ocamlc -g unix.cma adv_world.cmo hclient.ml -o hclient
roboclient: adv_world.cmo roboclient.ml
	ocamlc -g unix.cma adv_world.cmo roboclient.ml -o roboclient
adv_world.cmo: adv_world.mli adv_world.ml
	ocamlc -g -c adv_world.mli
	ocamlc -g -c adv_world.ml

clean:
	rm -Rf *~ *.cm[io] advserver hclient roboclient

[adv_world.ml]
let find (map, n, _) c =
  let rec find_aux i =
    if i = n - 1 then raise Not_found
    else try (i, String.index map.(i) c) with Not_found -> find_aux (i + 1)
  in find_aux 0

let get_items (map, n, m) =
  let rec get_items_aux accu = function
      (i, j) when i = n -> accu
    | (i, j) when j = m -> get_items_aux accu (i + 1, 0)
    | (i, j) -> get_items_aux (if map.(i).[j] = 'S' then (i, j) :: accu else accu) (i, j + 1)
  in
  get_items_aux [] (0, 0) ;;

let num_of_items world = List.length (get_items world) ;;

let output oc (map, n, m) =
  for i = 0 to n - 1 do
    for j = 0 to m - 1 do
      output_char oc map.(i).[j]
    done ;
    output_char oc '\n'
  done

let input ic =
  let rec input_aux () =
    try let line = input_line ic in line :: input_aux () with End_of_file -> []
  in
  let m = Array.of_list (input_aux ()) in m, Array.length m, String.length m.(0)

let send oc (map, n, m) ((x, y), _) =
  output_string oc (Printf.sprintf "%d\n" n) ;
  for i = 0 to n - 1 do
    for j = 0 to m - 1 do
      output_char oc (if x = i && y = j then '@' else map.(i).[j])
    done ;
    output_char oc '\n'
  done

let recv_common ic n =
  let rec rc_aux = function
      0 -> []
    | n -> let line = input_line ic in line :: rc_aux (n - 1)
  in
  rc_aux n

let recv ic =
  let n = int_of_string (input_line ic) in
  let map = Array.of_list (recv_common ic n) in map, n, String.length map.(0)

let recv_stat ic = recv_common ic 3

let send_stat oc (map, n, m) ((x, y), is_empty) =
  List.iter (Printf.fprintf oc "%s\n")
    [if num_of_items (map, n, m) = 0 && is_empty then "You won!" else "Game is in progress";
     if is_empty then "Your hand are empty" else "You carry an item";
     if map.(x).[y] = 'S' then "Here lies 1 item" else "Here lies 0 items"]

[adv_world.mli]
val find : string array * int * 'a -> char -> int * int
val get_items : string array * int * int -> (int * int) list
val num_of_items : string array * int * int -> int
val output : out_channel -> string array * int * int -> unit
val input : in_channel -> string array * int * int
val send : out_channel -> string array * int * int -> (int * int) * bool -> unit
val recv : in_channel -> string array * int * int
val recv_stat : in_channel -> string list
val send_stat : out_channel -> string array * int * int -> (int * int) * bool -> unit 

[advserver.ml]
let make_step (map, n, m) (x, y) cmd =
  let cmds = [("north", (-1, 0)); ("south", (1, 0)); ("west", (0, -1)); ("east", (0, 1))] in
  let x', y' = (fun (dx, dy) -> x + dx, y + dy) (try List.assoc cmd cmds with Not_found -> 0, 0) in
  if x' < 0 || x' >= n || y' < 0 || y' >= m || map.(x').[y'] = '#' then x, y else x', y'

let serve_cmd (map, n, m) ((x, y), is_empty) = function
    "pickup" when is_empty && map.(x).[y] = 'S' ->
      map.(x).[y] <- ' ' ;
      ((x, y), false)
  | "drop" when not is_empty && map.(x).[y] != 'S' ->
      map.(x).[y] <- if map.(x).[y] = '.' then '.' else 'S' ;
      ((x, y), true)
  | cmd ->
      (make_step (map, n, m) (x, y) cmd, is_empty)

let serve in_channel out_channel =
  let world = Adv_world.input (open_in Sys.argv.(1)) in
  let rec loop state =
    Adv_world.send out_channel world state ;
    Adv_world.send_stat out_channel world state ;
    flush out_channel ;
    try
      let state = serve_cmd world state (input_line in_channel) in
      loop state
    with
      End_of_file -> ()
  in
  loop ((Adv_world.find world '.'), true) ;;

Unix.establish_server serve (Unix.ADDR_INET (Unix.inet_addr_loopback, int_of_string Sys.argv.(2))) ;; 

[hclient.ml]
let in_channel, out_channel = Unix.open_connection
  (Unix.ADDR_INET ((Unix.inet_addr_of_string Sys.argv.(1)), int_of_string Sys.argv.(2)))
in
while true do
  Adv_world.output stdout (Adv_world.recv in_channel) ;
  List.iter (Printf.printf "%s\n") (Adv_world.recv_stat in_channel) ;
  flush stdout ;
  Printf.fprintf out_channel "%s\n" (read_line ()) ;
  flush out_channel
done ;; 

[roboclient.ml]
let dfs (map, n, m) (sx, sy) =
  let dxy = [(-1, 0); (1, 0); (0, -1); (0, 1)] in
  let f = Array.make_matrix n m (-1) in
  let q = Queue.create () in
  Queue.push (sx, sy) q ; f.(sx).(sy) <- 0 ;
  while not (Queue.is_empty q) do
    let x, y = Queue.pop q in
    List.iter
      (fun (x', y') -> Queue.push (x', y') q ; f.(x').(y') <- f.(x).(y) + 1)
      ( List.filter
          (fun (x', y') -> x' >= 0 && x' < n && y' >= 0 && y' < m && map.(x').[y'] <> '#' && f.(x').(y') = -1)
          (List.map (fun (dx, dy) -> x + dx, y + dy) dxy) )
  done ;
  f

let calc_commands f (x, y) =
  let rec find_path (x, y) path =
    let dxy = [(-1, 0); (1, 0); (0, -1); (0, 1)] in
    let cmds = [((-1, 0), "south"); ((1, 0), "north"); ((0, -1), "east"); ((0, 1), "west")] in

    if f.(x).(y) = 0 then path
    else
      let find_path_aux (dx, dy) =
        if f.(x + dx).(y + dy) + 1 = f.(x).(y) then
          find_path (x + dx, y + dy) (List.assoc (dx, dy) cmds :: path)
        else raise Not_found
      in
      let rec iter = function
          []      -> raise Not_found
        | d :: tl -> try find_path_aux d with Not_found -> iter tl
      in
      iter dxy
  in
  let invert_path path =
    let map = [("north", "south"); ("south", "north"); ("west", "east"); ("east", "west")] in
    let rec invert_path_aux accu = function
        []        -> accu
      | cmd :: tl -> invert_path_aux (List.assoc cmd map :: accu) tl
    in
    invert_path_aux [] path
  in

  let path = find_path (x, y) [] in
  path @ ["pickup"] @ (invert_path path) @ ["drop"]

let main () =
  let in_channel, out_channel = Unix.open_connection
    (Unix.ADDR_INET ((Unix.inet_addr_of_string Sys.argv.(1)), int_of_string Sys.argv.(2)))
  in
  let world = Adv_world.recv in_channel in
  Adv_world.output stdout world ;
  List.iter (Printf.printf "%s\n") (Adv_world.recv_stat in_channel) ;

  let start = Adv_world.find world '@' in
  let marks = dfs world start in

  List.iter
    ( fun (x, y) ->
        List.iter
          ( fun cmd ->
              Printf.printf "\ncommand: %s\n" cmd ;
              Printf.fprintf out_channel "%s\n" cmd ;
              flush out_channel ;
              Adv_world.output stdout (Adv_world.recv in_channel) ;
              List.iter (Printf.printf "%s\n") (Adv_world.recv_stat in_channel) )
          (calc_commands marks (x, y)) )
    ( Adv_world.get_items world ) ;;

main () ;;

Написано примерно за 3 часа, наверное можно сильно сократить. Но буду
это делать, только если кто напишет сильно короче. Пока без пустых 156
строк. Не думаю, что на python или lisp будет сильно по другому.
Больно задача общая. Уж ocaml здесь точно большого выигрыша не дает.

satanic-mechanic
()
Ответ на: комментарий от redvasily

>> Замеряем таким образом?

> Замеряйте :-)

> Результаты сведите в общую таблицу

Ну, соорудил мерялку, как описывал -- по лексемам. Результаты
получились довольно занятные :-).

Для версии с БД программы на C++ не участвовали, потому сравниваются
только Лисп и Питон.

Параметр                     | Lisp | Python
--------------------------------------------
Общая длина                  |  511 |   677
Смысловая длина              |  248 |   289
Общий тезаурус               |  112 |   128
Смысловой тезаурус           |   85 |    93
Насыщенность (в %)           |   49 |    43
Выразительность (в %)        |   76 |    73
Общая изменчивость (в %)     |   22 |    19
Смысловая изменчивость (в %) |   34 |    32

Для версии со словарями оказалось возможно сравнить все три языка,
однако я не проверял их на работоспособность.

Параметр                     | Lisp | Python | C++
--------------------------------------------------
Общая длина                  |  176 |    186 | 421
Смысловая длина              |   60 |     66 | 172
Общий тезаурус               |   42 |     52 |  88
Смысловой тезаурус           |   24 |     27 |  55
Насыщенность (в %)           |   34 |     35 |  41
Выразительность (в %)        |   57 |     52 |  62
Общая изменчивость (в %)     |   24 |     28 |  21
Смысловая изменчивость (в %) |   40 |     41 |  32

Расшифровка терминов следующая:

Общая длина -- число всех лексем в программе. По идее, определяет
основной параметр -- интуитивный размер программы.

Смысловая длина -- число всех значимых лексем (не ключевых слов и не
спецсимволов, т.е., идентификаторов, строк, чисел и т.п.).
Приблизительно определяет общее количество определений и использования
новых сущностей в программе. Параметр может быть определен неточно,
так как в "ключевые слова" попали также все идентификаторы,
определенные стандартом, или, по другому, использовать которые
оказалось возможно без подключения внешних библиотек или пакетов. Сами
имена библиотек/пакетов не считаются ключевыми.

Общий тезаурус -- размер словаря программы, число неповторяющихся
лексем. Дает грубую оценку общего числа понятий, используемых в
программе.

Смысловой тезаурус -- размер смыслового словаря программы, число
неповторяющихся значимых лексем (определение такое же, как и для
смысловой длины). Дает оценку числа новых понятий, определенных в
программе.

Насыщенность -- отношение смысловой длины к общей, выражается в
процентах. Определяет степень "засахаренности" синтаксиса программы --
чем больше насыщенность, тем меньшую роль играет синтаксис языка. По
идее, это близость программы к человеческому определению.

Выразительность -- отношение смыслового тезауруса к общему, выражается
в процентах. Похоже на насыщенность, но относится к составу словаря.

Общая изменчивость -- отношение общего тезауруса к общей длине
программы, выражается в процентах. По идее, эта величина является
обратной к регулярности -- среднему количеству использований одной
лексемы. Возможно, определяет "высокоуровневость" языка, так как
интуитивно ассемблеры должны иметь низкую изменчивость (длинные
программы с небольшим набором команд), а, например, для BrainF**k и
WhiteSpace изменчивость практически равна 0, что напоминает ситуацию с
характеристикой словаря людоедки-Эллочки.

Смысловая изменчивость -- отношение смыслового тезауруса к смысловой
длине программы, выражается в процентах. Похожа на общую изменчивость,
но только в применении к смысловым лексемам. Для BrainF**k и
WhiteSpace смысловая изменчивость определяется неопределенным
отношением 0/0 (в этих языках нет неключевых слов), для простоты я
определил ее в таком случае, как 0, что соответствует "вырожденности"
этих языков.

Можно заметить, что для Лиспа и Питона относительные параметры
практически равны, а абсолютные заметно отличаются. Насколько
"заметно" -- зависит от субъективного восприятия. Для питоноводов это
может быть "всего лишь на десяток (сотню) строк", а для лисперов это
может быть "аж целых 10 (25) процентов". Можно ли на таких задачах
считать выигрыш в четверть длины "существенным" -- личное дело
каждого. Кроме того, в процессе написания мерялки я нашел задачу, где
использование макров на лиспе может дать выигрыш в длине кода раз в
10, то есть, примерно на порядок. Когда сделаю, покажу кусочек, хотя
по сути это именно то, что я описывал по отношению к написанию крупных
синтаксических и лексических анализаторов для нетривиальных языков.
Если дело дойдет до принципа, то придется писать лексический
анализатор на Питоне. Пока что попробую позже написать, как это
делается на Лиспе.

Одинаковость относительных параметров наводит на мысль, что они
характеризуют равный характер квалификации программистов и
одинаковость алгоритмов, использованных в программе. Возможно, это
удастся использовать для косвенной оценки.

Из всей этой картинки выбивается С++. По абсолютным параметрам он
проигрывает в разы (примерно в 3 раза), а по относительным показывает
меньшую изменчивость и большую выразительность/насыщенность. Это можно
интерпретировать, как низкоуровневость (типа низкая изменчивость
характерна именно для ассемблеров), а можно посчитать, что эта
программа решает не совсем ту задачу. В частности, очевидно, что
программа на C++ не выполняет поиска по всем трем критериям, которые
были в условии задачи.

Если интересно, могу прогнать через мерялку еще и задачу о
перестановках. Кроме того, могу опубликовать код мерялки (она на
Лиспе) с целью выяснения принципов ее работы, поиска ошибок и
неточностей (в частности, с разделением на ключевые и неключевые
слова) и замеров других параметров.

eugine_kosenko ★★★
()
Ответ на: комментарий от satanic-mechanic

> Пока без пустых 156 строк.

Total length                                         1627
Meaning length                                        603
Total thesaurus                                       164
Meaning thesaurus                                     113
Saturation (%)                                         37
Expressiveness (%)                                     69
Total variability (%)                                  10
Meaning variability (%)                                19

;-)

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

Удалось сократить на 5 строк, изменив функцию output модуля adv_world.ml

let output oc (map, _, _) =
  Array.iter (Printf.fprintf oc "%s\n") map

Просто изначально функции output и send были одной, поэтому output была такой большой. В принципе и send можно уменьшить, но не очень красиво - пока этого делать не буду.

satanic-mechanic
()
Ответ на: комментарий от satanic-mechanic

Кстати, флейм как-то поутих, а я только добрался :( Может найдутся новые возможности развития дискуссии в рамках выбранной темы?..

satanic-mechanic
()
Ответ на: комментарий от satanic-mechanic

>Кстати, флейм как-то поутих, а я только добрался :( Может найдутся новые возможности развития дискуссии в рамках выбранной темы?..

Я уже тоже похоронил про себя топик, но теперь, похоже, все только начинается. LOR contest :)

Zubok ★★★★★
()
Ответ на: комментарий от eugine_kosenko

Вчера по зрелому размышлению возникла мысль переопределить
относительные параметры программы. Отношение числа смысловых лексем к
их общему количеству всегда будем называть "насыщенностью", причем она
может определяться, как "общая насыщенность" и "насыщенность
тезауруса". То, что раньше называлось выразительностью, становится
"насыщенностью тезауруса", а изменчивость теперь будем называть
"выразительностью", которая тоже может измеряться двумя способами.

Такое переопределение ближе к интуитивному пониманию. Выразительность
определяет не только возможности языка, но и степень применения
"метода китайских программистов" (copy-paste). Чем меньше повторяются
слова в программе, тем она выразительнее, хотя для полной оценки нужно
учитывать многократное использование изоморфных грамматических
конструкций.

Теперь к вопросу об использовании макросов для повышения
читабельности.

Для считалки нужно было определить лексический анализатор, который
будет пропускать сепараторы (пробельные символы и комментарии), а
остальные лексемы делить на ключевые и смысловые слова. В моем первом
варианте на Лиспе это выглядело вот так:

(deflexer make-lisp-token-stream
  :flex-compatible
  ("\\(" (return (values :keyword %0)))
  ("\\)" (return (values :keyword %0)))
  ("'"   (return (values :keyword %0)))
  ("#'"  (return (values :keyword %0)))
  ; И т.д.

  ("(\\-)?[0-9]+" (return (values :meanword %0)))
  ("[\\[]" (return (values :meanword %0)))
  ("[\\]]" (return (values :meanword %0)))
  ("[A-Za-z][A-Za-z\\-]*" (return (values :meanword %0)))
  ; И т.п.

  (";.*$") ("[:space:]+"))

Понятно, что тут дофига повторяющихся фрагментов кода (добавьте сюда
еще 3 языка), в результате чего программа оказалось изрядно распухшей.
После применения макросов получаем следующее решение:

(defun lex-class (class-def)
  (mapcar 
     #'(lambda (regex) `(,regex (return (values ,(car class-def) %0))))
     (cdr class-def)))

(defmacro defclassifier (name class-list skip-list)
  `(deflexer ,name
      :flex-compatible 
      ,@(mapcan #'lex-class class-list)
      ,@(mapcar #'list skip-list)))

(defclassifier make-ocaml-classifier
  ((:keyword
    .("!=" "%" "&" "&&" "," ":" "::" ";" ";;" "<" "<\\-" "=" ">" ">=" "@" "Array"
      "List" "Queue" "\\(" "\\)" "\\*" "\\+" "\\-" "\\->" "\\." "\\[" "\\]" "\\{"
      "\\|" "\\|\\|" "\\}" "assoc" "create" "do" "done" "else" "flush" "for" "fun"
       "function" "if" "in" "iter" "length" "let" "loop" "make_matrix" "map" "not"
       "pop" "push" "raise" "then" "to" "true" "try" "with"))

   (:meanword
    .("\"[^\"]*\"" "'[^']*'" "(-)?[0-9]+" "[A-Za-z_][A-Za-z_]*(')?")))

  ;skipword
  ("//.*$" "[:space:]+"))

(defclassifier make-c++-classifier
  ((:keyword
    .("!=" "#include" "%" "&" "," ":" "::" ";" "<" "<<" "=" ">" ">=" ">>" "\\("
      "\\)" "\\*" "\\+" "\\+\\+" "\\->" "\\." "\\[" "\\]" "\\{" "\\|\\|" "\\}"
      "bool" "class" "const" "for" "if" "int" "namespace" "operator" "return" "std"
      "struct" "try" "typedef" "using" "void"))

   (:meanword
    .("\"[^\"]*\"" "(-)?[0-9]+" "[A-Za-z_][A-Za-z_]*")))

  ;skipword
  ("//.*$" "[:space:]+"))

(defclassifier make-python-classifier
  ((:keyword 
    .("!=" "%" "," ":" "<" "=" ">" ">=" "\\(" "\\)" "\\*" "\\+" "\\." "\\[" "\\]"
      "__class__" "__init__" "__name__" "__unicode__" "append" "class" "cond" "def"
      "dict" "except" "for" "if" "import" "in" "join" "lambda" "len" "list" "print"
      "return" "setattr" "try" "unicode" "yield"))

   (:meanword
    .("\"[^\"]*\"" "(-)?[0-9]+" "[A-Za-z_][A-Za-z_]*" "u?'[^']*'")))

  ;skipword	
  ("#.*$" "[:space:]+"))

(defclassifier make-lisp-classifier
  ((:keyword 
    .("\\." "#'" "%" "&key" "&optional" "'" "," ",@" "/" "1\\+" ":" ":test" "<" "<>" "="
      ">" ">=" "\\(" "\\)" "\\*" "\\+" "`" "and" "break" "caar" "cond" "defun" "eq"
      "equal" "gethash" "if" "in-package" "lambda" "length" "list" "make-hash-table"
      "make-instance" "not" "print" "progn" "push" "setf" "setq" "slot-value"
      "string=" "t" "terpri"))

   (:meanword
    .("\"[^\"]*\"" "(\\-)?[0-9]+" "[A-Za-z][A-Za-z\\-\\+]*" "[\\[]" "[\\]]")))

  ;skipword	
  (";.*$" "[:space:]+"))

Как видим, получилось не только короче, но и понятнее, удалось описать
только существенную часть. В результате замеры показали:

Параметр                        | Без макро | С макро
-----------------------------------------------------
Общая длина                     |      3110 |    896
Смысловая длина                 |      1192 |    446
Общий тезаурус                  |       252 |    256
Смысловой тезаурус              |       222 |    225
Общая насыщенность (в %)        |        38 |     50
Насыщенность тезауруса (в %)    |        88 |     88
Общая выразительность (в %)     |         8 |     29
Смысловая выразительность (в %) |        19 |     50

То есть, практически без изменения словаря удалось сократить программу
в 3.5 раза и примерно в 3 раза повысить выразительность программы. А
по мере увеличения количества языков и ключевых слов в них эта цифра
может стать еще больше.

Кстати, это хорошо показывает, что понимается под
"быдлопрограммированием", и что никакой язык не застрахован от такого
стиля программирования. Другое дело, позволяет ли язык писать
компактно. Например, интересно посмотреть, как эта проблема может быть
решена в Питоне.

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

Ну вот. На 38-й странице наконец пошёл конструктив :)

Наконец-то приоткрылась полезность макров на _конкретном_ примере. Спасибо.

Буду читать про лисп, давно хотел, но всё в полезности сомневался.

realsmart
()
Ответ на: комментарий от eugine_kosenko

>(defclassifier make-lisp-classifier...)

С методом категорически не согласен. Повторю свою точку зрения. Нам надо программы привести к виду синтаксического дерева. Осуществлять подсчет по ключевым словам неправильно. Особенно в LISP! В LISP надо подсчитать толко узлы деревьев, т. е. количество окрывающихся скобочек. А так ты получишь, что LISP имеет бесконечно большое количество ключевых слов. Хоть ты и пытаешься использовать какое-то подмножество их, но вот (defclass...) ты куда денешь? А это макрос уже. Учесть, получается, нельзя. Не учесть -- тоже неправильно, потому что объявление class в C++ вроде есть (+1 в keyword), а в LISP ты посчитаешь, что это (+1 в meanword). Получается, ты сравниваешь не структуру программ, а число используемых ключевых слов и идентификаторов, что для LISP не имеет смысла. Скажу кощунство, но в LISP нет синтаксиса. Программирование в LISP -- это составление синтаксического дерева, т. е. низкоуровневой синтаксической структуры, к которой могут приведены и другие языки после парсинга. А вот макросы LISP не могут быть приведены к C++, так как они просто не могут быть описаны в терминах C++. Получается, что LISP -- это синтаксическое надмножество.

if (a == getSomeValue (b)) { return a };

Если распарсить по синтаксическому дереву, то получим:

(if (== a (getSomeValue b)) (return a))

Отсутсвие возможности делать макросы, как в LISP сразу же вылезет наружу при таком вот анализе. Ты получишь ситуацию, когда синтаксическое дерево C++ не сможет выйти за рамки оспользования ключевых слов и вызова функций. А в LISP я смогу переопределить ключевые слова, и твой алгоритм начнет сбоить. Переопределю if на if* и буду везде использовать последний. Твой алгоритм один раз посчитает if в макросе или функции, а в остальной программе больше никогда его не найдет. LISP-программа обхитрит твой алгоритм.

А вот по размеру и *структуре* (структурный анализ тоже можно проводить: подумать, есть ли смымл в "ветвистости" и пр.) синтаксического дерева можно вполне судить обо всех параметрах языков. При использовании макросов ты сразу увидишь сокращение синтаксического дерева. синтаксический анализ не должен уходить в учет ключевых слов и идентификаторов.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

> В LISP надо подсчитать толко узлы деревьев, т. е. количество окрывающихся скобочек.

Оформляя почти любой блок кода через loop я резко снижу количество этих самх скобок.

yyk ★★★★★
()
Ответ на: комментарий от satanic-mechanic

Если просто переписать впрямую этот код, то код на Лиспе будет на 20% короче и существенно понятнее за счет одной только ликвидации извратов с рекурсией:

#| ;; OCaml let get_items (map, n, m) = let rec get_items_aux accu = function (i, j) when i = n -> accu | (i, j) when j = m -> get_items_aux accu (i + 1, 0) | (i, j) -> get_items_aux (if map.(i).[j] = 'S' then (i, j) :: accu else accu) (i, j + 1) in get_items_aux [] (0, 0) ;; |#

;; Common Lisp (defun get-items (map n) (loop for i from 0 below n append (loop with cpos = 0 for p = (position #\S (aref map i) cpos) when p collect (cons i p) do (setf cpos p))))

#| ;; OCaml let find (map, n, _) c = let rec find_aux i = if i = n - 1 then raise Not_found else try (i, String.index map.(i) c) with Not_found -> find_aux (i + 1) in find_aux 0

;; Common Lisp (defun find (map n c) (loop for row across map for p = (position с row) when p do (return (values i p))))

anonymous
()
Ответ на: комментарий от satanic-mechanic

Если просто переписать впрямую этот код, то код на Лиспе будет на 20% короче и существенно понятнее за счет одной только ликвидации извратов с рекурсией: 

#| ;; OCaml 
let get_items (map, n, m) =
  let rec get_items_aux accu = function
      (i, j) when i = n -> accu
    | (i, j) when j = m -> get_items_aux accu (i + 1, 0)
    | (i, j) -> get_items_aux (if map.(i).[j] = 'S' then (i, j) :: accu else accu) (i, j + 1)
  in get_items_aux [] (0, 0) ;;
|# 

;; Common Lisp 
(defun get-items (map n) 
    (loop for i from 0 below n append 
        (loop with cpos = 0 
              for p = (position #\S (aref map i) cpos) when p  
              collect (cons i p) do (setf cpos p))))

#| ;; OCaml 
let find (map, n, _) c =
  let rec find_aux i =
    if i = n - 1 then raise Not_found
    else try (i, String.index map.(i) c) with Not_found -> find_aux (i + 1)
  in find_aux 0
|#


;; Common Lisp 
(defun find (map n c) 
    (loop for row across map 
          for p = (position с row) 
          when p do (return (values i p))))

anonymous
()
Ответ на: комментарий от satanic-mechanic

Исправление:

(defun find (map n c)
  (loop for i from 0 below (length map)
        for p = (position c (aref map i))
        when p do (return (values i p))))


anonymous
()
Ответ на: комментарий от anonymous

Исправление:

(defun get-items (map n) (loop for i from 0 below n append (loop with cpos = 0 for p = (position #\S (aref map i) :start cpos) while p collect (cons i p) do (setf cpos p))))

anonymous
()
Ответ на: комментарий от anonymous

Исправление:

(defun get-items (map n m)
  (loop for i from 0 below n nconc
     (loop for j from 0 below m
           when (eql (elt (aref map i) j) #\S) 
           collect (cons i j))))

anonymous
()
Ответ на: комментарий от anonymous

Да, я вижу, что loop это круто. Но все же не вижу никакого изврата в своих рекурсиях - стандартный подход в ФП, код прозрачный и понятный. Думаю реализация в виде цикла вам была бы понятнее, но лично мне так нравится гораздо больше.

satanic-mechanic
()
Ответ на: комментарий от Zubok

> А так ты получишь, что LISP имеет бесконечно большое количество ключевых слов.

Стандарт Common Lisp конечен (хотя и велик). Поэтому количество ключевых слов тоже конечно.

> Хоть ты и пытаешься использовать какое-то подмножество их, но вот (defclass...) ты куда денешь?

Если определено в стандарте, то это ключевое слово. Вообще говоря, ключевыми являются те слова, которые определены сразу после запуска без подключения дополнительных библиотек или пакетов. То есть, это что-то вроде "батареек из коробки".

> Скажу кощунство, но в LISP нет синтаксиса.

Если бы в Лиспе не было синтаксиса, то не было бы и синтаксических ошибок. А они есть. Начиная с неверного числа скобок и неправильного числа аргументов при вызове функции, и заканчивая нарушением правил обратной блокировки.

> А в LISP я смогу переопределить ключевые слова, и твой алгоритм начнет сбоить.

А в С++ я могу переопределить стандартные операторы, как это сделано, например, для потокового вывода.Ты и сам это косвенно подтвердил -- переопределение ключевого слова не делает его смысловым.

> А вот по размеру и *структуре* (структурный анализ тоже можно проводить: подумать, есть ли смымл в "ветвистости" и пр.) синтаксического дерева можно вполне судить обо всех параметрах языков.

Любая методика несовершенна. Например, в С++ тоже есть макросы, и их далеко не всегда можно учесть на синтаксическом уровне. Важнее добиться приемлемого соотношения качества методики и усилий, потраченных на ее реализацию. Лексеры я смог сделать играючи, но с грамматиками (тем более, контекстно-зависимыми) мне возиться уже не хочется. Есть задачи и поважнее. Пусть синтаксическим разбором занимаются недовольные моей методикой.

eugine_kosenko ★★★
()
Ответ на: комментарий от satanic-mechanic

Вот что получается при переписывании первой части кода c OCaml на CL:

(defstruct world map w h)

(defmacro with-world ((x y &optional p inner-body) w &body body)
  `(block with-world
     (loop for ,y fixnum from 0 below (world-h ,w) do
        (loop for ,x fixnum from 0 below (world-w ,w) 
              ,@(when p `(for ,p = (aref (world-map ,w) ,y ,x)))
              do ,@body)
        ,@(when inner-body `(,inner-body)))))

(defmacro promise ((fn &rest args))
  (let ((iargs (mapcar #'(lambda (x) (if (equal (symbol-name x) "_")
                                         (gensym) x)) args)))
    `(lambda ,(remove-if (lambda (x) (position x args)) iargs)
       (,fn ,@iargs))))
 
(defun lies-thing-p (world x y &optional (c #\S))
  (eql (aref (world-map world) y x) c))

(defun get-items (world)
  (let ((items ()))
    (with-world (x y) world
        (when (lies-thing-p world x y) (push (cons y x) items)))
    items))

(defun find (world c)
  (with-world (x y p) world
     (when (eql p c) (return-from find (cons y x)))))

(defun n-items (world) (length (get-items world)))

(defun output (stream world) 
   (with-world (x y p (terpri stream)) world 
     (princ p stream)))
      
(defun input-map (stream)
 (let ((lines (loop for line = (read-line stream nil 'eof)
                    until (eq line 'eof) collect line)))
   (make-array (list (length lines) (length (first lines))) :initial-contents acc)))


(defun send (stream world x y)
  (format stream "~D~%" (world-height world))
  (with-world (j i p (terpri stream)) world
    (princ (if (and (= x j) (= y i)) #\@ p) stream)))

(defun recv-common (stream n)
  (loop for line = (read-line stream nil 'eof) 
        unless (eq line 'eof) collect line))

(defun recv (stream)
  (input-map stream))

(defun recv-stat (stream) (recv-common stream 3))

(defun send-stat (stream world x y is-empty-p)  
 (map nil (promise (print _ stream)) (list
    (if (and (zerop (n-items world)) is-empty-p) "You won!" "Game is in progress"))
    (if is-empty-p "Your hand are empty" "You carry an item")
    (format nil "Here lies ~D item(s)" (if (lies-thing-p world y x) 1 0))))

кривовато, но код на CL в целом получается короче из-за прямолинейности и некоторой экономии на макрах.

anonymous
()
Ответ на: комментарий от anonymous

Исправление:

(defun input-map (stream)
 (let ((lines (loop for line = (read-line stream nil 'eof)
                    until (eq line 'eof) collect line)))
   (make-array (list (length lines) (length (first lines))) 
               :initial-contents lines)))

anonymous
()
Ответ на: комментарий от satanic-mechanic

> стандартный подход в ФП, код прозрачный и понятный

Я вовсе не против рекурсии, но IMHO в данном примере задача решается задом наперед. Если бы вспомогательные функции использовались повторно, то польза такого подхода была бы очевидной, но они все равно повторяются, тогда какой смысл все делать задом наперед, вручную рулить циклами как в функции:

let rec get_items_aux accu = function (i, j) when i = n -> accu | (i, j) when j = m -> get_items_aux accu (i + 1, 0) | (i, j) -> get_items_aux (if map.(i).[j] = 'S' then (i, j) :: accu else accu) (i, j + 1) in ...

Если строка последняя, то вернуть список вещей, иначе если кончилась строка, то перейти на следующую строку, иначе собрать вещи (если здесь вещь то добавить в список) левее.

Зачем мучиться такими низкоуровневыми деталями ?

IMHO проще:

Перебирая карту, если *здесь* лежит-вещь, добавить *координаты* в список.

anonymous
()
Ответ на: комментарий от satanic-mechanic

Да, и кстати имена вспомогательных функций - это тоже лишние детали. Хотя наверняка тут еще можно оптимизировать с помощью функций высшего порядка, чтобы код для обхода карты не повторялся. Потом есть функции с идентичным кодом:

let input ic =
  let rec input_aux () =
    try let line = input_line ic in line :: input_aux () with End_of_file -> []
  in  let m = Array.of_list (input_aux ()) in m, Array.length m, String.length m.(0)

let recv_common ic n =
  let rec rc_aux = function
      0 -> []
    | n -> let line = input_line ic in line :: rc_aux (n - 1)
  in  rc_aux n

let recv ic =
  let n = int_of_string (input_line ic) in
  let map = Array.of_list (recv_common ic n) in map, n, String.length map.(0)

почти то же самое для вывода:

let output oc (map, n, m) =
  for i = 0 to n - 1 do
    for j = 0 to m - 1 do
      output_char oc map.(i).[j]
    done ;
    output_char oc '\n'
  done

let send oc (map, n, m) ((x, y), _) =
  output_string oc (Printf.sprintf "%d\n" n) ;
  for i = 0 to n - 1 do
    for j = 0 to m - 1 do
      output_char oc (if x = i && y = j then '@' else map.(i).[j])
    done ;
    output_char oc '\n'
  done

anonymous
()
Ответ на: комментарий от satanic-mechanic

Да, и кстати имена вспомогательных функций - это тоже лишние детали. Хотя наверняка тут еще можно оптимизировать с помощью функций высшего порядка, чтобы код для обхода карты не повторялся. Потом есть функции с почти идентичным кодом:

let input ic = let rec input_aux () = try let line = input_line ic in line :: input_aux () with End_of_file -> [] in let m = Array.of_list (input_aux ()) in m, Array.length m, String.length m.(0)

let recv_common ic n = let rec rc_aux = function 0 -> [] | n -> let line = input_line ic in line :: rc_aux (n - 1) in rc_aux n

let recv ic = let n = int_of_string (input_line ic) in let map = Array.of_list (recv_common ic n) in map, n, String.length map.(0)

почти то же самое для вывода:

let output oc (map, n, m) = for i = 0 to n - 1 do for j = 0 to m - 1 do output_char oc map.(i).[j] done ; output_char oc '\n' done

let send oc (map, n, m) ((x, y), _) = output_string oc (Printf.sprintf "%d\n" n) ; for i = 0 to n - 1 do for j = 0 to m - 1 do output_char oc (if x = i && y = j then '@' else map.(i).[j]) done ; output_char oc '\n' done

anonymous
()
Ответ на: комментарий от anonymous

На счет input и recv я так и думал, но не очень красиво получалось. Тем более, что для меня критерием являлся не меньший размер, а эстетичность (степень эстетичности разумеется определяется мной по моим субъективным критериям).

output и send так похожи как раз по той причине, что изначально были одной функцией, которую я потом разнес на две. Ниже на пару постов я переопределил output в две строки и указал, что могу уменьшить send, но выглядеть (опять же на мой взгляд) она будет хуже.

По поводу эстетичности и функциональных вызовов вместо циклов - я люблю ФП, поэтому, если какую-либо логику довольно удобно реализовывать без использования изменения состояния, я так и поступлю. По этой причине я и использовал рекурсию с накоплением для поиска всех вещей вместо циклов. Просто я не считаю, что цикл является сдесь более красивым решением. А вот для поиска в ширину, я осознанно использовал обыкновенную очередь. То есть я не фанатег - когда можно и удобно использовать ФП, я его использую, а когда оно не вписывается красиво в рамки логики задачи, я обхожусь императивным программированием.

P. S. Конечно мое решение далеко от совершенства и тут еще много где можно развернуться. Я и не претендовал на что-то. Появятся решения гораздо лучше, я займусь оптимизацией своего...

satanic-mechanic
()
Ответ на: комментарий от yyk

>Оформляя почти любой блок кода через loop я резко снижу количество 
этих самх скобок.


Люблю контрпримеры. Они позволяют двигаться в правильном направлении. 
:)

Вопрос-то непростой. Такая же проблема встанет и в методе, приведенном
 выше, который бегает по ключевым словам и символам:

for (i = 0; i < n; i = i + 2) { body };

посчитается пять раз: на "for", на "=", на "<" и на "=" с "+", а loop 
повезет больше -- он только один раз, хотя синтаксически выглядят 
идентично. Какая-то несправедливость будет по отношению к Си.

(loop :for i :from 0 :below n :by 2 :do ( body ))

Я специально написал через ':', чтобы было понимание, что это не 
функции, а парметры loop, которые используются для раскрытия макроса. 
for, below, do не отловятся, так как это просто символы. Тогда в целях
 сравнения надо потребовать, чтобы loop был хотя бы так:

(let ((i 0)) (loop :while (< i n) :do ( body ) (setq i (+ i 2))))

Тогда выравниваются очки.

Zubok ★★★★★
()
Ответ на: комментарий от satanic-mechanic

Решение на питоне. В качестве middleware :-) платформы используется
Pyro (pyro.sf.net)

[world.dat]
##########
#  # $ # #
#$ #     .
#     #  #
##########

[advserver.py]
#!/usr/bin/env python

import sys
import Pyro.core

from advworld import World

class Server(Pyro.core.ObjBase):
    def init(self, fname):
        self.world = World(fname)
    
    def read_world(self):
        return self.world
    
    def perform_action(self, action):
        self.world.performAction(action)


def main():
    fname = sys.argv[1]
    port = sys.argv[2]
    
    server = Server()
    server.init(fname)
    
    Pyro.core.initServer()
    daemon = Pyro.core.Daemon(host='127.0.0.1', port=int(port))
    daemon.connect(server, 'adventure_server')
    daemon.requestLoop()
    
if __name__ == '__main__':
    main()

[advworld.py]
class World:
    def __init__(self, world_file):
        self.map = []
        self.items = []
        
        f = open(world_file)
        
        row = 0
        while True:
            l = f.readline().strip()
            
            if l == '':
                break
            
            map_line = str(l).replace('$', ' ').replace('.', ' ')
            self.map.append(list(map_line))
            
            for col in xrange(len(l)):
                if l[col] == '$':
                    self.items.append((row, col))
                if l[col] == '.':
                    self.entry = (row, col)
            
            row += 1
        
        self.height = len(self.map)
        self.width = len(self.map[0])
        self.hands_empty = True
        self.position = self.entry
        
    def gameWon(self):
        ok = True
        for item in self.items:
            if item != self.entry:
                ok = False
                break
        return ok and self.hands_empty
    
    def move(self, dx, dy):
        new_col = self.position[1] + dx
        new_row = self.position[0] + dy
        
        try:
            new_place = self.map[new_row][new_col]
        except IndexError:
            new_place = None
        
        if new_place == ' ':
            self.position = (new_row, new_col)
    
    def action_north(self):
        self.move(0, -1)
    
    def action_south(self):
        self.move(0, 1)
    
    def action_east(self):
        self.move(1, 0)
    
    def action_west(self):
        self.move(-1, 0)
    
    def action_pickup(self):
        if self.position in self.items:
            self.items.remove(self.position)
        self.hands_empty = False
    
    def action_drop(self):
        self.hands_empty = True
        self.items.append(self.position)
    
    def performAction(self, action):
        func = None
        try:
            func = getattr(self, 'action_'+action)
        except IndexError:
            pass
        
        if func is not None:
            func()
    
    def __str__(self):
        s = []
        
        for row in xrange(self.height):
            line = ''
            for col in xrange(self.width):        
                pos = (row, col)
                char = self.map[row][col]
                if pos == self.position:
                    char = '@'
                elif pos == self.entry:
                    char = '.'
                elif pos in self.items:
                    char = '$'
                line += char
            s.append(line)
            
        if self.gameWon():
            s.append('You won!')
        else:
            s.append('Game is in progress')
        
        if self.hands_empty:
            s.append('Your hands are empty')
        else:
            s.append('You carry an item')
        
        s.append('Here lie(s) %d item(s)' % (self.items.count(self.position)))
        
        return '\n'.join(s)

[hclient.py]
#!/usr/bin/env python

import sys
import Pyro.core

shortcuts = {
    'n': 'north',
    'e': 'east',
    'w': 'west',
    's': 'south',
    'd': 'drop',
    'p': 'pickup'}

def main():
    host = sys.argv[1]
    port = sys.argv[2]
    
    uri = 'PYROLOC://%s:%s/adventure_server' % (host, port)
    server = Pyro.core.getProxyForURI(uri)
    
    while True:
        print server.read_world()
        
        sys.stdout.write('> ')
        cmd = sys.stdin.readline().strip().lower()[0]
        server.perform_action(shortcuts[cmd])

if __name__ == '__main__':
    main()

[roboclient.py]
#!/usr/bin/env python

import sys
import copy
import time
import Pyro.core

class RoutingError(Exception):
    pass

class Robot:
    wait, goin, goout = range(3)
    
    def __init__(self, server, delay=1):
        self.server = server
        self.delay = 1
        
    def findPath(self, world, target_position):
        map = copy.deepcopy(world.map)
        map[world.position[0]][world.position[1]] = [world.position]
        
        def propagate(pos):
            deltas = [(0, 1), (0, -1), (1, 0), (-1, 0)]
            new_positions = []
            current_path = map[pos[0]][pos[1]]
            
            for d in deltas:
                new_pos = (pos[0] + d[0], pos[1] + d[1])
                new_path = list(current_path) + [new_pos]
                
                try:
                    location = map[new_pos[0]][new_pos[1]]
                except IndexError:
                    location = '#'
                
                if location != '#':
                    if location == ' ' or (len(location) > len(new_path)):
                        map[new_pos[0]][new_pos[1]] = new_path
                        new_positions.append(new_pos)
            return new_positions
        
        positions = [world.position]
            
        while True:
            new_positions = []
            for pos in positions:
                new_positions += propagate(pos)
            positions = new_positions
            
#            print positions
            if not positions:
                raise RoutingError()
            
            path = map[target_position[0]][target_position[1]]
            if isinstance(path, list):
                break
        return path
    
    def moveTo(self, position):
        world = self.server.read_world()
        path = self.findPath(world, position)[1:]
        for pos in path:
            self.stepTo(pos)
    
    def stepTo(self, pos):
        world = self.server.read_world()
        
        dr = pos[0] - world.position[0]
        dc = pos[1] - world.position[1]
        
        directions = {
            (0, -1): 'west',
            (0, 1): 'east',
            (1, 0): 'south',
            (-1, 0): 'north'}
        
        action = directions.get((dr, dc), None)
        if action is None:
            raise RoutingError()
        self.performAction(action)
    
    def performAction(self, action):
        print self.server.read_world()
        print 'Robot action:', action
        time.sleep(self.delay)
        self.server.perform_action(action)
    
    def play(self):
        while True:
            world = self.server.read_world()
            items = [i for i in world.items if i != world.entry]
            
            if not items:
                break
            
            self.moveTo(items[0])
            self.performAction('pickup')
            self.moveTo(world.entry)
            self.performAction('drop')
        print world

def main():
    host = sys.argv[1]
    port = sys.argv[2]
    
    uri = 'PYROLOC://%s:%s/adventure_server' % (host, port)
    server = Pyro.core.getProxyForURI(uri)
    robot = Robot(server)
    robot.play()
    
if __name__ == '__main__':
    main()



redvasily
()
Ответ на: комментарий от redvasily

Общий размер в непустых строках: 217 
Бросается в глаза, то что у меня константы словарей перекодировок 
записаны в несколько строк, напр:

        directions = {
            (0, -1): 'west',
            (0, 1): 'east',
            (1, 0): 'south',
            (-1, 0): 'north'}

Также, если сравнить hclient.py и hclient.ml, сразу бросается в глаза,
что в OCaml импорты неявные, т.е. не надо писать import sys и т.д.

В питоне объявляются переменные host, port, uri, без которых, с одной
стороны можно обойтись, а с другой стороны они служат коментариями.

Также во многих местах в OCaml-е ифы/елзы записаны в строку, в питное
я так не делал никогда.

Общее впечатление от программ:
Питон - много коротких строк
OCaml - мало длинных строк

Сравнение по непустым символам это подтверждает:
OCaml - 4634
Питон - 4427

Написано тоже часа за три. Писал как обычно, нигде особо не ужимался.
Объекты называл как обычно.

Ждём лисповерсию, и eugene_kosenko с его мегаанализом :-)

redvasily
()
Ответ на: комментарий от Zubok

> посчитается пять раз: на "for", на "=", на "<" и на "=" с "+", а loop повезет больше -- он только один раз, хотя синтаксически выглядят идентично. Какая-то несправедливость будет по отношению к Си.

Я согласен добавить к ключевым словам _все_ "ключи" основных макр (defun, defmacro, defclass, loop & etc.) :) Это справедливо? ;)

Можно ещё оговорить ограничение - не переопределять "ключевые" формы (за исключением варианта сокращения вида их использования) :)

yyk ★★★★★
()
Ответ на: комментарий от redvasily

> По моему хорошая задача, т.е. решить такую задачу вобщем-то может 
> каждый, т.е. это не сравнение кто придумает более хитрожопый
> алгоритм, а сравнение именно языков программирования.

Ну, забабахал и я свой опус на Лиспе. Писал два дня, в общей сложности
8 часов из которых треть ушла на обдумывание алгоритма, половина на
чтение документации и примерку структур данных и оставшееся время --
на написание и оптимизацию. То есть, подозреваю, что для грамотного
лиспера понадобилось бы примерно столько же, сколько и для окамлера.

В связи с тем, что я пока не силен в написании серверов на Лиспе,
обмен через сокеты не реализован. Если будет время, допишу. С другой
стороны, отсутствие серверных фенечек вполне компенсируется форматными
рюшечками, которые тыкались для отладки, так что, думаю, это не сильно
повлияет на длину.

Наконец, есть вопросы к формулировке задачи. Во-первых, считается ли,
что роботу доступна вся карта, то есть, известных расположения всех
предметов? Я посчитал, что да, это упрощает алгоритм. Во-вторых, что
делать роботу, если он обнаруживает принципиальную недостижимость
некоторых предметов, которые находятся в замкнутой комнате? У меня в
этом случае выбрасывается исключение, но я его нигде не обрабатываю.
Еще хуже, если робот не видит всей карты -- тогда он в этом случае
вообще не найдет замкнутых предметов.

Статистика:

Total length                                         1158
Meaning length                                        331
Total thesaurus                                       160
Meaning thesaurus                                      85
Total saturation (%)                                   29
Thesaurus saturation (%)                               53
Total expressiveness (%)                               14
Meaning expressiveness (%)                             26

Если сравнивать с решением на Окамле, то получается короче (хотя этот
запас может сожрать работа с сокетами) и менее насыщено, зато более
выразительно. Возможно, это из-за loop и желания новичка перепробовать
весь доступный арсенал. Возможно, циклы могли быть покороче -- на мой
взгляд, это самая "пухлая" часть программы.

Наконец, насколько я понял, по ходу соревнования программы можно
оптимизировать, поэтому оставляю за собой право улучшать этот код по
советам старших товарищей.

---------------------------------------------------------------------

(defun defentities (form names)
  (mapcar #'eval (mapcar form names)))

(defentities
  #'(lambda (name) `(defvar ,name nil))
  '(image-name bound-x bound-y wall-points entry-point 
	 thing-points hero-point hero-carries-thing-p trace-p))

(defun inside-interval-p (interval value)
  (and 
	(>= value (car interval))
	(<= value (cdr interval))))

(defun inside-world-p (point)
  (and
	(inside-interval-p (cons 1 bound-x) (realpart point))
	(inside-interval-p (cons 1 bound-y) (imagpart point))))

(defun wallp (point)
  (or
	(not (inside-world-p point))
	(not (null (member point wall-points)))))

(defun thingp (point)
  (not (null (member point thing-points))))

(defun herop (point)
  (eql point hero-point))

(defun show-world (&optional (markup (make-hash-table)))
  (loop 
	for y from 1 to bound-y
	do (loop
		 for x from 1 to bound-x
		 do (let ((point (complex x y)))
				(cond
				 ((wallp point) (princ #\#))
				 ((herop point) 
				  (princ 
					(cond 
					 (hero-carries-thing-p #\@)
					 ((thingp point) #\*)
					 (t #\.))))
				 ((thingp point) (princ #\$))
				 ((gethash point markup) (format t "~100R" (gethash point markup)))
				 (t (princ " "))))
		 finally (terpri))))

(defun read-world (file-name)
  (setq image-name file-name)
  (setq wall-points ())
  (setq thing-points ())
  (setq hero-carries-thing-p nil)
  (with-open-file 
	(file file-name)
	(loop 
	 for y upfrom 1 
	 while (listen file)
	 do (let ((line (read-line file)))
			(loop
			 for x upfrom 1 
			 for c across line 
			 do (cond
				  ((eq c #\#) (push (complex x y) wall-points))
				  ((eq c #\$) (push (complex x y) thing-points))
				  ((eq c #\.) 
					(setq entry-point (complex x y))
					(setq hero-point (complex x y))))
			 finally (setq bound-x (1- x))))
	 finally (setq bound-y (1- y))))
  (if trace-p (show-world)))

(defun reset-world ()
  (read-world image-name))

(defun go-step (step)
  (let ((new-point (+ hero-point step)))
	 (if (not (wallp new-point))
		  (setq hero-point new-point))
	 (if trace-p (show-world))
	 hero-point))

(defconstant directions
  (pairlis 
	`(#c(1 0) #c(-1 0) #c(0 -1) #c(0 1))
	'(go-east go-west go-north go-south)))

(defentities
  #'(lambda (pair) 
		`(defun ,(cdr pair) () (go-step ,(car pair))))
  directions)

(defun pickup-thing ()
  (cond
	((and (thingp hero-point)
			(not hero-carries-thing-p))
	 (setq hero-carries-thing-p t)
	 (setq thing-points (remove hero-point thing-points :count 1))
	 (if trace-p (show-world)))))

(defun drop-thing ()
  (cond
	(hero-carries-thing-p
	 (setq hero-carries-thing-p nil)
	 (push hero-point thing-points)
	 (if trace-p (show-world)))))

(defmacro do-program (program)
  `(progn ,@(mapcar #'(lambda (command) `(,command)) (eval program))))

(defun neighbours (point)
  (remove-if #'wallp (mapcar #'(lambda (direction) (+ point (car direction))) directions)))

(defun point-front (point markup)
  (remove-if #'(lambda (neighbour) (gethash neighbour markup)) (neighbours point)))
  
(defun next-front (prev-front markup)
  (remove-duplicates (mapcan #'(lambda (point) (point-front point markup)) prev-front)))

(defun mark-front (label front markup)
  (mapcar #'(lambda (point) (setf (gethash point markup) label)) front))

(defun mark-world (label front start-point markup)
  (let ((next-front (next-front front markup)))
	 (mark-front label front markup)
	 (cond
	  ((gethash start-point markup) markup)
	  ((null next-front) (throw :unreachable markup))
	  (t (mark-world (1+ label) next-front start-point markup)))))

(defun make-world-markup (finish-point start-point)
  (mark-world 0 (list finish-point) start-point (make-hash-table)))

(defun next-point (point markup)
  (let ((neighbours (neighbours point))
		  (labels (mapcar #'(lambda (point) (gethash point markup)) (neighbours point))))
	 (cdr (assoc
	  (reduce #'min labels)
	  (pairlis labels neighbours)))))

(defun make-path (start-point finish-point markup)
  (if (eql start-point finish-point)
	 (list finish-point)
	 (cons start-point (make-path (next-point start-point markup) finish-point markup))))

(defun direction (point1 point2)
  (cdr (assoc (- point2 point1) directions)))

(defun path-program (path)
  (if (null (cdr path)) 
	 ()
	 (cons (direction (car path) (cadr path)) (path-program (cdr path)))))

(defun find-path-program (start-point finish-point)
  (path-program (make-path start-point finish-point (make-world-markup finish-point start-point))))

(defconstant command-reversion
  (pairlis
	'(go-east go-west go-north go-south pickup-thing drop-thing)
	'(go-west go-east go-south go-north drop-thing pickup-thing)))

(defun reverse-command (command)
  (cdr (assoc command command-reversion)))

(defun reverse-program (program)
  (reverse (mapcar #'reverse-command program)))

(defun bring-thing-program (thing-point)
  (let ((path-program (find-path-program entry-point thing-point)))
	 (append path-program '(pickup-thing) (reverse-program path-program) '(drop-thing))))

(defun bring-things-program ()
  (reduce #'append (mapcar #'bring-thing-program thing-points)))

eugine_kosenko ★★★
()
Ответ на: комментарий от redvasily

> Ждём лисповерсию, и eugene_kosenko с его мегаанализом :-)

Шутить изволите...

Параметр                        | Лисп | Питон | Окамл
-------------------------------------------------------
Общая длина                     | 1158 |  1462 |  1627
Смысловая длина                 |  331 |   604 |   603
Общий тезаурус                  |  160 |   195 |   164
Смысловой тезаурус              |   85 |   154 |   113
Общая насыщенность (в %)        |   29 |    41 |    37
Насыщенность тезауруса (в %)    |   53 |    79 |    69
Общая выразительность (в %)     |   14 |    13 |    10
Смысловая выразительность (в %) |   26 |    25 |    19

Лисповая версия пока без сокетов, потому преимущества по длине у него,
скорее всего, нет. Зато смысловая длина и смысловой тезаурус (создание
и использование новых понятий) почти в два раза ниже. Причем могу эту
цифру еще уменьшить за счет удаления некоторых функций путем
подстановки, хотя выигрыш в Лиспе достигается за счет малых затрат на
определение функций. Кстати, в этом деле абсолютным чемпионом является
Форт, а я при написании использовал его парадигму -- создание
множества коротких определений. Поэтому результат почти очевиден. По
насыщенности разница примерно на треть, то есть, в Лиспе использовано
больше "сахара", но это скорее мое стремление задействовать весь
арсенал. По выразительности получается почти то же самое.

Кстати, эту программу писал полностью сам, не "обезьянничая", выбрал
довольно оригинальные структуры данных. В целом кажется, что Лисп
оставляет больше времени на обдумывание.

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

Респект. Веремени на это дело сейчас нет ;-( Но судя по всему программу можно укоротить раза в 2. Например не понял, зачем такой замысловатый способ вывода карты. Вот наброски сокетов для LispWorks:

Сервер:
(defun serve-world (port)
  (labels ((talk-with-client (stream)
              (unwind-protect
                 (let ((world (make-world-from-lines (load-map stream))))
                   (serve-world-client world stream))
                   (close stream)))
           (world-service-server (handle)
             (let ((stream (make-instance 'comm:socket-stream
                               :socket handle                               
                               :direction :io                               
                               :element-type 'base-char)))
               (mp:process-run-function "World" () 'talk-with-client stream))))
   (comm:start-up-server :function 'world-service-server :service port)))

Клиент:
(defun connect-world-server (address port)
  (with-open-stream (world-service (comm:open-tcp-stream address port))
    (talk-with-world-service ...)))

Еще не понятно запускают ли OCaml и Python версии отдельные сервера и процессы для каждого клиента ?

anonymous
()
Ответ на: комментарий от eugine_kosenko

Всё сразу охватить времени нет. По кусочкам :)

> (defun inside-interval-p (interval value)
>   (and 
> 	(>= value (car interval))
> 	(<= value (cdr interval))))
>
> (defun inside-world-p (point)
>   (and
> 	(inside-interval-p (cons 1 bound-x) (realpart point))
> 	(inside-interval-p (cons 1 bound-y) (imagpart point))))

Зачем так "навороченно"? :)

(defmacro inside-interval-p (margin value)
  `(and (>= ,value 1) (<= ,value ,margin)))

(defun inside-world-p (point)
  (and
	(inside-interval-p bound-x (realpart point))
	(inside-interval-p bound-y (imagpart point))))

или совсем только так

(defun inside-world-p (point)
  (and (>= #1=(realpart point) 1) (<= #1# bound-x)
       (>= #2=(imagpart point) 1) (<= #2# bound-y)))

может можно ещё короче? :) Раз вызывается один раз - можно и её раскрыть. Вместо 

> (defun wallp (point)
>   (or
> 	(not (inside-world-p point))
> 	(not (null (member point wall-points)))))

(defun wallp (point)
  (or
    (not (and (>= #1=(realpart point) 1) (<= #1# bound-x)
              (>= #2=(imagpart point) 1) (<= #2# bound-y)))
    (not (null (member point wall-points)))))

Да, возможно читается несколько хуже. Но, имхо, нагляднее :)

P.S. Ладно, остально позже.

yyk ★★★★★
()
Ответ на: комментарий от anonymous

Да, у меня (ocaml версия) запускается отдельный процесс на каждого клиента.

satanic-mechanic
()
Ответ на: комментарий от yyk

Тут без концептуальных изменений существенно не укоротить. Для кросс-платформенных сокетов вероятно сойдет trivial-sockets (http://www.cliki.net/trivial-sockets):

Usage examples:

(with-open-stream (s (trivial-sockets:open-stream "www.google.com" 80)) 
  (format s "HEAD / HTTP/1.0~%Host: www.google.com~%~%") 
  (force-output s) 
  (loop 
    (let ((l (read-line s nil nil))) 
      (unless l (return)) 
      (princ l) (terpri))))

(trivial-sockets:with-server (s (:port 8913 :reuse-address t))
   (loop
    (with-open-stream (c (trivial-sockets:accept-connection s)) 
        (read-line c)
        (format c "Hi there!~%"))))

anonymous
()
Ответ на: комментарий от anonymous

> Еще не понятно запускают ли OCaml и Python версии отдельные сервера и процессы для каждого клиента ?

Ну у меня в питоне так:

Запускается процесс сервер: advserver.py world.dat 9876

Теперь к нему может цепляться любой клент. Все они работают с одним миром, который обсчитывается сервером.

Человеческий клиент работает так: hclient.py localhost 9876

Робот-клиент: hclient.py localhost 9876

redvasily
()
Ответ на: комментарий от eugine_kosenko

Вы однако вступили на темную сторону силы ;-) использование EVAL здесь явный overkill. Еще заметно множество подозрительных setq. Ну и так по мелочи: например with-open-file без указания :direction. А все равно Вы молодец.

anonymous
()
Ответ на: комментарий от eugine_kosenko

А как запустить лисповую версию, что для этого надо?

> Во-первых, считается ли, что роботу доступна вся карта, то есть, известных расположения всех предметов?

Да.

> Во-вторых, что делать роботу, если он обнаруживает принципиальную недостижимость некоторых предметов, которые находятся в замкнутой комнате? У меня в этом случае выбрасывается исключение, но я его нигде не обрабатываю.

А фиг его знает, что ему делать :-) Исключение, наверное, нормально.

У меня тоже в роботе происходит исключение RoutingError, и оно тоже нигде не обрабатывается.

Кстати, я не понял, а в лисповой версии человеческий клиент есть? Или только робот?

В Питоне и OCaml-е есть и человеческий клиент, и робот-клиент.

Кстати, по линкам с D нашёл такую телегу про C++ vs Lisp http://userpages.umbc.edu/~bcorfm1/C++-vs-Lisp.html

redvasily
()
Ответ на: комментарий от redvasily

>Запускается процесс сервер: advserver.py world.dat 9876 >Теперь к нему может цепляться любой клент. Все они работают с одним >миром, который обсчитывается сервером.

Несколько роботов шарятся по одной и той же карте ? Что значит "любой клиент" ? IMHO каждому клиенту свой свежий мир надо давать.

anonymous
()
Ответ на: комментарий от redvasily

> Кстати, я не понял, а в лисповой версии человеческий клиент есть? Или только робот?

Человеческий клиент сводится к набору тривиальных функций-команда go-east, go-west, go-north, go-south, pickup-thing, drop-thing, show-world, reset-world и макро do-program, которое исполняет список команд, переданный в качестве аргумента. Кроме того, можно включить трассировку, тогда после каждой команды будет выводиться карта мира.

Робот сводится к тривиальному вызову bring-things-program, который возвращает список-программу для сбора всех вещей. Эта программа может быть подана в do-program.

> В Питоне и OCaml-е есть и человеческий клиент, и робот-клиент.

Я ж сказал, что сокеты не сделаны. Сейчас расковырял cl-trivial-sockets, похоже, получится еще красивее. Просто сетевое взаимодействие -- не мой профиль. Лет 5 назад баловался многопоточными игрушечными серверами на Ruby, но это все несерьезно.

eugine_kosenko ★★★
()
Ответ на: комментарий от anonymous

> Тут без концептуальных изменений существенно не укоротить.

Не результата ради, а демонстрации для:

> (defun defentities (form names)
>   (mapcar #'eval (mapcar form names)))

> (defentities
>   #'(lambda (name) `(defvar ,name nil))
>   '(image-name bound-x bound-y wall-points entry-point 
> 	 thing-points hero-point hero-carries-thing-p trace-p))

Это тоже можно заменить на

(defmacro definities (&rest args)
  `(progn ,@(loop for d in args collect `(defvar ,d nil))))

(definities image-name bound-x bound-y wall-points entry-point 
            thing-points hero-point hero-carries-thing-p trace-p)

yyk ★★★★★
()
Ответ на: комментарий от yyk

Далее: (not (null x)) равносильно самому x, если только тебе не надо приципиально получить T вместо конкретного значения.

yyk ★★★★★
()
Ответ на: комментарий от anonymous

Согласен, но до глобального передела проекта дело ещё не дошло :)

Все по порядку ;)

Вот несколько сокращённая версия read-world:

(defun read-world (file-name)
  (setf image-name file-name
	wall-points ()
	thing-points ()
	hero-carries-thing-p nil)
  (with-open-file (file file-name)
    (loop for line = (read-line file nil nil)
	  for y upfrom 1 
	  while line
	  do (loop for x upfrom 1 
		   for c across line 
		   do (cond
		       ((eq c #\#) (push (complex x y) wall-points))
		       ((eq c #\$) (push (complex x y) thing-points))
		       ((eq c #\.) 
			(setq entry-point (complex x y))
			(setq hero-point (complex x y))))
		   finally (setq bound-x (1- x)))
	  finally (setq bound-y (1- y))))
  (if trace-p (show-world)))

Хотя мне совсем непонятна система координат с 1, а не с 0. Имхо, ещё несколько можно было упростить программу :)

yyk ★★★★★
()
Ответ на: комментарий от anonymous

> Ну где tailgunner тыкните его в проги носом:)

Я за него!

А если серьёзно, у тебя есть какой-то анализ, выводы, аналитика по поводу решений на разных языках?

Если есть, то не держи это в себе, расскажи нам...

redvasily
()
Ответ на: комментарий от anonymous

Однако и без макросов програмки ничего выглядят...

У меня есть версия: лисп рулит по той же причине по какой рулит питон, а именно встроенные в язык типы данных высокого уровня + автоматическое управление памятью.

См. про EasySTL и D см. shootout про OCaml

И макросы здесь не причём. Ну да, сделали на макросах CLOS, ну молодцы, в других языках сделали объектную систему без макросов.

Ну допустим используя макросы можно использотвать огрехи дизайнера языка, напр. (loop ...), а можно сразу пользоваться языком в котором дизайнеры не далали огрехов.

redvasily
()
Ответ на: комментарий от anonymous

>Имеется в виду ответ на вопрос на хуа макросы:)Програмка ниче так с макросами выглядит.

Как будто он не знал.

anonymous
()
Ответ на: комментарий от redvasily

>И макросы здесь не причём. Ну да, сделали на макросах CLOS, ну >молодцы, в других языках сделали объектную систему без макросов.

В "других языках" кроме объектной системы ничего не предлагается. А на макрах можно статический вывод типов сделать (делали как-то раз библиотеку поточных функторов, надстроили над CLOS еще один уровень с библиотекой TypeL). Потом опять же что-то вроде CELLS никак не сделать. В AllegroCL встраивается Prolog, на котором можно писать запросы к ООБД. Это уже одними библиотеками не осилить.

>Ну допустим используя макросы можно использотвать огрехи дизайнера >языка, напр. (loop ...), а можно сразу пользоваться языком в >котором дизайнеры не далали огрехов.

А можно вместо огрехов взять библиотеку iterate и закинуть loop куда подальше, или сделать свой loop. Идеальный язык без огрехов, существует ли он вообще ?

anonymous
()
Ответ на: комментарий от redvasily

Самый большой недостаток CL (и множества других Лиспов), это наличие чрезмерной свободы, язык мало ограничивает кодера. Поэтому написать ужасный неподдерживаемый код очень даже легко. Хотя я на CL и Scheme больше видел красивый код, видимо кривой код на Лиспе редко доживает до стороннего использования.

Неплохой выход из этой ситуации, небольшой группой из 2-3 человек создавать узкозаточенный DSL под задачу, который подхватят уже менее квалифицированные кадры и не смогут на нем делать бардак, а продуктивность их будет выше, чем если просто взять какой-то искусственно ограниченный язык (вроде Java). Но в отличие от DSL, который можно соорудить посредством lex/yacc, этим кодерам не надо будет на каждый DSL знакомиться с полностью новым языком, достаточно базовых знаний Лиспа + документация по особенностям конкретного DSL.

anonymous
()
Ответ на: комментарий от redvasily

> У меня есть версия: лисп рулит по...

И Ваша версия имеет право на жизнь ;) А если уточнить - для кого именно "лисп рулит" по указанным Вами причинам - так и версия вполне даже может оказаться верной :) Надеюсь, Вы на большее и не претендовали?

> Ну допустим используя макросы можно использотвать огрехи дизайнера языка, напр. (loop ...)

1. Вы хотели сказать не "использотвать огрехи", а "исправить огрехи"? :) И какой-же "огрех", по-вашему, исправляет loop? Уж не DO? :) И где я могу ознакомиться с факторами, определяющими "огрехи"?

2. Макры можно использовать много для чего. Но самое главное - их _можно_ использовать, и их удобно использовать. В отличие от большинства остальных языков ;)

> а можно сразу пользоваться языком в котором дизайнеры не далали огрехов.

Где, где это чудо "без огрехов"? :)

yyk ★★★★★
()
Ответ на: комментарий от yyk

> Упс, не заметил, что definities используется не один раз - прошу прощения :)

В версии с сокетами уже не используется. Пришлось вернуться к полноценной структуре. Код увеличился, но подозреваю, это можно починить переходом на классы.

eugine_kosenko ★★★
()
Ответ на: комментарий от anonymous

> Самый большой недостаток CL (и множества других Лиспов), это наличие чрезмерной свободы, язык мало ограничивает кодера. Поэтому написать ужасный неподдерживаемый код очень даже легко. Хотя я на CL и Scheme больше видел красивый код, видимо кривой код на Лиспе редко доживает до стороннего использования.

Да нет, встречается. Особенно когда стараются минимизировать код "писательством" в стиле перловки - ужас 8-Е

> Неплохой выход из этой ситуации, небольшой группой из 2-3 человек создавать узкозаточенный DSL под задачу, который подхватят уже менее квалифицированные кадры и не смогут на нем делать бардак, а продуктивность их будет выше, чем если просто взять какой-то искусственно ограниченный язык (вроде Java). Но в отличие от DSL, который можно соорудить посредством lex/yacc, этим кодерам не надо будет на каждый DSL знакомиться с полностью новым языком, достаточно базовых знаний Лиспа + документация по особенностям конкретного DSL.

Может быть. Если "кодерам" будет доступен _только_ DSL - то уж лучше пусть это делает какой-нибудь "автомат-кодогенератор" ;) А если и DSL и остальной лисп - опять же так можно завернуть...

От этих скобочек действительно может тошнить, если ты не понимаешь что они тебе дают. Т.е. тупо набивать монотонный код в стиле FoxPro/dBase на лиспе, не задумываясь об оптимизации _собственного труда_ - большей пытки для лиспера наверное и быть не может ;)

yyk ★★★★★
()
Ответ на: комментарий от eugine_kosenko

> В версии с сокетами уже не используется. Пришлось вернуться к полноценной структуре. Код увеличился, но подозреваю, это можно починить переходом на классы.

А код где? :)

yyk ★★★★★
()
Ответ на: комментарий от redvasily

Человеческим языком. Попробую. CELLS - это библиотека, позволяющая определять классы, у которых есть вычисляемые поля. Прямая аналогия -электронная таблица, изменяем одну клеточку, меняются зависимые клетки. Мы определяем модель, пишем код, спокойно вплетая в него ссылки на другие клетки, далее CELLS при необходимости инициирует пересчет полей, так чтобы в нем участвовали только зависимые клетки. Вообще там не обязательно делать клетку именно полем какого-то класса, но так просто удобнее. Такое скорее всего можно сделать без макр, но пользоваться будет очень гиморно и будет тормозить.

anonymous
()
Ответ на: комментарий от yyk

> Вы хотели сказать не "использотвать огрехи", а "исправить огрехи"? :) И какой-же "огрех", по-вашему, исправляет loop? Уж не DO? :)

Угу. Всё так.

> Где, где это чудо "без огрехов"? :)

Это провокация. Нискажууу...

redvasily
()
Ответ на: комментарий от yyk

> Вот несколько сокращённая версия read-world:

Спасибо, приму.

> Хотя мне совсем непонятна система координат с 1, а не с 0. Имхо, ещё несколько можно было упростить программу :)

Исключительно в целях отладки. Стандартный принтер оптимизирует вывод комплексных чисел с нулевой мнимой частью, и координаты становятся трудночитаемыми. Сейчас, когда версия уже готова, можно и переделать под 0. А где упростится?

> Далее: (not (null x)) равносильно самому x, если только тебе не надо приципиально получить T вместо конкретного значения.

А это правильно? Я сам долгое время использовал для проверок не булевые значение. А потом в учебнике нашел, что правильно писать (null x). (not (null x)) видимо получилось в результате эволюции. Может быть, исправлю.

> Глобальные переменные - это зло ;-)

Небольшой трюк для оптимизации кода. В сетевой версии глобальных переменных уже нет. Кстати, извиняюсь, что сам не ковырял код на Питоне и Окамле (в данном случае я выступаю в роли чукчи-писателя :-), там мир представлен глобально или локально? Как насчет "разделения миров" для пользователей, которое тут упоминалось?

Сетевая версия уже почти готова. Но она мощнее заданной спецификации. В частности, добавлена команда reload-world, которая сбрасывает мир в исходное состояние, у пользователя есть возможность за один прием ввести целую цепочку команд (программу), а также в любой точке применить метакоманду autocollect, аналогичная запуску робота, который соберет все предметы в точку текущего положения героя. Если герой находится на выходе, то autocollect автоматически решает задачу. Минус в том, что при этом не трассируются промежуточные действия робота. Правильно было бы ввести возможность задания подпрограмм и параметр trace-level для программ и метакоманды auto, который позволит выполнять демонстрировать промежуточные состояния мира с заданной точностью. Пока что приделал отдельный вызов робота с дополнительным параметром trace-level, который позволит детализировать действия робота на трех уровнях -- "показать только результат", "показать порядок сбора предметов" и "показать все шаги" (уровень детализации определяется подпрограммами. Наконец, реализована метакоманда quit, которая позволяет корректно завершить работу клиента.

Интересно, насколько сложно реализовать все это в других языках? Я к тому, что на задаче такого уровня Лисп только начинает проявлять свою силу. То есть, предложенный DSL команд в оригинальной постановке оказался слишком примитивен.

eugine_kosenko ★★★
()
Ответ на: комментарий от redvasily

> > Вы хотели сказать не "использотвать огрехи", а "исправить огрехи"? :) И какой-же "огрех", по-вашему, исправляет loop? Уж не DO? :)

> Угу. Всё так.

Неа, не согласен (с тем, что DO - огрех). Но спорить не буду, так как определение огреха не получил. Мало того, кое-где DO реализован через LOOP :)

> Это провокация. Нискажууу...

Т.е. его нет? ;)

yyk ★★★★★
()
Ответ на: комментарий от yyk

> А код где? :)

В состоянии завершения. Дописываю подпрограммы и трейсер (уж очень не хочется отдельного клиента для робота делать), а также собственно замеры сложности.

К сожалению, сегодня вряд-ли допишу -- иду на тайную сходку питонистов. Может быть, завтра. И так до 4 утра курил доку по сокетам. Честно говоря, сделаны они там кривовато. Одна особенность чтения сокета на сервере и на клиенте стоила мне 3 часов экспериментов.

И вообще, общее впечатление, что неформатный ввод в Лиспе сосет нипадецки. Вечером покажу куски кода -- может, я чего не понял?

eugine_kosenko ★★★
()
Ответ на: комментарий от redvasily

Вот один из примерчиков, сейчас еще найду менее лохматый:

(in-package :cells)

(defmodel computer ()
  ((hear :cell :ephemeral :accessor hear :initform (c-in nil))
   (salutation :initarg :salutation :accessor salutation :initform "hello")
   (response :initform nil :initarg :response
	             :unchanged-if Сstring= :accessor response)))

(def-c-output response ()
  (when new-value
    (format t "~&hear: ~a~%respond: ~a" (hear self) new-value)))

(defun hello-world ()
  (cell-reset)
  (let ((system (make-instance 'computer
                 :response (c? (let ((r (case (hear self)
                                          (:knock-knock "who's there?")
                                          (:world (concatenate 'string
                                                     (salutation self)
                                                    ", "
                                                    (string (hear self))))
                                          ((nil) "<silence>"))))
                                 (if (string= r .cache)
                                     (format nil "i said, \"~a\"" r)
                                   r))))))
    (format t "~&to-be initialization complete")
    (setf (hear system) :knock-knock)
    (setf (hear system) :knock-knock)
    (setf (hear system) :world)
    (setf (salutation system) "hiya")
    (values)))

#+test
(hello-world)

#| output

hear: nil
respond: <silence>
hear: knock-knock
respond: who's there?
hear: knock-knock
respond: i said, "who's there?"
hear: world
respond: hello, world

|#

anonymous
()
Ответ на: комментарий от redvasily

Вот отсюда: http://bc.tech.coop/blog/030911.html Примерчик:

(defmodel motor () ((status :cell t :initarg :status :accessor status :initform nil) (fuel-pump :cell t :initarg :fuel-pump :accessor fuel-pump :initform (c? (ecase (^status) (:on :open) (:off :closed)))) (temp :cell t :initarg :temp :accessor temp :initform (cv 0))))

(def-c-echo status ((self motor)) (trc "motor status changing from" old-value :to new-value))

(def-c-echo fuel-pump ((self motor)) (trc "motor fuel-pump changing from" old-value :to new-value))

(def-c-echo temp ((self motor)) (trc "motor temperature changing from" old-value :to new-value))

(defparameter *motor1* (to-be (make-instance 'motor :status (c? (let ((filtered-temp (^temp self (fsensitivity 0.05)))) (if (< filtered-temp 100) :on :off))))))

(dotimes (x 2) (dotimes (y 10) (let ((newtemp (+ 99 x (random 0.04) -.02))) (setf (temp *motor1*) newtemp))))

This produces the following results:

0> motor temperature changing from NIL :TO 0 0> motor temperature changing from 0 :TO 98.99401 0> motor temperature changing from 98.99401 :TO 99.01954 [snipped 8 intermediate readings] 0> motor temperature changing from 99.00016 :TO 100.00181 0> motor status changing from :ON :TO :OFF 0> motor fuel-pump changing from :OPEN :TO :CLOSED 0> motor temperature changing from 100.00181 :TO 100.0177 0> motor temperature changing from 100.0177 :TO 99.98742 0> motor temperature changing from 99.98742 :TO 99.99313 [snipped 6 intermediate readings]

anonymous
()
Ответ на: комментарий от redvasily

Пардон. Забыл про форматирование:

(defmodel motor ()
  ((status :cell t :initarg :status :accessor status :initform nil)
   (fuel-pump :cell t :initarg :fuel-pump :accessor fuel-pump 
	      :initform (c? (ecase (^status) (:on :open) (:off :closed))))
   (temp :cell t :initarg :temp :accessor temp :initform (cv 0))))


(def-c-echo status ((self motor))
  (trc "motor status changing from" old-value :to new-value))

(def-c-echo fuel-pump ((self motor))
  (trc "motor fuel-pump changing from" old-value :to new-value))

(def-c-echo temp ((self motor))
  (trc "motor temperature changing from" old-value :to new-value))


(defparameter *motor1* (to-be (make-instance 'motor 
		 :status (c? (let ((filtered-temp (^temp self (fsensitivity 0.05))))
			       (if (< filtered-temp 100) :on :off))))))

(dotimes (x 2)
  (dotimes (y 10)
    (let ((newtemp (+ 99 x (random 0.04) -.02))) 
      (setf (temp *motor1*) newtemp))))


This produces the following results: 

0> motor temperature changing from NIL :TO 0 
0> motor temperature changing from 0 :TO 98.99401 
0> motor temperature changing from 98.99401 :TO 99.01954 
[snipped 8 intermediate readings] 
0> motor temperature changing from 99.00016 :TO 100.00181 
0> motor status changing from :ON :TO :OFF 
0> motor fuel-pump changing from :OPEN :TO :CLOSED 
0> motor temperature changing from 100.00181 :TO 100.0177 
0> motor temperature changing from 100.0177 :TO 99.98742 
0> motor temperature changing from 99.98742 :TO 99.99313 
[snipped 6 intermediate readings]

anonymous
()
Ответ на: комментарий от eugine_kosenko

> А где упростится?

Возможно анализ значений кое-где можно будет упростить. Но будем уже смотреть в новой версии :)

> А это правильно? Я сам долгое время использовал для проверок не булевые значение. А потом в учебнике нашел, что правильно писать (null x). (not (null x)) видимо получилось в результате эволюции. Может быть, исправлю.

Ну, в самом начале может и полезно пользоваться такими методами. А на практике чаще всего так не делают. Более того, IF-ы с одним выражением, имхо, лучше менять на when/unless :)

> Интересно, насколько сложно реализовать все это в других языках? Я к тому, что на задаче такого уровня Лисп только начинает проявлять свою силу. То есть, предложенный DSL команд в оригинальной постановке оказался слишком примитивен.

Ну, можешь проделать с оппонентами "злую шутку" - решить заданную задачу, а потом предоставить "слегка доработанный" вариант (как в первой задачке было с добавлением БД) и попросить реализовать такую функциональность :)

yyk ★★★★★
()
Ответ на: комментарий от redvasily

>А как оно работает, вычисляется при обращении или при изменении >объекта, указанного в формуле?

Видимо при изменении, ведь цель - максимально сократить множество зависимых клеток, которые требуется пересчитать. Вроде есть возможность форсировать пересчет при необходимости.

anonymous
()
Ответ на: комментарий от eugine_kosenko

> там мир представлен глобально или локально?

Т.к. у меня мозг намерво искалечен ООП, то у меня world это или 
атрибут у объекта класса Server или локальная переменная в классе 
Robot

> Как насчет "разделения миров" для пользователей, которое тут 
> упоминалось?

Имхо излишнее. Нафиг, городить ещё user-id, session-id  и т.д.

> Интересно, насколько сложно реализовать все это в других языках? Я 
> к тому, что на задаче такого уровня Лисп только начинает проявлять 
> свою силу. То есть, предложенный DSL команд в оригинальной 
> постановке оказался слишком примитивен.

Ну простая оказалась задача, сам не ожидал, что всё окажется настолько просто. Но зато написал быстро :-)

Мне это сделать совсем не сложно, например perform_action() 
получает список комманд, и возвращает список промежуточных 
состояний мира.

Мне даже совсем несложно добавить autocollect, т.к. программа у меня 
написана как завещал ugoday по методолгоии СВН (сверху вниз наискосок)
и цикл сбора предметов у робота выглядит так:

while True:
    world = self.server.read_world()
    items = [i for i in world.items if i != world.entry]
            
    if not items:
        break
            
    self.moveTo(items[0])
    self.performAction('pickup')
    self.moveTo(world.entry)
    self.performAction('drop')

Можно на сервере при получении команды автоколлект, создвать робота,
и аналогично делать метод moveTo к предмету и обратно

redvasily
()
Ответ на: комментарий от redvasily

Правильно ли я понимаю - робот не видит всего мира целиком, только текущие свободные направления ?

anonymous
()
Ответ на: комментарий от eugine_kosenko

Как тебе такой вариант доработок?

1. Добавляется комманда perform_actions(), принимающая список комманд, и возвращает список состояний мира _после_ исполнения этих комманд.

2. Добавляется комманда autocollect() которая стаскивает все предметы с карты в текущее положение персонажа.

3. Добавляется комманда move_to(x, y) перемещает персонажа в положение x, y и возвращает список промежуточных состояний мира.

redvasily
()
Ответ на: комментарий от redvasily

>Робот видит весь мир сразу

В первоначальной задаче вроде бы было, что он видит только часть (???)

anonymous
()
Ответ на: комментарий от anonymous

> Пардон. Забыл про форматирование:

Я так понимаю, что здесь просто вызываются функции при изменении атрибутов класса, собственно вычисления атрибутов не происходит, так?

Ты не мог бы пояснить что здесь и где происходит, а то боюсь неправильно пойму, и буду спорить совсем не с тем, что надо :-)

redvasily
()
Ответ на: комментарий от redvasily

>Я так понимаю, что здесь просто вызываются функции при изменении >атрибутов класса, собственно вычисления атрибутов не происходит, >так?

Здесь пример простой очень. В цикле задается температура двигателя. Если температура больше 100.0 градусов, то двигатель выключается (status меняется на OFF), при этом задвижка топливного насоса закрывается. Как только температура снизится, двигатель снова запускается, при этом задвижка топливного насоса открывается.

anonymous
()
Ответ на: комментарий от anonymous

>В "других языках" кроме объектной системы ничего не предлагается. А на >макрах можно статический вывод типов сделать (делали как-то раз >библиотеку поточных функторов, надстроили над CLOS еще один уровень с >библиотекой TypeL). Потом опять же что-то вроде CELLS никак не сделать. >В AllegroCL встраивается Prolog, на котором можно писать запросы к >ООБД. Это уже одними библиотеками не осилить.

если не секрет, где это таким занимаются?

anonymous
()
Ответ на: комментарий от anonymous

>если не секрет, где это таким занимаются?

Контора небольшая, малоизвестная пока.

anonymous
()
Ответ на: комментарий от anonymous

> Рано еще тыкать, лисповерсии можно считать еще нет.

Будем считать, что теперь есть:

Параметр                        | Лисп 1 | Лисп 2| Питон | Окамл
----------------------------------------------------------------
Общая длина                     |   1158 |  1778 |  1462 |  1627
Смысловая длина                 |    331 |   552 |   604 |   603
Общий тезаурус                  |    160 |   210 |   195 |   164
Смысловой тезаурус              |     85 |   126 |   154 |   113
Общая насыщенность (в %)        |     29 |    31 |    41 |    37
Насыщенность тезауруса (в %)    |     53 |    60 |    79 |    69
Общая выразительность (в %)     |     14 |    12 |    13 |    10
Смысловая выразительность (в %) |     26 |    23 |    25 |    19

То есть, в конечном итоге получилось и в самом деле не ахти. Правда,
во-первых, тут еще не оптимизирован ввод-вывод (в том числе, не учтены
замечания yyk, попробую улучшить в следующей версии), во-вторых,
произошло серьезное "распухание" за счет многократного использования
дополнительного параметра "world" (IMHO, решается за счет классов), и
в-третьих, как я уже упомянул, у второй лисп-программы функционал
выше, чем у всех остальных. Многоуровневой трассировки, к сожалению не
получилось, но есть понятие подпрограмм, которые выполняются целиком,
а после каждой подпрограммы выводится состояние мира. Робот всегда
выводит состояние пошагово, а пользователь может регулировать
детальность вывода в программе. Наконец, делаем поправку на то, что я
новичок в Лиспе. Будем посмотреть, что предложат труъ лисперы.

Кроме всего прочего у программы наблюдаются определенные глюки с
интеракцией клиента и сервера, то есть, иногда в режиме autocollect
сервер может отваливаться с ошибкой "EOF", и он почти наверняка
отваливается, если попытаться собрать предметы не в точке входа. Опять же, делаем поправку, что я новичок не только в лиспе, но и в сетевом взаимодействии.

Я обломился разъединять программу на три файла, так как у них много
общих частей. После загрузки всей программы сервер можно вызвать
командой (advserver "world.dat" 7766), клиент -- (hclient "localhost"
7766). Робот вызывается из человеческого клиента командой autoclean.

Мнэ, с исходником получается слишком много. Текст исходника смотрим здесь:

http://aroks.kiev.ua/pub/wiki/ProgrammaLabirinta

eugine_kosenko ★★★
()
Ответ на: комментарий от yyk

> Вот несколько сокращённая версия read-world

Total length                                         1750
Meaning length                                        545
Total thesaurus                                       210
Meaning thesaurus                                     126
Total saturation (%)                                   31
Thesaurus saturation (%)                               60
Total expressiveness (%)                               12
Meaning expressiveness (%)                             23

То есть, это все мелочи. Нужно что-то более радикальное. Кстати, я
подозреваю, что переусердствовал с функциями в волновом алгоритме. Может
быть, некоторые из них можно подставить...

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

> Вот несколько сокращённая версия read-world

Евгений, в следующей версии анализа (если она будет :) прошу включить в таблицу и вторую питон-программу. Вам ведь не сложно один раз запустить свой анализатор? Я, можно сказать, начал учавствовать, чтобы посмотреть на эти циферки. А тут такой облом.

realsmart
()
Ответ на: комментарий от realsmart

> Я, можно сказать, начал учавствовать, чтобы посмотреть на эти циферки. А тут такой облом.

Просто не успеваю. Во-первых, количество вариантов уже достаточно велико, чтобы понять, где новая программа, а где вариант старой. А во-вторых я каждый раз проверяю на наличие новых ключевых слов.

Постараюсь сделать вечером, на крайний случай -- в субботу.

eugine_kosenko ★★★
()
Ответ на: комментарий от yyk

> Как-то оно там крововато выглядит... (кто-то чать буковок съел)

Я тоже вчера заметил, но я честно указал преформат, думал, что показалось.

> Добавь туда файл с архивом

Добавил

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

> Добавил

Ок, посмотрел. Есть несколько предложений, но пока "чисто косметических" - никаких изменений в алгоритме. В виде diff-ов :)

1. Об этом я уже писал
-(defun inside-interval-p (interval value)
-  (and
-       (>= value (car interval))
-       (<= value (cdr interval))))
-
-(defun inside-world-p (world point)
-  (and
-       (inside-interval-p (cons 1 (bound-x world)) (realpart point))
-       (inside-interval-p (cons 1 (bound-y world)) (imagpart point))))
-
 (defun wallp (world point)
-  (or
-       (not (inside-world-p world point))
-       (member point (wall-points world))))
+  (or (not (and (>= (realpart point) 1) (<= (realpart point) (bound-x world))
+               (>= (imagpart point) 1) (<= (imagpart point) (bound-y world))))
+      (member point (wall-points world))))

Не уверен, что в этой части что-то понадобится менять, поэтому просто
"свернул" пару функций :)

2. Раскрыть в объявлении констант pairlis - помимо экономии слова,
имхо, нагляднее

-(defconstant directions
-  (pairlis
-       `(#c(1 0) #c(-1 0) #c(0 -1) #c(0 1))
-       '(go-east go-west go-north go-south)))
+(defconstant +directions+ '((#c(0 1)  . go-south)
+                           (#c(0 -1) . go-north)
+                           (#c(-1 0) . go-west)
+                           (#c(1 0)  . go-east)))

и

-(defconstant command-reversion
-  (pairlis
-       '(go-east go-west go-north go-south pickup-thing drop-thing)
-       '(go-west go-east go-south go-north drop-thing pickup-thing)))
+(defconstant command-reversion '((go-east . go-west)
+                                (go-west . go-east)
+                                (go-north . go-south)
+                                (go-south . go-north)
+                                (pickup-thing . drop-thing)
+                                (drop-thing . pickup-thing))

3. Мелкие исправления

 (defun path-program (path)
-  (if (null (cdr path))
-        ()
-        (cons (direction (car path) (cadr path)) (path-program (cdr path)))))
+  (when (cdr path)
+    (cons (direction (car path) (cadr path)) (path-program (cdr path)))))

-  (cond
-       ((hero-carries-thing-p world)
-        (setf (hero-carries-thing-p world) nil)
-        (push (hero-point world) (thing-points world)))))
+  (when (hero-carries-thing-p world)
+    (setf (hero-carries-thing-p world) nil)
+    (push (hero-point world) (thing-points world))))

-  (progn
-        (format stream "~S~%" command)
-        (force-output stream)))
+  (format stream "~S~%" command)
+  (force-output stream))

4. Многострочные setf

-                       (setq entry-point (complex x y))
-                       (setq hero-point (complex x y))))
+                       (setf entry-point (complex x y)
+                             hero-point (complex x y))))

-        (setf (hero-carries-thing-p world) t)
-        (setf
-         (thing-points world)
-         (remove (hero-point world) (thing-points world) :count 1)))))
+        (setf (hero-carries-thing-p world) t
+              (thing-points world) (remove (hero-point world) (thing-points world) :count 1)))))

5. От одного eval можно легко избавиться (но это как раз увеличивает код)

-(mapcar
- #'eval
- (mapcar
-  #'(lambda (pair)
-               `(defun ,(cdr pair) (world) (go-step world ,(car pair))))
-  directions))
+
+(defmacro def-commands (directions)
+  `(progn
+     ,@(mapcar #'(lambda (pair)
+                  `(defun ,(cdr pair) (world) (go-step world ,(car pair))))
+              directions)))
+
+(def-commands #.+directions+)

Серьёзнее проанализирую потом.

yyk ★★★★★
()
Ответ на: комментарий от yyk

> Не уверен, что в этой части что-то понадобится менять, поэтому просто > "свернул" пару функций :)

(or (< (realpart point) 1) (> (realpart point) (bound-x world)) (< (imagpart point) 1) (> (imagpart point) (bound-y world)) (member point (wall-points world)))

:-)))

> Раскрыть в объявлении констант pairlis - помимо экономии слова, > имхо, нагляднее

Я пробовал, но оно у меня ругнулось, когда я попробовал применить к такому списку assoc. Я думал, ассоциативные списки делаются только специальными функциями. Дома проверю.

> (defconstant +directions+ ..

А в чем сакральный смысл плюсов в дефиниции? Если это соглашение по именам констант, то почему command-reversion сделано без них? И я еще видел переменные, окаймленные астериксами -- *blah* -- что это значит? И вообще, есть ли соглашения по кодированию и стилю программ на Лиспе и где об этом можно почитать?

> 3. Мелкие исправления

Понятно, для меня это вообще проблема -- отличить место, где есть неявный progn. Очень часто пытаюсь применить его в теле функции, кажется, так нельзя? По крайней мере, было несколько странных эффектов, с тех пор стараюсь, когда сомневаюсь, указывать progn явно или вообще пользоваться cond. Про (if (null x) () ...) -- хотел показать, что основой рекурсии является пустой список.

> Многострочные setf

Просто не знал :-). Получается, что для атомарных имен setf ничем не отличается от setq, но позволяет писать несколько присваиваний? Почему такой возможности нет у setq?

> 5. От одного eval можно легко избавиться (но это как раз увеличивает код

Каюсь, именно в этом месте погнался за оптимизацией.

> +(def-commands #.+directions+)

Что делает #.? Насколько я знаю, хэш означает блокировку, для чего она в этом случае?

eugine_kosenko ★★★
()
Ответ на: комментарий от anonymous

> Потом опять же что-то вроде CELLS никак не сделать.

Мы сейчас как раз пытаемся использовать некую rule-based систему. Причем, так как наши программисты -- самые программисты в мире, то сей велосипед был написан нами полностью с нуля в три прыжка. Каюсь, я к этому тоже руку приложил.

Когда зашла речь о CELLS, мои архаровцы тоже стали искать что-то похожее и таки нашли RETE для Oracle и еще какую-то поделку для .Net. Но менять технологию, похоже, уже поздно...

eugine_kosenko ★★★
()
Ответ на: комментарий от yyk

> Как-то оно там крововато выглядит... (кто-то чать буковок съел)

Мнэ, сейчас посмотрел на исходник внимательнее, таки в самом деле вака сожрала пару скобок. У нее это элемент разметки.

Вот, кстати, вопрос -- боевая раскраска в виках. Для Питона есть, для Java есть, даже для Эйфеля есть, а для Лиспа не сподобились сделать.

eugine_kosenko ★★★
()
Ответ на: комментарий от yyk

> 2. Раскрыть в объявлении констант pairlis - помимо экономии слова, имхо, нагляднее

Понял, почему у меня не пошел экспериментальный пример. Я писал

'((1.2) (3.4))

и оно приняло точечную пару за число с плавающей точкой. :-(

eugine_kosenko ★★★
()
Ответ на: комментарий от yyk

> 2. Раскрыть в объявлении констант pairlis - помимо экономии слова, имхо, нагляднее

Понял, почему у меня не пошел экспериментальный пример. Я писал

'((1.2) (3.4))

и оно приняло точечную пару за число с плавающей точкой. :-(

eugine_kosenko ★★★
()
Ответ на: комментарий от yyk

> Есть несколько предложений, но пока "чисто косметических" - никаких
> изменений в алгоритме.

Все принял, но все никак не пойму, что делает #. В стандарте сказано,
что это read-time evaluation (я правильно понял?), но я не пойму, когда
это на самом деле вычисляется.

В любом случае, это все еще косметика:

Total length                                         1745
Meaning length                                        545
Total thesaurus                                       211
Meaning thesaurus                                     125
Total saturation (%)                                   31
Thesaurus saturation (%)                               59
Total expressiveness (%)                               12
Meaning expressiveness (%)                             23

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

> Если это соглашение по именам констант, то почему command-reversion сделано без них?

Забыл :(

> И я еще видел переменные, окаймленные астериксами -- *blah* -- что это значит? И вообще, есть ли соглашения по кодированию и стилю программ на Лиспе и где об этом можно почитать?

Звёздочками принято окаймлять глобальные переменные. Читать можно http://www.norvig.com/luv-slides.ps и есть ещё http://www.lisp.org/table/style.htm

> Понятно, для меня это вообще проблема -- отличить место, где есть неявный progn. Очень часто пытаюсь применить его в теле функции, кажется, так нельзя?

Можно, но необязательно :) Т.е. он там просто лишний

> По крайней мере, было несколько странных эффектов, с тех пор стараюсь, когда сомневаюсь, указывать progn явно или вообще пользоваться cond.

CLtL явно говорит, что нужно - form или forms :)

> Про (if (null x) () ...) -- хотел показать, что основой рекурсии является пустой список.

Лучше уж комментарии писать (хотя по мере того, как код становится всё проще и легче читать - очень трудно заставить себя это делать)

> Просто не знал :-). Получается, что для атомарных имен setf ничем не отличается от setq, но позволяет писать несколько присваиваний? Почему такой возможности нет у setq?

Есть и у setq. А setf для атомарных имён именно setq и использует (как правило - зависит от реализации, но результат в любом случае тот-же). Посему просто срабатывает привычка setq не использовать :)

P.S. А по малеёшим подозрениям лучше лезть в CLtL/HyperSpec :)

> Что делает #.? Насколько я знаю, хэш означает блокировку, для чего она в этом случае?

Ну, ты уже всё нашёл :) Да, read-time evaluation. Т.е. форма за #. вычесляется именно сразу после прочтения. Это позволяет в макру передать именно список, а не имя перемнной, его содержащей. Но нам это позволяет ещё сделать то, что defconstant выполняется в момент компиляции. С обычной переменной так не получится, если только не засунуть код в (eval-when...)

yyk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.