support type hints; make metadata coherent
The reader expanded ^X form to (with-meta form X), which evaluated the tag (so
^String errored 'Unable to resolve symbol: String') and, as a param, was no
longer a bare symbol (so the arg bound to nil). Now a keyword/symbol/string hint
on a symbol attaches to the symbol's :meta and the symbol stays bare, so type
hints are transparent in params, lets, and bodies. Map metadata still uses a
runtime with-meta form.
meta now returns a symbol's :meta, and def applies the name's metadata
(^:dynamic, ^:private, ^Type tag, ^{:doc}) to the var, so (meta (var x)) is
consistent. Specs in metadata-spec; grammar note in the ebnf.
README notes regex \p{...} as unsupported (separate from this).
This commit is contained in:
parent
f749ec3c19
commit
761a2b8f72
8 changed files with 94 additions and 39 deletions
|
|
@ -9,3 +9,21 @@
|
|||
["vary-meta" "{:a 2}" "(meta (vary-meta (with-meta [1] {:a 1}) update :a inc))"]
|
||||
["meta reader ^" "{:tag :int}" "(meta ^{:tag :int} [1 2])"]
|
||||
["with-meta on fn ok" "true" "(fn? (with-meta inc {:a 1}))"])
|
||||
|
||||
(defspec "metadata / type hints"
|
||||
# ^Type / ^:kw / ^"str" on a symbol attach as metadata and are otherwise inert:
|
||||
# the symbol stays a symbol so hints are transparent in every position.
|
||||
["type hint on param" "\"hi\"" "(do (defn f [^String s] s) (f \"hi\"))"]
|
||||
["type hint, extra params" "[1 2]" "(do (defn g [^String x y] [x y]) (g 1 2))"]
|
||||
["type hint in let" "6" "(let [^long x 5] (inc x))"]
|
||||
["type hint in body" "2" "(let [s \"ab\"] (count ^String s))"]
|
||||
["type hint in destructure" "3" "(let [{:keys [^long a]} {:a 3}] a)"]
|
||||
["symbol hint -> :tag" "\"String\"" "(:tag (meta (read-string \"^String x\")))"]
|
||||
["keyword hint -> true" "true" "(:foo (meta (read-string \"^:foo x\")))"])
|
||||
|
||||
(defspec "metadata / def metadata"
|
||||
["^:dynamic var binds" "9" "(do (def ^:dynamic *d* 1) (binding [*d* 9] *d*))"]
|
||||
["^:private on var" "true" "(do (def ^:private pv 1) (:private (meta (var pv))))"]
|
||||
["^Type tag on var" "\"String\"" "(do (def ^String tv \"a\") (:tag (meta (var tv))))"]
|
||||
["^{:doc} on var" "\"hi\"" "(do (def ^{:doc \"hi\"} dv 1) (:doc (meta (var dv))))"]
|
||||
["(def name doc val) doc" "\"d\"" "(do (def dd \"d\" 5) (:doc (meta (var dd))))"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue