JVM bytecode backend for Idris
- Haskell Stack
- Java 8
git clone https://github.com/mmhelloworld/idris-jvm.git
bin/setup. Windows users, please follow the instructions here before running this.
For details on what the
setup script does, please see here.
module Main pythag : Int -> List (Int, Int, Int) pythag max = [(x, y, z) | z <- [1..max], y <- [1..z], x <- [1..y], x * x + y *y == z * z] main : IO () main = print (pythag 50)
$ bin/idrisjvm pythag.idr -o pythag
$ java -cp ~/.idrisjvm/idris-jvm-runtime-1.0-SNAPSHOT.jar:pythag main.Main
All Idris types are supported. Idris
Intis mapped to Java primitive
Stringis mapped to Java
Integeris represented as Java
Doubleis mapped to Java
Bits32are mapped to Java
Bits64is mapped to Java
FFI - Calling Java from Idris: From Idris, invoking Java static methods, instance methods, constructors are all supported. See here for an example.
FFI: Calling Idris from Java: Idris functions can be exported as Java instance methods, static methods and constructors. The exported class with Idris implementations can also extend a Java class and implement interfaces. It can also have static and instance fields and the field values can be set from Idris. Idris types (monomorphic, for example,
List Int) can also be exported as a Java class. See here for an example.
Tail recursion is eliminated using JVM's
GOTO. For the following code,
sum 50000wouldn't blow up the stack.
sum : Nat -> Nat sum n = go 0 n where go : Nat -> Nat -> Nat go acc Z = acc go acc n@(S k) = go (acc + n) k
Non-recursive tail call is handled using trampolines. For the following code,
evenT 10909000007would work just fine and return the result after few seconds.
IOis used here as otherwise Idris inlines the function calls and the functions end up being tail recursive instead of mutually recursive.
mutual evenT : Nat -> IO Bool evenT Z = pure True evenT (S k) = oddT k oddT : Nat -> IO Bool oddT Z = pure False oddT (S k) = evenT k
It compiles to Java 8 class files. Tail calls are delayed using Java 8 lambdas and use JVM's
forkfor running in parallel and creating threads are supported using Java's
ExecutorService. See here for an example.
Maybetype can be used in an FFI function to avoid Java
nullgetting into Idris code.
Maybeused in an argument position will pass
nullto the Java code if the value is
Nothingotherwise the unwrapped value will be passed to Java. In the similar way,
Maybetype used in the return type position would return
Nothingif the FFI function returns
nullotherwise returns the actual value in