przestrzegać następujących sesji repl:^char wskazówka nie jest dozwolone dla parametru clojure defn
user=> (set! *warn-on-reflection* true)
true
user=> (defn blah [s] (for [c s] (if (Character/isDigit c) true false)))
Reflection warning, NO_SOURCE_PATH:1:31 - call to isDigit can't be resolved.
Reflection warning, NO_SOURCE_PATH:1:31 - call to isDigit can't be resolved.
#'user/blah
user=> (blah "abc123abc")
(false false false true true true false false false)
user=> (defn blah [s] (for [^char c s] (if (Character/isDigit c) true false)))
#'user/blah
user=> (blah "abc123abc")
(false false false true true true false false false)
więc użyliśmy typu podpowiedź ^char
pozbyć refleksji - świetnie. Teraz spróbuj to samo w parametrze funkcji:
user=> (defn blah-c [c] (if (Character/isDigit c) true false))
Reflection warning, NO_SOURCE_PATH:1:22 - call to isDigit can't be resolved.
#'user/blah-c
user=> (defn blah-c [^char c] (if (Character/isDigit c) true false))
CompilerException java.lang.IllegalArgumentException: Only long and double primitives are supported, compiling:(NO_SOURCE_PATH:1:1)
user=> (defn blah-c [^Character c] (if (Character/isDigit c) true false))
#'user/blah-c
user=> (blah-c \1)
true
user=> (blah-c \a)
false
Rozumiem, że Clojure only supports long or double type hints for numeric primitives i że Java char
jest numeryczny typ danych - nie trzeba wyjaśnić. Ale powyższe wydaje się niespójne - podpowiedź typu ^char
jest dozwolona w pierwszej funkcji wewnątrz for
, ale nie w sygnaturze funkcji blah-c
, gdzie musiałem określić Character
. Jaki jest tego powód (tj. Z perspektywy implementacji kompilatora)?
Kombinatoryczna eksplozja - do dynamicznej kompilacji musi istnieć interfejs dla każdej dozwolonej kombinacji elementów pierwotnych i obiektów. –
To brzmi jak wspaniała odpowiedź, jeśli chcesz ją rozwinąć, podać referencje/przykłady. – noahlz
@ nahlz cf. [clojure.lang.IFn] (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java) – kotarak