clojureclojureclr

ClojureCLR coercion error


I'm getting a compiler exception in the ClojureCLR REPL for basic coercion:

=> (class 12)
System.Int64

=> (class 12.34)
System.Double

=> (class (new System.Double 12))
CompilerException System.InvalidOperationException: No constructor in type: Double with 1 arguments
at clojure.lang.CljCompiler.Ast.NewExpr.ComputeCtor() in D:\work\clojure-clr-1.4.1-fix\Clojure\Clojure\CljCompiler\Ast\NewExpr.cs:line 73
at clojure.lang.CljCompiler.Ast.NewExpr..ctor(Type type, List`1 args, IPersistentMap spanMap) in D:\work\clojure-clr-1.4.1-fix\Clojure\Clojure\CljCompiler\Ast\NewExpr.cs:line 49
at clojure.lang.CljCompiler.Ast.NewExpr.Parser.Parse(ParserContext pcon, Object frm) in D:\work\clojure-clr-1.4.1-fix\Clojure\Clojure\CljCompiler\Ast\NewExpr.cs:line 117
at clojure.lang.Compiler.AnalyzeSeq(ParserContext pcon, ISeq form, String name) in D:\work\clojure-clr-1.4.1-fix\Clojure\Clojure\CljCompiler\Compiler.cs:line 1560, compiling: (NO_SOURCE_PATH:60)

Sorry if this is a newbish question, but isn't behaving the same as Java interop!

Is the syntax different for .NET?


Solution

  • Interop in ClojureCLR is very similar to interop in Clojure, but platform differences do show through.

    java.lang.Double is a very different creature than System.Double. The JVM's Double is a wrapper class that is distinct from the class of primitive double values. CLR's Double actually is the class of primitive double values. j.l.Double has many methods not paralleled in S.Double. Re your example: j.l.Double has several constructors; S.Double has none. To accomplish what you want, use clojure.core/double:

    user=> (class (double 2))
    System.Double
    

    The Java wrapper types are a likely place to run into platform differences: CLR does not have explicit wrapper types. I don't know of any place that has tried to cover this in detail.

    For hints on how to handle CLR interop for things not in the JVM, such as by-ref parameters, enums, etc., check out the wiki on the github repo for ClojureCLR.