dhall-eta
is a eta library that wraps the
haskell implementation
of dhall configuration language with a friendly java api.
Its main goal is to create a language binding to make possible configure java
libraries and applications with dhall
files.
We already can use eta
to compile the dhall haskell
implementation
and etlas (a
specific build tool for eta
) to install dhall
and its tools (dhall-to-json
or
dhall-text
)
as java cli applications. However, the classes generated by eta can't
be used directly in java code in a easy way. Hence the need for this library.
- The quick way to explore the java api is use
jshell
the java repl tool present since java 9.- To start a session with the library in the classpath you can do:
> jshell --class-path /path/to/dhall-eta-all-${version}.jar
NOTE: The version of java used is openjdk-9.0.4.
- To use the api in your project simply download from last release the
dhall-eta-all-${version}.jar
and put it in the project classpath. - The project has an executable class with some more examples.
The main class to compile dhall expressions and get java objects is
the class org.dhall.eta.Input
.
- The class has methods to compile simple types and convert them to java:
jshell> import org.dhall.eta.Input
jshell> Input.bool("True")
$2 ==> true
jshell> Input.str("\"This is a dhall Text\"")
$3 ==> "This is a dhall Text"
jshell> Input.bigInt("-1234567890")
$4 ==> -1234567890
jshell> Input.natural("123456789 * 123456789")
$5 ==> Natural [15241578750190521]
- Those are shorthands for the main method
Input.type
. To use it we need to build aorg.dhall.eta.Type<R>
used by the api to extract a java value (of typeR
) and typecheck the dhall expression. Methods for basic types are already defined inorg.dhall.eta.Types
:
jshell> import org.dhall.eta.Type
jshell> import org.dhall.eta.Types
jshell> Type<Boolean> boolTy = Types.bool()
boolTy ==> eta.org.dhall.eta.Type$Eta@67bf0d91
jshell> Input.type(boolTy, "True && False")
$6 ==> false
- The class
org.dhall.eta.Types
has methods to build standard "container" types asList
,Optional
orMap
.- For extract a java
Map
from a dhall record, we need to build aMap
with the keys and types of the fields expected and then useTypes.objMap
to get aType<Map<String, Object>>
suitable to use withInput.type
:
- For extract a java
jshell> Map<String,Type<? extends Object>> fieldTypes=new HashMap<>();
fieldTypes ==> {}
jshell> fieldTypes.put("name",Types.str());
$9 ==> null
jshell> fieldTypes.put("nats",Types.list(Types.natural()))
$10 ==> null
jshell> Type<Map<String,Object>> mapTy=Types.objMap(FieldTypes.upcast(fieldTypes))
mapTy ==> eta.org.dhall.eta.Type$Eta@35884aff
jshell> Input.type(mapTy, "{ name = \"name\", nats=[1, 2, 3] }")
$11 ==> {name=name, nats=[Natural[1], Natural[2], Natural[3]]}
- Of course you can use the api to create an arbitrary java object from dhall code. We should use the generic
Input.type
method and create the appropiate type:- From a dhall record, using the method
Types.record
and implementingorg.dhall.eta.RecordType
- See an example implementation here.
- From a dhall union, using the method
Types.union
and implementingorg.dhall.eta.UnionType
- See an example implementation here.
- From arbitrary dhall code implementing the low-level
org.dhall.eta.Type
interface and using directlyInput.type
.
- From a dhall record, using the method
- A more detailed overview of the low level api is coming soon.
- For now we can list the classes that can be used to handle each dhall compiler phase and a link to some example case uses:
- Parsing:
org.dhall.eta.Parser
- Resolving imports:
org.dhall.eta.Import
- Normalizing and pretty printing:
org.dhall.eta.Core
- Typechecking:
org.dhall.eta.TypeCheck
- Binary encoding/decoding:
org.dhall.eta.Binary
- Parsing:
-
Download etlas from https://eta-lang.org/docs/user-guides/eta-user-guide/installation/etlas- WARNING: Actually
dhall-eta
can only be built usingeta
andetlas
built themselves from master. We are in the cutting edge!
- WARNING: Actually
-
Run
etlas build --enable-uberjar-mode
to compile and generate an uberjar with all dependecies included in./dist/build/eta-${version}/dhall-eta-${version}/x/dhall-eta-all/build/dhall-eta-all/dhall-eta-all.jar
- The output jar is not minimized and include an example executable with
etlas run dhall-eta-all
- The output jar is not minimized and include an example executable with
-
Run
etlas test
to execute the test suite againstdhall-lang
acceptance tests- As a previous step you'll need to checkout
dhall-lang
project in the same parent directory asdhall-eta
- Current dhall standard version supported is
4.0.0
and we have to use a fixed version of tests for4.0.0
in https://github.com/jneira/dhall-lang - So the command to get them could be (being in the
dhall-eta
project dir):
- As a previous step you'll need to checkout
> git clone --branch v4.0.0 --depth=1 https://github.com/jneira/dhall-lang.git ../dhall-lang
- The test suite does not check the validity of
dhall-haskell
(and it should not do it!), only that thedhall-haskell
implementation compiled byeta
anddhall-eta
itself are consistent.
- WARNING: For now, the
gradle
build is configured to use the system wide versions ofeta
andetlas
so you will must have them built from source and available inPATH
. We are in the cutting edge here too! - This is the preferred method to build the project and the used one to generate the artifacts needed for a release of the library.
- It uses the
gradle
plugin for eta and the proguard and shadow ones to generate a minimized jar with all the dependencies included. - It is recommended to use the
gradle
wrapper cause the etagradle
plugin will likely work with it. - So
./gradlew build
will generate the following artifacts:- A minimized uberjar ready to be used standalone in
./lib/dhall-eta-${version}-all.jar
- An artefact with the objects representing the core business model of dhall. In this one will not be any code for actually parse, normalize o compile dhall code.
- The package root name has not reference to
eta
: it is simplyorg.dhall
. - The code is in a
gradle
subproject nameddhall-model
in the folder./java
- The artifact generated is
./java/build/libs/dhall-model-${version}.jar
- The package root name has not reference to
- An artefact with the java executable example
org.dhall.eta.examples.Client
.- The code is in a gradle subproject named
dhall-eta-examples
in the folderexamples
- You can run it with
./gradlew run
.
- The code is in a gradle subproject named
- A minimized uberjar ready to be used standalone in