Sistem

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare
Sistem
limbaj de programare
Lambda lc.svg
Calculul simbolului Lambda
Autor Guy L. Steele ,
Gerald Jay Sussman
Data de origine 1970
Ultima versiune R7RS (2013)
Utilizare Lingvistic
Paradigme Funcțional , procedural , metaprogramare
Tastare Puternic, dinamic
Extensii comune .scm .ss
Influențată de Lisp , ALGOL și MDL
Implementare referință
Site-ul web www.scheme-reports.org/

Scheme este un limbaj de programare funcțional , un dialect al lui Lisp, care păstrează toate caracteristicile, care a fost dezvoltat în anii 1970 de Guy L. Steele și Gerald Jay Sussman , care l-au introdus în mediul academic cu o serie de articole cunoscute sub numele de le Lambda Papers și în cartea Structura și interpretarea programelor de calculator , folosită de zeci de ani ca text în unele examene de științe ale informației. Managerul de desktop GNOME încorporează interpretul Scheme Guile .

Exemple de programe

Salut Lume

Următorul exemplu afișează textul „Hello world”.

 (Afișați „Hello World!”)
( linie nouă )

Câteva exemple mai complexe

Următorul exemplu calculează cel mai mare divizor comun al argumentelor numerice x și y.

 ( definiți ( mcd x y )
  ( cond (( = x y ) x )
        (( > x y ) ( mcd ( - x y ) y ))
        ( else ( gcd x ( - y x ))))))

Următorul exemplu este folosit pentru a inversa ordinea caracterelor dintr-un șir; de exemplu, din „abcdef” obținem „fedcba”.

 (Defini (sl w) (substring w (sub1 (string de lungime w)) (string de lungime w)))
(Defini (dl w) (subșir w 0 (sub1 (string de lungime w))))
( definiți ( reversem s w )
   ( if ( = ( string-length s ) 0 ) w
      ( reversem ( dl s ) ( string-append w ( sl s )))))

În schimb, acest lucru face același lucru ca și exemplul de mai sus, dar folosind unele funcții Scheme.

 ( definiți ( inversa s ) ( reversem s "" )) ; recursivitatea cozii
( definiți ( invers2 w )
  ( list-> șir ( invers ( șir-> listă w )))) ; standard

Această funcție este utilizată pentru a ști dacă un număr este prim:

 ( definiți ( primul? m n s )
  ( dacă ( = ( sub1 n ) s ) "este prim"
  ( În cazul în care (= 0 (rest n (ADD1 s))) (string-Adăugare "nu este prim, este divizibil cu:" (> string (numeric ADD1 s)))
      ( primul? m n ( add1 s ))))))
( definește ( primul? n ) ( primul? m n 1 ))

Schița programării în schemă

Spre deosebire de majoritatea celorlalte limbaje de programare, Scheme folosește o notație de prefix, care este o notație în care în loc să scrieți (2 + 3) scrieți (+ 2 3). Această notație se propagă la toate funcțiile, astfel încât dacă avem o funcție N-ary f, reprezentarea acesteia va fi (f argument1 argument2 ... argumentN).

Tipuri de date

Schema implementează toate tipurile de date fundamentale: booleeni, numere, caractere, șiruri, vectori. Cu toate acestea, include și tipuri speciale, inclusiv liste (perechi), porturi (fluxuri de date), simboluri și proceduri.

Pentru a recunoaște aceste tipuri de date, Scheme oferă anumite funcții al căror identificator are formatul "typeDiD?" care returnează adevăratul boolean dacă argumentul trecut este în formatul tipului de date. Iată un tabel rezumat:

Funcţie Explicaţie
(boolean? argomento) este argumentul un boolean?
(number? argomento) argumentul este un număr?
(char? argomento) argumentul este un personaj?
(string? argomento) argumentul este un șir?
(vector? argomento) argumentul este un vector?
(list? argomento) subiectul este o listă?
(port? argomento) argumentul este o ușă?
(symbol? argomento) argumentul este un simbol?
(procedure? argomento) argumentul este o procedură?

Să vedem acum câteva detalii despre aceste tipuri de date.

Booleeni

Acestea sunt indicate prin caracterul hash și litera T (TRUE) pentru adevărat și F (FALSE) pentru fals. Deci #T este adevărat, în timp ce #F este fals.

Funcțiile pe booleeni sunt cele obișnuite:

Funcţie Rezultatul a fost returnat
(not arg) neagă arg. fals-> adevărat și adevărat-> fals
(and arg1 arg2 ...) fals, fals-> fals fals, adevărat-> fals adevărat, adevărat-> adevărat
(or arg1 arg2 ....) fals, fals-> fals fals, adevărat-> adevărat adevărat, adevărat-> adevărat

Numeric

Constantele numerice sunt scrise conform regulilor uzuale. Sunt disponibile diferite tipuri de date numerice: numere pozitive și negative, numere cu virgule și numere în notație exponențială. Pentru a recunoaște la ce clasă de numere aparține o expresie numerică, puteți utiliza una dintre următoarele funcții, din nou desemnate printr-un identificator de semn de întrebare, care returnează o valoare booleană:

Funcţie Rezultatul a fost returnat
(integer? argomento) argumentul este un număr întreg
(rational? argomento) argumentul este un număr rațional
(real? argomento) argumentul este real
(complex? argomento) argumentul este un număr complex

De asemenea, este posibil să specificați baza de numerotare folosind #fN, unde f este baza și N un număr:

Posibile baze Tipul de bază
#bN N este binar
#oN N este octal
#dN N este zecimal
#xN N este hexadecimal
  1. dN nu este practic folosit niciodată, deoarece baza este zecimală în mod implicit.

Apoi, există următoarele funcții booleene (semn de întrebare) și conversie:

Funcții funcționalitate
(exact? espressione) Expresia returnează un număr exact?
(inexact? espressione) Expresia returnează un număr aproximativ?
(exact->inexact espressione) Aproximează valoarea expresiei
(inexact->exact espressione) Convertește o valoare aproximativă într-o valoare exactă.

Pentru a clasifica în continuare numerele, de exemplu între pozitiv și negativ, sau par și impar, Scheme oferă următoarele primitive:

Funcții funcționalitate
(zero? numero) Numărul este zero?
(positive? numero) Numărul este pozitiv?
(negative? numero) Numărul este negativ?
(odd? numero) Este numărul impar?
(even? numero) Este numărul par?

Evident, atunci, ca în majoritatea limbilor, sunt disponibili atât operatori aritmetici, cât și multe funcții matematice.

Funcții Rezultatul a fost returnat tip
(+ arg1 arg2 ... argN) arg1 + arg2 + ... + argN numeric
(- arg1 arg2 ... argN) arg1-arg2 -...- argN numeric
(* arg1 arg2 ... argN) arg1 * arg2 * ... * argN numeric
(/ arg1 arg2 arg3... argN) (.. (arg1 / arg2) / arg3) ... / argN numeric
(log arg) jurnal natural al arg numeric
(exp arg) exponențială a arg numeric
(sin arg) sinusul arg numeric
(cos arg) cosinusul arg numeric
(tan arg) tangenta arg numeric
(asin arg) arcsine de arg numeric
(acos arg) arccosine de arg numeric
(atan arg) arctangent de arg numeric
(sqrt arg) rădăcină pătrată arg numeric
(expt base potenza) baza ^ putere numeric
(abs arg) valoarea absolută a arg numeric
(quotient arg1 arg2) rezultat întreg al diviziunii arg1 / arg2 numeric
(remainder arg1 arg2) (pozitiv) restul diviziunii numeric
(modulo arg1 arg2) restul diviziei numeric
(ceiling arg) acoperișul arg (aproximarea părții întregi în sus) numeric
(floor arg) etaj arg (aproximarea întregii părți în jos) numeric
(round arg) aproximare generică a arg numeric
(truncate arg) trunchierea arg numeric
(max arg1 ... argN) valoarea maximă între arg1 și argN numeric
(min arg1 ... argN) valoarea minimă între arg1 și argN numeric
(gcd arg1 ... argN) cel mai mare factor comun între arg1..e .. argN numeric
(lcm arg1 ... argN) cel mai mic multiplu comun între arg1 .. și .. argN numeric
(numerator arg) numărător al arg numeric
(denominator arg) numitor al arg numeric
(= arg1 arg2 ... argN) arg1 = arg2 = ... = argN? boolean
(< arg1 arg2 ... argN) arg1 <arg2 <... <argN? boolean
(> arg1 arg2 ... argN) arg1> arg2> ...> argN? boolean
(>= arg1 arg2 ... argN) arg1> = arg2> = ...> = argN? boolean
(<= arg1 arg2 ... argN) arg1 <= arg2 <= ... <= argN? boolean

Personaje

În Schemă, caracterele sunt indicate cu un hash, urmat de o bară inversă și de caracterul care trebuie exprimat (fără bară inversă, ar exista ambiguitate între caracterele T și F și booleenii ADEVĂRAT și FALS).

Printre funcțiile relevante găsim:

Funcții Rezultatul a fost returnat
(char=? char1 char2) Char1 este același cu char2?
(char<? char1 char2) Char1 este inferior lexicografic față de char2?
(char>? char1 char2) Char1 este lexicografic superior lui char2?
(char<=? char1 char2) char1 nu este lexicografic superior lui char2?
(char>=? char1 char2) char1 nu este lexicografic inferior lui char2?

Există, de asemenea, versiunea ci a acestor funcții, insensibilă la majuscule: avem deci char-ci =?, Char-ci <?, char-ci <=? Și așa mai departe.

Alte funcții care operează pe caractere sunt următoarele:

Funcții Rezultatul a fost returnat tip
(char? arg) arg este un personaj? boolean
(char-alphabetic? arg) arg este un caracter alfabetic? boolean
(char-numeric? arg) arg este un personaj care reprezintă un număr? boolean
(char-whitespace? arg) arg este un personaj în spațiu alb? boolean
(char-upper-case? arg) arg este un caracter alfabetic cu majuscule? boolean
(char-lower-case? arg) arg este un caracter alfabetic minuscul? boolean
(char->integer arg) personajul se transformă într-un număr numeric
(integer->char arg) numărul se transformă în personaj caracter
(char-upcase arg) caracterul alfabetic devine majuscul caracter
(char-downcase arg) caracterul alfabetic devine minuscul caracter

Siruri de caractere

Șirurile din schemă sunt reprezentate prin ghilimele duble (exemplu: „acesta este un șir”). Unele funcții pentru gestionarea șirurilor sunt următoarele:

Funcții Rezultatul a fost returnat tip
(make-string n) creează un șir lung n şir
(make-string n ch) creează un șir lung n, format doar din caracterul ch şir
(string char1 char2 ..charN) creează un șir format din caracterele char1, char2, ... charN şir
(string-length str) returnează mărimea str numeric
(string-ref str idx) returnează caracterul în poziția idx a șirului str caracter
(substring str beg end) returnează porțiunea șirului de caractere conținută între cei doi indici beg și end şir
(string-set! str idx ch) înlocuiește cu ch, caracterul la poziția idx în șirul str şir
(string-append str1 str2...strN) concatenează str1, str2, ..., strN şir
(string-copy str) returnează o copie a șirului str şir
(string->list str) returnează o listă formată din caracterele șirului str listă
(list->string lst) returnează un șir format din caracterele din prima listă şir

În ceea ce privește caracterele, avem operatori de comparare a șirurilor, care sunt analogi cu cei pentru caractere. Principalele sunt enumerate mai jos și există, de asemenea, în versiunea string-ci (insensibilă la majuscule):

Funcții Rezultatul a fost returnat
(string=? str1 str2) Str1 este la fel ca str2?
(string<? str1 str2) Str1 este lexicografic inferior str2?
(string>? str1 str2) Str1 este lexicografic superior str2?
(string<=? str1 str2) str1 nu este lexicografic superior str2?
(string>=? str1 str2) str1 nu este lexicografic inferior str2?

Liste

După cum sa specificat mai sus, listele reprezintă un anumit tip de date. La fel ca tablourile, ele reprezintă colecții ordonate de elemente; spre deosebire de tablouri, elementele pot fi eterogene (de diferite tipuri) și, de asemenea, nu pot fi indexate. Listele sunt realizate ca perechi: (2 3) reprezintă un exemplu de listă care este evident o pereche; dar și (2 3 4) este de fapt un cuplu, format din primul element (2) și de toate celelalte (3 4). La rândul său, elementul „toți ceilalți” este o pereche formată din primul său element (3) și de toți ceilalți (în acest caz doar 4). Lista este apoi descrisă foarte natural în termeni recursivi.

O listă poate conține orice tip de date, cum ar fi caractere, șiruri, booleeni și chiar alte liste (exemplu: "(2 3 (4 5))"); așa cum am menționat, pot conține și tipuri de date mixte (exemplu: "(# \ T 4 (4 #F (" șir ")))").

Cele două funcții fundamentale pentru acționarea pe liste se referă la definiția recursivă menționată mai sus: avem astfel funcția car , care returnează primul element și cdr , care returnează al doilea element (elementul „toți ceilalți”).

Principalele funcții pe care le oferă Scheme pentru liste sunt următoarele:

Funcții Rezultatul a fost returnat tip
(list arg1 arg2 ... argN) construiește o listă formată din arg1, arg2, ..., argN argumente listă
(pair? lst) prima listă este ne-goală? boolean
(car lst) returnează primul element din prima listă amestecat
(cdr lst) returnează lista formată din elementele de la al doilea la ultimul element al listei lst listă
(cadr lst) returnează primul element al listei care ar fi obținut prin invocarea (cdr lst) amestecat
(cons arg lst) returnează o listă cu arg în primul rând listă
(append lst1 lst2) concatenează cele două liste lst1 și lst2 listă
(length lst) returnează numărul de elemente din listă numeric
(reverse lst) inversează elementele listei listă

Observăm că în această listă există funcții agregate care corespund compoziției car și cdr: expresia (cdr (cdr lst)) poate fi scrisă mai succint ca cddr (lst), în timp ce (car (cdr lst)) este can sintetizează cu cadr (lst).

Schema prezintă apoi alte funcții compuse, dintre care unele simulează funcții pe vectori, iar altele conversia listei în vector și invers:

Funcții Rezultatul a fost returnat tip
(null? lst) prima listă este goală? boolean
(set-car! lst arg) setați prima poziție la valoarea arg listă
(set-cdr! lst arg) setați a doua poziție la valoarea arg listă
(list-ref lst k) returnează elementul în poziția k din prima listă amestecat
(list->vector lst) returnează un vector format din elementele listei lst vector
(vector->list vctr) returnează o listă formată din elementele vel vector vctr vector

Funcțiile speciale care acționează pe liste sunt aplicarea, harta și pentru fiecare funcție:

Funcții Rezultatul a fost returnat
(apply f lst) execută funcția f folosind ca elemente cele prezente în listă
(map f lst1...lstN) execută funcția f pe elemente la același index ca lista
(for-each f lst1...lstN) execută funcția f pe elementele listei

Pentru a explica mai bine, să luăm un exemplu:

 > (definiți lst1 (lista 2 3 4 5 6))
> (aplicați + lst1)
>> 20
> (definiți lst2 (lista 1 2 3 4 5))
> (hartă + lst1 lst2)
>> (3 5 7 9 11)

Vectori

Vectorii sunt tablouri standard, adică sunt o structură care conține un singur tip de date. Ele sunt reprezentate ca liste cu un prefix hash, adică # (el1 el2 ... elN), unde el1 are index 0 și elN are index N-1.

Funcțiile pe care le oferă Scheme pentru gestionarea vectorilor sunt următoarele:

Funcții Rezultatul a fost returnat tip
(vector arg1 arg2 ... argN) construiește un vector format din elementele arg1, arg2, ..., argN vector
(make-vector n) construiește un vector format din n elemente goale vector
(make-vector n arg) construiește un vector format din n elemente de tip arg vector
(vector-length vctr) returnează numărul de elemente ale vectorului vctr numeric
(vector-ref vctr idx) returnează elementul în poziția idx a vectorului vctr vector
(vector-set! vctr idx arg) setează elementul vector vctr, la indexul idx la valoarea arg vector

Ușile

Porturile sunt obiecte care reprezintă fluxuri de date. Numeroase funcții sunt disponibile pe porturi, printre care găsim citirea / scrierea de la intrarea / ieșirea standard (citirea / scrierea caracterelor de la / către terminal, similar cu funcțiile printf și scanf în limbajul C) și gestionarea fișierelor. Porturile pot fi deschise în intrare (citirea datelor) și în ieșire (scrierea datelor).

Unele dintre funcțiile oferite de schemă sunt următoarele:

Funcții Rezultatul a fost returnat tip
(input-port? arg) arg este un port de intrare? boolean
(output-port? arg) arg este un port de ieșire? boolean
(open-input-file str) deschide un fișier al cărui nume este șirul str ca port de intrare aduce
(open-output-file str) deschide un fișier al cărui nume este șirul str ca port de ieșire aduce
(close-input-file str) închide un fișier al cărui nume este șirul de caractere, deschis în intrare nimic
(close-output-file str) închide un fișier al cărui nume este șirul de caractere, deschis în ieșire nimic
Citirea datelor

Citirile de date, numite „operații de intrare”, au loc prin următoarele funcții:

Funcții Rezultatul a fost returnat tip
(read-char port) returnează următorul caracter din portul portului caracter
(peek-char port) returnează următorul caracter din portul portului (dar nu mișcă indicatorul) caracter
(read port) citiți din portul ușii amestecat
(eof-object port) suntem la sfârșitul dosarului? boolean

Notă: dacă portul portului nu este specificat pe read-char și read, citirea are loc de la intrarea standard (citirea de pe consolă).

Scrierea datelor

Scrierile de date, numite „operații de ieșire”, au loc prin următoarele funcții:

Funcții Rezultatul a fost returnat
(write-char char port) scrie caracterul char în portul port
(write obj port) scrie obiect obiect în portul portului
(display obj port) afișați obiectul obj prin portul portului
(newline port) scrie o linie goală pe portul portului

Notă: dacă portul portului nu este specificat pe write-char și write, scrierea are loc pe ieșirea standard (scriere pe consolă).

Definiția procedurilor

Definiția unei date

În Scheme, definiția datelor de orice tip se face prin funcția de definire:

 Definiția unei valori numerice:
(definiți numărul meu 3)
Definiția unui șir:
(definiți șirul_meu „Hello World”)
Definiția unei liste:
(definiți lista_meu (lista # T 6 2 # / G))

Prin urmare, define este folosit și pentru proceduri. Cea mai simplă modalitate de a crea o procedură care acceptă mai multe argumente are următoarea structură:

 (definește (procedura mea_arg1 arg2 ... argN)
  ...)

Funcția lambda este disponibilă în Scheme pentru a crea proceduri nenumite. Ne oferă o modalitate alternativă de a defini o procedură, prin crearea unei proceduri anonime și atribuirea acesteia, ca și cum ar fi o valoare convențională, unei variabile.

Definiția unei proceduri, utilizând funcția lambda:

 (definiți_procedura mea
  (lambda (arg1 arg2 ... argN)
    ...))

Lambda permite, de asemenea, definirea procedurilor în cadrul altor proceduri.

Construcții fundamentale

Stare simplă (dacă)

După ce am văzut tipurile de date și funcțiile pentru a le opera și după ce am înțeles cum să definim o procedură, să trecem la constructele fundamentale.

Construcția if arată astfel:

 (dacă condiția_expresie_în_caz_ condiția_este_adevărată
               event_expression_in_case_the_condition_is_ false)
; spune dacă argumentul dat este egal sau diferit de 5
( definește ( test_if arg1 )
  ( dacă ( = arg1 5 ) "argumentul dat este 5"
                 „argumentul furnizat este diferit de 5” ))

Cu alte cuvinte, s-ar putea spune că Scheme's conține și celelalte limbaje de programare.

Stare compusă (cond)

Este echivalent cu un lanț de multipli dacă și arată astfel:

 (cond
  (expresie first_condition)
  (a doua expresie condiție)
  ...
  (altfel expresie))

Există câteva lucruri de remarcat:

  1. celălalt nu este obligatoriu: dacă condițiile specificate sunt exhaustive, adică acoperă 100% din cazurile posibile, acesta poate fi omis. Dimpotrivă, în absența altcuiva, în cazul în care nu s-a produs niciun caz, va fi generată o eroare de rulare .
  2. Este o funcție derivată, implementabilă prin construcția if și begin.
Condiție bazată pe valoarea returnată de o expresie (caz)

Este o expresie supusă unei condiții, al cărei rezultat depinde de valoarea asumată de expresia însăși. Valorile posibile sunt specificate în structură ca val1, val2, val3:

 (expresie de caz_care_este_evaluată
  ((val1) expresie)
  ((val2) expresie)
  ...
  (altfel expresie))

Ca și în cazul construcției cond, celălalt este opțional.

Blocuri de expresie (începe)

Pentru a exprima un bloc de expresii în Schemă, folosim funcția begin:

 (începe first_expression
       a doua_expresie
       ...
       n-a_expresie)

Acest lucru vă permite să specificați mai multe expresii (cele cuprinse de begin) într-un punct în care o singură expresie este necesară din punct de vedere sintactic. Un exemplu tipic este în ifs.

Un construct non-fundamental (a face)

Fiind un limbaj funcțional, în Scheme ar fi frumos să puteți folosi întotdeauna dacă și recursivitate . În măsura în care este posibil în teorie, această soluție nu ajută întotdeauna la lizibilitate și nici nu dă naștere neapărat la soluția algoritmică cea mai eficientă sau naturală. Schema oferă apoi constructul do, care vă permite să executați bucle. În acest sens, constructul do joacă un rol similar cu pentru și în timp ce altor limbaje de programare.

Do vine în multe forme. Primul, care arată ca construcția while a java, este următorul:

 (face ()
  (condition_of_exit, dacă există_expresie_pentru_executare_înainte_exitarea)
  first_expression_of_ loop
  a doua_expresie_de_ ciclu
  ...
  n-a_expresia_ciclului)

Uită-te la condiția de ieșire: dacă este adevărată, următoarele expresii sunt evaluate secvențial (prima_expresie_de_ ciclu, a doua_expresie_de_ ciclu ... n-a_expresie_de_ ciclu). Execuția este apoi iterată, cu o nouă verificare a condiției de ieșire. Când acest lucru eșuează, expresia (opțională) care urmează este executată, iar apoi bucla se termină.

A doua formă seamănă mult cu genericul pentru constructe:

 (faceți ((variabilă_initială_valoră_de_expresie_actualizare_variabilă))
  (condition_of_exit, dacă există_expresie_pentru_executare_înainte_exitarea)
  first_expression_of_ loop
  a doua_expresie_de_ ciclu
  ...
  n-a_expresia_ciclului)

Variabila este inițializată la o anumită valoare; la fiecare iterație ulterioară, variabila este actualizată prin executarea update_expression, care poate include o creștere sau scădere a variabilei, dar și o operație mai generală. Pentru orice alt aspect, execuția are loc ca în cazul anterior, unde totuși condiția exit_ este îndeplinită în mod obișnuit în funcție de valorile asumate de variabila de ciclu.

 ; exemplu care afișează numere naturale mai mici decât numărul variabil
( definește ( test_do number )
( faceți (( index 0 ( + index 1 )))
    (( > = număr index ))
    ( afișare index )
    ( linie nouă )
)))

Program în schemă

După cum sa menționat deja, Schema este adecvată în special pentru exprimarea algoritmilor într-o formă recursivă .

Recursivitatea simplă se realizează apelând procedura în sine o singură dată. De exemplu, să presupunem că operatorul * nu este disponibil și că dorim să definim multiplicarea între numere întregi prin adunări succesive. Deoarece k * n este echivalent cu k + k + ... + k, cu k repetat de n ori, atunci putem scrie următorul cod:

 ( defini ( molt a b )
  ( dacă ( = a 0 ) 0
   ( + b ( molt ( - a 1 ) b ))))

În acest exemplu, funcția molt este numită în propriul cod.

Cum funcționează recursivitatea? Să presupunem că avem (molt 3 4): rezultatul așteptat este 3 * 4 = 12. Să aruncăm o privire mai atentă asupra fluxului de execuție:

 > (molt 3 4)
[prima iterație: recursivitate]
  (+ 4 (molt (- 3 1) 4))
[a doua iterație: recursivitate]
  (+ 4 (+ 4 (molt (- 2 1) 4)))
[a treia iterație: recursivitate]
  (+ 4 (+ 4 (+ 4 (molt (- 1 1) 4))))
[a patra iterație: suntem în condiția în care a este egal cu 0, înlocuim (molt 0 4) cu 0]
  (+ 4 (+ 4 (+ 4 0)))
[prima rezoluție]
  (+ 4 (+ 4 4))
[a doua rezoluție]
  (+ 4 8)
[returnarea rezultatului]
  12

Un al doilea tip de recursivitate implică o recursivitate care la fiecare iterație poate efectua apeluri diferite, în funcție de condițiile care apar. Să vedem un exemplu folosind secvența Fibonacci .

 ( definiți ( fibonacci n )
  ( cond (( = n 1 ) 1 )
        (( = n 2 ) 2 )
        ( else ( + ( Fibonacci ( - n 1 )) ( Fibonacci ( - n 2 ))))))

Deși este posibil să se descrie fluxul de execuție ca mai sus, acesta crește foarte repede (vezi Teoria complexității computaționale ) și, prin urmare, nu va fi raportat.

Diverse exemple de programare în Scheme

Un exemplu de program care interacționează cu utilizatorul:

 (Define (maxpot b n k) ( în cazul în care (nu (> = n (Expt b k))) (sub1 k) (maxpot b n (ADD1 k))))
( definiți b 0 )
( definiți n 0 )
( citați „Acum puterea maximă va fi calculată pentru b ^ k <= n” )
( citați „Inserați acum b:” )
( set! b ( citire ))
( citați „Inserați acum n:” )
( set! n ( citit ))
( dacă ( și ( > b 1 ) ( > n 0 )) 
(String-append "Puterea maximă care satisface b ^ k <= ne:" (numeric și > string (maxpot b n 0)))
( citat "A apărut o eroare: trebuie să fi setat b <= 1 și / sau n <= 0" ))

Implementarea problemei mesei rotunde (sau a lui Caesar):

 ( definiți ( aski s ) ; poziția în ASCII
  ( char-> întreg ( șir-ref s 0 )))

(Defini (spate e) din ASCII în șir
  ( list- > string ( list ( integer-> char s ))))

( definiți ( dl s ) ; ștergeți ultimul "char"
  (Substring s 0 (- (string lungime s) 1)))
( definiți ( sl s ) ; selectați ultimul „char”
  ( substring s ( - ( string-length s ) 1 ) ( string-length s )))

( definește ( lwc? s ) ( și ( > ( aski s ) 96 ) ( < ( aski s ) 123 ))) ; minuscule?
( definiți ( upc? s ) ( și ( > ( aski s ) 64 ) ( < ( aski s ) 91 ))) ; majuscule?

( define ( modGC vechi n nou ) ; modul gcesare
( define ( h s ) ( modGC ( dl old ) n ( string-append ( back s ) new )))) ;
; (aski (sl old)) este unitatea de caractere în număr, ar fi bine să o redenumiți!, cu un let ch de exemplu, dar unde? precum și (sl vechi) ...
; a doua și a treia condiție ar trebui combinate într-una la care trebuie schimbate două caractere..min (65 sau 97) și maxim (90 sau 122)
          ( cond (( string =? "" old ) new ) ; condiție de ieșire
                (( și ( lwc? ( sl vechi )) ( > ( + n ( aski ( sl vechi ))) 122 )) ( h ( + 97 ( - ( sub1 n ) ( - 122 ( aski ( sl vechi )))) ))) ; managementul reportării
                (( și ( upc? ( sl vechi )) ( > ( + n ( aski ( sl vechi ))) 90 )) ( h ( + 65 ( - ( sub1 n ) ( - 90 ( aski ( sl vechi )))) )))
                (( nu ( sau ( lwc? ( sl vechi )) ( upc? ( sl vechi )))) ( h ( aski ( sl vechi ))))) ; excepții: numere, spațiu alb etc.
                ( else ( h ( + n ( aski ( sl old )))))))) ; suntem în normalitate, alfabetul nici nu trebuie să înceapă de la început
( definiți ( gcesare vechi n w ) ( dacă ( și ( < n 26 ) ( > n 0 ))
    ( cond (( șir =? w "cod" ) ( modGC vechi n "" )) (( șir =? w "dec" ) ( modGC vechi ( - 26 n ) "" )) ( altfel "opțiune nevalidă, încercați din nou cu dec sau cod " ))
 "n trebuie să fie un număr, între 0 și 26, extreme excluse!" )))

Un exemplu mai complex, jocul Tic Tac Toe (implementare simplă ASCII):

 ( definiți n 0 ) ; intrare
( define ( slst? l ) ( if ( nul? l ) #t ( if ( number? ( car l )) #f ( slst? ( cdr l ))))) ; listă simbolică?
( definiți ( vizualizați l ) ( începeți ( afișați "Situația curentă este următoarea: \ n" ) ; Vizualizator ^ _ ^
                         ( afișaj ( contra ( mașină l ) ( contra ( cadr l ) ( listă ( caddr l ))))) ( linie nouă )
                         ( afișare ( contra ( cadddr l ) ( contra ( cadddr ( cdr l )) ( listă ( cadddr ( cddr l )))))) ( newline )
                         ( afișaj ( cdddr ( cdddr l ))) ( linie nouă )))
( definiți ( gratuit? l e ) ( dacă ( nul? l ) #f ( dacă ( nu ( egal? ( mașina l ) e )) ( gratuit? ( cdr l ) e ) #t )))
( definiți ( tr l și s ) ; găsiți și înlocuiți
    ( if ( egal? ( car l ) e ) ( contra s ( cdr l ))
        ( contra ( car l ) ( tr ( cdr l ) e s ))))
( define ( win l wpos ) ( cond (( null? wpos ) #f ) ; poziția câștigătoare? -> mergi să câștigi? ..
                           (( eqc? ( auto wpos ) l ) #t )
                           ( altfel ( câștiga l ( cdr wpos ))))))
( define ( win? l ) ( win l ' (( 1 2 3 ) ( 4 5 6 ) ( 7 8 9 ) ( 1 4 7 ) ( 2 5 8 ) ( 3 6 9 ) ( 1 5 9 ) ( 7 5 3 )))) ; poziții câștigătoare
( definește ( eqc? l1 l2 ) ( if ( nul? l1 ) #t ( if ( cc l2 ( car l1 )) ( eqc? ( cdr l1 ) l2 ) #f ))) ; elementele listei <l1> apar în listă <l2>?
( definește ( cc l e ) ( if ( nul? l ) #f ( if ( egal? ( car l ) e ) #t ( cc ( cdr l ) e )))) ; <e> este conținut în listă < eu>?
( definiți ( wplay genlst plslst mnslst turn )
( let (( wis ' ( afișează „Jucătorul câștigat:” ))) 
( vezi genlst )
  ( cond (( win? plslst ) ( eval wis ) ( display "+" ))
        (( win? mnslst ) ( eval wis ) ( afișează "-" ))
        (( slst? genlst ) ( afișați  Remiză , nimeni nu a câștigat!” ))
        ( altfel ( începeți ( afișați „Introduceți un număr, de la 1 la 9, este rândul vostru” ) ( afișați rândul ) ( linie nouă )
                (Set! N (citit)) (afișați „Ați introdus:”) (Fără afișaj) (linie nouă)
                ( dacă ( număr? n )
                    ( dacă ( < n 10 ) 
                       ( dacă ( gratuit? genlst n )
                         [ if ( equal? turn '+ ) ( wplay ( tr genlst n ' + ) ( append plslst ( list n )) mnslst '- )
                                              ( wplay ( tr genlst n '- ) plslst ( append mnslst ( list n )) ' + )]
                        ( începeți ( afișați „Locul introdus este ocupat \ n" ) ( wplay genlst plslst mnslst turn )))
                      ( începe ( afișează „Locul introdus nu există \ n” ) ( wplay genlst plslst mnslst turn )))
                 ( începeți ( afișați „Locul este indicat printr-un număr de la 1 la 9 \ n" ) ( wplay genlst plslst mnslst turn ))))))))
( definiți jocul ( începeți ( afișați „Jocul începe, începe +. \ n” )) ( wplay ( lista 1 2 3 4 5 6 7 8 9 ) ( lista '+ ) ( lista ' - ) '+ )))

Alte proiecte

linkuri externe

Implementări

Alte resurse

Controlul autorității LCCN (EN) sh87003834 · GND (DE) 4378962-6
Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT