Recherche…


S-Expression

Une expression dans Scheme est ce qui va être exécuté. Une expression S, comme on l'appelle habituellement, commence par un ( et se termine par un ) . Le premier membre de l'expression est ce qui va être exécuté. Les membres suivants de l'expression sont les paramètres qui seront envoyés à l'expression lors de l'évaluation de l'expression.

Par exemple, ajouter des nombres:

(+ 1 2 3)

Dans ce cas, + est un symbole pour une fonction d' ajout qui prend plusieurs paramètres. 1 , 2 et 3 sont envoyés à la fonction + .

S-Expression peut contenir des expressions S comme paramètres, comme illustré dans l'exemple suivant:

(if (< x y)
  x
  y)

Ce qui peut être lu comme si x est inférieur à y retourne x sinon retourne y . Dans cet exemple, nous évaluons l'expression de la condition, en fonction de la valeur résolue, x ou y seront renvoyés. Il pourrait être évalué à cette

(if #t x y)
x
(if #f x y)
y

Un exemple moins évident pour les débutants est d'avoir une expression S dans le premier membre d'une expression S. De cette façon, nous pouvons changer le comportement d’une méthode en modifiant la fonction qui sera appelée sans avoir à créer de branches avec les mêmes paramètres. Voici un exemple rapide d'une expression qui ajoute ou soustrait des nombres si x est inférieur à y.

((if (< x y) + -) 
  1 2 3)

Si x est inférieur à y , l'expression sera évaluée comme suit:

(+ 1 2 3)
6

autrement

(- 1 2 3)
-4

Comme vous pouvez le voir, Scheme permet au programmeur de construire un morceau de code complexe tout en donnant au programmeur les outils nécessaires pour éviter la duplication de code. Dans d'autres langues, nous pourrions voir le même exemple écrit en tant que tel:

(si (<xy) (+ 1 2 3) (- 1 2 3))

Le problème avec cette méthode est que nous dupliquons beaucoup de code alors que la seule chose qui change est la méthode appelée. Cet exemple est assez simple mais avec plus de conditions, nous pourrions voir beaucoup de lignes similaires dupliquées.

Macro simple laisser

Les expressions let dans le schéma sont en fait des macros. Ils peuvent être exprimés avec des lambda. Un simple let pourrait ressembler à ceci:

(let ((x 1) (y 2))
  (+ x y))

Il retournera 3 car la valeur de la dernière expression du corps let est renvoyée. Comme vous pouvez le voir, une expression-let est en train d'exécuter quelque chose. Si nous traduisons cette partie de code avec lambdas, nous aurons quelque chose comme ceci:

((lambda (x y) (+ x y)) 1 2)

Ici, nous pouvons voir que nous appelons le lambda anonyme avec 1 et 2 directement. Donc, le résultat dans ce cas est également 3.

Dans cette optique, nous comprenons qu’une expression let est composée de deux parties. Il a des paramètres et un corps comme un lambda, mais la différence est que let expression est appelée juste après son évaluation.

Pour expliquer comment une expression laisser fonctionner d'un résumé à une vue concrète, cela ressemblerait à ceci.

(let params body ...)
(let (param1 param2 ...) body ...)
(let ((p1 val1) (p2 val2) ...) body ...)

Les paramètres sont une liste de paires de (name value) à utiliser dans le corps du let .

Pourquoi utiliser let expression?

Les expressions sont particulièrement utiles pour stocker des variables dans une méthode, tout comme les initialisations de variables dans les langages similaires à c. Il est favorable à l'utilisation de define parce que, à partir de l'expression let, les variables ont disparu ... L'utilisation d'une définition ajoute en fait une variable à l'environnement d'exécution actuel. Les variables ajoutées à l'environnement global ne peuvent pas être supprimées. Soit expression peut être utilisé n'importe où. Il peut également être utilisé pour créer des variables fantômes sans toucher aux portées parents.

Par exemple:

(let ((x 1))
  (let ((x 2) (y x))
    (display x)
    (display y))
  (display x))

Il va imprimer:

2
1
1

Dans ce cas, x est défini avec 1, puis fantôme par le x dans le second let avec la valeur 2 . La variable y est initiée avec la valeur x de la portée parent. Une fois let expression interne let est exécutée, elle affiche la valeur initiale de x avec 1. L'expression let interne n'a pas modifié la valeur de l'étendue parent.

Chaque fois que vous avez besoin d'initialiser des variables, vous devez utiliser les expressions let comme ceci:

(let (
  (user (get-current-user session))
  (db (get-current-db session))
  (ids (get-active-ids session))
  )
  (mark-task-completed db user ids)
  (change-last-logged db user)
  (db-commit db))

Ici, dans cet exemple, les variables sont initialisées et utilisées plusieurs fois dans le bloc de code. Et lorsque l'expression let est terminée, les variables sont automatiquement libérées car elles ne sont plus nécessaires.

Syntaxe pointillée pour les paires

Il y a une syntaxe particulière qui nous permettent d'écrire cons la cellule d'une manière plus compacte que d' utiliser le cons constructeur.

Une paire peut être écrite comme telle:

'(1 . 2) == (cons 1 2)

La grande différence est que nous pouvons créer des pairs aide de devis. Sinon, Scheme créerait une liste appropriée (1 . (2 . '())) .

La syntaxe à points oblige l'expression à n'avoir que 2 membres. Chaque membre peut être de tout type, y compris des paires.

'(1 . (2 . (3 . 4)))
> (1 2 3 . 4)

Notez que la liste incorrecte doit être affichée avec un point à la fin pour indiquer que le cdr de la dernière paire de la liste n'est pas la liste vide '() .

Cette façon de montrer des listes est parfois déroutante car l'expression suivante serait exprimée comme on ne s'y attendrait pas.

'((1 . 2) . ( 3 . 4))
> ((1 . 2) 3 . 4)

Depuis la liste habituellement sauter le . , le premier argument de la liste serait (1 . 2) , le deuxième argument serait 3 mais puisque la liste est incorrecte, la dernière . est montré pour montrer que le dernier élément de la liste n'est pas '() . Même si les données sont présentées différemment, les données internes sont telles qu’elles ont été créées.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow