LINUX.ORG.RU
ФорумTalks

Разброд в Scheme

 ,


0

7

Как многими и ожидалось, ратификация R7RS привнесла в Scheme еще больший элемент зоопарка, чем тот, что там был раньше. Теперь у нас есть олдскульные R4RS-R5RS реализации (среди которых компилирующиеся в натив): Gambit, Chicken, Bigloo, Scheme 48, есть R6RS (среди которых часть уже поумирала): Vicare/Ikarus, Guile, Ypsilon, Sagittarius, есть R7RS (почему-то исключительно интерпретаторы): Gauche, Chibi, Picrin, Foment. Кто-то вообще перестал быть Scheme (Racket).

Печаль.

Если нужен вопрос, то вот он: почему никто не пилит компиляторы R7RS?

Ни одной реализации R7RS Large не видно вообще.

inb4: Мое мнение таково, что R7RS, как и R6RS оказался не особо нужен схемерам старой закалки, для которых Scheme — это некоторый совсем минимальный стандарт + детали конкретной реализации (да, есть R7RS Small, но он все равно, по мнению некоторых, недостаточно Ъ). Люди же, которые хотят батареек в лиспе, находят их в CL, Clojure и Racket.

★★★★★

Последнее исправление: buddhist (всего исправлений: 1)

Разброд в Scheme

lisp, scheme

Не угадал автора.

А для чего щас Схема используется? (не для похолливарить вопрос, просто интересно)

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

Единственная действительно годная область применения, которая у нее осталась — использование в качестве встраиваемого язычка. Нет, конечно, в университетах пилят и целые относительно серьезные проекты, написанные полностью на схеме, вроде Nanopass и Hop, но в последнее время наблюдается спад.

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

buddhist ★★★★★
() автор топика

Мне кажется, что r7rs - это тот стандарт, который достоин наконец стать настоящим стандартом. И я думаю, компиляторы подтянутся, когда поймут, что дальше держаться за r4-r6 нет смысла.

Наконец-то в стандарте появилась такая важная вещь, как cond-expand. И наконец-то подсистему библиотек привели в порядок.

Puzan ★★★★★
()
Последнее исправление: Puzan (всего исправлений: 1)

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

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от Virtuos86

Хорошо бы, если бы была одна референсная реализация и куча тестов на соответствие стандарту. А остальным выдавать значок «соответствует» при прохождении всех тестов.

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

r7rs - это тот стандарт, который достоин наконец стать настоящим стандартом

Схема головного мозга — это более серьезное заболевание, чем ты думаешь :)

У нас:

I'd say that R6RS does not mean the same thing as a standard in some popular languages. R6RS doesn't represent the essence of the language, best practices, nor consensus.

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

r6rs не был самодостаточным стандартом, по этому городились несовместимые друг с другом костыли. Теперь же есть cond-expand и нормальные библиотеки, что должно, как мне кажется, кардинально изменить ситуацию с совместимостью.

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

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

Вангую, что оно может остаться академической игрушкой, как CakeML :)

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

быстрой реализации

Медленнее любого R5RS-компилятора

r6rs не был самодостаточным стандартом

Это и есть scheme-way.

есть cond-expand и нормальные библиотеки

Да, это годнота, но у разработчиков почему-то очень разные взгляды на то, какими должны быть модули. От С++-образных неймспейсов (Gambit), до ML-like модулей (Scheme 48).

ракет - это уже не схема, к сожалению

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

buddhist ★★★★★
() автор топика
Последнее исправление: buddhist (всего исправлений: 2)
Ответ на: комментарий от ymn

Согласен с buddhist'ом. Слишком это далеко от практики.

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

Медленнее любого R5RS-компилятора

Сегодня потестю. Я недавно проверял на задачке обработки большого бинарного файла. Ракет оказался в три раза медленней C, при том, что в схемном варианте не было деструктивных присваиваний. Gauche был вровень с Guile - в 10 раз медленней Racket, а Chibi в 10 раз медленней Gauche.

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

Так Gauche и Guile это интерпретаторы :) В Guile, правда, вроде бы впиливали JIT, не помню уже. Сравни с Bigloo, Gambit, Chicken.

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

Так Gauche и Guile это интерпретаторы :)

Да, я знаю, интерпретаторы с jit. И racket интерпретатор, но байткода.

Сравни с Bigloo, Gambit, Chicken.

Сегодня сравню и отпишу сюда результаты.

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

Спасибо. Буду приятно удивлен, если окажусь неправ. Тогда в ракетке останется запилить одну фичу - виртуальную ФС с возможностью вкомпилить все в один большой бинарник (как в starkit)

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

Guile

А для чего щас Схема используется?

Guile объявлен главным языком конфигов в GNU. Guix его использует.

Camel ★★★★★
()

Ни одной реализации R7RS Large не видно вообще.Ни одной реализации R7RS Large не видно вообще.

R7RS Large устаканился? Можно ссылку на спек?

vaulter
()

Сорри за небольшой оффтоп, но у меня есть вопрос.

Я читал в Википедии, что язык Scheme (и в какой-то степени Common Lisp) повлиял на R. Отсюда у меня вопрос: Можно же использовать данный ЯП для последующего упрощенного обучения языку Common Lisp и главное R?

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

Результаты:

c                1.48s user 0.01s system 99% cpu 1.495 total
racket           5.66s user 0.15s system 100% cpu 5.804 total
chicken         11.44s user 0.06s system 100% cpu 11.492 total
gambit-4.7.1    23.01s user 0.05s system  99% cpu 23.063 total
gauche-0.9.5    39.40s user 0.12s system 110% cpu 35.817 total
guile           85.80s user 0.20s system  99% cpu 1:26.01 total
chibi          698.82s user 0.16s system  99% cpu 11:38.98 total

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

Код на C:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    char bits, in;
    int bit, n;
    FILE *infile, *outfile;
    
    if (argc != 3) {
        printf("Usage: %s <infile> <outfile>\n\n", argv[0]);
        return -1;
    }

    infile = fopen(argv[1], "r");
    if (!infile) {
        printf("Cannot open %s file\n", argv[1]);
        return -2;
    }
    
    outfile = fopen(argv[2], "w");
    if (!outfile) {
        printf("Cannot open %s file\n", argv[2]);
        return -3;
    }

    bits = 0;
    bit = 0;
    
    while(!feof(infile)) {
        in = fgetc(infile);

        for (n = 0; n < 8; n += 2) {
            if (bit == 8) {
                fputc(bits, outfile);
                bits = 0;
                bit = 0;
            }
            
            switch ((in >> n) & 3) {
            case 2:
                bits |= 1 << bit;
            case 1:
                bit ++;
            }
        }
    }

    fclose(infile);
    fclose(outfile);

    return 0;
}

Код на Scheme (для chibi и gauche):

(import (scheme base)
        (scheme file)
        (scheme cxr)
        (scheme process-context))

(cond-expand
 (chibi  (import (srfi 33)))
 (gauche (import (srfi 60))))

(define (whitening in-port out-port)
  (let rloop ((bits 0) (bit 0))
    (let ((in (read-u8 in-port)))
      (if (eof-object? in) '()
          (let loop ((mask-shift 0)
                     (bt (cons bits bit)))
            (let ((bits (car bt))
                  (bit (cdr bt)))
              (if (= mask-shift 8) (rloop bits bit)
                  (if (= bit 8)
                      (begin
                        (write-u8 bits out-port)
                        (loop mask-shift (cons 0 0)))
                      (loop (+ mask-shift 2)
                            (case (bitwise-and 3 (arithmetic-shift in (- mask-shift)))
                              ((0 3) (cons bits bit))
                              ((1)   (cons bits (+ bit 1)))
                              ((2)   (cons
                                      (bitwise-ior bits (arithmetic-shift 1 bit))
                                      (+ bit 1)))))))))))))

(define (main args)
  (if (> 3 (length args))
      (error "Usage: prog infile outfile")
      (let ((in-port (open-binary-input-file (cadr args)))
            (out-port (open-binary-output-file (caddr args))))
        (whitening in-port out-port)
        (close-port in-port)
        (close-port out-port))))

(main (command-line))

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

Сам сейчас подергал разные реализации — в Racket и правда неслабо подтянули производительность. Годно.

Кстати, опять на удивление быстрой оказалась Kawa, запиленная на жабе.

buddhist ★★★★★
() автор топика
Последнее исправление: buddhist (всего исправлений: 1)
Ответ на: комментарий от bookman900

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

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

А то вроде говорил мне Quasar, что R легко с нуля изучать....но хотелось концепции понять, а тут оказалось, что наработки Lisp Scheme были как раз в R :)

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

Это сделано для того, чтобы потом передавать два аргумента за раз:

(let loop ((mask-shift 0)
          (bt (cons bits bit)))
  ...
  (loop (+ mask-shift 2)
        (case (...)
          (() (cons a b))

Можно наверное более красиво сделать:

(let loop ((mask-shift 0) (bits bits) (bit bit))
  ...
  (apply loop (cons (+ mask-shift 2)
                    (case (...)
                      (() (list a b))

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

А почему не так?

(let ((ms (+ mask-shift 2)))
      (case (bitwise-and 3 (arithmetic-shift in (- mask-shift)))
        ((0 3) (loop ms bits bit))
        ((1)   (loop ms bits (+ bit 1)))
        ((2)   (loop ms
                     (bitwise-ior bits (arithmetic-shift 1 bit))
                     (+ bit 1)))))

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

Ну и вообще

(define (whitening in-port out-port)
  (let rloop ([bits 0]
              [bit 0])
    (let ([in (read-u8 in-port)])
      (unless (eof-object? in)
        (let loop ([mask-shift 0]
                   [bits bits]
                   [bit bit])
          (cond
           [(= mask-shift 8)
            (rloop bits bit)]
           [(= bit 8)
            (write-u8 bits out-port)
            (loop mask-shift 0 0)]
           [else
            (let ([ms (+ mask-shift 2)])
              (case (bitwise-and 3 (arithmetic-shift in (- mask-shift)))
                [(0 3) (loop ms bits bit)]
                [(1)   (loop ms bits (+ bit 1))]
                [(2)   (loop ms
                             (bitwise-ior bits (arithmetic-shift 1 bit))
                             (+ bit 1))]))]))))))     

qaqa ★★
()
Последнее исправление: qaqa (всего исправлений: 1)
Ответ на: комментарий от buddhist

Тогда в ракетке останется запилить одну фичу - виртуальную ФС с возможностью вкомпилить все в один большой бинарник (как в starkit)

А чем тебе папка lib рядом с бинарником так мешает? Если в системе Racket установлен, так вообще бинарник без всего будет.

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

Потому что это нетехнический вопрос

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

А почему не так?

Так тоже было.

Ну и вообще

И так можно.

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

А зачем это решать на схеме, если она и медленнее, и код длиннее и непонятнее?

Из академического интереса. Эта задача не показательна ни в плане кода ни в плане скорости.

Puzan ★★★★★
()

Как многими и ожидалось, ратификация R7RS привнесла в Scheme еще больший элемент зоопарка, чем тот, что там был раньше.
Если нужен вопрос, то вот он: почему никто не пилит компиляторы R7RS?

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

Я не думаю, что старые, развитые проекты всерьёз возьмуться за R7RS из принципа. Те, кто реализовал R6RS, вряд ли будут переползать на менее батареечный R7RS. Те, кто уже более десятка лет пилит R5RS, вряд ли будут ставить поддержку R7RS первым приоритетом, а просто продолжат фиксить баги и писать библиотеки. Racket вообще (уже) не Scheme, так что влияние оказывает лишь косвенное.

Если это и случится, то это будет целенаправленная реализация from scratch, а не приведение уже существующей реализации в соответствие с R7RS, которое может натолкнуться на различные трудности, начиная от просто нежелания авторов или низкого приоритета этой работы, проходя через поломку обратной совеместимости и необходимость поддержки фактически двух реализаций для сохранения совместимости, и заканчивая фундаментальной неприспособленностью реализаций для R7RS.

Ни одной реализации R7RS Large не видно вообще.

Мне кажется, я не один скептически отношусь к этой идее и считаю, что Common Scheme не нужен. Для батареек есть уже упомянутые Common Lisp, Racket, Clojure, а также любая другая реализация Scheme с библиотеками. Поэтому R7RS (large) буксует.

Scheme вряд ли станет production-level языком общего назначения — тем самым, что называется популярным языком,— который будут выбирать для использования из-за преимуществ экосистемы в общем (как Java и компания), а не из-за каких-то конкретных преимуществ языка применительно к задаче (вон как для эмбеддед).

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

Но не production-level язык. Хотя бы потому, что Lisp curse и то, что RnRS не являются стандартами. Само сообщество, его менталитет и дух языка подталкивают к сегрегации, а не консолидации. У Scheme нет стержня, который бы объединил сообщество.

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

Я вон тоже надеюсь выстрогать свой компилятор R7RS, как наиграюсь с переписыванием Nanopass на R7RS. В первую очередь потому что это интересно лично мне, и потому что R7RS имеет модули, в отличие от R5RS; но далеко не потому, что все существующие IDE для Scheme ужасны, или в силу моих убеждений в том, что в отсутствии реализаций R7RS виноват лично я, потому что не написал её; и уж точно не потому, что меня искренне волнует популярность и положение Scheme в мире.

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

я не один скептически отношусь к этой идее и считаю, что Common Scheme не нужен

Я тоже так думаю

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