6
votes

Contrôler l'évaluation dans le schéma (Guile)

Cela semble être une question simple; Peut-être qu'il est si simple qu'il est difficile de trouver une recherche qui trouvera la réponse. Dans le schéma (plus précisément, la mise en œuvre de la guil si cela fait toute différence) Comment puis-je évaluer quelque chose qui a été cité?

Voici ce que j'essaie de faire.

J'ai essentiellement besoin de vous assurer que La fonction que je définis obtient ses arguments évalués dans un ordre spécifique, car les effets secondaires causés par l'évaluation d'un argument sont dépendants lors de l'évaluation d'autres arguments. Toutefois, les arguments peuvent être évalués dans n'importe quel ordre. Je tiens donc à le forcer manuellement en citant les arguments et en les évaluant manuellement dans l'ordre nécessaire.

Il apparaît que "EVAL" est supposé faire ce que je veux, mais il a deux problèmes:

  1. Son utilisation est découragée, alors je me sens comme s'il devrait y avoir une meilleure façon d'accomplir ce que je veux faire ici.
  2. Dans le schéma, il apparaît que EVAL prend un deuxième paramètre qui est l'environnement. Cela me déroute. Je veux qu'il soit évalué dans le même environnement, la déclaration apparaît, alors pourquoi je devrais avoir besoin d'un deuxième paramètre? Est-ce seulement possible? J'ai joué avec eval un peu et il semble que certaines implémentations nécessitent différents paramètres (par exemple, le schéma de mit ne savent même pas quoi (interaction-environnement) est !!!)

    J'ai essayé d'autres astuces, comme dans la construction d'une Lambda: xxx

    mais il semble que cela devra alors être évalué pour générer une procédure . J'ai aussi essayé: xxx

    mais cela renvoie une "macro-macro intégrée primitive" qui ne fonctionne pas non plus.

    EDIT: On dirait qu'une macro travaillera pour contrôler l'ordre d'évaluation: (Test de Defmacro1 (A b) `(Begin, B, A))


0 commentaires

3 Réponses :


3
votes

Si vous devez évaluer une structure de liste (listes imbriquées avec des symboles cités représentant un texte de programme de schéma), vous devez utiliser eval code>. Schéma nécessite de transmettre un environnement comme un deuxième argument, même s'il s'agit de l'environnement actuel: xxx pré>

Si vous avez juste besoin de faire vos calculs dans un ordre particulier, vous pouvez appliquer l'ordre d'évaluation pour Effets secondaires en utilisant Commencez code>, laisse code> ou juste un corps de fonction. Ils définissent une séquence d'évaluations: p> xxx pré>

edit: strong> Si vous devez avoir un bloc de code paramétré où vous pouvez passer des expressions inévaluées, puis forcer Leur évaluation dans un ordre particulier, vous pouvez utiliser l'une de ces techniques: p>

  • une macro (comme vous l'avez déjà mentionné, juste pour complétude): p>

    > (define (test1 a b) (begin (b) (a)))
    > (test1 (lambda () (display 2)) (lambda () (display 3)))
    32
    
  • Un calcul retardé (syntaxe spéciale du schéma pour évaluation paresseuse): p>

    > (define (test1 a b) (begin (force b) (force a)))
    > (test1 (delay (display 2)) (delay (display 3)))
    32
    
  • Abstraction et application Lambda régulière p>

    > (defmacro test1 (a b) `(begin ,b ,a))
    > (test1 (display 2) (display 3)
    32
    


3 commentaires

Comment fonctionne la macro si j'ai besoin d'un nombre variable d'arguments? (Defmacro Test1 (a. B) `(Begin, B, A)) ne fonctionne pas car B est maintenant une liste. Je dois en quelque sorte l'épineuse au début, mais diverses tentatives telles que `(commencez (si (paire?, B) (test1, b)), a)) ne fonctionne pas.


En outre, je ne peux pas utiliser (Defmacro Test1 (a. B) `(Début (Début de début, B), a)) Parce que je ne peux pas appliquer une macro.


celui que vous avez manqué est (DEFMACRO test1 (a. B) `(Begin, (Begin 'Begin B), a))



8
votes

eval est totalement le mauvais outil pour simplement changer l'ordre d'évaluation des arguments. Créez une macro à la place: xxx

ou utilisez défmacro , si vous le devez.


0 commentaires

0
votes

Vous étiez sur la bonne voie avec le passage à Lambdas. Si vous avez

(f
  (lambda () a)
  (lambda () b)
  (lambda () c))


0 commentaires