LINUX.ORG.RU

Он и был стандартом, только предыдущий стандарт назывался R5RS. :)

ero-sennin ★★
()

Журнализм плюс реклама левого сайта.

1. Правильный заголовок: принят новый стандарт scheme - r6rs

2. Правильная ссылка: http://r6rs.org/

А так новость хорошая. :)

Teak ★★★★★
()

Дебильный заголовок новости.

anonymous
()

Что в этом стандарте появилось нового?

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

> Журнализм плюс реклама левого сайта. 1. Правильный заголовок: принят новый стандарт scheme - r6rs 2. Правильная ссылка: http://r6rs.org/ А так новость хорошая. :)

Товарищи модераторы! Просьба прислушаться к комментариям учаснега Teak.

http://www.linux.org.ru/view-message.jsp?msgid=2112726 - эта новость так и не была исправлена, не смотря на то, что в обсуждении было разъяснено в чём заключается ошибка.

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

> Товарищи модераторы! Просьба прислушаться к комментариям учаснега Teak.

Присоединяюсь. А то сейчас новость только дезинформирует.

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

Какая нафиг разница? Всё равно редиректит. В любом случае моя ссылка значительно более правильная, чем в новости. :)

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

> Какая нафиг разница? Всё равно редиректит

Не редиректит.

> моя ссылка значительно более правильная, чем в новости

Это да.

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

> что там с Clisp'ом

"Там" — это где? В R6RS?!

anonymous
()

>Furthermore, if you are in the pragmatist camp, the proposed R6RS does not go far enough. Pragmatists want things like complete, pervasive object systems; built-in support for concurrency; and beefy standard libraries including most common OS and networking functions, having been spoilt on such features from exposure to the likes of Common Lisp, Perl, Python, C# and Java. As a pragmatic standard the proposed R6RS doesn't go nearly far enough; its benefit is mainly in political issues, as a "step in the right direction" for the Scheme community. Many of the problems that the proposed report addresses have been addressed better by SRFIs to R5RS, with which the report conflicts in subtle ways.

Полностью согласен. Без библиотек даже самый мощный язык никому не нужен

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

> Полностью согласен. Без библиотек даже самый мощный язык никому не нужен

а они как известно, в отличие от анонимусов, из вакуума не появляются, их писать нужно, так что вперед и с песней :)

defmacro
()

Я вообще расстроен новым стандартом. Это уже не схема, это какой-то недо-cl :( 
Стандарт распух до 160 страниц против бывших сорока. 
Включили совершенно ненужный синтаксис.

Вот так теперь предлагается возвращать несколько значений из функциии:

(define return-many
  (lambda ()
    (let ((a (read))
          (b (read)))
      (values a b))))

И вот так принимать:

(call-with-values
    (lambda () (return-many))
  (lambda (x y)
    (+ x y)))

Можно было раньше обойтись без этого? Разумеется:

;; lisp style
(define return-many
  (lambda ()
    (let ((a (read))
          (b (read)))
      (list a b))))

(apply + (return-many))

;; scheme style
(define return-many
  (lambda ()
    (let ((a (read))
          (b (read)))
      (lambda (f) (f a b)))))

((return-many) (lambda (x y) (+ x y)))

Зачем придумали (и включили в стандарт) велосипед? Ответ мутный: 
типа, так нам будет проще реализовывать и оптимизировать компиляторы.

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

> Быдлосхема

О-о-о! Просто убили :)))

anonymous
()

Господа, а какая реализация на данный момент наиболее полно соответствует стандарту R6RS?

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

>Можно было раньше обойтись без этого? Разумеется:

Осознай разницу между (values a b c d ...) и (lisb a b c d...). Тут разная реализация, и в случае с (values..) она может быть эффективнее, так как чтобы добраться до десятого элемента списка , надо пропахать весь список, а в случае с (values...) значения укладываются в стек и могут адресоваться напрямую.

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

>а в случае с (values...) значения укладываются в стек и могут адресоваться напрямую.

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

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

Если values сделаны как в CL, то есть еще одно преимущество — если "принимающей стороне" не нужны дополнительные значения, то она может их просто игнорировать. Новые схемовские values будут работать так же?

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

>Новые схемовские values будут работать так же?

А кто запретит? Это даже как-то оговаривать стандартом странно было бы. Думаю, что это поведение списывается на конкретную имплементацию. Я думаю, что из CL это и утащили.

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

>Вот так теперь предлагается возвращать несколько значений из функциии:

Поправьте меня, если не прав, но values и call-with-values были и в прошлой редакции стандарта (по крайней мере это работало во всех реализациях, с которыми я встречался).

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

> Осознай разницу между (values a b c d ...) и (lisb a b c d...). Тут разная реализация, и в случае с (values..) она может быть эффективнее

Чем это кошернее, чем вернуть замыкание, как я привел в примере? Зачем мне, как пользователю _лиспа_, просчитывать в башке варианты с регистрами, стеками и прочей x86-ересью? :) Пусть компилятор за меня эти моменты оптимизируют (тем более, конкретно вышеприведенный пример просчитать нетрудно). Если мне это надо залезть в кишки машины, я лучше возьмусь за Си, правильно? А так имеем одну лишнюю конструкцию (длинную причем), не несущую смысловой нагрузки.

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

> Поправьте меня, если не прав, но values и call-with-values были и в прошлой редакции стандарта (по крайней мере это работало во всех реализациях, с которыми я встречался).

Ну он действительно много где работает, но в r5rs его нет :)

swizard
()

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

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

>Вот так теперь предлагается возвращать несколько значений из функциии:

что за бред: 1. values ещё до R6RS были 2. вариант с list никто не отменяет.

Изучайте мат.часть ;)

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

>Чем это кошернее, чем вернуть замыкание, как я привел в примере? 

Нет адресации к элементам списка. А если мне возвращаемое значение не 
нужно в виде списка, у элементов которого одинаковая смысловая 
нагрузка и они подвергаются одной операции (у тебя -- сложение)? Если 
мне разные по смыслу возвращаемые объекты нужны? А если мне не все 
значения нужны, а десятое (и такие примеры у меня есть практические, 
но в CL). И компилятор ничего оптимизировать не сможет из-за природы 
списка, так как он не знает наперед, тебе список нужен или набор 
независимых значений, пока ты ему специальным образом не укажешь на
семантику твоего списка. Вот и сделали (values...).

Придание особой семантики набору 
возвращаемых значений из функции не противоречит духу Scheme. Список 
возвращать никто тебе не запретит. Если твоя программа, еще раз 
повторю, использует возвращаемое значение, как список (например (apply
 '+ ...)), то и возвращай список.

А CL, например, если используется values, это дело понимает и пытается
 оптимизировать. Вот тупой пример из SBCL без всяких оптимизаций:

* (defun foo () (values 1 2 3 4 5 6))

FOO
* (disassemble 'foo)

; 0A7D0692:       BA04000000       MOV EDX, 4                 ; no-arg-parsing entry point
;       97:       BF08000000       MOV EDI, 8
;       9C:       BE0C000000       MOV ESI, 12
;       A1:       C745F010000000   MOV DWORD PTR [EBP-16], 16
;       A8:       C745EC14000000   MOV DWORD PTR [EBP-20], 20
;       AF:       C745E818000000   MOV DWORD PTR [EBP-24], 24
;       B6:       8BDD             MOV EBX, EBP
;       B8:       B918000000       MOV ECX, 24
;       BD:       8B6DFC           MOV EBP, [EBP-4]
;       C0:       8D63E8           LEA ESP, [EBX-24]
;       C3:       F9               STC
;       C4:       FF63F8           JMP DWORD PTR [EBX-8]
;       C7:       90               NOP
;       C8:       CC0A             BREAK 10                   ; error trap
;       CA:       02               BYTE #X02
;       CB:       18               BYTE #X18                  ; INVALID-ARG-COUN
T-ERROR
;       CC:       4D               BYTE #X4D                  ; ECX
;       CD:       CC0A             BREAK 10                   ; error trap
;       CF:       02               BYTE #X02
;       D0:       18               BYTE #X18                  ; INVALID-ARG-COUN
T-ERROR
;       D1:       4D               BYTE #X4D                  ; ECX
; 
NIL
* 

Ну там используется внутренее прдставление этих 1..6, но это не важно.
Как видишь, первые три значения упихиваются в регистры, а остальные 
три располагаются в памяти. Если бы регистров было больше, то значения
раскидались бы максимально в регистры.

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

> что за бред: 1. values ещё до R6RS были

Да, действительно ступил. Нашел в r5rs

> 2. вариант с list никто не отменяет.

Зачем несколько вариантов делать одно и то же? Итак стандарт распух, какие уж там теперь embedded реализации...

swizard
()

Мне всегда было интересно, почему народ просто обожает Scheme (по сути усеченного лиспа), при наличие достаточного числа свободных реализаций лиспа?

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

> И компилятор ничего оптимизировать не сможет из-за природы 
списка,
> так как он не знает наперед, тебе список нужен или набор 
независимых значений,
> пока ты ему специальным образом не укажешь на
семантику твоего списка.
> Вот и сделали (values...).

Слушай, я это все понимаю :)
Я сам в свое время писал компилятор tcl-подобного языка.

Я вот о чем: у меня есть задача -- вернуть несколько значений. Почему мне, вместо компилятора,
надо выбирать подходящую реализацию этой задачи? Возьмем r4rs-совместимый вариант:

(define return-3
 (lambda () (lambda (f) (f (read) (read) (read)))))

((return-many) (lambda (a b c) (+ a c)))

Оптимизируется для компиляции элементарно: инлайнится return-3, 
удостоверяется, что параметр b не используется, выкидывается, и 
получаем в итоге (+ (read) (read)). Зачем тут какие-то values?

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

> выкидывается, и получаем в итоге (+ (read) (read))

Ну, наврал, конечно :) Средний (read) выкидывать нельзя, но суть, все равно понятна

swizard
()
Ответ на: комментарий от Sun-ch

> почему народ просто обожает Scheme (по сути усеченного лиспа), при наличие достаточного числа свободных реализаций лиспа?

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

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

>Оптимизируется для компиляции элементарно: инлайнится return-3, удостоверяется, что параметр b не используется, выкидывается, и получаем в итоге (+ (read) (read)). Зачем тут какие-то values?

Ха, а если функция не инлайнится (ну большая и сложная функция), вызывается она в десяти разных функциях, а возвращаемые параметры используются по-разному. Как тут быть? Инлайнить десять раз функцию во всех местах, где она вызывается? Вот пример: есть функция, возвращающая три координаты x, y и z. Она не инлайнится. И в одной вызывающей функции мне нужно только проверить координату z. Вызывается эта функция в цикле 1000 раз. Вопрос: как получить эту координату без прохода по списку (list x y z) 1000 раз.

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

> Ха, а если функция не инлайнится (ну большая и сложная функция), вызывается она в десяти разных функциях, а возвращаемые параметры используются по-разному. Как тут быть?

Чувствую, у тебя серьезный опыт работы с CL :) На схеме программы пишутся несколько по-другому -- обязательная оптимизация хвостовых вызовов благоприятствует функциональному подходу.

> Вот пример: есть функция, возвращающая три координаты x, y и z. Она не инлайнится. И в одной вызывающей функции мне нужно только проверить координату z. Вызывается эта функция в цикле 1000 раз. Вопрос: как получить эту координату без прохода по списку (list x y z) 1000 раз.

Конкретно в этом примере -- передать в функцию с координатами тело цикла в замыкании :)

Наши мнения расходятся вот в чем: CL -- это мощный императивный язык с развитой макросистемой и инкрементальной компиляцией, в нем идет явное разделение на код и данные. В твоем примере про точки ты мыслишь как раз этими категориями: есть код, вычисляющий точки, и есть данные -- возвращаемые точки. Программирование на схеме изначально сдвинуто в более функциональную область -- код с данными уже так четко не делят (в схеме даже имена функции с переменными делять одну зону видимости -- отсутствуют function / funcall).

Что мне конкретно не нравится: по стандарту R6RS отчетливо видно, что схема явно идет к Common Lisp'у. Дело в том, что если мне будет нужен CL, я буду программировать на CL, а не на "недо"-CL R6+RS Scheme. Это тупиковый путь развития, следует именно подчеркивать отличия языков, нежели делать их одинаковыми.

swizard
()
Ответ на: комментарий от Sun-ch

Так ведь и Scheme и Common Lisp -- это разные языки.

Scheme -- это continuations, хвостовая рекурсия, удобное функциональное программирование, академическая простота языка и компактная реализация. Я сейчас пишу код в связке scheme (chicken) + Си, они отлично друг с другом взаимодействуют, поэтому в огромной стандартной библиотеке я не нуждаюсь.

Common Lisp, прежде всего, это отличный самостоятельный язык, с богатой собственной стандартной библиотекой. Из killer-features особо отмечу лучшую в мире макро-систему, и инкрементальную компиляцию. Люди, которые с CL близко знакомы, знают, насколько это мощные инструменты.

swizard
()
Ответ на: комментарий от Sun-ch

> почему народ просто обожает Scheme

потому что он красив. был.

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

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

я бы сказал, что он *и* императивный. Никто функциональщины у CL не отнимал.

Мне пришлось подзадержаться с ответом, так как решил ознакомиться с мощными баталиями по вопросу values в comp.lang.scheme. Там мнения, как за, так и против. И вообще, там очень много всего. За короткое время мне не ознакомиться. Основное из "за", что я успел захватить -- это оптимизация вызовов (о чем, собственно я тут и речь вел) и еще кое-какие аргументы с примерами встречались в области ограждения от ошибок программиста (как я понял). Еще были предложения по поводу введения tuples, что автоматом решит для Scheme проблему values (по сути отпадет необходимость), так как будет возвращаться одно значение, но в котором будет tuple [1 2 3]. А случай с одним возвращаемым значением считать [a] = a. Ну и, соответственно, там вопросы, надо ли делать это first-class объектом или нет. Мне тяжеловато глубоко погружаться в такие длинные обсуждения там. Я понял одно: спор этот среди схемотехников уже имеет статус *религиозного*, а частью этого спора мне никак не стать -- мало конкретных знаний.

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

> Никто функциональщины у CL не отнимал.

Да, но в этом стиле программировать на CL официально не рекомендуется, как минимум из-за того, что стандарт не требует обязательной tail-call optimization.

> Я понял одно: спор этот среди схемотехников уже имеет статус *религиозного*

Согласен :) В основном, канат перетягивается либо в сторону компактности, чистоты и академической красоты языка, либо в сторону универсальной практичной платформы а-ля CL. Лично я придерживаюсь первых, но, судя по прогрессу стандартов, побеждают вторые :(

swizard
()

Новость хорошая.

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

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

Сам лично пользуюсь реализацией схемы на яве - SISC (http://sisc-scheme.org/). Полезная штука, из которой можно пользоваться существующими библиотеками/наработками на яве и в то же время программировать на действительно красивом и выразителном языке - на лиспе.

Для SISC есть фреймворк на основе сервлетов для разработки веб-приложений: http://siscweb.sourceforge.net.

Мой скромный вклад: небольшая библиотека для текстовых шаблонов, при помощи которой можно генерировать динамические странички или любой другой текст: http://text-template.sourceforge.net

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

>Да, но в этом стиле программировать на CL официально не рекомендуется, как минимум из-за того, что стандарт не требует обязательной tail-call optimization.

Ну, скажем так, те, кто ориентируются на определенные реализации, которые это поддерживают (а это подавляющее большинство реализаций), могут использовать хвостовые вызовы без проблем. Но если говорить о переносимости между реализациями, то лучше, конечно, воздерживаться от хвостовых вызовов или использовать их при небольших объемах данных. Я нарвался один разок, когда писал патчи, чтобы CLX на clisp работал. Там был пример рисования узора (в demos::do-all-demos) с весьма глубокой рекурсией. SBCL ее оптимизировал без проблем и шустренько рисовал, а clisp вываливался с переполнением стека. Я голову ломал, а потом вот А после меня на это же наступил один француз, которому я объяснял, как поднять Garnet/CLX на CLISP под MacOS. Пришлось запрашивать при старте clisp бОльший стек. Так что я от хвостовых рекурсий действительно воздерживаюсь.

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