Sistem

Sistem
Semantică funcţional
Clasa de limba limbaj de programare , limbaj de programare multi-paradigma , limbaj de programare funcțional ,de programare procedural și limbaj de metaprogramare [d]
Tipul de execuție interpret sau compilator
Aparut in 1975
Autor Guy Steele și Gerald Sussman
Extensie de fișier .scm, .ss
Eliberare
Tip sistem puternic, dinamic
Implementări majore Schema PLT , Schema MIT , Scheme48 , Guile , JScheme
Dialectele T
A fost influențat Lisp , ALGOL
influențat Common Lisp , JavaScript , R , Ruby , Dylan , Lua , Hop, Rachetă
Site-ul web scheme-reports.org
 Fișiere media la Wikimedia Commons

Scheme [ skiːm ] este un limbaj de programare funcțional , unul dintre cele mai populare trei dialecte Lisp (împreună cu Common Lisp și Clojure ). Creat la mijlocul anilor 1970 de cercetătorii MIT Guy L. Steele și Gerald Jay Sussman .  

Are un design minimalist, conține un minim de structuri primitive și vă permite să exprimați tot ce aveți nevoie, construind deasupra acestora. De exemplu, folosește doar două mecanisme de buclă - recursiunea cozii și o abordare iterativă (care folosește variabile temporare pentru a stoca un rezultat intermediar).

Limbajul a început ca o încercare de a implementa modelul de actor al lui Carl Hewitt , pentru care Steele și Sussman au scris „un mic interpret Lisp” și apoi „au adăugat un mecanism pentru crearea actorilor și trimiterea de mesaje”. Scheme a fost primul dialect al Lisp care a folosit exclusiv variabile statice (mai degrabă decât dinamice) , care a garantat optimizarea recursiunii de coadă și a oferit suport de tip boolean ( #tși #fîn loc de tradiționalele Tși NIL). De asemenea, a devenit una dintre primele limbi care a sprijinit continuările . Începând cu specificația R⁵RS, limbajul a dobândit o facilitate pentru scrierea macro -urilor bazate pe modele de transformare sintactică cu „ macro igienic.  Este oferită „ Colectarea gunoiului ” (eliberarea automată a memoriei de la obiectele care nu mai sunt utilizate).

Limbajul folosește liste și matrice unidimensionale ("vectori") ca structuri de date de bază. În conformitate cu minimalismul declarat, nu există (încă) o sintaxă standard pentru structurile de suport cu câmpuri numite, precum și facilități OOP  - toate acestea pot fi implementate de programator după preferințele sale, deși majoritatea implementărilor de limbaj oferă mecanisme gata făcute.

Numele original al limbii, Schemer, a fost schimbat din cauza limitării lungimii numelor de fișiere în ITS ; ( Engleză  schemer  - „aventurier”, „combinator”; aparent, un indiciu la alte limbi asemănătoare lisp care au apărut din MIT - Planner (într-unul dintre sensuri - „proiector”) și Conniver („conniving) "). O contribuție semnificativă la popularizarea limbajului a avut-o cartea „ The Structure and Interpretation of Computer Programs ” de Abelson și Sussman , care a fost folosită multă vreme ca manual de programare de bază la Institutul de Tehnologie din Massachusetts.

Exemple

Operatii matematice simple:

( + 2 ( * 2 2 )) > 6 ( + 1 2 3 4 ) > 10

Apelul către fiecare operație (sau funcție) este reprezentat de o listă în care simbolul operației (care este în esență numele funcției) ocupă întotdeauna poziția inițială.

Tip predicate:

( număr? 5 ) ( număr? „foo” ) ( șir? „foo” )

Prin convenție, toate numele predicatelor se termină cu ?.

Verificări de egalitate:

( egal? "foo" "bar" ) ( eqv? 5 ( + 2 3 )) ( eq? 'a 'A )

Definirea macrocomenzilor pentru operațiunile tradiționale push și pop:

( define-sintaxă push! ( sintaxă-reguli () (( push! x l ) ( set! l ( cons x l ))))) ( define-sintaxă pop! ( sintaxă-reguli () (( pop! l ) ( let (( x ( car l ))) ( set! l ( cdr l )) x ))))

Definiții ale funcției:

;; factorial în stil recursiv (ineficient) ( definiți ( fapt x ) ( dacă ( < x 2 ) 1 ( * ( fapt ( - x 1 )) x ))) ;; Funcția Fibonacci - necesită recursivitate paralelă ( define ( fib n ) ( cond (( = n 0 ) 0 ) (( = n 1 ) 1 ) ( else ( + ( fib ( - n 1 ) )) ( fib ( - n 2 )) )))) ;; suma elementelor listei într-un stil tipic Scheme ;; (funcția de ajutor de buclă exprimă o buclă cu ;; recursivitate coadă și o variabilă de acumulator) ( define ( sum-list x ) ( let loop (( x x ) ( n 0 )) ( if ( null? x ) n ( bucla ( cdr x ) ( + ( car x ) n ))))) ( fapt 14 ) ( fib 10 ) ( sum-list ' ( 6 8 100 )) ( sum-list ( hartă fib ' ( 1 2 3 4 )))

Definiția funcției trebuie să fie conformă cu următorul prototip:

( definește numele funcției ( lambda ( argumente ) ( implementarea funcției )))

deși în practică este adesea folosită forma prescurtată:

( definește ( argumente nume-funcție ) ( implementare-funcție ))

I/O

Schema folosește tipul de port pentru intrare și ieșire ( port, R5RS sec 6.6) [1] . R5RS definește două porturi standard, disponibile ca current-input-portși current-output-port, corespunzătoare fluxurilor standard de I/O Unix . Majoritatea implementărilor oferă și current-error-port. Redirecționarea I/O este acceptată în standard prin procedurile with-input-from-fileși with-output-to-file. Implementările au, de asemenea, porturi string prin care multe operațiuni I/O pot fi efectuate pe un buffer string în loc de un fișier, folosind proceduri din SRFI 6 [2] . Standardul R6RS definește proceduri mai complexe pentru a trata porturile și multe tipuri noi de porturi.

Următoarele exemple sunt scrise în Schema R5RS.

( scrie ( + ( citește ) ( citește )))

Ieșire la portul implicit (current-output-port):

( let (( hello0 ( lambda () ( afișează „Hello world” ) ( newline )))) ( hello0 ))

Transmiterea unui port ca argument:

( let (( hello1 ( lambda ( p ) ) ( afișează „Hello world” p ) ( newline p )))) ( hello1 ( curent-output-port )))

Redirecționarea ieșirii către un fișier:

( let (( hello0 ( lambda () ( afișează „Hello world” ) ( newline )))) ( cu-ieșire-în-fișier „outputfile” hello0 ))

Deschiderea explicită a unui fișier și închiderea unui port:

( let (( hello1 ( lambda ( p ) ) ( afișează „Hello world” p ) ( newline p ))) ( portul de ieșire ( open-output-file „outputfile” ))) ( hello1 output-port ) ( close-output -port ieșire-port ) )

apel-cu-fișier-ieșire:

( let (( hello1 ( lambda ( p ) ) ( afișează „Hello world” p ) ( newline p )))) ( call-with-output-file „outputfile” hello1 ))

Există proceduri similare pentru introducere. Schema R5RS oferă predicate input-port?și output-port?. Pentru introducerea și ieșirea caracterelor , există write-char, și . Procedurile și sunt folosite pentru a citi și scrie expresii Scheme . Dacă portul a ajuns la sfârșitul fișierului la o operație de citire, este returnat un obiect eof care poate fi recunoscut de predicatul . read-charpeek-charchar-ready?readwriteeof-object?

SRFI

Datorită minimalismului limbajului, multe proceduri și forme sintactice comune nu sunt definite în standard. Pentru a menține nucleul limbajului mic și pentru a promova standardizarea extensiilor, comunitatea Scheme a adoptat un proces „Scheme Request for Implementation” prin care extinderile propuse sunt discutate cu atenție. Acest lucru contribuie la portabilitatea codului. Multe SRFI sunt acceptate de toate sau de majoritatea implementărilor Scheme.

Următoarele SRFI [3] sunt susținute pe scară largă de implementări :

  • 0: verificați extensiile cucond-expand
  • 1: bibliotecă pentru liste
  • 4: vectori numere omogene
  • 6: porturi pentru șiruri
  • 8: receive: se leagă la mai multe valori
  • 9: tipuri de înregistrări
  • 13: bibliotecă pentru șiruri
  • 14: biblioteca setului de caractere
  • 16: sintaxă pentru procedurile de aritate variabilă
  • 17: generalizatset!
  • 18: suport multithreading
  • 19: tipuri de date și proceduri de lucru cu timpul
  • 25: tablouri multidimensionale
  • 26: notație pentru fixarea argumentelor de procedură fără curry
  • 27: surse de biți aleatori
  • 28: formatare de bază a șirurilor
  • 29: localizare
  • 30: comentarii imbricate pe mai multe linii
  • 31: o formă specială de execuție recursivă
  • 37: args-fold: procesor de argumente program
  • 39: obiecte parametri
  • 41: fluxuri de date
  • 42: înțelegeri dornice
  • 43: bibliotecă vectorială
  • 45: primitive pentru exprimarea algoritmilor iterativi leneși
  • 60: operații pe biți
  • 61: mai generalcond
  • 66: vectori octet
  • 67: proceduri de comparare

Implementări majore

GNU Guile , limbajul de extensie al Proiectului GNU , este un interpret Scheme implementat ca o bibliotecă care permite aplicațiilor să creeze un interpret Scheme intern.

Limbajul Racket a fost inițial o implementare a Scheme (numită inițial PLT Scheme).

Schema MIT  este o implementare gratuită ( GPL ) pentru platforma x86 sub Linux , FreeBSD , IBM OS/2 și Win32 . Chicken Scheme este  un interpret care acceptă traducerea C. JScheme  este un interpret scris în Java ; Kawa este un compilator Scheme to JVM  bytecode . Compilatorul Chez Scheme a fost furnizat ca produs comercial de mult timp, din 2016 a devenit distribuit gratuit ( Apache ).

În total, există un număr mare de implementări de limbaj pentru diferite platforme, în special, există un interpret Armpit Scheme pentru microcontrolere bazate pe arhitectura ARM [4] .

Note

  1. Richard Kelsey; William Clinger; Jonathan Rees; Rozas, GJ; Adams IV, N.I.; Friedman, D.P.; Kohlbecker, E.; Steele Jr., G.L.; Bartley, DH Revised 5 Report on the Algorithmic Language Scheme  //  Higher-Order and Symbolic Computation : journal. - 1998. - august ( vol. 11 , nr. 1 ). - P. 7-105 . - doi : 10.1023/A:1010051815785 .
  2. William D Clinger. SRFI 6: Porturi șiruri de bază . The SRFI Editors, schemers.org (1 iulie 1999). Preluat la 9 august 2012. Arhivat din original la 21 octombrie 2021.
  3. Scheme Systems Support SRFIs . The SRFI Editors, schemers.org (30 august 2009). Preluat la 9 august 2012. Arhivat din original la 20 iunie 2021.
  4. Un interpret de schemă pentru microcontrolere ARM . Data accesului: 30 decembrie 2014. Arhivat din original la 30 decembrie 2014.

Literatură

Link -uri