Planche : 1




Le langage Scheme

Revision: 1.7





  Révisions générales





Christian Queinnec   UPMC--LIP6


Planche : 2


Les concepts programmatiques de base

Les variables (représentées par des symboles).

Les citations implicites (représentées par des nombres, chaînes, booléens ou caractères).

L'invocation de fonction (représentée par une liste). On dit aussi l'application fonctionnelle.

Les formes spéciales, représentées par des listes dont le premier terme est un symbole spécial. On y trouve: Les définitions (représentées par des listes débutant par le symbole define). Les définitions peuvent être locales ou globales.

Des formes spéciales dérivées: let, let*, letrec, cond, case, and, or, delay (sans oublier do et le let nommé) qui toutes peuvent se réécrire avec les formes spéciales essentielles.

Quelques abréviations pour quote (ainsi que quasiquote, unquote et unquote-splicing).


Planche : 3


Une grammaire




<forme> ::= <variable> | <constante> | <invocation
          |  <citation> | <alternative> | <séquence
          |  <abstraction> | <affectation> | <définition>
<constante> ::= <nombre> | <booléen> | <caractère> | <chaîne>
<invocation> ::= ( <forme> <forme>* )
<citation> ::= (quote <donnée>) | '<donnée>
<donnée> ::= <constante> | <symbole> | <procédure> | <flux>
           |  (<donnée> . <donnée>) |  #( <donnée>* ) | ()
<alternative> ::= (if <forme> <forme> <forme>) 
                |  (if <forme> <forme>)
<séquence> ::= (begin <forme> <forme>*)
<affectation> ::= (set! <variable> <forme>) 

<abstraction> ::= (lambda <varlist
                     <définition>*      ; définitions locales
                     <forme> <forme>* )
<varlist> ::= <variable> | ( <variable>* )
            |  ( <variable> <variable>* . <variable> )
<définition> ::= (define <variable> <forme>)
               |  (define (<variable> <variable>*)
                     <définition>*      ; définitions locales
                     <forme> <forme>* ) 


(let ((<variable> <forme>) ; idem pour let* et letrec
      ...
      (<variable> <forme>) )
  <définition>*
  <forme> <forme>* )
                        (cond (<forme> <forme>*
                              ... )
                        (cond (<forme> <forme>*
                              ...
                              (else <forme>*))
(case <forme
  ((<constante> <constante>*) <forme> <forme>*
  ... )
(case <forme
  ((<constante> <constante>*) <forme> <forme>*
  ... 
  (else <forme> <forme>*) )
                         (and <forme> <forme>* )   ; idem pour or
                         (delay <forme>)       


Planche : 4


Variable (référence et affectation)

Tout identificateur est possible sauf ceux nommant les formes spéciales essentielles ou dérivées (et quelques mots-clés supplémentaires comme else, =>, unquote, unquote-splicing).

Convention de nommage ?, !, -> pour, respectivement prédicat, effet de bord (et valeur non spécifiée) et convertisseur.

À l'évaluation, les variables doivent être définies avant d'être modifiées. La définition peut cependant apparaître après mention de son usage.

Il est erroné de lire une variable avant qu'elle ne soit initialisée (par une définition). Le problème ne se pose que pour les variables globales (il n'y a pas de forme introduisant des variables locales non initialisées).


(define (modifier x)
  (set! bar x) )
(define (lire)
  bar )
(lire)             ; erreur: bar n'est pas initialisée
(define bar 'wait) ; cette ligne est obligatoire

Pour toute variable, il existe une forme liante (essentiellement lambda ou define global).


Planche : 5


Séquence

Une séquence contient au moins une forme, les évalue séquentiellement et retourne la valeur de la dernière d'entre elles. Utile que lorsque des effets de bord sont utiles (set!, display, read, set-car! etc.)

Le corps des lambda, des let, des clauses de cond forment des séquences implicites. En plus, le corps des lambda et des diverses formes let autorisent des définitions locales.


Planche : 6


Alternative

Comme toutes les formes, une alternative retourne une valeur.

L'alternant (la partie else) peut être absent. Le système en insère un par défaut qui peut être n'importe quoi.

En DrScheme, c'est #<void> qui n'est pas imprimé lorsque rendu en valeur (il est imprimé lorsqu'il apparaît dans une valeur composite l'englobant).


Planche : 7


Citation

Les citations peuvent être implicites avec les données non confondables avec des programmes ou explicites pour les listes et les symboles. Il est erroné de modifier physiquement une valeur citée (explicitement ou implicitement).

L'abréviation 'expression correspond, à sa lecture, au traitement suivant: (list 'quote (read)).


Planche : 8


Abstraction et invocation

Les fonctions (ou procédures ou fermetures) sont créées par lambda. Elles capturent leur environnement de définition (et non pas seulement les valeurs des variables libres de leur corps).

Une fonction prend un nombre fixe d'arguments ou au moins un certain nombre. Une erreur est signalée si la fonction est invoquée avec plus ou moins d'arguments que spécifiés par l'arité de l'abstraction.

Il faut distinguer les variables (paramètres formels), les arguments (les valeurs qui sont transmises lors de l'invocation), les paramètres qui sont les programmes qui figurent dans le texte de l'appel et qui, évalués, conduiront aux arguments.

On dit également, à l'invocation, que les variables sont liées aux arguments ou que l'environnement lexical est étendu par de nouvelles liaisons.


Planche : 9


Valeur

Les valeurs sont des citoyennes de première classe. Elles ont tous les droits des citoyennes à savoir que l'on peut les passer en argument, les retourner en résultat, les stocker dans des variables ou dans des données composites modifiables.

Elles sont typées. Tous les types sont disjoints et sont:

booléen nombre caractère chaîne
symbol paire liste vide vecteur
procédure flux  

Il y a des « sous-types » distinguables comme les promesses, les flux d'entrée ou de sortie (et différentes sortes de nombres).

Toute valeur peut être inspectée, on peut en déduire son type. Les valeurs sont partagées lors des appels et des retours de fonctions.

Même modèle mémoire que Java.


Planche : 10


Booléens

Graphie #t et #f insensible à la casse. Reconnaissables par boolean?.

Les opérateurs sont classiques not, and et or. Attention, ces derniers sont des formes spéciales dérivées à court-circuit.

Les prédicats, les opérateurs de comparaison génériques produisent des booléens. Rappel: toute valeur a une valeur booléenne associée: ils sont tous vrais sauf #f.


Planche : 11


Paires

Prédicats pair? et list?.

Attention null? n'est pas (not (pair? []))!

Notion de liste propre ou impropre. Notion de listes plates ou profondes. Notion de liste homogène ou hétérogène.


(a b c)         ; propre plate homogène
(a #f 3.4)      ; propre plate hétérogène
(a #f 3 . 4)    ; impropre plate hétérogène
(if (a . ()) b) ; propre profonde hétérogène

Ne pas confondre cons, append et list.




(cons a list(a))             ; ® list(a)(list a...a) ; ® list(a)(append list(a)...list(a)) ; ® list(a)

Accesseurs: car, cdr, set-car!, set-cdr!.

Utilitaires variés: length, reverse, list-tail, list-ref, member, memq, memv.

Utilitaires pour Alistes: assoc, assq, assv.


Planche : 12


Symboles

Deux symboles ayant des noms equal? sont eq?. Attention au problème de la casse.

Un constructeur string->symbol et un accesseur symbol->string.


Planche : 13


Nombres

La tour des nombres: nombre ³ complexe ³ réel ³ rationnel ³ entier

Les fonctions génériques +, -, *, /, abs, les arrondisseurs floor, ceiling, truncate et round et les comparateurs: <, =, <=, > et >= (pas d'inégalité).

Les fonctions sur les entiers: quotient, remainder, modulo, gcd, lcm

Quelques fonctions spécialisées rationalize (s'il y a des rationnels), numerator, denominator.

Mais aussi en tenant compte des (éventuellement présents) complexes; make-rectangular, make-polar, real-part et imag-part, magnitude et angle. Sont liées sqrt et expt.

Les convertisseurs inexact->exact et exact->inexact. Seuls les exacts peuvent être utilisés comme index dans des vecteurs ou chaînes.

Autres convertisseurs number->string string->number.


Planche : 14


Caractères

Graphie #\C, et quelques caractères nommés comme #\space ou #\newline. Reconnaisseur char?. Reconnaisseur de sous-type char-alphabetic?, char-numeric?, char-whitespace?, char-upper-case?, char-lower-case?.

Comparateur char=? et les autres, char=-ci? et les autres.

Convertisseurs char->integer, integer->char, char-upcase, char-downcase.

DrScheme accepte les accents.


Planche : 15


Chaînes

Graphie: entre guillemets. Les guillemets internes sont préfixés d'une anti-oblique (tout comme donc les anti-obliques). Attention "\n" c'est la chaîne "n". Les chaînes sont reconnues par string?.

Constructeurs make-string, string.

Accesseurs string-length, string-ref Modifieur: string-set!. Comparateurs string<? et les autres ou string<-ci? et les autres.

Utilitaires variés substring, string-append, string-copy et string-fill! sans oublier string->list et list->string.


Planche : 16


Vecteurs

Graphie #( ) reconnus par vector?.

Constructeur make-vector ou vector.

Accesseurs vector-length, vector-ref Modifieur: vector-set!.

Utilitaires variés vector->list, list->vector, vector-fill!.


Planche : 17


Flux

Reconnus par input-port? ou output-port?. Créés par open-input-file ou open-output-file. Doivent être fermés par close-input-port ou close-output-port.

On peut également obtenir les flux courants par current-input-port et current-output-port. Ces flux par défaut sont spécifiés par les fonctions with-input-from-file ou with-output-to-file. Il vaut mieux utiliser explicitement call-with-input-file et call-with-output-file.

Les lectures se font par read, ou read-char (et peek-char). Ces fonctions retournent un objet qui satisfait eof-object? quand il n'y a plus rien à lire.

Les impressions s'effectuent par display, newline et write-char.

La fonction load sera vue plus tard.


Planche : 18


Conclusions

Tout est dans le R4RS!

Une grande partie de ces fonctions n'est pas essentielle, on peut les définir en Scheme même mais d'autres sont primitives.

N'ont pas encore été vues les macros, la notation backquote et les continuations.

Distinguer les programmes de leur représentation.


Ce document a été traduit de LATEX par HEVEA.