Pourquoi ne pouvons-nous pas écrire des fonctions abrégées imbriquées dans Clojure?


11

J'ai essayé d'évaluer une expression Clojure avec des fonctions sténographiques imbriquées aujourd'hui, et cela ne m'a pas permis.

L'expression était:

(#(+ % (#(+ % (* % %)) %)) 5) ; sorry for the eye bleed

Le résultat était:

IllegalStateException Nested #()s are not allowed  clojure.lang.LispReader$FnReader.invoke (LispReader.java:630)
...and a bunch of other garbage

2
je trouve que ne pas pouvoir écrire un tel code est une bonne chose pour clojure.
Simon Bergot

3
Parce que ça fait saigner les yeux.
Michael Shaw

N'avez-vous pas besoin de (# (+% 1 (# (+% 2 (*% 3% 4))% 5)) 5)?
innova

Réponses:


5

Vous sauriez que% appartient à la fonction interne. L'inconvénient est que vous perdriez l'accès au% dans la fonction externe.

Utilisez fn [x]plutôt la syntaxe.


1
Donc? La plupart du temps, je n'ai pas besoin d'accéder à la %fn externe, et les fois où vous l'avez fait, vous pourriez vous replier sur (fn), non?
Zaz

10

C'est complètement arbitraire; il y a quelques lignes dans l'analyseur qui le désactivent explicitement. Si vous modifiez cette ligne, vous pouvez avoir des fonctions anonymes imbriquées et elles agissent exactement comme vous vous y attendez.

en particulier, les lignes 634-635 dans https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java

public static class FnReader extends AFn{
    public Object invoke(Object reader, Object lparen) {
        PushbackReader r = (PushbackReader) reader;
        if(ARG_ENV.deref() != null) // <-- line 634
            throw new IllegalStateException("Nested #()s are not allowed");
        // ...

Pourriez-vous identifier la ligne dans l'analyseur et démontrer que le code réécrit pour ne pas avoir de fonction imbriquée anon et que le code avec la ligne supprimée de l'analyseur et une fonction imbriquée anon fonctionne de la même manière?

2
@MichaelT: voilà. et vous pouvez simplement le tester; c'est facile à faire car vous pouvez les désactiver lors de l'exécution. l'analyseur clojure est vraiment assez facilement piratable
amara

4
Eh bien, pas complètement arbitraire; à moins que Rick Hickey n'ait juste eu une journée arbitraire, il doit y avoir une raison pour laquelle il l'a mis là-dedans, et vous ne semblez pas savoir quelle est cette raison. Duh.
Robert Harvey

Wow, quelle trouvaille! Nice - +1.

Ce changement entraînerait-il des analyses ambiguës des méthodes imbriquées? Je suis curieux d'une fn [x]réécriture du code de l'OP aurait des fonctionnalités identiques à une version clojure modifiée. De plus, y aurait-il un problème avec la portabilité du code de clôture?

3

Vous pouvez avoir des fonctions anonymes imbriquées de type (fn [params] (body)). Seule la syntaxe # ne prend pas en charge l'imbrication.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.