Unlambda
Paradygmat | Prawie czysta funkcjonalność |
---|---|
Zaprojektowany przez | Davida Madore'a |
Deweloper | Davida Madore'a |
Po raz pierwszy pojawiły się | 28 czerwca 1999 |
Wersja stabilna | 2.0.0 / 20 grudnia 1999
|
Dyscyplina pisania | Niewpisane |
Język implementacji | Schemat , C , Java |
Licencja | GPL 2.0 lub nowszy |
Strona internetowa |
Unlambda to minimalny, „prawie czysty ” funkcjonalny język programowania wymyślony przez Davida Madore. Opiera się na logice kombinatorycznej , systemie wyrażeń bez operatora lambda i zmiennych wolnych. Opiera się głównie na dwóch wbudowanych funkcjach ( s
i k
) oraz operatorze zastosowania (zapisanym `
, znak cudzysłowu ). Tylko one sprawiają, że jest to Turing-complete , ale są też pewne dane wejściowe/wyjściowe (I/O) umożliwiające interakcję z użytkownikiem, niektóre funkcje skrótów i funkcję leniwej oceny . Zmienne nie są obsługiwane.
Unlambda to darmowe oprogramowanie o otwartym kodzie źródłowym, rozpowszechniane na licencji GNU General Public License (GPL) 2.0 lub nowszej. [ wymagane wyjaśnienie ]
Podstawowe zasady
Jako ezoteryczny język programowania , Unlambda jest pomyślany jako demonstracja bardzo czystego programowania funkcjonalnego, a nie do praktycznego użytku. Jego główną cechą jest brak konwencjonalnych operatorów i typów danych – jedynym rodzajem danych w programie są funkcje jednoparametrowe. Niemniej jednak dane mogą być symulowane za pomocą odpowiednich funkcji, jak w rachunku lambda . Funkcje wieloparametrowe można przedstawić metodą curry .
Unlambda opiera się na zasadzie eliminacji abstrakcji , czyli eliminacji wszystkich zapisanych zmiennych, w tym funkcji. Jako czysto funkcjonalny język, funkcje Unlambdy są obiektami pierwszej klasy i są jedynymi takimi obiektami.
Oto implementacja programu hello world w Unlambda:
`r```````````.Hello .worldi
Oryginalne wbudowane funkcje
notacja . x
oznacza funkcję, która pobiera jeden argument i zwraca go bez zmian, wyświetlając pojedynczy znak x jako efekt uboczny przy wywołaniu. i
reprezentuje wersję funkcji tożsamości, która nie ma takiego efektu ubocznego; jest tutaj użyty jako fałszywy argument. Program `.di
stosuje funkcję d
-printing do fałszywego argumentu i
, zwracając i
i wypisując literę d
jako efekt uboczny. Podobnie, ``.l.di
stosuje najpierw .l
do .d
, wypisując literę l
i zwracając .d
; ten wynik .d
jest następnie stosowany do i
, jak w poprzednim przykładzie. Funkcja r
jest cukrem składniowym dla funkcji, która drukuje znak nowej linii.
Inne ważne funkcje zapewniane przez Unlambda obejmują funkcje k
i s
. k
tworzy stałe funkcje: wynikiem `k x
jest funkcja, która po wywołaniu zwraca x . Zatem wartością ``k xy
jest x dla dowolnych x i y .
s
jest uogólnionym operatorem oceny. ```s xyz
daje w wyniku `` xz ` yz
dla dowolnych x , y i z . Niezwykłym faktem jest to, że s
i k
są wystarczające do wykonania dowolnego obliczenia, jak opisano w rachunku kombinatorów SKI . Jako krótki przykład, funkcję tożsamości i
można zaimplementować jako ``skk
, ponieważ ```skk x
daje x dla wszystkich x .
Jedynym konstruktem kontroli przepływu Unlambdy jest call z bieżącą kontynuacją , oznaczoną jako c
. Kiedy oceniane jest wyrażenie postaci `c x
, konstruowany jest specjalny obiekt kontynuacji , reprezentujący stan interpretera w tym momencie. Następnie x , a następnie jako argument podawany jest obiekt kontynuacji. Jeśli kontynuacja nigdy nie zostanie zastosowana do argumentu, wartość wyrażenia `c x
jest taka sama jak wartość x . Ale jeśli obiekt kontynuacji zostanie zastosowany do wartości y , wykonanie x jest natychmiast przerywane, a wartość całego wyrażenia `c x
wynosi y .
Semantyka wykonania Unlambdy to zwykle chętna ocena , ale istnieje opcja leniwej oceny , na co wskazuje użycie operatora d
. Zwykle, aby oszacować wyrażenie w postaci ` xy
, unlambda najpierw ocenia x , potem y , a następnie stosuje x do y . Jeśli jednak x ma wartość specjalną d
, wówczas y nie jest oceniane; zamiast tego wartość wyrażenia `d y
to specjalny obiekt „obliczeń opóźnionych”, który po zastosowaniu do argumentu z oblicza y , a następnie stosuje swoją wartość do z . Przy braku skutków ubocznych jest to dokładnie to samo, co `i y
. Różnica polega na tym, że `i y natychmiast
wykonuje skutki uboczne w y , podczas gdy `d y
odracza skutki uboczne, dopóki wynik nie zostanie zastosowany do innego argumentu.
Kolejnym wbudowanym operatorem Unlambdy jest v
, który ignoruje jego argument i zwraca v
. Ta cecha nie jest bezwzględnie konieczna, ponieważ v
może być zaimplementowana jako ``s`k``s``s`kskk`k``s``s`kskk
, ale jest dostarczana dla wygody. (To wyrażenie powyżej to po prostu `Yk
, gdzie Y
oznacza kombinator punktów stałych .)
Wbudowane funkcje wersji 2
Więcej wbudowanych elementów zostało wprowadzonych w wersji 2 Unlambda. Wejście jest ułatwione przez operatory @
i ? ty
. Kiedy @
jest stosowane do funkcji x , znak jest odczytywany z wejścia i zapisywany jako „bieżący znak”; wtedy x jest stosowane do i
. Jeśli jednak na wejściu nie było dostępnych więcej znaków, bieżący znak pozostaje niezdefiniowany, a x jest zamiast tego stosowane do v
. Kiedy funkcja ? u
jest stosowany do funkcji x , wynikiem jest ocena ` x i ,
jeśli bieżącym znakiem jest u , w przeciwnym razie obliczane jest ` x v .
Istnieje również operator „przedruku” |
. Kiedy `| x
jest oceniany, funkcja x jest stosowana do . u
, jeśli u jest bieżącym znakiem, lub do v
, jeśli nie ma bieżącego znaku.
Wreszcie istnieje operator wyjścia e
. Kiedy e
jest stosowane do x , wykonywanie programu zostaje przerwane, a x jest traktowany jako wynik programu (większość obecnie istniejących interpreterów i tak ignoruje wynik).
Zobacz też
- Felix-Hernandez Campos (1 kwietnia 2002), Wykład 28: Więcej o programowaniu funkcjonalnym , University of North Carolina COMP144
- 原悠 (Yutaka Hara) (2008). Rubyで作る奇妙なプログラミング言語 (po japońsku). Tōkyō: Mainichikomyunikēshonzu. s. 205–214. ISBN 978-4-8399-2784-4 .