Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are Clojure Intrinsics

Browsing the Clojure source code I came across an Intrinsics.java file. It looks like it is a mapping of some clojure runtime functions to JVM opcodes.

However, I am not sure where they get applied. The following code

(def ^:const pi 3.141592)
(defn circumference [^double r] (* r 2.0 pi))

compiles to

public static java.lang.Object invokeStatic(double r);
 0  dload_0 [r]
 1  ldc2_w <Double 2.0> [14]
 4  dmul
 5  ldc2_w <Double 3.141592> [16]
 8  invokestatic clojure.lang.Numbers.multiply(double, double) : double [23]
11  invokestatic java.lang.Double.valueOf(double) : java.lang.Double [29]
14  areturn

and I see that clojure.lang.Numbers.multiply(double, double) : double did not get replaced to DMUL.

How exactly are intrinsics used? Thank you.

like image 757
erdos Avatar asked Oct 28 '25 17:10

erdos


1 Answers

Currently intrinsics are only used where the expression being compiled is meant to remain unboxed. Thus the (* r 2.0) multiplication in your example does receive the intrinsic treatment (resulting in the one dmul in your example invokeStatic), but the (* #<result of (* r 2.0)> 3.141592) multiplication does not.

You can get the clojure.lang.Numbers.multiply(double, double) : double intrinsic to be applied to the multiplication by r as well by ensuring that the return type is double as well.

For example this:

(def ^:const pi 3.141592)
(defn circumference ^double [^double r] (* r 2.0 pi))

compiles to the following:

public static double invokeStatic(double r);
   0  dload_0 [r]
   1  ldc2_w <Double 2.0> [14]
   4  dmul
   5  ldc2_w <Double 3.141592> [16]
   8  dmul
   9  dreturn
like image 79
Michał Marczyk Avatar answered Oct 31 '25 12:10

Michał Marczyk