Skip to content

Instantly share code, notes, and snippets.

@fogus
Last active April 26, 2024 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fogus/ce8721b9156bf924b452c37060c712e1 to your computer and use it in GitHub Desktop.
Save fogus/ce8721b9156bf924b452c37060c712e1 to your computer and use it in GitHub Desktop.

Clojure 1.12.0-alpha10

Clojure 1.12.0-alpha10 is now available! Please read the release notes below.

Clojure is a hosted language and fully embraces that host including the Java Virtual Machine, the JDK (Java Development Kit), and interop with Java APIs. Over the last decade, all of these have seen significant evolution and Java APIs are increasingly using recent Java features like streams, functional interfaces, and lambdas.

Clojure 1.12.0-alpha10 delivers significant enhancements to Java interop focusing on two main areas:

Method values

Clojure programmers often want to use Java methods in higher-order functions (e.g. passing a Java method to map). Until now, this has required programmers to manually wrap methods in functions. This is verbose, and might require manual hinting for overload disambiguation, or incur incidental reflection or boxing.

With this release, programmers can now use Java qualified method symbols as ordinary functions in value contexts - the compiler will automatically generate the wrapping function. Method symbols signifying values must resolve to a single method at compile time, using the new qualified method symbols and/or :param-tags metadata as necessary.

Qualified method symbols have value semantics when used in non-invocation positions:

  • Classname/method - value is a Clojure function that invokes a static method

  • Classname/.method - value is a Clojure function that invokes an instance method

  • Classname/new - value is a Clojure function that invokes a constructor

See the following tickets for more information:

  • CLJ-2844 - Qualified methods w/o param-tags may use reflection and inference

  • CLJ-2835 - Error message for constructor method value arity mismatch says "method" instead of "constructor"

Uniform qualified method syntax - Class/method, Class/.method, and Class/new

Java members inherently exist in a class. For methods as values we need a way to explicitly specify the class of an instance method because there is no possibility for inference.

Qualified method invocations with param-tags use only the tags to resolve the method. Without param-tags they behave like equivalent dot syntax except the qualifying class takes precedence over hints of the target object, and over its runtime type when invoked via reflection.

Note: Static fields are values and should be referenced without parens unless they are intended as function calls, e.g (System/out) should be System/out. Future Clojure releases will treat the field’s value as something invokable and invoke it.

See: CLJ-2844

:param-tags metadata

When using methods as values, only the class and method names are provided in the symbol, if the method is overloaded the parameter types must be provided to resolve to one specific method.

:param-tags metadata can now be supplied on qualified method symbols to specify the signature of a single desired method ('resolving' it). The :param-tags metadata is a vector of zero or more tags: […​ tag …​]. A tag is any existing valid :tag metadata value. Each tag corresponds to a parameter in the desired signature (arity should match the number of tags). Parameters with non-overloaded types can use the placeholder _ in lieu of the tag.

A new metadata reader syntax ^[ …​ ] attaches :param-tags metadata to member symbols, just as ^tag attaches :tag metadata to a symbol.

See: CLJ-2805

Array class symbols

Clojure supports class symbols both as a value (for class object) and as a type hint, but has not provided syntax for array classes other than strings.

Clojure now provides array class symbols, where the symbol’s namespace part comprises the name of the array component type: primitive, fully-qualified class, or imported class, and the symbol’s name part signifying the dimensionality of the array between 1 and 9. Array class symbols can be used as type hints, or as values that resolves to the corresponding array class object.

Examples: String/1, java.lang.String/1, long/2.

See: CLJ-2807

Other enhancements

Bug fixes

  • CLJ-2843 - Reflective calls to Java methods that take primitive long or double now work when passed a narrower boxed number at runtime (Integer, Short, Byte, Float). Previously, these methods were not matched during reflection and an error was thrown.

  • CLJ-2841 - IDeref should also implement DoubleSupplier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment