Парадигмы | Мультипарадигма : функциональная , императивная , мета |
---|---|
Семья | Лисп |
Разработано | Гай Л. Стил и Джеральд Джей Сассман |
Впервые появился | 1975 |
Стабильный выпуск | R7RS / 2013 |
Печатная дисциплина | Динамичный , скрытый , сильный |
Сфера | Лексический |
Расширения имени файла | .scm, .ss |
Веб-сайт | www |
Основные реализации | |
Многие (см. Реализации схемы ) | |
Под влиянием | |
АЛГОЛ , Лисп , MDL | |
Под влиянием | |
Clojure , Common Lisp , Dylan , EuLisp , Haskell , Hop , JavaScript , Julia , Lua , MultiLisp , R , Racket , Ruby , Rust , S , Scala , T | |
|
Схема является минималистским говором из Лиспа семейства языков программирования . Схема состоит из небольшого стандартного ядра с несколькими инструментами для расширения языка. [1]
Схема была создана в 1970-х годах в лаборатории искусственного интеллекта Массачусетского технологического института и выпущена ее разработчиками Гаем Л. Стилом и Джеральдом Джей Сассманом в виде серии заметок, теперь известных как Lambda Papers . Это был первый диалект Лиспа, который выбрал лексическую область видимости и первый, который потребовал реализации для выполнения оптимизации хвостового вызова , обеспечивая более сильную поддержку функционального программирования и связанных методов, таких как рекурсивные алгоритмы. Это был также один из первых языков программирования, поддерживающих первоклассные продолжения . Это оказало значительное влияние на усилия, приведшие к разработке Common Lisp . [2]
Язык Scheme стандартизирован в официальном IEEE стандарта [3] и де - факто стандартом называется Пересмотренный п Отчет о языковой схеме алгоритмической (R п RS). Наиболее широко применяемый стандарт - R5RS (1998). [4] Самый последний стандарт, R7RS, [5] предоставляет «малые» и «большие» версии языка схемы; «малый» языковой стандарт был ратифицирован в 2013 году [6].Scheme имеет разнообразную пользовательскую базу благодаря своей компактности и элегантности, но ее минималистская философия также вызвала большие расхождения между практическими реализациями, настолько большие, что Руководящий комитет Scheme назвал его «самым непереносимым языком программирования в мире» и « семейством диалектов». а не на одном языке. [7]
История [ править ]
Истоки [ править ]
Схема началась в 1970 - х годах , как попытка понять Carl Hewitt «s модель Actor , для чего Стила и Сассмен написали„крошечный интерпретатор Лиспа“ с помощью Maclisp , а затем„добавлены механизмов для создания актеров и отправки сообщений“. [8] Scheme изначально назывался «Schemer» в традициях других языков, производных от Lisp, таких как Planner или Conniver . Текущее название возникло в результате использования авторами операционной системы ITS , которая ограничивала имена файлов двумя компонентами, каждая из которых не более шести символов. В настоящее время «Schemer» обычно используется для обозначения программиста Scheme.
R6RS [ править ]
Новый процесс стандартизации языка начался на семинаре Scheme в 2003 году с целью создания стандарта R6RS в 2006 году. Этот процесс порвал с ранее применявшимся единогласным подходом R n RS.
R6RS [9] имеет стандартную модульную систему, позволяющую разделить базовый язык и библиотеки. Было выпущено несколько проектов спецификации R6RS, окончательной версией является R5.97RS. Успешное голосование привело к ратификации нового стандарта, объявленного 28 августа 2007 г. [9]
В настоящее время новейшие версии различных реализаций Scheme [10] поддерживают стандарт R6RS. Существует переносимая эталонная реализация предлагаемых неявно поэтапных библиотек для R6RS, называемая psyntax, которая правильно загружается и самонастраивается на различных старых реализациях Scheme. [11]
Особенностью R6RS является дескриптор типа записи (RTD). Когда RTD создается и используется, представление типа записи может отображать структуру памяти. Он также вычислял битовую маску поля объекта и изменяемую битовую маску поля объекта схемы и помогал сборщику мусора знать, что делать с полями, не просматривая весь список полей, сохраненных в RTD. RTD позволяет пользователям расширять базовый RTD для создания новой системы записи. [12]
R6RS вносит в язык множество значительных изменений. [13] Исходный код теперь указан в Unicode , и большое подмножество символов Unicode теперь может появляться в символах и идентификаторах схемы., и есть другие незначительные изменения в лексических правилах. Символьные данные теперь также указываются в Unicode. Многие стандартные процедуры были перемещены в новые стандартные библиотеки, которые сами по себе являются большим расширением стандарта, содержащим процедуры и синтаксические формы, которые ранее не были частью стандарта. Была введена новая модульная система, и теперь системы для обработки исключений стандартизированы. Синтаксические правила были заменены более выразительным средством синтаксической абстракции (syntax-case), которое позволяет использовать всю схему во время расширения макроса. Теперь требуются совместимые реализации для поддержки полной числовой башни Scheme , а семантика чисел была расширена, в основном в направлении поддержки IEEE 754. стандарт для числового представления с плавающей запятой.
R7RS [ править ]
Стандарт R6RS вызвал споры, поскольку считается, что он отошел от минималистской философии. [14] [15] В августе 2009 года Руководящий комитет Scheme, который наблюдает за процессом стандартизации, объявил о своем намерении рекомендовать разделение Scheme на два языка: большой современный язык программирования для программистов; и небольшая версия, подмножество большой версии, сохраняющее минимализм, одобренный преподавателями и случайными разработчиками. [7] Для работы над этими двумя новыми версиями схемы были созданы две рабочие группы. На сайте Scheme Reports Process есть ссылки на уставы рабочих групп, общественные обсуждения и систему отслеживания проблем.
Девятый проект R7RS (малый язык) был представлен 15 апреля 2013 года. [16] Голосование по ратификации этого проекта завершилось 20 мая 2013 года [17], а окончательный отчет был доступен с 6 августа 2013 года, описывающий «маленький» язык этих усилий: поэтому его нельзя рассматривать изолированно как преемника R6RS ». [6]
1955 г. | 1960 г. | 1965 г. | 1970 г. | 1975 г. | 1980 г. | 1985 г. | 1990 г. | 1995 г. | 2000 г. | 2005 г. | 2010 г. | 2015 г. | 2020 г. | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LISP 1, 1.5, LISP 2 (заброшен) | ||||||||||||||
Маклисп | ||||||||||||||
Интерлисп | ||||||||||||||
Лисп-машина Лисп | ||||||||||||||
Схема | R5RS | R6RS | R7RS маленький | |||||||||||
Ноль | ||||||||||||||
Ференц Лисп | ||||||||||||||
Common Lisp | ||||||||||||||
Le Lisp | ||||||||||||||
Т | ||||||||||||||
Chez Scheme | ||||||||||||||
Emacs Lisp | ||||||||||||||
AutoLISP | ||||||||||||||
ПикоЛисп | ||||||||||||||
EuLisp | ||||||||||||||
ISLISP | ||||||||||||||
OpenLisp | ||||||||||||||
Схема PLT | Ракетка | |||||||||||||
GNU Guile | ||||||||||||||
Визуальный LISP | ||||||||||||||
Clojure | ||||||||||||||
Дуга | ||||||||||||||
LFE | ||||||||||||||
Hy |
Отличительные особенности [ править ]
Схема - это прежде всего функциональный язык программирования . Он имеет много общих характеристик с другими членами семейства языков программирования Lisp. Очень простой синтаксис Scheme основан на s-выражениях , списках в скобках, в которых за префиксным оператором следуют его аргументы. Таким образом, программы-схемы состоят из последовательностей вложенных списков. Списки также являются основной структурой данных в Scheme, что приводит к близкой эквивалентности исходного кода и форматов данных ( гомоиконность ). Программы на схеме могут легко создавать и динамически оценивать фрагменты кода схемы.
Использование списков как структур данных разделяется всеми диалектами Лиспа. Схема наследует богатый набор списков обработки примитивов , таких как cons, carиcdr из его предшественников лисповских. Схема использует строго, но динамически типизированные переменные и поддерживает процедуры первого класса . Таким образом, процедуры могут быть присвоены как значения переменным или переданы как аргументы процедурам.
В этом разделе основное внимание уделяется инновационным возможностям языка, включая те особенности, которые отличают Scheme от других Lisp. Если не указано иное, описания функций относятся к стандарту R5RS.
В примерах, представленных в этом разделе, обозначение «===> результат» используется для обозначения результата вычисления выражения в непосредственно предшествующей строке. Это то же соглашение, что и в R5RS.
Основные конструктивные особенности [ править ]
В этом подразделе описаны те особенности Scheme, которые отличали его от других языков программирования с момента его зарождения. Это аспекты Scheme, которые наиболее сильно влияют на любой продукт языка Scheme, и они являются аспектами, которые разделяют все версии языка программирования Scheme, начиная с 1973 года.
Минимализм [ править ]
Scheme - очень простой язык, который намного проще реализовать, чем многие другие языки сопоставимой выразительной силы . [18] Эта легкость объясняется использованием лямбда-исчисления для вывода большей части синтаксиса языка из более примитивных форм. Например, из 23 синтаксических конструкций на основе s-выражений, определенных в стандарте схемы R5RS, 14 классифицируются как производные или библиотечные формы, которые могут быть записаны как макросы, включающие более фундаментальные формы, в основном лямбда. Как говорит R5RS (R5RS раздел 3.1): «Самой фундаментальной из конструкций связывания переменных является лямбда-выражение, потому что все другие конструкции связывания переменных можно объяснить с помощью лямбда-выражений». [4]
- Основные формы : define, lambda, quote, if, define-syntax, let-syntax, letrec-syntax, syntax-rules, set!
- Производные формы : do, let, let *, letrec, cond, case и, or, begin, named let, delay, unquote, unquote-splicing, quasiquote
Пример: макрос для реализации let
в виде выражения с использованием lambda
привязки переменных.
( определить-синтаксис let ( syntax-rules () (( let (( var expr ) ... ) body ... ) (( lambda ( var ... ) body ... ) expr ... ))))
Таким образом, при использовании, let
как определено выше, реализация схемы будет переписывать " (let ((a 1)(b 2)) (+ b a))
" как " ((lambda (a b) (+ b a)) 1 2)
", что сводит задачу реализации к задаче создания экземпляров процедур кодирования.
В 1998 году Сассман и Стил отметили, что минимализм Scheme был не сознательной целью дизайна, а скорее непреднамеренным результатом процесса проектирования. «Мы на самом деле пытались построить что-то сложное и случайно обнаружили, что случайно разработали что-то, что соответствовало всем нашим целям, но было намного проще, чем мы планировали ... мы поняли, что лямбда-исчисление - небольшой простой формализм - может служить ядром мощного и выразительного языка программирования ». [8]
Лексический объем [ править ]
Подобно большинству современных языков программирования и в отличие от более ранних Lisp, таких как Maclisp , Scheme имеет лексическую область видимости: все возможные привязки переменных в программном модуле могут быть проанализированы путем чтения текста программного модуля без учета контекстов, в которых он может быть вызван. Это контрастирует с динамической областью видимости, которая была характерна для ранних диалектов Лиспа, из-за затрат на обработку, связанных с примитивными методами текстовой замены, используемыми для реализации алгоритмов лексической области видимости в компиляторах и интерпретаторах того времени. В этих Лиспах ссылка на свободную переменную внутри процедуры могла ссылаться на совершенно разные привязки, внешние по отношению к процедуре, в зависимости от контекста вызова.
Толчком к включению лексической области видимости, которая была необычной моделью области видимости в начале 1970-х годов, в их новую версию Лиспа, послужили исследования Алгола Сассманом . Он предположил, что подобные АЛГОЛу механизмы лексической области видимости помогут реализовать их первоначальную цель - реализацию модели акторов Хьюитта в Лиспе. [8]
Ключевые идеи о том, как ввести лексическую область видимости в диалект Лиспа, были популяризированы в Lambda Paper 1975 года Суссмана и Стила «Схема: интерпретатор расширенного лямбда-исчисления» [19], где они приняли концепцию лексического замыкания (на стр. 21). ), который был описан в Меморандуме ИИ в 1970 году Джоэлом Мозесом , который приписал идею Питеру Дж. Ландину . [20]
Лямбда-исчисление [ править ]
Математическая нотация Алонзо Черча , лямбда-исчисление, вдохновила Лисп на использование «лямбда» в качестве ключевого слова для введения процедуры, а также повлияла на развитие методов функционального программирования , включающих использование функций высшего порядка в Лиспе. Но ранние Лиспы не были подходящими выражениями лямбда-исчисления из-за их обработки свободных переменных . [8]
Формальная лямбда-система имеет аксиомы и полное правило вычисления. Это полезно для анализа с использованием математической логики и инструментов. В этой системе расчет можно рассматривать как направленную дедукцию. Синтаксис лямбда-исчисления следует рекурсивным выражениям из x, y, z, ..., круглых скобок, пробелов, периода и символа λ. [21] Функция вычисления лямбда включает: Во-первых, служить отправной точкой мощной математической логики. Во-вторых, он может снизить потребность программистов в рассмотрении деталей реализации, поскольку его можно использовать для имитации машинной оценки. Наконец, лямбда-вычисление создало существенную метатеорию. [22]
Введение лексической области видимости разрешило проблему, сделав эквивалентность между некоторыми формами лямбда-нотации и их практическим выражением на рабочем языке программирования. Суссман и Стил показали, что новый язык можно использовать для элегантного получения всей императивной и декларативной семантики других языков программирования, включая ALGOL и Fortran , а также динамической области видимости других Лиспов, используя лямбда-выражения не как простые экземпляры процедур, а как «контроль». конструкции и модификаторы окружающей среды ". [23] Они ввели стиль передачи продолжения. вместе с их первым описанием схемы в первом из лямбда-статей и в последующих статьях они продолжили демонстрировать грубую силу этого практического использования лямбда-исчисления.
Структура блока [ править ]
Схема унаследовала свою блочную структуру от более ранних языков с блочной структурой, особенно от ALGOL . На схеме, блоки реализуются три обязательных конструкций : let
, let*
и letrec
. Например, следующая конструкция создает блок, в котором вызываемый символ var
привязан к числу 10:
( определите var "гусь" ) ;; Любая ссылка на var здесь будет привязана к "goose" ( здесь идут операторы let (( var 10 )) ;;. Любая ссылка на var здесь будет привязана к 10. ) ;; Любая ссылка на var здесь будет привязана к "goose".
Блоки могут быть вложенными для создания произвольно сложных блочных структур в соответствии с потребностями программиста. Использование блочного структурирования для создания локальных привязок снижает риск конфликта пространств имен, который в противном случае может произойти.
Один из вариантов let
, let*
, разрешений привязок для обозначения переменных , определенных ранее в одной и той же конструкции, таким образом:
( let * (( var1 10 ) ( var2 ( + var1 12 ))) ;; Но определение var1 не может относиться к var2 )
Другой вариант, letrec
разработан, чтобы позволить взаимно рекурсивным процедурам быть привязанными друг к другу.
;; Расчет мужских и женских последовательностей Хофштадтера в виде списка пар( define ( hofstadter-male-female n ) ( letrec (( female ( lambda ( n ) ( if ( = n 0 ) 1 ( - n ( male ( female ( - n 1 )))))) ( мужчина ( лямбда ( n ) ( если ( = n 0 ) 0 ( - n ( женский ( мужской ( - n 1 )))))))) ( let loop (( i 0 )) ( if ( > i n ) ' () ( cons ( cons ( female i ) ( male i )) ( loop ( + я 1 )))))))( hofstadter-мужчина-женщина 8 )===> (( 1 . 0 ) ( 1 . 0 ) ( 2 . 1 ) ( 2 . 2 ) ( 3 . 2 ) ( 3 . 3 ) ( 4 . 4 ) ( 5 . 4 ) ( 5 . 5 ) )
(См. Определения, используемые в этом примере, в мужских и женских последовательностях Хофштадтера .)
Все процедуры, связанные в одном, letrec
могут ссылаться друг на друга по имени, а также к значениям переменных, определенных ранее в том же самом letrec
, но они не могут ссылаться на значения, определенные позже в том же самом letrec
.
Вариант формы let
"named let" имеет идентификатор после let
ключевого слова. Это связывает переменные let с аргументом процедуры, имя которой является заданным идентификатором, а тело - телом формы let. Тело может быть повторено по желанию путем вызова процедуры. Именованный let широко используется для реализации итераций.
Пример: простой счетчик
( let loop (( n 1 )) ( if ( > n 10 ) ' () ( cons n ( loop ( + n 1 )))))===> ( 1 2 3 4 5 6 7 8 9 10 )
Как и любая процедура в Scheme, процедура, созданная в именованном let, является объектом первого класса.
Правильная хвостовая рекурсия [ править ]
Схема имеет конструкцию итерации do
, но в Scheme более идиоматично использовать хвостовую рекурсию для выражения итерации . Соответствующие стандарту реализации схемы требуются для оптимизации хвостовых вызовов, чтобы поддерживать неограниченное количество активных хвостовых вызовов (R5RS, раздел 3.5) [4] - свойство, которое отчет Scheme описывает как надлежащую хвостовую рекурсию - что делает безопасным для программистов на Scheme писать итерационные алгоритмы с использованием рекурсивных структур, которые иногда более интуитивно понятны. Хвостовые рекурсивные процедуры и именованнаяlet
форма обеспечивают поддержку итерации с использованием хвостовой рекурсии.
;; Составление списка квадратов от 0 до 9: ;; Примечание: цикл - это просто произвольный символ, используемый в качестве метки. Подойдет любой символ.( определить ( список квадратов n ) ( let loop (( i n ) ( res ' ())) ( if ( < i 0 ) res ( loop ( - i 1 ) ( cons ( * i i ) res )) )))( список квадратов 9 ) ===> ( 0 1 4 9 16 25 36 49 64 81 )
Первоклассные продолжения [ править ]
Продолжения в Scheme - это первоклассные объекты . Схема предоставляет процедуру call-with-current-continuation
(также известную как call/cc
) для захвата текущего продолжения, упаковывая его как процедуру выхода, привязанную к формальному аргументу в процедуре, предоставленной программистом. (R5RS, раздел 6.4) [4] Первоклассные продолжения позволяют программисту создавать нелокальные управляющие конструкции, такие как итераторы , сопрограммы и отслеживание с возвратом .
Продолжения можно использовать для имитации поведения операторов возврата в императивных языках программирования. Следующая функция find-first
, заданная функция func
и список lst
, возвращает первый элемент x
в lst
таким образом, что (func x)
возвращает истину.
( define ( find-first func lst ) ( call-with-current-continue ( lambda ( return-moment ) ( for-each ( lambda ( x ) ( if ( func x ) ( return-moment x ))) lst ) # е )))( Найти первое целое число? ' ( 1 /2 3 /4 5,6 - 8 /9 10 11 )) ===> 7 ( найти первый ноль? ' ( 1 2 3 4 )) ===> #f
Следующий пример, традиционная головоломка программиста, показывает, что Scheme может обрабатывать продолжения как первоклассные объекты, привязывая их к переменным и передавая их в качестве аргументов процедурам.
( let * (( yin (( lambda ( cc ) ( display "@" ) cc ) ( call-with-current-continue ( lambda ( c ) c )))) ( ян (( lambda ( cc ) ( display "* " ) cc ) ( вызов-с-продолжением-текущим ( лямбда ( c ) c ))))» ( инь янь ))
При выполнении этот код отображает последовательность подсчета: @*@**@***@****@*****@******@*******@********...
[ править ]
В отличие от Common Lisp, все данные и процедуры в Scheme имеют общее пространство имен, тогда как в Common Lisp функции и данные имеют отдельные пространства имен, что позволяет функции и переменной иметь одно и то же имя и требует специальной нотации для ссылки на функция как значение. Иногда это называют различием « Лисп-1 против Лисп-2 », имея в виду унифицированное пространство имен Scheme и отдельные пространства имен Common Lisp. [24]
В Scheme для связывания процедур можно использовать те же примитивы, которые используются для манипулирования и связывания данных. Нет эквивалента Common Lisp defun
и #'
примитивов.
;; Переменная, привязанная к числу: ( определите f 10 ) f ===> 10 ;; Мутация (изменение связанного значения) ( set! F ( + f f 6 )) f ===> 26 ;; Назначение процедуры той же переменной: ( set! F ( lambda ( n ) ( + n 12 ))) ( f 6 ) ===> 18 ;; Назначение результата выражения той же переменной: ( set! F ( f 1 )) f ===> 13 ;; функциональное программирование: ( apply + ' ( 1 2 3 4 5 6 )) ===> 21 ( set! f ( lambda ( n ) ( + n 100 ))) ( map f ' ( 1 2 3 )) === > ( 101 102 103 )
Стандарты реализации [ править ]
В этом подразделе документируются проектные решения, которые были приняты на протяжении многих лет и придали Scheme особый характер, но не являются прямым результатом первоначального дизайна.
Цифровая башня [ править ]
Схема определяет сравнительно полный набор числовых типов данных, включая сложные и рациональные типы, который известен в Схеме как числовая башня (R5RS раздел 6.2 [4] ). Стандарт рассматривает их как абстракции и не связывает разработчика с какими-либо конкретными внутренними представлениями.
Числа могут иметь качество точности. Точное число может быть получено только последовательностью точных операций с другими точными числами - поэтому неточность заразительна. Стандарт определяет, что любые две реализации должны давать одинаковые результаты для всех операций, приводящих к точным числам.
Стандарт определяет процедуру R5RS exact->inexact
и inexact->exact
которые могут быть использованы , чтобы изменить точность числа. inexact->exact
производит «точное число, которое численно ближе всего к аргументу». exact->inexact
производит «неточное число, которое численно ближе всего к аргументу». Стандарт R6RS опускает эти процедуры из основного отчета, но определяет их как процедуры совместимости с R5RS в стандартной библиотеке (rnrs r5rs (6)).
В стандарте R5RS реализации Scheme не требуются для реализации всей числовой башни, но они должны реализовывать «согласованное подмножество, совместимое как с целями реализации, так и с духом языка Scheme» (R5RS раздел 6.2.3). [4] Новый стандарт R6RS требует реализации всей башни и «точных целочисленных объектов и объектов с точными рациональными числами практически неограниченного размера и точности, а также для реализации определенных процедур ... поэтому они всегда возвращают точные результаты, когда заданы точные аргументы. "(Р6РС раздел 3.4, раздел 11.7.1). [9]
Пример 1: точная арифметика в реализации, которая поддерживает точные рациональные комплексные числа.
;; Сумма трех рациональных действительных чисел и двух рациональных комплексных чисел ( определить х ( + 1 /3 1 /4 -1 / 5 -1 / 3i 405 /50 + 2 / 3i )) х ===> 509 /60 + 1 / 3i ;; Проверить на точность. ( точно? x ) ===> #t
Пример 2: Та же арифметика в реализации, которая не поддерживает ни точные рациональные числа, ни комплексные числа, но принимает действительные числа в рациональной нотации.
;; Сумма четырех рациональных действительных чисел ( определить хт ( + 1 /3 1 /4 -1 / 5 405 /50 )) ;; Сумма двух рациональных действительных чисел ( определить XI ( + -1 / 3 2 /3 )) хт ===> +8,48333333333333 XI ===> 0,333333333333333 ;; Проверить на точность. ( точное? xr ) ===> #f ( точное? xi ) ===> #f
Обе реализации соответствуют стандарту R5RS, но вторая не соответствует R6RS, поскольку не реализует полную числовую башню.
Отложенная оценка [ править ]
Схема поддерживает отложенную оценку с помощью delay
формы и процедуры force
.
( Определяют на 10 ) ( определить EVAL-aplus2 ( задержку ( + а 2 ))) ( набор! Есть 20 ) ( усилие EVAL-aplus2 ) ===> 22 ( определяют EVAL-aplus50 ( задержку ( + в 50 ))) ( let (( a 8 )) ( force eval-aplus50 )) ===> 70 ( set! a 100 )( принудительно eval-aplus2 ) ===> 22
Лексический контекст исходного определения обещания сохраняется, и его значение также сохраняется после первого использования force
. Обещание оценивается только один раз.
Эти примитивы, которые создают или обрабатывают значения, известные как обещания , могут использоваться для реализации расширенных конструкций отложенного вычисления, таких как потоки . [25]
В стандарте R6RS они больше не являются примитивами, а вместо этого предоставляются как часть библиотеки совместимости R5RS (rnrs r5rs (6)).
В R5RS предлагается предлагаемая реализация delay
и force
, реализующая обещание как процедура без аргументов ( преобразователь ) и использующая мемоизацию, чтобы гарантировать, что она будет вычисляться только один раз, независимо от того, сколько раз force
вызывается (R5RS раздел 6.4. ). [4]
SRFI 41 позволяет выражать как конечные, так и бесконечные последовательности с необычайной экономией. Например, это определение последовательности Фибоначчи с использованием функций, определенных в SRFI 41: [25]
;; Определите последовательность Фибоначчи: ( define fibs ( stream-cons 0 ( stream-cons 1 ( stream-map + fibs ( stream-cdr fibs ))))) ;; Вычислите сотое число в последовательности: ( stream-ref fibs 99 ) ===> 218922995834555169026
Порядок оценки аргументов процедуры [ править ]
Большинство Лиспов определяют порядок вычисления аргументов процедуры. Схемы нет. Порядок оценки, включая порядок, в котором оценивается выражение в позиции оператора, может быть выбран реализацией на основе вызова за вызовом, и единственным ограничением является то, что «эффект любой одновременной оценки оператора и Выражения операндов должны согласовываться с некоторым последовательным порядком оценки ". (R5RS, раздел 4.1.3) [4]
( let (( ev ( lambda ( n ) ( display "Evaluating" ) ( display ( if ( procedure? n ) "procedure" n )) ( newline ) n ))) (( ev + ) ( ev 1 ) ( ev 2 ))) ===> 3
ev - это процедура, которая описывает переданный ей аргумент, а затем возвращает значение аргумента. В отличие от других Лиспов, появление выражения в позиции оператора (первый элемент) выражения схемы вполне законно, если результатом выражения в позиции оператора является процедура.
При вызове процедуры «+» для сложения 1 и 2 выражения (ev +), (ev 1) и (ev 2) могут быть вычислены в любом порядке, если эффект не такой, как если бы они оценивались параллельно. . Таким образом, следующие три строки могут отображаться в любом порядке стандартной схемой при выполнении приведенного выше примера кода, хотя текст одной строки не может чередоваться с другим, потому что это нарушит ограничение последовательной оценки.
- Оценка 1
- Оценка 2
- Процедура оценки
Гигиенические макросы [ править ]
В стандарте R5RS, а также в более поздних отчетах синтаксис Scheme можно легко расширить с помощью макросистемы. Стандарт R5RS представил мощную гигиеническую макросистему, которая позволяет программисту добавлять новые синтаксические конструкции к языку, используя простой подъязык сопоставления с образцом (R5RS раздел 4.3). [4] До этого гигиеническая макросистема была отнесена к приложению к стандарту R4RS как система «высокого уровня» наряду с макросистемой «низкого уровня», обе из которых рассматривались как расширения схемы, а не как существенная часть языка. [26]
Реализации гигиенической макросистемы, также называемой syntax-rules
, должны уважать лексическую область видимости остального языка. Это обеспечивается специальными правилами именования и области видимости для расширения макросов и позволяет избежать распространенных ошибок программирования, которые могут возникать в макросистемах других языков программирования. R6RS определяет более сложную систему преобразования syntax-case
, которая некоторое время была доступна как языковое расширение схемы R5RS.
;; Определите макрос для реализации варианта «if» с несколькими выражениями ;; истинная ветвь и нет ложной ветви. ( Определить-синтаксис , когда ( синтаксических правил () (( когда ПРЕД ехр EXPS ... ) ( если пред ( начать ехр EXPS ... )))))
Вызов макросов и процедур очень похож (оба являются s-выражениями), но обрабатываются по-разному. Когда компилятор встречает в программе s-выражение, он сначала проверяет, определен ли символ как синтаксическое ключевое слово в текущей лексической области видимости. Если это так, он затем пытается развернуть макрос, рассматривая элементы в хвосте s-выражения как аргументы без компиляции кода для их оценки, и этот процесс повторяется рекурсивно до тех пор, пока не останется никаких вызовов макроса. Если это не синтаксическое ключевое слово, компилятор компилирует код для оценки аргументов в хвосте s-выражения, а затем для оценки переменной, представленной символом в начале s-выражения, и вызывает ее как процедуру с вычисленные выражения хвоста, переданные ему как фактические аргументы.
Большинство реализаций Scheme также предоставляют дополнительные макросистемы. Среди популярных - синтаксические замыкания , явное переименование макросов и define-macro
негигиеничная макросистема, аналогичная defmacro
системе, представленной в Common Lisp .
Невозможность указать, является ли макрос гигиеничным, является одним из недостатков макросистемы. Альтернативные модели расширения, такие как комплекты осциллографов, представляют собой потенциальное решение. [27]
Среды и eval [ править ]
До R5RS в Scheme не было стандартного эквивалента eval
процедуры, которая повсеместно используется в других Lisp, хотя первая Lambda Paper описывалась evaluate
как «аналогичная функции LISP EVAL» [19], а в первом пересмотренном отчете 1978 года эта процедура была заменена на enclose
, которая взял два аргумента. Во втором, третьем и четвертом пересмотренных отчетах не было никаких эквивалентов eval
.
Причина этой путаницы в том, что в Scheme с ее лексической областью видимости результат вычисления выражения зависит от того, где оно вычисляется. Например, неясно, должен ли результат вычисления следующего выражения быть 5 или 6: [28]
( let (( name '+ )) ( let (( + * )) ( оценка ( имя списка 2 3 ))))
Если он оценивается во внешней среде, где name
определено, результатом является сумма операндов. Если он оценивается во внутренней среде, где символ «+» привязан к значению процедуры «*», результатом является произведение двух операндов.
R5RS устраняет эту путаницу, определяя три процедуры, возвращающие среды, и предоставляя процедуру, eval
которая принимает s-выражение и среду и оценивает выражение в предоставленной среде. (R5RS раздел 6.5) [4] R6RS расширяет это, предоставляя процедуру, вызываемую, с environment
помощью которой программист может точно указать, какие объекты импортировать в оценочную среду.
С современной схемой (обычно совместимой с R5RS) для оценки этого выражения вам необходимо определить функцию, evaluate
которая может выглядеть так:
( определить ( оценить выражение ) ( eval expr ( среда-взаимодействие )))
interaction-environment
это глобальная среда от вашего интерпретатора.
Обработка небулевых значений в логических выражениях [ править ]
В большинстве диалектов Лиспа, включая Common Lisp, по соглашению значение NIL
оценивается как значение false в логическом выражении. В Scheme, начиная со стандарта IEEE 1991 года [3], все значения, кроме #f, включая NIL
эквивалент в схеме, который записан как '(), оцениваются как истинное значение в логическом выражении. (R5RS раздел 6.3.1) [4]
В T
большинстве Лиспов константа, представляющая логическое значение true , так и есть #t
.
Непересекаемость примитивных типов данных [ править ]
В схеме примитивные типы данных не пересекаются. Только один из следующих предикатов может быть справедливо для любого объекта схемы: boolean?
, pair?
, symbol?
, number?
, char?
, string?
, vector?
, port?
, procedure?
. (R5RS, раздел 3.2) [4]
В числовом типе данных, напротив, числовые значения перекрываются. Например, значение удовлетворяет целочисленное все из integer?
, rational?
, real?
, complex?
и number?
предикатов в то же время. (R5RS, раздел 6.2) [4]
Предикаты эквивалентности [ править ]
Схема состоит из трех различных типов эквивалентности между произвольными объектами , обозначенными тремя различными предикатами эквивалентности , реляционные операторы для проверки равенства eq?
, eqv?
и equal?
:
eq?
оценивается до,#f
если его параметры не представляют один и тот же объект данных в памяти;eqv?
обычно то же самое,eq?
но обрабатывает примитивные объекты (например, символы и числа) специально, так что числа, представляющие одно и то же значение,eqv?
даже если они не относятся к одному и тому же объекту;equal?
сравнивает структуры данных, такие как списки, векторы и строки, чтобы определить, соответствуют ли они структуре иeqv?
содержанию. (R5RS раздел 6.1) [4]
В Scheme также существуют операции эквивалентности, зависящие от типа: string=?
и string-ci=?
сравнение двух строк (последняя выполняет сравнение, не зависящее от регистра); char=?
и char-ci=?
сравнить персонажей; =
сравнивает числа. [4]
Комментарии [ редактировать ]
До стандарта R5RS стандартный комментарий в Scheme состоял из точки с запятой, что делало остальную часть строки невидимой для Scheme. Многочисленные реализации поддерживают альтернативные соглашения, разрешающие расширение комментариев более чем на одну строку, и стандарт R6RS допускает два из них: все s-выражение может быть превращено в комментарий (или «закомментировано»), если перед ним стоит #;
(введено в SRFI 62 [29] ), а многострочный комментарий или «блочный комментарий» можно создать, заключив текст в символы #|
и |#
.
Ввод / вывод [ править ]
Ввод и вывод схемы основаны на типе данных порта . (R5RS сек. 6.6) [4] R5RS определяет два порта по умолчанию, доступных с помощью процедур current-input-port
и current-output-port
, которые соответствуют представлениям Unix о стандартном вводе и стандартном выводе . Большинство реализаций также предоставляют current-error-port
. Перенаправление ввода и стандартный вывод поддерживается в стандарте стандартными процедурами, такими как with-input-from-file
и with-output-to-file
. Большинство реализаций предоставляют строковые порты с аналогичными возможностями перенаправления, позволяя выполнять многие обычные операции ввода-вывода над строковыми буферами вместо файлов, используя процедуры, описанные в SRFI 6. [30] Стандарт R6RS определяет гораздо более сложные и функциональные процедуры портов и много новых типов портов.
Следующие примеры написаны на строгой схеме R5RS.
Пример 1: с выходом по умолчанию (текущий-выходной-порт):
( Пусть (( hello0 ( лямбда () ( дисплей "Привет мир" ) ( перевод строки )))) ( hello0 ))
Пример 2: Как 1, но с использованием необязательного аргумента порта для процедур вывода
( let (( hello1 ( lambda ( p ) ( display "Hello world" p ) ( newline p )))) ( hello1 ( current-output-port )))
Пример 3: Как 1, но вывод перенаправляется во вновь созданный файл
;; NB: with-output-to-file - это необязательная процедура в R5RS ( let (( hello0 ( lambda () ( display «Hello world» ) ( newline )))) ( with-output-to-file «helloworldoutputfile» hello0 ) )
Пример 4: Как 2, но с явным открытием файла и закрытым портом для отправки вывода в файл
( let (( hello1 ( lambda ( p ) ( display "Hello world" p ) ( newline p ))) ( output-port ( open-output-file "helloworldoutputfile" ))) ( hello1 output-port ) ( close-output -port выходной-порт ))
Пример 5: Как 2, но с использованием call-with-output-file для отправки вывода в файл.
( let (( hello1 ( lambda ( p ) ( display "Hello world" p ) ( newline p )))) ( call-with-output-file "helloworldoutputfile" hello1 ))
Аналогичные процедуры предусмотрены для ввода. Схема R5RS предоставляет предикаты input-port?
и output-port?
. Для ввода и вывода символов write-char
, read-char
, peek-char
и char-ready?
предусмотрены. Для записи и чтения выражений Scheme в Scheme предусмотрены read
и write
. При операции чтения возвращаемый результат - это объект конца файла, если входной порт достиг конца файла, и это можно проверить с помощью предиката eof-object?
.
В дополнение к стандарту SRFI 28 определяет базовую процедуру форматирования, напоминающую format
функцию Common Lisp , после чего она названа. [31]
Новое определение стандартных процедур [ править ]
В схеме процедуры привязаны к переменным. В R5RS стандарт языка официально предписывает программам изменять привязки переменных встроенных процедур, эффективно переопределяя их. (R5RS «Изменения языка») [4] Например, можно расширить, +
чтобы принимать как строки, так и числа, переопределив их:
( set! + ( let (( original + + )) ( lambda args ( apply ( if ( or ( null? args ) ( string? ( car args ))) string-append original + ) args )))) ( + 1 2 3 ) ===> 6 ( + "1" "2" "3" ) ===> "123"
В R6RS каждая привязка, включая стандартные, принадлежит некоторой библиотеке, и все экспортируемые привязки неизменяемы. (R6RS раздел 7.1) [9] Из-за этого переопределение стандартных процедур путем мутации запрещено. Вместо этого можно импортировать другую процедуру под именем стандартной, что по сути аналогично переопределению.
Номенклатура и соглашения об именах [ править ]
В стандартной схеме процедуры, которые преобразуют один тип данных в другой, содержат строку символов «->» в своем имени, предикаты заканчиваются знаком «?», А процедуры, которые изменяют значение уже выделенных данных, заканчиваются знаком «!». Программисты Scheme часто следуют этим соглашениям.
В формальных контекстах, таких как стандарты схемы, слово «процедура» используется вместо «функция» для обозначения лямбда-выражения или примитивной процедуры. В обычном использовании слова «процедура» и «функция» взаимозаменяемы. Применение процедуры иногда формально называют комбинацией .
Как и в других Lisp, термин « преобразователь » используется в Scheme для обозначения процедуры без аргументов. Термин «правильная хвостовая рекурсия» относится к свойству всех реализаций схемы, что они выполняют оптимизацию хвостового вызова, чтобы поддерживать неопределенное количество активных хвостовых вызовов .
Форма названий документов по стандартизации с момента R3RS, «Пересмотренный п Отчет о языке Scheme алгоритмической», является ссылкой на название Алгол 60 стандартного документа «Пересмотренный отчет об алгоритмическом языке Алгол 60» Сводка страницы R3RS подробно смоделирован на странице «Сводка» отчета ALGOL 60. [32] [33]
Обзор стандартных форм и процедур [ править ]
В этом разделе не процитировать любые источники . Май 2013 г. ) ( Узнайте, как и когда удалить этот шаблон сообщения ) ( |
Язык формально определен в стандартах R5RS (1998) и R6RS (2007). Они описывают стандартные «формы»: ключевые слова и сопутствующий синтаксис, которые обеспечивают структуру управления языком, и стандартные процедуры, которые выполняют общие задачи.
Стандартные формы [ править ]
В этой таблице описаны стандартные формы схемы. Некоторые формы появляются более чем в одной строке, потому что их нелегко классифицировать в одну функцию на языке.
Формы, отмеченные буквой «L» в этой таблице, классифицируются как производные «библиотечные» формы в стандарте и часто реализуются как макросы с использованием более фундаментальных форм на практике, что значительно упрощает задачу реализации, чем в других языках.
Цель | Формы |
---|---|
Определение | определять |
Связывающие конструкции | лямбда, do (L), let (L), let * (L), letrec (L) |
Условная оценка | if, cond (L), case (L) и (L) или (L) |
Последовательная оценка | начинать (*) |
Итерация | лямбда, делать (L), названный let (L) |
Синтаксическое расширение | определить-синтаксис, let-синтаксис, letrec-синтаксис, правила синтаксиса (R5RS), регистр синтаксиса (R6RS) |
Цитирование | quote ('), unquote (,), quasiquote (`), unquote-сплайсинг (, @) |
Назначение | набор! |
Отсроченная оценка | задержка (L) |
Обратите внимание, что begin
это определено как синтаксис библиотеки в R5RS, но расширитель должен знать об этом для достижения функциональности соединения. В R6RS это больше не синтаксис библиотеки.
Стандартные процедуры [ править ]
В следующих двух таблицах описаны стандартные процедуры схемы R5RS. R6RS гораздо более обширен, и краткое изложение этого типа нецелесообразно.
Некоторые процедуры появляются более чем в одной строке, потому что их нельзя легко классифицировать в одну функцию на языке.
Цель | Процедуры |
---|---|
Строительство | вектор, make-vector, make-string, list |
Предикаты эквивалентности | eq ?, eqv ?, equal ?, string = ?, string-ci = ?, char = ?, char-ci =? |
Преобразование типов | вектор-> список, список-> вектор, число-> строка, строка-> число, символ-> строка, строка-> символ, char-> integer, integer-> char, string-> list, list-> string |
Числа | См. Отдельную таблицу |
Струны | строка ?, make-строка, строка, длина строки, ссылка на строку, набор строк !, строка = ?, строка-ci = ?, строка <? строка-ci <?, строка <=? строка-ci <= ?, строка>? строка-ci> ?, строка> =? строка-ci> = ?, подстрока, добавление строки, строка-> список, список-> строка, копия строки, заполнение строки! |
Символы | char ?, char = ?, char-ci = ?, char <? char-ci <?, char <=? char-ci <= ?, char>? char-ci> ?, char> =? char-ci> = ?, char-alphabetic?, char-numeric?, char-whitespace?, char-upper-case?, char-lower-case?, char-> integer, integer-> char, char-upcase, char-downcase |
Векторы | make-vector, vector, vector ?, vector-length, vector-ref, vector-set !, vector-> list, list-> vector, vector-fill! |
Символы | символ-> строка, строка-> символ, символ? |
Пары и списки | пара ?, cons, car, cdr, set-car !, set-cdr !, ноль?, список?, список, длина, добавление, реверс, хвост списка, ссылка на список, memq. memv. член, assq, assv, assoc, список-> вектор, вектор-> список, список-> строка, строка-> список |
Предикаты идентичности | логическое?, пара?, символ?, число?, символ?, строка?, вектор?, порт?, процедура? |
Продолжение | вызов-с-текущим-продолжением (вызов / cc), значения, вызов-со значениями, динамический ветер |
Среды | eval, схема-отчет-среда, нулевая-среда, взаимодействие-среда (необязательно) |
Ввод, вывод | display, newline, read, write, read-char, write-char, peek-char, char-ready ?, eof-объект? open-input-file, open-output-file, close-input-port, close-output-port, input-port ?, output-port ?, текущий-вход-порт, текущий-выходной-порт, call-with- файл ввода, вызов с файлом вывода, с вводом из файла (необязательно), с выводом в файл (необязательно) |
Системный интерфейс | загрузка (необязательно), добавление стенограммы (необязательно), отключение стенограммы (необязательно) |
Отсроченная оценка | сила |
Функциональное программирование | процедура ?, применить, карта, для каждого |
Булевы | логическое? нет |
Строковые и символьные процедуры, содержащие «-ci» в своих именах, выполняют независимые от регистра сравнения между своими аргументами: версии одного и того же символа в верхнем и нижнем регистре считаются равными.
Цель | Процедуры |
---|---|
Основные арифметические операторы | +, -, *, /, abs, частное, остаток, по модулю, gcd, lcm, expt, sqrt |
Рациональное число | числитель, знаменатель, рациональное?, рационализировать |
Приближение | пол, потолок, усеченный, круглый |
Точность | неточный-> точный, точный-> неточный, точный?, неточный? |
Неравенства | <, <=,>,> =, = |
Разные предикаты | ноль?, отрицательный?, положительный? странный? четный? |
Максимум и минимум | макс, мин |
Тригонометрия | грех, соз, загар, асин, акос, атан |
Экспоненты | exp, log |
Комплексные числа | сделать-прямоугольный, сделать-полярный, действительная часть, воображаемая часть, величина, угол, сложный? |
Ввод, вывод | число-> строка, строка-> число |
Предикаты типа | целое?, рациональное?, действительное?, комплексное?, число? |
Реализации - и /, которые принимают более двух аргументов, определены, но оставлены необязательными в R5RS.
Запросы схемы на реализацию [ править ]
Из-за минимализма Scheme многие общие процедуры и синтаксические формы не определены стандартом. Чтобы сделать базовый язык небольшим, но упростить стандартизацию расширений, сообщество Scheme разработало процесс «Scheme Request for Implementation» (SRFI), с помощью которого библиотеки расширений определяются путем тщательного обсуждения предложений по расширению. Это способствует переносимости кода. Многие из SRFI поддерживаются всеми или большинством реализаций Scheme.
SRFI с довольно широкой поддержкой в различных реализациях включают: [34]
- 0: функциональная конструкция условного расширения
- 1: список библиотеки
- 4: однородные числовые векторные типы данных
- 6: основные строковые порты
- 8: получение, привязка к нескольким значениям
- 9: определение типов записей
- 13: строковая библиотека
- 14: библиотека наборов символов
- 16: синтаксис для процедур переменной арности
- 17: обобщенный набор!
- 18: Поддержка многопоточности
- 19: типы данных и процедуры времени
- 25: примитивы многомерного массива
- 26: обозначение специализированных параметров без каррирования
- 27: источники случайных битов
- 28: строки основного формата
- 29: локализация
- 30: вложенные многострочные комментарии
- 31: специальная форма для рекурсивного вычисления
- 37: args-fold: процессор аргументов программы
- 39: объекты параметров
- 41: потоки
- 42: нетерпеливое понимание
- 43: векторная библиотека
- 45: примитивы для выражения итеративных ленивых алгоритмов
- 60: целые числа как биты
- 61: более общий условный пункт
- 66: октетные векторы
- 67: сравнить процедуры
Реализации [ править ]
Элегантный, минималистичный дизайн сделал Scheme популярной целью для языковых дизайнеров, любителей и преподавателей, а из-за своего небольшого размера, как у типичного интерпретатора , он также является популярным выбором для встроенных систем и сценариев . Это привело к появлению множества реализаций, [35] большинство из которых настолько отличаются друг от друга, что перенос программ с одной реализации на другую довольно затруднен, а небольшой размер стандартного языка означает, что написание полезной программы любой большой сложности в стандартной переносной схеме это практически невозможно. [7] Стандарт R6RS определяет гораздо более широкий язык в попытке сделать его более привлекательным для программистов.
Почти все реализации предоставляют традиционный цикл чтения-оценки-печати в стиле Лиспа для разработки и отладки. Многие также компилируют программы Scheme в исполняемый двоичный файл. Поддержка для встраивания Схемы коды в программах , написанных на других языках , также распространена, так как относительная простота реализации Scheme делает его популярным выбором для добавления возможности создания сценариев крупных систем , разработанных на таких языках, как C . В Гамбит , курицы и Bigloo переводчики Схема компиляции Схемы С, что делает особенно легко вложение. Кроме того, компилятор Bigloo можно настроить для генерации байт-кода JVM. , а также имеет экспериментальный генератор байт-кода для .NET .
Некоторые реализации поддерживают дополнительные функции. Например, Kawa и JScheme обеспечивают интеграцию с классами Java, а компиляторы Scheme to C часто упрощают использование внешних библиотек, написанных на C, вплоть до встраивания реального кода C в исходный код Scheme. Другой пример - Pvts , который предлагает набор визуальных инструментов для поддержки изучения Scheme.
Использование [ править ]
Схема широко используется в ряде [36] школ; в частности, в ряде вводных курсов по информатике используется схема в сочетании с учебником « Структура и интерпретация компьютерных программ» (SICP). [37] В течение последних 12 лет, PLT управлял ProgramByDesign (ранее TeachScheme!) Проект, который подвергается около 600 учителей средней школы и тысяч старшеклассников зачаточного программирования Scheme. Старый вводный курс программирования 6.001 Массачусетского технологического института преподавался на схеме [38]. Хотя курс 6.001 был заменен более современными курсами, SICP по-прежнему преподается в Массачусетском технологическом институте. [39]Точно так же вводный курс в Калифорнийском университете в Беркли , CS 61A, до 2011 года преподавался полностью на Scheme, за исключением незначительных отклонений в Logo для демонстрации динамической области. Сегодня, как и Массачусетский технологический институт, Беркли заменил учебную программу более современной версией, которая в основном преподается на Python 3 , но текущая программа по-прежнему основана на старой учебной программе, и некоторые части курса все еще преподаются на схеме. [40]
Учебник « Как разрабатывать программы » Матиаса Феллейзена, который в настоящее время работает в Северо-Восточном университете, используется некоторыми высшими учебными заведениями для проведения вводных курсов по информатике. И Северо-Восточный университет, и Вустерский политехнический институт используют Scheme исключительно для своих вводных курсов «Основы компьютерных наук» (CS2500) и «Введение в разработку программ» (CS1101) соответственно. [41] [42] Роуз-Хульман использует Scheme в своем более продвинутом курсе "Концепции языка программирования". [43] Основной курс Университета Брандейса , Структура и интерпретация компьютерных программ (COSI121b), также преподается исключительно на схеме ученым-теоретиком.Гарри Майерсон . [44] Вводный класс C211 Университета Индианы преподается полностью на Scheme. В версии курса для самостоятельного изучения CS 61AS по-прежнему используется Scheme. [45] Вводные курсы информатики в Йельском университете и Гриннелл-колледже также преподаются на Scheme. [46] Парадигмы проектирования программирования, [47] обязательный курс для аспирантов по информатике в Северо-Восточном университете., также широко использует Scheme. Бывший вводный курс информатики в Университете Миннесоты - Города-побратимы, CSCI 1901, также использовал Scheme в качестве основного языка, за которым последовал курс, знакомящий студентов с языком программирования Java; [48] однако, следуя примеру Массачусетского технологического института, кафедра заменила 1901 на CSCI 1133 на основе Python, [49] в то время как функциональное программирование подробно рассматривается в курсе третьего семестра CSCI 2041. [50] В индустрии программного обеспечения, Tata Consultancy Services , крупнейшая в Азии консалтинговая компания по программному обеспечению, использует Scheme в своей месячной программе обучения для выпускников колледжей. [ необходима цитата ]
Схема также использовалась для следующего:
- Язык семантики и спецификации стилей документа (DSSSL), который предоставляет метод определения таблиц стилей SGML , использует подмножество схем. [51]
- Хорошо известный редактор растровой графики с открытым исходным кодом GIMP использует TinyScheme в качестве языка сценариев . [52]
- Guile был принят проектом GNU в качестве официального языка сценариев, и эта реализация Scheme встроена в такие приложения, как GNU LilyPond и GnuCash в качестве языка сценариев для расширений. Точно так же, Коварство раньше язык сценариев для настольной среды GNOME , [53] и GNOME все еще есть проект , который обеспечивает Guile привязку к его библиотеке стек. [54] Существует проект по включению Guile в GNU Emacs , флагманскую программу GNU, взамен текущего интерпретатора Emacs Lisp . [ необходима цитата ]
- Elk Scheme используется Synopsys в качестве языка сценариев для своих технологических инструментов CAD (TCAD) . [55]
- Широ Каваи, старший программист фильма Final Fantasy: The Spirits Within , использовал Scheme в качестве языка сценариев для управления движком рендеринга в реальном времени. [56]
- Google App Inventor для Android использует Scheme, где Kawa используется для компиляции кода Scheme до байт-кодов для виртуальной машины Java, работающей на устройствах Android. [57]
См. Также [ править ]
- Сталинский компилятор , компилятор для схемы.
- Основы языков программирования , еще один классическийучебник по информатике .
- SXML , иллюстративное представление XML в Scheme, которое обеспечивает простой подход к обработке данных XML в Scheme.
Ссылки [ править ]
- ^ "Язык программирования схем" . Массачусетский технологический институт .
- ^ Common LISP: Язык, 2-е изд., Гай Л. Стил младший, цифровая пресса; 1981. ISBN 978-1-55558-041-4 . «Common Lisp - это новый диалект Lisp, преемник MacLisp, на который сильно повлияли ZetaLisp и в некоторой степени Scheme и InterLisp».
- ^ a b 1178-1990 (Reaff 2008) Стандарт IEEE для языка программирования схем. Номер детали IEEE STDPD14209, единогласно подтвержденный на заседании Комитета по обзору стандартов Совета по стандартам IEEE-SA, 26 марта 2008 г. (пункт 6.3 в протоколе), протокол повторного подтверждения доступен в октябре 2009 г. ПРИМЕЧАНИЕ: этот документ доступен только для покупки из IEEE и недоступен в Интернете на момент написания (2009 г.).
- ^ Б с д е е г ч я J к л м п о р д Richard Kelsey; Уильям Клингер; Джонатан Рис; и другие. (Август 1998 г.). «Пересмотренный отчет 5 по алгоритмической языковой схеме» . Вычисление высшего порядка и символическое вычисление . 11 (1): 7–105. DOI : 10,1023 / A: 1010051815785 . S2CID 14069423 . Проверено 9 августа 2012 .
- ^ Шинн, Алекс; Коуэн, Джон; Глеклер, Артур (июль 2013 г.). «Пересмотренный отчет 7 об алгоритмической языковой схеме (R7RS)» . Проверено 8 ноября 2020 .
- ^ a b «Доступен финальный вариант R7RS» (PDF) . 2013-07-06.
- ^ a b c Уилл Клинджер, Марк Фили, Крис Хэнсон, Джонатан Рис и Олин Шиверс (20 августа 2009 г.). «Изложение позиции (проект) » . Руководящий комитет схемы . Проверено 9 августа 2012 .CS1 maint: multiple names: authors list (link)
- ^ a b c d Сассман, Джеральд Джей; Стил, Гай Л. (1 декабря 1998 г.). «Пересмотренный первый отчет о схеме». Вычисление высшего порядка и символическое вычисление . 11 (4): 399–404. DOI : 10,1023 / A: 1010079421970 . S2CID 7704398 .
- ^ a b c d Спербер, Майкл; Дибвиг, Р. Кент; Флатт, Мэтью; Ван Страатен, Антон; и другие. (Август 2007 г.). «Пересмотренный отчет 6 по алгоритмической языковой схеме (R6RS)» . Руководящий комитет схемы . Проверено 13 сентября 2011 .
- ^ «Реализации R6RS» . r6rs.org . Проверено 24 ноября 2017 .
- ^ Абдулазиз Ghuloum (2007-10-27). «Библиотеки R6RS и синтаксически-падежная система (псинтаксис)» . Схема Икара . Проверено 20 октября 2009 .
- ^ Keep, Эндрю В .; Дибвиг, Р. Кент (ноябрь 2014 г.). «Представление типов записи схемы во время выполнения». Журнал функционального программирования . 24 (6): 675–716. DOI : 10.1017 / S0956796814000203 . S2CID 40001845 .
- ^ «Пересмотренный отчет ^ 6 по алгоритмической языковой схеме, приложение E: изменения языка» . Руководящий комитет схемы. 2007-09-26 . Проверено 20 октября 2009 .
- ^ "Электорат R6RS" . Руководящий комитет схемы. 2007 . Проверено 9 августа 2012 .
- ^ Марк Фили (сборник) (2007-10-26). «Намерения разработчиков в отношении R6RS» . Руководящий комитет схемы, список рассылки r6rs-обсуждения . Проверено 9 августа 2012 .
- ^ «Доступен 9-й проект R7RS» (PDF) . 2013-04-15.
- ^ Уилл Клингер (2013-05-10). «продление срока голосования» . Руководящий комитет по языку схемы, список рассылки отчетов по схемам. Архивировано из оригинала на 2013-07-21 . Проверено 7 июля 2013 .
- ^ Схема 48 реализация так назван потомучто переводчик был написан Ричард Келси и Джонатан Риз в48 часов (6 августа - 7, 1986. См Ричард Келси; Джонатан Риз, Майк Спербер (2008-01-10). «The Неполная схема Руководство для выпуска 1.8" 48 Reference . Джонатан Риз, s48.org . Источник 2012-08-09 .
- ^ a b Джеральд Джей Сассман и Гай Льюис Стил-младший (декабрь 1975 г.). «Схема: интерпретатор для расширенного лямбда-исчисления» . AI Memos . MIT AI Lab . AIM-349. Архивировано из оригинала (постскриптум или PDF) 10 мая 2016 года . Проверено 9 августа 2012 .
- ↑ Джоэл Мозес (июнь 1970 г.), Функция FUNCTION в LISP, или Почему проблема FUNARG должна называться проблемой окружающей среды , hdl : 1721.1 / 5854 , AI Memo 199,
Полезная метафора для различия между FUNCTION и QUOTE в LISP - рассматривать QUOTE как пористое или открытое покрытие функции, поскольку свободные переменные ускользают в текущее окружение. ФУНКЦИЯ действует как закрытое или непористое покрытие (отсюда термин «закрытие», используемый Ландином). Таким образом, мы говорим об «открытых» лямбда-выражениях (функции в LISP обычно являются лямбда-выражениями) и «закрытых» лямбда-выражениях. [...] Мой интерес к проблеме окружающей среды возник, когда Ландин, глубоко понимавший эту проблему, посетил Массачусетский технологический институт в 1966-67 годах. Затем я понял соответствие между списками FUNARG, которые являются результатами оценки «закрытых» лямбда-выражений в LISP, и лямбда-замыканиями ISWIM .
- ^ ван Тондер, Андре (1 января 2004 г.). «Лямбда-исчисление для квантовых вычислений». SIAM Journal on Computing . 33 (5): 1109–1135. arXiv : квант-ph / 0307150 . DOI : 10,1137 / S0097539703432165 . S2CID 613571 .
- ^ Niehren, J .; Schwinghammer, J .; Смолка, Г. (ноябрь 2006 г.). «Параллельное лямбда-исчисление с фьючерсами» (PDF) . Теоретическая информатика . 364 (3): 338–356. DOI : 10.1016 / j.tcs.2006.08.016 .
- ↑ Джеральд Джей Сассман и Гай Льюис Стил-младший (март 1976 г.). «Лямбда: высший императив» . AI Memos . MIT AI Lab . AIM-353. Архивировано из оригинала (постскриптум или PDF) 10 мая 2016 года . Проверено 9 августа 2012 .
- ^ Габриэль, Ричард П .; Питман, Кент (1988). «Технические вопросы разделения функциональных ячеек и ячеек значений» . Лисп и символьные вычисления . 1 (1) (опубликовано в июне 1988 г.). С. 81–101. DOI : 10.1007 / BF01806178 . Проверено 9 августа 2012 .
- ^ a b Филип Л. Бевиг (24 января 2008 г.). «СРФИ 41: Потоки» . Редакторы SRFI, schemers.org . Проверено 9 августа 2012 .
- ^ Уильям Клинджер и Джонатан Рис, редакторы (1991). «Пересмотренный отчет 4 по алгоритмической языковой схеме» . Указатели ACM Lisp . 4 (3): 1–55 . Проверено 9 августа 2012 .
- ^ Flatt, Мэтью (2016). «Переплет комплектов прицелов». Материалы 43-го ежегодного симпозиума ACM SIGPLAN-SIGACT по принципам языков программирования . С. 705–717. DOI : 10.1145 / 2837614.2837620 . ISBN 978-1-4503-3549-2. S2CID 15401805 .
- ^ Джонатан Рис, Схема вещей Встреча в июне 1992 г. Архивировано 16 июля 2011 г. в Wayback Machine (постскриптум), в Lisp Pointers, V (4), октябрь – декабрь 1992 г. Дата обращения 09.08.2012.
- ↑ Тейлор Кэмпбелл (21 июля 2005 г.). «SRFI 62: комментарии S-выражения» . Редакторы SRFI, schemers.org . Проверено 9 августа 2012 .
- ^ Уильям Д. Клингер (1999-07-01). «SRFI 6: Основные строковые порты» . Редакторы SRFI, schemers.org . Проверено 9 августа 2012 .
- ^ Скотт Г. Миллер (2002-06-25). «SRFI 28: Строки основного формата» . Редакторы SRFI, schemers.org . Проверено 9 августа 2012 .
- ^ JW Backus; Ф.Л. Бауэр; Дж. Грин; К. Кац; Дж. Маккарти П. Наур; и другие. (Январь – апрель 1960 г.). «Пересмотренный отчет по алгоритмическому языку Algol 60» . Numerische Mathematik, Коммуникации ACM и Журнал Британского компьютерного общества . Проверено 9 августа 2012 .
- ^ Джонатан Рис; Уильям Клингер, ред. (Декабрь 1986 г.). «Пересмотренный (3) отчет по алгоритмической языковой схеме (посвященный памяти АЛГОЛА 60)» . Уведомления ACM SIGPLAN . 21 (12): 37–79. CiteSeerX 10.1.1.29.3015 . DOI : 10.1145 / 15042.15043 . S2CID 43884422 . Проверено 9 августа 2012 .
- ^ "Схемы систем, поддерживающих SRFIs" . Редакторы SRFI, schemers.org. 2009-08-30 . Проверено 9 августа 2012 .
- ^ 75 известных реализаций Scheme перечислены в "scheme-faq-standard" . Схема сообщества Wiki. 2009-06-25 . Проверено 20 октября 2009 .
- ^ Эд Мартин (2009-07-20). «Список школ, использующих Схему» . Махинаторы Inc . Проверено 20 октября 2009 .
- ^ "Список школ, использующих SICP" . MIT Press. 1999-01-26 . Проверено 20 октября 2009 .
- ↑ Эрик Гримсон (весна 2005 г.). «6.001 Структура и интерпретация компьютерных программ» . Открытые курсы MIT . Проверено 20 октября 2009 .
- ↑ Алекс Вандивер; Нельсон Эльхаге; и другие. (Январь 2009 г.). «6.184 - Зомби пьют с кофеином 6.001» . MIT CSAIL . Проверено 20 октября 2009 .
- ^ Джон ДеНеро (осень 2019). «Компьютерные науки 61A, Беркли» . Департамент электротехники и компьютерных наук, Беркли . Проверено 17 декабря 2019 .
- ^ CS 2500: Основы информатики I , Северо-Восточный университет
- ^ CS 1101: Введение в разработку программ (A05): программное обеспечение курса , Вустерский политехнический институт
- ^ «CSSE 304: Концепции языка программирования» . Технологический институт Роуза-Халмана .
- ^ "Spring 2021 CS121b Syllabus" (PDF) . Университет Брандейса .
- ^ https://berkeley-cs61as.github.io
- ^ Дана Энглина (осень 2009 г.). «Введение в информатику (CPSC 201)» . Зоопарк факультета компьютерных наук Йельского университета . Проверено 20 октября 2009 .
- ^ "Парадигмы дизайна программирования CSG107 Курсы чтения" . Северо-Восточный университетский колледж компьютерных и информационных наук. Осень 2009 . Проверено 9 августа 2012 .
- ^ Структура компьютерного программирования I Архивировано 19июня 2010 г.в Wayback Machine , факультет компьютерных наук, Университет Миннесоты, весна 2010 г. (дата обращения 30 января 2010 г.).
- ^ CSci Обязательные описания курсов и другая информация, заархивированные 25 октября 2019 г. в Wayback Machine , факультет компьютерных наук, Университет Миннесоты (доступ 2019-10-25)
- ^ CSCI 2041 — Комитет по учебной программе нового курса CSE, Университет Миннесоты (доступ 2019-10-25)
- ↑ Робин Кавер (25 февраля 2002). «DSSSL - Семантика стилей документов и язык спецификаций. ISO / IEC 10179: 1996» . Титульные страницы . Проверено 9 августа 2012 .
- ^ « Основным языком сценариев для GIMP, который был присоединен к нему сегодня, является Scheme». От Дова Гробгельда (2002). «Учебное пособие по базовой схеме GIMP» . Команда GIMP . Проверено 9 августа 2012 .
- ^ Тодд Грэм Льюис; Дэвид Золл; Джулиан Миссиг (2002). «Часто задаваемые вопросы по GNOME из Интернет-архива» . Команда Gnome, gnome.org. Архивировано из оригинала на 2000-05-22 . Проверено 9 августа 2012 .
- ^ "лукавый гном" . Фонд свободного программного обеспечения . Проверено 9 августа 2012 .
- ^ Лоуренс Бревард (2006-11-09). « Обновление программы Synopsys MAP-in SM : Форум разработчиков совместимости EDA» (PDF) . Сводка Inc . Проверено 9 августа 2012 .
- Перейти ↑ Kawai, Shiro (октябрь 2002 г.). «Склеивание вещей вместе - схема в производстве контента компьютерной графики в реальном времени» . Труды Первой Международной конференции по Лисп, Сан-Франциско : 342–348 . Проверено 9 августа 2012 .
- ^ Билл Магнусон; Хэл Абельсон и Марк Фридман (11 августа 2009 г.). «Под капотом App Inventor для Android» . Google Inc, официальный блог Google Research . Проверено 9 августа 2012 .
Дальнейшее чтение [ править ]
- Введение в схему и ее реализацию ( зеркало )
- Кристофер Т. Хейнс (1999-06-22). "Опыт стандартизации языка программирования схем" .
- Гай Л. Стил-младший , Ричард П. Габриэль . «Эволюция Лиспа» (PDF) .CS1 maint: multiple names: authors list (link)
- Джеральд Сассман и Гай Стил , СХЕМА: Интерпретатор для расширенного лямбда-исчисления AI Memo 349 , Лаборатория искусственного интеллекта Массачусетского технологического института, Кембридж, Массачусетс, декабрь 1975 г.
Внешние ссылки [ править ]
- Схема в Curlie
- Программирование схем в Викиучебнике
- Напишите себе схему за 48 часов в Викиучебнике
- СМИ, связанные со схемой (языком программирования) на Викискладе?
- Букмарклет, добавляющий интерактивную схему REPL на любой веб-сайт