next up previous contents index
Next: Le futur d'un programme Up: Eléments avancés Previous: Introduction   Contents   Index

Subsections

Eléments du langage

Dans cette section, nous allons examiner des éléments du langage Scheme indispensables pour la suite.


Quasiquotation

Nous avons vu jusqu'à maintenant le mécanisme de quotation qui empêche l'évaluation d'une expression. Ce mécanisme est très utile pour construire des listes de constantes ou manipuler les symboles :

Osm> '(1 2 3)
  => (1 2 3)

Osm> '(1 2 (3 4))
  => (1 2 (3 4))

De même, la quotation permet d'utiliser les symboles en tant que tels, sans les évaluer au préalable. Ainsi :

Osm> 'toto
  => toto

Osm> (symbol? 'toto)
  => #t

Osm> (symbol? toto)
  => ERROR: symbol `toto' is unbounded

Dans la dernière écriture, le système Scheme tente d'évaluer le symbole toto afin d'appliquer au résultat la fonction symbol?. Comme toto n'est pas défini, cette évaluation provoque une erreur.

La quotation est introduite avec une apostrophe ; elle peut aussi s'écrire à l'aide de la forme spéciale quote. Les deux expressions suivantes sont équivalentes :

'expression
(quote expression)

Scheme définit aussi la quasiquotation qui s'écrit comme la quotation, mais avec le caractère `. C'est une forme de quotation dans laquelle les expressions précédées d'une virgule sont évaluées. Ainsi :

Osm> `(1 2 3)
  => (1 2 3)

Osm> `(1 2 ,(+ 1 2 4))
  => (1 2 7)

Les deux expressions suivantes sont identiques :

,expression
(unquote expression)

Si la quotation avait été utilisée dans la dernière expression, au lieu de la quasiquotation, nous aurions eu :

Osm> '(1 2 ,(+ 1 2 4))
  => (1 2 (unquote (+ 1 2 4)))

Lorsque la virgule est immédiatement suivie du caractère @, l'expression qui suit doit être une liste ; les éléments de cette liste sont alors concaténés à la liste principale :

Osm> `(1 2 ,@ (list 3 4 5))
  => (1 2 3 4 5)

Les deux expressions suivantes sont identiques :

,@ expression
(unquote-slicing expression)

Sans le @, nous aurions :

Osm> `(1 2 ,(list 3 4 5))
  => (1 2 (3 4 5))

La quasiquotation est introduite avec une apostrophe inverse ; elle peut aussi s'écrire à l'aide de la forme spéciale quasiquote. Les deux expressions suivantes sont équivalentes :

`expression
(quasiquote expression)

La quotation et la quasiquotation sont très utilisées pour construire des structure de listes de manière simple. En particulier, elles sont très employées dans l'écriture des interprètes ou compilateurs de langages.


Apply

La fonction apply permet d'appliquer une fonction à une liste d'arguments. Elle s'utilise comme dans les exemples ci-dessous :

Osm> (apply + '(1 2 3))
  => 6

Osm> (define une-liste '(1 2 3))
  => #unspecified

Osm> (apply car une-liste)
  => 1

Osm> (apply (lambda (a b c d) (+ a b c d 10))
            (list 1 2 3 4))
  => 20

Cette fonction est utile lorsque les arguments d'une fonction sont disponibles sous la forme d'une liste. Ecrivons par exemple, une fonction qui calcule le produit scalaire deux listes de nombres a=(a1, ..., an) et b=(b1, ..., bn). Le produit scalaire est la somme a1b1+...+anbn. La fonction Scheme calculant un tel produit s'écrirait :

(define (produit-scalaire a b)
  (apply + (map * a b)))


Evaluation paresseuse

Le langage Scheme est un langage en mode applicatif, ce qui signifie que les arguments des fonctions sont préalablement évalués avant que la fonction ne soit effectivement appelée (comme on l'a vu dans un chapitre précédent, certaines formes spéciales échappent cependant à ce mode d'évaluation, comme if et define).

Il existe une autre famille de langages dits paresseux. Dans ces langages, les arguments de toutes les fonctions ne sont évaluées que lorsque cela est strictement nécessaire ; on appelle ce mode d'évaluation le mode normal.

Ce mode d'évaluation a montré qu'il était dans certain cas beaucoup plus performant que le mode applicatif, et surtout qu'il aboutit toujours à un résultat, lorsqu'il existe.

Les lecteurs souhaitant pousser un peu plus leur connaissances pourrons consulter les livres sur le lambda-calcul et les langages fonctionnels donnés en annexe.

En Scheme, il est possible de construire explicitement une structure qui conserve une expression sans l'évaluer afin de permettre une évaluation ultérieure. Cette structure est appelée promesse et se construit à l'aide de la fonction delay comme suit :

Osm> (delay (+ 1 2))
  => #promise

Bien sûr, une promesse conserve l'environnement dans lequel elle a été construite.

Pour forcer l'évaluation d'une promesse, on utilise la fonction force :

Osm> (define promesse (delay (+ 1 2)))
  => #unspecified

Osm> (force promesse)
  => 3

Les promesses peuvent être utilisées pour construire des flots de données.


next up previous contents index
Next: Le futur d'un programme Up: Eléments avancés Previous: Introduction   Contents   Index
© 1993 to 2001 Erian Concept