Skip to content

Commit

Permalink
Cleaning up param-tag info
Browse files Browse the repository at this point in the history
  • Loading branch information
puredanger committed Aug 29, 2024
1 parent e7be68d commit 9dcf517
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 19 deletions.
15 changes: 1 addition & 14 deletions content/reference/metadata.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,6 @@ Modify or reset the metadata respectively for a namespace/var/ref/agent/atom.

In addition to `with-meta`, there is reader support (<<reader#metadata,Metadata Reader>>) for applying metadata to the expression following it at read-time.

For a metadata value of type:
See <<java_interop#typehints,Type Hints>> and <<java_interop#paramtags,param-tags>> for more information on how metadata is used by the compiler for method overload selection.

* Map: `^{:key value ...}` yields itself
* Keyword: `^:key` yields `^{:key true}`
* Symbol: `^AClass` or `^package.AClass` yields `{:tag package.AClass}` (also see special <<java_interop#TypeAliases,type aliases>>)
* Vector: `^[AClass prim _ ...]` yields `{:param-tags [package.AClass prim _ ...]}`
* *deprecated* String: `^"[Lpackage.AClass;"` yields `{:tag "[Lpackage.AClass;"}` - since 1.12, use array class symbols instead, e.g. `^package.AClass/1`

The `:tag` key is used to hint an objects type to the Clojure compiler. See <<java_interop#typehints,Java Interop: Type Hints>> for more information and a complete list of special type hints.

Since Clojure 1.12, the `:param-tags` key is used on qualified static, instance, and constructor method symbols to specify the arity and parameter types of the desired method overload. The `:param-tags` vector takes any valid `:tag` value or `_` as a placeholder for non-overloaded parameters.

It is possible to add multiple pieces of metadata by chaining the metadata reader macros together.
For example: `^:dynamic ^ints obj` would apply both the :dynamic flag and ints type-hint to obj. Metadata chains from right to left (left takes precedence).

Note that metadata reader macros are applied at read-time, not at evaluation-time, and can only be used with values that support metadata, like symbols, vars, collections, sequences, namespaces, refs, atoms, agents, etc. Some important exceptions that *don't* support metadata are strings, numbers, booleans, Java objects, keywords (these are cached and can be shared within the runtime), and deftypes (unless they explicitly implement clojure.lang.IMeta).
8 changes: 3 additions & 5 deletions content/reference/reader.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,12 @@ Metadata is a map associated with some kinds of objects: Symbols, Lists, Vector,
`^{:a 1 :b 2} [1 2 3]` yields the vector `[1 2 3]` with a metadata map of `{:a 1 :b 2}`. +

A shorthand version allows the metadata to be a simple symbol or string, in which case it is treated as a single entry map with a key of `:tag` and a value of the (resolved) symbol or string, e.g.: +
`^String x` is the same as `^{:tag java.lang.String} x` +
`^String x` is the same as `^{:tag java.lang.String} x`.

A shorthand version for type signatures allows the metadata to be a vector, in which case it is treated as a single entry map with a key of `:param-tags` and a value of the (resolved) type hints, a vector of `:tag` values or `_`, e.g.: `^[String long _]` is the same as `^{:param-tags [java.lang.String long _]}`.

Such tags can be used to convey type information to the compiler. +
A shorthand version for type signatures allows the metadata to be a vector, in which case it is treated as a single entry map with a key of `:param-tags` and a value of the (resolved) type hints, a vector of `:tag` values or `_`, e.g.: `^[String long _]` is the same as `^{:param-tags [java.lang.String long _]}`. See <<java_interop#paramtags,`:param-tags`>> on how param-tags are used.

Another shorthand version allows the metadata to be a keyword, in which case it is treated as a single entry map with a key of the keyword and a value of true, e.g.: +
`^:dynamic x` is the same as `^{:dynamic true} x` +
`^:dynamic x` is the same as `^{:dynamic true} x`

Metadata can be chained in which case they are merged from right to left.

Expand Down

0 comments on commit 9dcf517

Please sign in to comment.