Scheme
Scheme |
- Тип исполнения:
- интерпретатор или компилятор
- Типизация:
- строгая, динамическая
- Дата появления:
- 1970
- Разработчики:
- Гай Стил и Джеральд Сассмен
- Реализации:
- PLT Scheme, MIT Scheme, Scheme48, Guile
- Повлиял на:
- Common Lisp
Scheme — это функциональный язык программирования, один из двух наиболее популярных в наши дни диалектов языка Лисп (другой популярный диалект — это Common Lisp). Aвторы языка Scheme — Гай Стил (Guy L. Steele) и Джеральд Сассмен (Gerald Jay Sussman) из Массачусетского технологического института — создали его в середине 1970-х годов.
Введение[править | править код]
При разработке Scheme упор был сделан на элегантность и простоту языка. Философия языка подчёркнуто минималистская. Его цель — не сваливать в кучу разные полезные конструкции и средства, а напротив — удалить слабости и ограничения, вызывающие необходимость добавления в язык новых возможностей. В результате, Scheme содержит минимум примитивных конструкций и позволяет выразить все, что угодно путём надстройки над ними. В качестве примера можно указать, что язык использует 2 механизма организации циклов:
- «остаточная» или «хвостовая» рекурсия (англ. tail recursion)
- итеративный подход (в котором используются временные переменные для сохранения промежуточного результата.
Scheme был первым диалектом Лиспа, применяющим исключительно статические (а не динамические) области видимости переменных, гарантирующим оптимизацию хвостовой рекурсии и поддерживающим данные булевского типа (#t и #f вместо традиционно неуклюжих T и NIL). Он также был одним из первых языков, непосредственно поддерживающих продолжения (англ. continuations). Начиная со спецификации R^5RS, язык приобрел исключительно мощное и удобное средство для записи макросов на основе шаблонов синтаксического преобразования с «соблюдением гигиены» (англ. hygienic_macro). В Scheme также реализована «сборка мусора» (англ. garbage collection), то есть автоматическое освобождение памяти от не используемых более объектов.
В качестве базовых структур данных язык использует списки и одномерные массивы («векторы»). В соответствии с декларируемым минимализмом, (пока) нет стандартного синтаксиса для поддержки структур с именованными полями, а также средств ООП — все это может быть реализовано программистом по его предпочтению, хотя большинство реализаций языка предлагают готовые механизмы.
Как курьёз, можно отметить, что первоначальное название языка Schemer было изменено на настоящее из-за тогдашнего ограничения на длину имён файлов (6 символов).
Примеры[править | править код]
Простые математические операции[править | править код]
(+ 2 (* 2 2))
(+ 1 2 3 4)
Вызов каждой операции (или функции) представляется списком, в котором символ операции (который, в сущности, является именем функции) всегда занимает начальную позицию.
Запросы типа[править | править код]
(number? 5)
(number? «foo»)
(string? «foo»)
По соглашению, имена всех функций-запросов (в том числе и типа) заканчиваются символом ?
.
Проверки на равенство[править | править код]
(eq? «foo» «bar»)
(eq? 5 (+ 2 3))
(eq? (eq? 2 3) (eq? 3 4))
Определение макросов для традиционных операций push/pop[править | править код]
(define-syntax push!
(syntax-rules ()
((push! x l)
(set! l (cons x l)))))
(define-syntax pop!
(syntax-rules ()
((pop! l)
(let ((x (car l)))
(set! l (cdr l))
x))))
Определение функций[править | править код]
;; факториал в (неэффективном) рекурсивном стиле
(define (fact x)
(if (< x 3)
x
(* (fact (- x 1)) x)))
;; функция Фибоначчи — требует двойной рекурсии
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))
;; сумма элементов списка в характерном для Scheme стиле
;; (вспомогательная функция loop выражает цикл с помощью
;; хвостовой рекурсии и переменной-аккумулятора)
(define (sum-list x)
(let loop ((x x) (n 0))
(if (null? x)
n
(loop (cdr x) (+ (car x) n)))))
(fact 14)
(fib 10)
(sum '(6 6 6 100))
(sum (map fib '(1 2 3 4)))
Определение функции должно соответствовать следующему прототипу:
(define имя_функции (lambda (список_аргументов) (реализация_функции))),
хотя на практике чаще используют сокращённую форму:
(define (имя_функции аргументы) (реализация_функции)).
Ввод / Вывод[править | править код]
(write (+ (read) (read)))
Ссылки[править | править код]
Русскоязычные ссылки[править | править код]
- Все про Scheme — страница, посвящённая языку Scheme.
- ru_scheme — сообщество в LiveJournal, посвящённое языку Scheme
Англоязычные ссылки[править | править код]
- A large collection of Scheme resources. Большая коллекция ресурсов по Scheme.
- MIT/GNU Scheme Свободная (GPL-licensed) реализация для x86 архитектуры. Работает на GNU/Linux, FreeBSD, IBM OS/2, и Microsoft Windows.
- Chez Scheme Бесплатная реализация интерпретатора Scheme и коммерческий Scheme компилятор для Microsoft Windows и нескольких UNIX systems.
- Chicken Интерпретатор Scheme, поддерживающий трансляцию в C.
- Gauche Интерпретатор Scheme
- Guile «Официальный» язык расширений проекта GNU. Этот интерпретатор Scheme реализован как библиотека, позволяющая приложениям создавать внутренний интерпретатор Scheme.
- The PLT Scheme suite Пакет программ для Scheme, для Windows, Mac, и Unix платформ. Включает интерпретатор (MzScheme), графические утилиты (MrEd), учебно-ориентированный графический редактор (DrScheme), и ряд других компонентов, в том числе COM и ODBC библиотеки.
- Kawa Программа для Scheme, написанная на Java, которая компилирует тексты Scheme программ в Java bytecode. Любая Java библиотека может быть легко использована в Kawa.
- Community Scheme Wiki Вики ресурсы по языку Scheme.
Учебники на английском[править | править код]
- Structure and Interpretation of Computer Programs
- Видео-лекции «Structure and Interpretation of Computer Programs», Hal Abelson и Gerald Jay Sussma
- The Scheme Programming Language, R. Kent Dybvig