Scheme: Różnice pomiędzy wersjami

Dodane 3626 bajtów ,  9 lat temu
dodanie przykładu fukcji z rekurencją ogonową, makra, zapis do plików i implementacje języka scheme
m (robot dodaje: et:Scheme)
(dodanie przykładu fukcji z rekurencją ogonową, makra, zapis do plików i implementacje języka scheme)
</pre>
 
Zamiast [[Pętla (informatyka)|pętli]] wykorzystuje się możliwości stwarzane przez [[rekursja|rekursję]], szczególnie przez [[rekursja ogonowa|rekursję ogonową]] w której wywołanie rekurencyjne występuje jako ostatnie wyrażenie, fukcje z rekurencją ogonową zamieniane jest na pętle przez kompilator.
 
Przykład funkcji z rekurencją ogonową do oblicznia silni.
<pre>
(define (! n)
(let iter ((n n) (product 1))
(if (zero? n)
product
(iter (- n 1) (* product n)))))
</pre>
 
Tak zdefiniowana rekursja może być wykonywana bez odkładania parametrów na stos, czyli tak jak zwykła [[iteracja]].
 
=== Makra ===
Za pomocą makr można przetwarzać kod scheme jak dane. Makra są przetwarzane w czasie kompilacji. Makro musi zwaracać kod jako dane (tzn. listę symboli) które zostaną obliczone (według specyfikacji języka scheme makra tworzy się za pomocą define-syntax, let-syntax, syntax-rule ale większość implementacji udostępnia makro define-macro lub defmacro za pomocą definiuje się makra w stylu [[Common Lisp|Common Lispa]]).
 
Znak ` (tylny apostrof) działa tak jak ' (cytat) z tym że wewnąrz można użyć przecinka, który oblicza dane wyrażenie lub ,@ (przecinek małpa) który oblicza wyrażenie i usuwa zewnętrzne nawiasy.
 
"`" jest to skrót do funkcji quasiquote, "," - to skrót do unquote a ",@" to skrót do unquote-splicing
<pre>
(define-macro (for params . body)
(let ((iter (gensym)) (step (if (= (length params) 4)
(cadddr params)
1)))
`(let ,iter ((,(car params) ,(cadr params)))
(if (<= ,(car params) ,(caddr params))
(begin
,@body
(,iter (+ ,(car params) ,step)))))))
 
; przykład użycia
(for (i 1 10) (display i) (newline))
 
(define-macro (when test . body)
`(if ,test (begin ,@body)))
 
(define-macro (for-list params . body)
(let ((iter (gensym)) (list (gensym)))
`(let ,iter ((,(car params) (car ,(cadr params)))
(,list (cdr ,(cadr params))))
(when (not (null? ,(car params)))
,@body)
(when (not (null? ,list))
(,iter (car ,list) (cdr ,list))))))
 
; przykład użycia
(for-list (i (list 10 20 30)) (display i) (newline))
</pre>
 
=== Kontynuacje ===
 
Standard języka opisuje również funkcje otwierające pliki i otwierające i zamykające porty.
Funkcja czytająca linie z pliku i zwracająca listę (działająca w interpreterze Guile).
 
<pre>
(define (read-lines filename)
(call-with-input-file filename
(lambda (file)
(let ((line ""))
(let loop ((result '()))
(set! line (read-line file))
(if (eof-object? line)
result
(loop (append result (list line)))))))))
</pre>
Fukcja zapisująca liste stringów do pliku
<pre>
(define (write-lines list port)
(let loop ((list list))
(unless (null? list)
(write-line (car list) port)
(loop (cdr list)))))
;unless to jest macro
(define-macro (unless test . body)
`(if (not ,test) (begin ,@body)))
;lub
(define (write-lines list port)
(for-each (lambda (line) (write-line line port)) list))
</pre>
== Definicja języka ==
Język Scheme ciągle się rozwija, dwa główne elementy tego rozwoju to dokument opisujący rdzeń języka (R<sup>n</sup>RS) oraz proces zgłaszania dokumentów SRFI (Scheme Requests for Implementation) czyli propozycji rozszerzeń i ulepszeń języka opracowywanych przez użytkowników.
=== Dokumenty SRFI ===
Dokumenty zgłoszone i przyjęte w procesie SRFI <ref>[http://srfi.schemers.org/ Scheme Requests for Implementation<!-- Tytuł wygenerowany przez bota -->]</ref>są sposobem na w miarę szybkie wprowadzanie przenośnych między implementacjami języka rozwiązań ułatwiających tworzenie programów. Obecnie istnieje około 60 dokumentów SRFI, opisują one sposób zaimplementowania takich funkcji czy rozwiązań jak np. sposób notacji tablic, strumienie, obsługa wyjątków, higieniczne makra, wykonywanie skryptów języka Scheme w systemach operacyjnych UNIX czy obsługa wielowątkowości. Rozwiązania te nie wchodzą w skład oficjalnej definicji języka, jednak mogą być brane pod uwagę przy tworzeniu kolejnych wersji raportu R<sup>n</sup>RS.
 
=== Implementacje ===
* [http://www.gnu.org/software/guile/guile.html Guile] implementacja napisana w języku C umożliwiająca zagnieżdzanie w języku C oraz jako języka skryptowego. Implementacja stworzona przez [[Free Software Foundation|FSF]].
* [http://en.wikipedia.org/wiki/Kawa_(Scheme_implementation) Kawa] implementacja języka scheme w języku Java.
* [http://www.biwascheme.org/ BiwaScheme] implementacja w javascrypcie.
* [http://practical-scheme.net/gauche/ Gauche] implementacja działająca na platformie N*IX.
* [http://www-sop.inria.fr/mimosa/fp/Bigloo/ Bigloo] Kompilator na platformę [[.NET Framework|.Net]], [[Java Virtual Machine|JVM]] oraz do kodu natywnego.
* [http://en.wikipedia.org/wiki/MIT_Scheme MIT Scheme] implementacja stworzona przez [[Free Software Foundation|FSF]]
* [[Gambit (Scheme implementation)|Gambit]] kompilator i interpreter stworzony przez [[Free Software Foundation|FSF]]
 
 
{{Przypisy}}
Anonimowy użytkownik