Ordning

Ordning
Semantik funktionelle
Sprog klasse programmeringssprog , multi-paradigme programmeringssprog , funktionelt programmeringssprog , proceduremæssigt programmeringssprog og metaprogrammeringssprog [d]
Udførelsestype tolk eller compiler
Dukkede op i 1975
Forfatter Guy Steele og Gerald Sussman
Filtypenavn _ .scm, .ss
Frigøre
Type system stærk, dynamisk
Større implementeringer PLT Scheme , MIT Scheme , Scheme48 , Guile , JScheme
Dialekter T
Blev påvirket Lisp , ALGOL
påvirket Common Lisp , JavaScript , R , Ruby , Dylan , Lua , Hop, Ketsjer
Internet side scheme-reports.org
 Mediefiler på Wikimedia Commons

Scheme [ skiːm ] er et funktionelt programmeringssprog , en af ​​de tre mest populære Lisp- dialekter (sammen med Common Lisp og Clojure ). Skabt i midten af ​​1970'erne af MIT - forskerne Guy L. Steele og Gerald Jay Sussman .  

Den har et minimalistisk design, indeholder et minimum af primitive strukturer og giver dig mulighed for at udtrykke alt, hvad du har brug for, ved at bygge oven på dem. For eksempel bruger den kun to looping-mekanismer - halerekursion og en iterativ tilgang (som bruger midlertidige variabler til at gemme et mellemresultat).

Sproget begyndte som et forsøg på at implementere Carl Hewitts skuespillermodel , hvortil Steele og Sussman skrev "en lille Lisp-fortolker" og derefter "tilføjede en mekanisme til at skabe skuespillere og sende beskeder." Scheme var den første dialekt af Lisp, der udelukkende brugte statisk (snarere end dynamisk) variabel scoping , som garanterede hale-rekursionsoptimering og gav boolesk støtte ( #tog #fi stedet for den traditionelle Tog NIL). Blev også et af de første sprog til at understøtte fortsættelser . Fra R⁵RS-specifikationen fik sproget en facilitet til at skrive makroer baseret på syntaktiske transformationsmønstre med " hygiejnisk makro " .  " Affaldsopsamling " er tilvejebragt (automatisk frigivelse af hukommelse fra objekter, der ikke længere bruges).

Sproget bruger lister og endimensionelle arrays ("vektorer") som grundlæggende datastrukturer. I overensstemmelse med den erklærede minimalisme er der (endnu) ingen standardsyntaks til at understøtte strukturer med navngivne felter, samt OOP -faciliteter  - alt dette kan implementeres af programmøren efter hans præference, selvom de fleste sprogimplementeringer tilbyder færdige mekanismer.

Det oprindelige navn på sproget, Schemer, blev ændret på grund af begrænsningen på længden af ​​filnavne i ITS ; ( Engelsk  planlægger  - "eventyrer", "kombinator"; tilsyneladende et hint til andre lisp-lignende sprog, der kom ud af MIT - Planner (i en af ​​betydningerne - "projektor") og Conniver ("conniving ") "). Et væsentligt bidrag til populariseringen af ​​sproget blev ydet af bogen " The Structure and Interpretation of Computer Programs " af Abelson og Sussman , som i lang tid blev brugt som en grundlæggende programmeringslærebog ved Massachusetts Institute of Technology.

Eksempler

Simple matematiske operationer:

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

Kaldet til hver operation (eller funktion) er repræsenteret af en liste, hvor operationssymbolet (som i det væsentlige er navnet på funktionen) altid indtager startpositionen.

Typeprædikater:

( nummer? 5 ) ( tal? "foo" ) ( streng? "foo" )

Efter konvention ender alle prædikatnavne med ?.

Ligestillingskontrol:

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

Definition af makroer til traditionelle push- og pop-operationer:

( define-syntax push! ( syntaks-regler () (( push! x l ) ( sæt! l ( cons x l ))))) ( define-syntax pop! ( syntaks-regler () (( pop! l ) ( lad (( x ( car l ))) ( sæt! l ( cdr l )) x ))))

Funktionsdefinitioner:

;; faktoriel i (ineffektiv) rekursiv stil ( definer ( fakta x ) ( if ( < x 2 ) 1 ( * ( fakta ( - x 1 )) x ))) ;; Fibonacci funktion - kræver parallel rekursion ( definer ( fib n ) ( cond (( = n 0 ) 0 ) (( = n 1 ) 1 ) ( else ( + ( fib ( - n 1 )) ( fib ( - n 2 )) )))) ;; summen af ​​elementerne i listen i en typisk skemastil ;; (løkkehjælperfunktionen udtrykker en sløjfe med ;; halerekursion og en akkumulatorvariabel) ( definer ( sum-list x ) ( lad loop (( x x ) ( n 0 )) ( if ( null? x ) n ( loop ( cdr x ) ( + ( bil x ) n ))))) ( fakta 14 ) ( fib 10 ) ( sum-liste ' ( 6 8 100 )) ( sum-liste ( kort fib ' ( 1 2 3 4 )))

Funktionsdefinitionen skal være i overensstemmelse med følgende prototype:

( definer funktionsnavn ( lambda ( argumenter ) ( funktionsimplementering )))

selvom i praksis den forkortede form ofte bruges:

( define ( funktionsnavn argumenter ) ( funktionsimplementering ))

I/O

Skema bruger porttypen til input og output ( port, R5RS sec 6.6) [1] . R5RS definerer to standardporte, tilgængelige som current-input-portog current-output-port, svarende til standard Unix I/O-streams . De fleste implementeringer giver også current-error-port. I/O-omdirigering understøttes i standarden gennem procedurerne with-input-from-fileog with-output-to-file. Implementeringer har også strengporte, hvorigennem mange I/O-operationer kan udføres på en strengbuffer i stedet for en fil ved hjælp af procedurer fra SRFI 6 [2] . R6RS-standarden definerer mere komplekse procedurer til håndtering af porte og mange nye typer porte.

Følgende eksempler er skrevet i R5RS Scheme.

( skriv ( + ( læs ) ( læs )))

Output til standardporten (aktuel-output-port):

( lad (( hello0 ( lambda () ( vis "Hello world" ) ( newline )))) ( hello0 ))

At sende en port som argument:

( lad (( hello1 ( lambda ( p ) ( vis "Hello world" p ) ( newline p )))) ( hello1 ( current-output-port )))

Omdirigerer output til en fil:

( lad (( hello0 ( lambda () ( vis "Hello world" ) ( newline )))) ( med-output-til-fil "outputfile" hello0 ))

Eksplicit åbning af en fil og lukning af en port:

( let (( hello1 ( lambda ( p ) ( vis "Hello world" p ) ( newline p ))) ( output-port ( open-output-fil "outputfile" ))) ( hello1 output-port ) ( close-output -port output-port ) )

opkald-med-output-fil:

( lad (( hello1 ( lambda ( p ) ( vis "Hello world" p ) ( newline p )))) ( call-with-output-fil "outputfile" hello1 ))

Der er lignende procedurer for input. R5RS Scheme giver prædikater input-port?og output-port?. Til indtastning og output af tegn er der write-char, read-char, peek-charog char-ready?. Procedurerne og bruges til at læse og skrive readskemaudtryk write. Hvis porten har nået slutningen af ​​filen ved en læseoperation, returneres et eof-objekt, som kan genkendes af prædikatet eof-object?.

SRFI

På grund af sprogets minimalisme er mange almindelige procedurer og syntaktiske former ikke defineret i standarden. For at holde kernen af ​​sproget lille og for at fremme standardisering af udvidelser, har Scheme-fællesskabet vedtaget en "Scheme Request for Implementation"-proces, hvor foreslåede udvidelser omhyggeligt diskuteres. Dette bidrager til kodens portabilitet. Mange SRFI'er understøttes af alle eller de fleste Scheme-implementeringer.

Følgende SRFI'er [3] er bredt understøttet af implementeringer :

  • 0: tjek for udvidelser medcond-expand
  • 1: bibliotek for lister
  • 4: homogene talvektorer
  • 6: strengporte
  • 8: receive: bind til flere værdier
  • 9: posttyper
  • 13: bibliotek for strygere
  • 14: tegnsætbibliotek
  • 16: syntaks for variable arity- procedurer
  • 17: generaliseretset!
  • 18: multithreading support
  • 19: datatyper og procedurer for at arbejde med tid
  • 25: multidimensionelle arrays
  • 26: notation til fastsættelse af procedureargumenter uden at tude
  • 27: kilder til tilfældige bits
  • 28: grundlæggende strengformatering
  • 29: lokalisering
  • 30: indlejrede kommentarer med flere linjer
  • 31: en særlig form for rekursiv henrettelse
  • 37: args-fold: program argument processor
  • 39: parameterobjekter
  • 41: datastrømme
  • 42: ivrige forståelser
  • 43: vektorbibliotek
  • 45: primitiver til at udtrykke dovne iterative algoritmer
  • 60: bit operationer
  • 61: mere genereltcond
  • 66: oktetvektorer
  • 67: sammenligningsprocedurer

Større implementeringer

GNU Guile , udvidelsessproget for GNU-projektet , er en Scheme-fortolker implementeret som et bibliotek, der tillader applikationer at oprette en intern Scheme-fortolker.

Racket - sproget var oprindeligt en implementering af Scheme (oprindeligt kaldet PLT Scheme).

MIT Scheme  er en gratis ( GPL ) implementering til x86 -platformen under Linux , FreeBSD , IBM OS/2 og Win32 . Chicken Scheme  er en tolk, der understøtter C -oversættelse . JScheme  er en tolk skrevet i Java ; Kawa er en Scheme to JVM  bytecode compiler . Chez Scheme -kompileren er blevet leveret som et kommercielt produkt i lang tid, siden 2016 er det blevet frit distribueret ( Apache ).

I alt er der et stort antal sprogimplementeringer til forskellige platforme, især er der en Armpit Scheme-fortolker til mikrocontrollere baseret på ARM-arkitekturen [4] .

Noter

  1. Richard Kelsey; William Clinger; Jonathan Rees; Rozas, GJ; Adams IV, N.I.; Friedman, D.P.; Kohlbecker, E.; Steele Jr., G.L.; Bartley, DH Revideret 5 Rapport om det algoritmiske sprogskema  //  Higher-Order and Symbolic Computation: journal. - 1998. - August ( bind 11 , nr. 1 ). - S. 7-105 . - doi : 10.1023/A:1010051815785 .
  2. William D Clinger. SRFI 6: Grundlæggende strengporte . SRFI Editors, schemers.org (1. juli 1999). Hentet 9. august 2012. Arkiveret fra originalen 21. oktober 2021.
  3. Plansystemer, der understøtter SRFI'er . SRFI Editors, schemers.org (30. august 2009). Hentet 9. august 2012. Arkiveret fra originalen 20. juni 2021.
  4. En skematolk til ARM-mikrocontrollere . Dato for adgang: 30. december 2014. Arkiveret fra originalen 30. december 2014.

Litteratur

Links