{"id":13531113,"url":"https://github.com/travisbrown/dhallj","last_synced_at":"2025-04-06T22:08:10.602Z","repository":{"id":39802418,"uuid":"250537970","full_name":"travisbrown/dhallj","owner":"travisbrown","description":"Dhall for Java","archived":false,"fork":false,"pushed_at":"2024-08-15T20:40:53.000Z","size":1389,"stargazers_count":173,"open_issues_count":45,"forks_count":9,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-03-30T19:09:01.126Z","etag":null,"topics":["dhall","java","json","scala","yaml"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/travisbrown.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-03-27T13:12:26.000Z","updated_at":"2025-03-03T22:09:08.000Z","dependencies_parsed_at":"2024-04-17T11:35:11.857Z","dependency_job_id":"958bc8aa-9cd3-4312-a3d3-c49659b4f3fd","html_url":"https://github.com/travisbrown/dhallj","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisbrown%2Fdhallj","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisbrown%2Fdhallj/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisbrown%2Fdhallj/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisbrown%2Fdhallj/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/travisbrown","download_url":"https://codeload.github.com/travisbrown/dhallj/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247557767,"owners_count":20958047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dhall","java","json","scala","yaml"],"created_at":"2024-08-01T07:01:00.176Z","updated_at":"2025-04-06T22:08:10.577Z","avatar_url":"https://github.com/travisbrown.png","language":"Java","readme":"# Dhall for Java\n\n[![Build status](https://img.shields.io/github/workflow/status/travisbrown/dhallj/Continuous%20Integration.svg)](https://github.com/travisbrown/dhallj/actions)\n[![Gitter](https://img.shields.io/badge/gitter-join%20chat-green.svg)](https://gitter.im/dhallj/)\n[![Maven Central](https://img.shields.io/maven-central/v/org.dhallj/dhall-core.svg)](https://maven-badges.herokuapp.com/maven-central/org.dhallj/dhall-core)\n\nThis project is an implementation of the [Dhall][dhall-lang] configuration language for the Java\nVirtual Machine.\n\nOur goal for this project is to make it as easy as possible to integrate Dhall\ninto JVM build systems (see the [dhall-kubernetes] demonstration\n[below](#converting-to-other-formats) for a concrete example of why you might want to do this).\n\nThe core modules have no external dependencies, are Java 7-compatible, and are fairly minimal:\n\n```bash\n$ du -h modules/core/target/dhall-core-0.10.0-M1.jar\n168K    modules/core/target/dhall-core-0.10.0-M1.jar\n\n$ du -h modules/parser/target/dhall-parser-0.10.0-M1.jar\n108K    modules/parser/target/dhall-parser-0.10.0-M1.jar\n```\n\nThere are also several [Scala][scala] modules that are published for Scala 2.12,\n2.13, and 3.0. While most of the examples in this README are focused on Scala, you\nshouldn't need to know or care about Scala to use the core DhallJ modules.\n\nThe initial development of this project was supported in part by [Permutive][permutive].\n\n## Table of contents\n\n* [Status](#status)\n* [Getting started](#getting-started)\n* [Converting to other formats](#converting-to-other-formats)\n* [Import resolution](#import-resolution)\n* [Command-line interface](#command-line-interface)\n* [Other stuff](#other-stuff)\n* [Developing](#developing)\n* [Community](#community)\n* [Copyright and license](#copyright-and-license)\n\n## Status\n\nThe current release of this project supports [Dhall 21.0.0][dhall-21-0-0].\nWe're running the [Dhall acceptance test suites][dhall-tests] for parsing, normalization,\n[CBOR][cbor] encoding and decoding, hashing, and type inference, and\ncurrently all tests are passing (with three exceptions; see the [0.10.0-M1 release notes for details](https://github.com/travisbrown/dhallj/releases/tag/v0.10.0-M1)).\n\nThere are several known issues:\n\n* The parser [cannot parse deeply nested structures](https://github.com/travisbrown/dhallj/issues/2) (records, etc., although note that indefinitely long lists are fine).\n* The type checker is [also not stack-safe](https://github.com/travisbrown/dhallj/issues/3) (this should be fixed soon).\n* Import resolution is not provided in the core modules, and is a work in progress.\n\nWhile we think the project is reasonably well-tested, it's very new, is sure to be full of bugs, and\nnothing about the API should be considered stable at the moment. Please use responsibly.\n\n## Getting started\n\nThe easiest way to try things out is to add the Scala wrapper module to your build.\nIf you're using [sbt][sbt] that would look like this:\n\n```scala\nlibraryDependencies += \"org.dhallj\" %% \"dhall-scala\" % \"0.10.0-M1\"\n```\n\nThis dependency includes two packages: `org.dhallj.syntax` and `org.dhallj.ast`.\n\nThe `syntax` package provides some extension methods, including a `parseExpr`\nmethod for strings (note that this method returns an\n`Either[ParsingFailure, Expr]`, which we unwrap here with `Right`):\n\n```scala\nscala\u003e import org.dhallj.syntax._\nimport org.dhallj.syntax._\n\nscala\u003e val Right(expr) = \"\\\\(n: Natural) -\u003e [n + 0, n + 1, 1 + 1]\".parseExpr\nexpr: org.dhallj.core.Expr = λ(n : Natural) → [n + 0, n + 1, 1 + 1]\n```\n\nNow that we have a Dhall expression, we can type-check it:\n\n```scala\nscala\u003e val Right(exprType) = expr.typeCheck\nexprType: org.dhallj.core.Expr = ∀(n : Natural) → List Natural\n```\n\nWe can \"reduce\" (or _β-normalize_) it:\n\n```scala\nscala\u003e val normalized = expr.normalize\nnormalized: org.dhallj.core.Expr = λ(n : Natural) → [n, n + 1, 2]\n```\n\nWe can also _α-normalize_ it, which replaces all named variables with\nindexed underscores:\n\n```scala\nscala\u003e val alphaNormalized = normalized.alphaNormalize\nalphaNormalized: org.dhallj.core.Expr = λ(_ : Natural) → [_, _ + 1, 2]\n```\n\nWe can encode it as a CBOR byte array:\n\n```scala\nscala\u003e alphaNormalized.getEncodedBytes\nres0: Array[Byte] = Array(-125, 1, 103, 78, 97, 116, 117, 114, 97, 108, -123, 4, -10, 0, -124, 3, 4, 0, -126, 15, 1, -126, 15, 2)\n```\n\nAnd we can compute its semantic hash:\n\n```scala\nscala\u003e alphaNormalized.hash\nres1: String = c57cdcdae92638503f954e63c0b3ae8de00a59bc5e05b4dd24e49f42aca90054\n```\n\nIf we have the official `dhall` CLI installed, we can confirm that this hash is\ncorrect:\n\n```bash\n$ dhall hash \u003c\u003c\u003c '\\(n: Natural) -\u003e [n + 0, n + 1, 1 + 1]'\nsha256:c57cdcdae92638503f954e63c0b3ae8de00a59bc5e05b4dd24e49f42aca90054\n```\n\nWe can also compare expressions:\n\n```scala\nscala\u003e val Right(other) = \"\\\\(n: Natural) -\u003e [n, n + 1, 3]\".parseExpr\nother: org.dhallj.core.Expr = λ(n : Natural) → [n, n + 1, 3]\n\nscala\u003e normalized == other\nres2: Boolean = false\n\nscala\u003e val Some(diff) = normalized.diff(other)\ndiff: (Option[org.dhallj.core.Expr], Option[org.dhallj.core.Expr]) = (Some(2),Some(3))\n```\n\nAnd apply them to other expressions:\n\n```scala\nscala\u003e val Right(arg) = \"10\".parseExpr\narg: org.dhallj.core.Expr = 10\n\nscala\u003e expr(arg)\nres3: org.dhallj.core.Expr = (λ(n : Natural) → [n + 0, n + 1, 1 + 1]) 10\n\nscala\u003e expr(arg).normalize\nres4: org.dhallj.core.Expr = [10, 11, 2]\n```\n\nWe can also resolve expressions containing imports (although at the moment\ndhall-scala doesn't support remote imports or caching; please see the\n[section on import resolution](#import-resolution) below for details about\nhow to set up remote import resolution if you need it):\n\n```scala\nval Right(enumerate) =\n     |   \"./dhall-lang/Prelude/Natural/enumerate\".parseExpr.flatMap(_.resolve)\nenumerate: org.dhallj.core.Expr = let enumerate : Natural → List Natural = ...\n\nscala\u003e enumerate(arg).normalize\nres5: org.dhallj.core.Expr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n```\n\nNote that we're working with values of type `Expr`, which comes from dhall-core,\nwhich is a Java module. The `Expr` class includes static methods for creating\n`Expr` values:\n\n```scala\nscala\u003e import org.dhallj.core.Expr\nimport org.dhallj.core.Expr\n\nscala\u003e Expr.makeTextLiteral(\"foo\")\nres6: org.dhallj.core.Expr = \"foo\"\n\nscala\u003e Expr.makeEmptyListLiteral(Expr.Constants.BOOL)\nres7: org.dhallj.core.Expr = [] : Bool\n```\n\nIf you're working from Scala, though, you're generally better off using the\nconstructors included in the `org.dhallj.ast` package, which provide more\ntype-safety:\n\n```scala\nscala\u003e TextLiteral(\"foo\")\nres8: org.dhallj.core.Expr = \"foo\"\n\nscala\u003e NonEmptyListLiteral(BoolLiteral(true), Vector())\nres9: org.dhallj.core.Expr = [True]\n```\n\nThe `ast` package also includes extractors that let you pattern match on\n`Expr` values:\n\n```scala\nscala\u003e expr match {\n     |   case Lambda(name, _, NonEmptyListLiteral(first +: _)) =\u003e (name, first)\n     | }\nres10: (String, org.dhallj.core.Expr) = (n,n + 0)\n```\n\nNote that we don't have exhaustivity checking for these extractors, although we\nmight be able to add that in an eventual Dotty version.\n\nIn addition to dhall-scala, there's a (more experimental) dhall-scala-codec\nmodule, which supports encoding and decoding Scala types to and from Dhall expressions.\nIf you add it to your build, you can write the following:\n\n```scala\nscala\u003e import org.dhallj.codec.syntax._\nimport org.dhallj.codec.syntax._\n\nscala\u003e List(List(1, 2), Nil, List(3, -4)).asExpr\nres0: org.dhallj.core.Expr = [[+1, +2], [] : List Integer, [+3, -4]]\n```\n\nYou can even decode Dhall functions into Scala functions (assuming you have the\nappropriate codecs for the input and output types):\n\n```scala\nval Right(f) = \"\"\"\n\n  let enumerate = ./dhall-lang/Prelude/Natural/enumerate\n\n  let map = ./dhall-lang/Prelude/List/map\n\n  in \\(n: Natural) -\u003e\n    map Natural Integer Natural/toInteger (enumerate n)\n\n\"\"\".parseExpr.flatMap(_.resolve)\n```\nAnd then:\n\n```scala\nscala\u003e val Right(scalaEnumerate) = f.as[BigInt =\u003e List[BigInt]]\nscalaEnumerate: BigInt =\u003e List[BigInt] = org.dhallj.codec.Decoder$$anon$11$$Lambda$15614/0000000050B06E20@94b036\n\nscala\u003e scalaEnumerate(BigInt(3))\nres1: List[BigInt] = List(0, 1, 2)\n```\n\nEventually we'll probably support generic derivation for encoding Dhall\nexpressions to and from algebraic data types in Scala, but we haven't\nimplemented this yet.\n\n## Converting to other formats\n\nDhallJ currently includes several ways to export Dhall expressions to other formats. The core module\nincludes very basic support for printing Dhall expressions as JSON:\n\n```scala\nscala\u003e import org.dhallj.core.converters.JsonConverter\nimport org.dhallj.core.converters.JsonConverter\n\nscala\u003e import org.dhallj.parser.DhallParser.parse\nimport org.dhallj.parser.DhallParser.parse\n\nscala\u003e val expr = parse(\"(λ(n: Natural) → [n, n + 1, n + 2]) 100\")\nexpr: org.dhallj.core.Expr.Parsed = (λ(n : Natural) → [n, n + 1, n + 2]) 100\n\nscala\u003e JsonConverter.toCompactString(expr.normalize)\nres0: String = [100,101,102]\n```\n\nThis conversion supports the same subset of Dhall expressions as [`dhall-to-json`][dhall-json] (e.g.\nit can't produce JSON representation of functions, which means the normalization in the example\nabove is necessary—if we hadn't normalized the conversion would fail).\n\nThere's also a module that provides integration with [Circe][circe], allowing you to convert Dhall\nexpressions directly to (and from) `io.circe.Json` values without intermediate serialization to\nstrings:\n\n```scala\nscala\u003e import org.dhallj.circe.Converter\nimport org.dhallj.circe.Converter\n\nscala\u003e import io.circe.syntax._\nimport io.circe.syntax._\n\nscala\u003e Converter(expr.normalize)\nres0: Option[io.circe.Json] =\nSome([\n  100,\n  101,\n  102\n])\n\nscala\u003e Converter(List(true, false).asJson)\nres1: org.dhallj.core.Expr = [True, False]\n```\n\nAnother module supports converting to any JSON representation for which you have a [Jawn][jawn]\nfacade. For example, the following build configuration would allow you to export [spray-json]\nvalues:\n\n```scala\nlibraryDependencies ++= Seq(\n  \"org.dhallj\"    %% \"dhall-jawn\" % \"0.4.0\",\n  \"org.typelevel\" %% \"jawn-spray\" % \"1.0.0\"\n)\n```\n\nAnd then:\n\n```scala\nscala\u003e import org.dhallj.jawn.JawnConverter\nimport org.dhallj.jawn.JawnConverter\n\nscala\u003e import org.typelevel.jawn.support.spray.Parser\nimport org.typelevel.jawn.support.spray.Parser\n\nscala\u003e val toSpray = new JawnConverter(Parser.facade)\ntoSpray: org.dhallj.jawn.JawnConverter[spray.json.JsValue] = org.dhallj.jawn.JawnConverter@be3ffe1d\n\nscala\u003e toSpray(expr.normalize)\nres0: Option[spray.json.JsValue] = Some([100,101,102])\n```\n\nNote that unlike the dhall-circe module, the integration provided by dhall-jawn is only one way\n(you can convert Dhall expressions to JSON values, but not the other way around).\n\nWe also support YAML export via [SnakeYAML][snake-yaml] (which doesn't require a Scala dependency):\n\n```scala\nscala\u003e import org.dhallj.parser.DhallParser.parse\nimport org.dhallj.parser.DhallParser.parse\n\nscala\u003e import org.dhallj.yaml.YamlConverter\nimport org.dhallj.yaml.YamlConverter\n\nscala\u003e val expr = parse(\"{foo = [1, 2, 3], bar = [4, 5]}\")\nexpr: org.dhallj.core.Expr.Parsed = {foo = [1, 2, 3], bar = [4, 5]}\n\nscala\u003e println(YamlConverter.toYamlString(expr))\nfoo:\n- 1\n- 2\n- 3\nbar:\n- 4\n- 5\n```\n\nYou can use the YAML exporter with [dhall-kubernetes], for example. Instead of\nmaintaining a lot of verbose and repetitive and error-prone YAML files, you can\nkeep your configuration in well-typed Dhall files (like\n[this example](https://github.com/dhall-lang/dhall-kubernetes/blob/506d633e382872346927b8cb9884d8b7382e6cab/1.17/examples/deploymentSimple.dhall))\nand have your build system export them to YAML:\n\n```scala\nimport org.dhallj.syntax._, org.dhallj.yaml.YamlConverter\n\nval kubernetesExamplePath = \"../dhall-kubernetes/1.17/examples/deploymentSimple.dhall\"\nval Right(kubernetesExample) = kubernetesExamplePath.parseExpr.flatMap(_.resolve)\n```\n\nAnd then:\n\n```scala\nscala\u003e println(YamlConverter.toYamlString(kubernetesExample.normalize))\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: nginx\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      name: nginx\n  template:\n    metadata:\n      name: nginx\n    spec:\n      containers:\n      - image: nginx:1.15.3\n        name: nginx\n        ports:\n        - containerPort: 80\n```\n\nIt's not currently possible to convert to YAML without the SnakeYAML dependency, although we may support a simplified\nversion of this in the future (something similar to what we have for JSON in the core module).\n\n## Import resolution\n\nThere are currently two modules that implement import resolution (to different degrees).\n\n### dhall-imports\n\nThe first is dhall-imports, which is a Scala library built on [cats-effect] that uses [http4s] for\nits HTTP client. This module is intended to be a complete implementation of the\n[import resolution and caching specification][dhall-imports].\n\nIt requires a bit of ceremony to set up:\n\n```scala\nimport cats.effect.{IO, Resource}\nimport org.dhallj.core.Expr\nimport org.dhallj.imports.syntax._\nimport org.dhallj.parser.DhallParser\nimport org.http4s.blaze.client.BlazeClientBuilder\nimport org.http4s.client.Client\nimport scala.concurrent.ExecutionContext\n\nval client: Resource[IO, Client[IO]] = BlazeClientBuilder[IO](ExecutionContext.global).resource\n```\n\nAnd then if we have some definitions like this:\n\n```scala\nval concatSepImport = DhallParser.parse(\"https://prelude.dhall-lang.org/Text/concatSep\")\n\nval parts = DhallParser.parse(\"\"\"[\"foo\", \"bar\", \"baz\"]\"\"\")\nval delimiter = Expr.makeTextLiteral(\"-\")\n```\n\nWe can use them with a function from the Dhall Prelude like this:\n\n```scala\nscala\u003e val resolved = client.use { implicit c =\u003e\n     |   concatSepImport.resolveImports[IO]\n     | }\nresolved: cats.effect.IO[org.dhallj.core.Expr] = IO(...)\n\nscala\u003e import cats.effect.unsafe.implicits.global\nimport cats.effect.unsafe.implicits.global\n\nscala\u003e val result = resolved.map { concatSep =\u003e\n     |   Expr.makeApplication(concatSep, Array(delimiter, parts)).normalize\n     | }\nresult: cats.effect.IO[org.dhallj.core.Expr] = IO(...)\n\nscala\u003e result.unsafeRunSync()\nres0: org.dhallj.core.Expr = \"foo-bar-baz\"\n```\n\n(Note that we could use dhall-scala to avoid the use of `Array` above.)\n\n#### Classpath imports\n\nWe support an extension of the spec which allows you to also import expressions\nfrom the classpath using the syntax `let e = classpath:/absolute/path/to/file in e`.\nThe semantics are subject to change as we get more experience with it but\ncurrently it should generally have the same behaviour as an absolute\npath import of a local file (but files on the classpath can import each other\nusing relative paths). This includes it being protected by the referential\nsanity check so that remote imports cannot exfiltrate information\nfrom the classpath.\n\nAlso note that classpath imports as location are currently not supported as the spec\nrequires that an import as Location must return an expression of type\n`\u003cLocal Text | Remote Text | Environment Text | Missing\u003e`.\n\n### dhall-imports-mini\n\nThe other implementation is dhall-imports-mini, which is a Java library that\ndepends only on the core and parser modules, but that doesn't support\nremote imports or caching.\n\nThe previous example could be rewritten as follows using dhall-imports-mini\nand a local copy of the Prelude:\n\n```scala\nimport org.dhallj.core.Expr\nimport org.dhallj.imports.mini.Resolver\nimport org.dhallj.parser.DhallParser\n\nval concatSep = Resolver.resolve(DhallParser.parse(\"./dhall-lang/Prelude/Text/concatSep\"), false)\n\nval parts = DhallParser.parse(\"\"\"[\"foo\", \"bar\", \"baz\"]\"\"\")\nval delimiter = Expr.makeTextLiteral(\"-\")\n```\n\nAnd then:\n\n```scala\nscala\u003e Expr.makeApplication(concatSep, Array(delimiter, parts)).normalize\nres0: org.dhallj.core.Expr = \"foo-bar-baz\"\n```\n\nIt's likely that eventually we'll provide a complete pure-Java implementation of import resolution,\nbut this isn't currently a high priority for us.\n\n## Command-line interface\n\nWe include a command-line interface that supports some common operations. It's currently similar to\nthe official `dhall` and `dhall-to-json` binaries, but with many fewer options.\n\nIf [GraalVM Native Image][graal-native-image] is available on your system, you can build the CLI as\na native binary (thanks to [sbt-native-packager]).\n\n```bash\n$ sbt cli/graalvm-native-image:packageBin\n\n$ cd cli/target/graalvm-native-image/\n\n$ du -h dhall-cli\n8.2M    dhall-cli\n\n$ time ./dhall-cli hash --normalize --alpha \u003c\u003c\u003c \"λ(n: Natural) → [n, n + 1]\"\nsha256:a8d9326812aaabeed29412e7b780dc733b1e633c5556c9ea588e8212d9dc48f3\n\nreal    0m0.009s\nuser    0m0.000s\nsys     0m0.009s\n\n$ time ./dhall-cli type \u003c\u003c\u003c \"{foo = [1, 2, 3]}\"\n{foo : List Natural}\n\nreal    0m0.003s\nuser    0m0.000s\nsys     0m0.003s\n\n$ time ./dhall-cli json \u003c\u003c\u003c \"{foo = [1, 2, 3]}\"\n{\"foo\":[1,2,3]}\n\nreal    0m0.005s\nuser    0m0.004s\nsys     0m0.001s\n```\n\nEven on the JVM it's close to usable, although you can definitely feel the slow startup:\n\n```bash\n$ cd ..\n\n$ time java -jar ./cli-assembly-0.4.0-SNAPSHOT.jar hash --normalize --alpha \u003c\u003c\u003c \"λ(n: Natural) → [n, n + 1]\"\nsha256:a8d9326812aaabeed29412e7b780dc733b1e633c5556c9ea588e8212d9dc48f3\n\nreal    0m0.104s\nuser    0m0.106s\nsys     0m0.018s\n```\n\nThere's probably not really any reason you'd want to use `dhall-cli` right now, but I think it's a\npretty neat demonstration of how Graal can make Java (or Scala) a viable language for building\nnative CLI applications.\n\n## Other stuff\n\n### dhall-testing\n\nThe dhall-testing module provides support for property-based testing with [ScalaCheck][scalacheck]\nin the form of `Arbitrary` (and `Shrink`) instances:\n\n```scala\nscala\u003e import org.dhallj.core.Expr\nimport org.dhallj.core.Expr\n\nscala\u003e import org.dhallj.testing.instances._\nimport org.dhallj.testing.instances._\n\nscala\u003e import org.scalacheck.Arbitrary\nimport org.scalacheck.Arbitrary\n\nscala\u003e Arbitrary.arbitrary[Expr].sample\nres0: Option[org.dhallj.core.Expr] = Some(Optional (Optional (List Double)))\n\nscala\u003e Arbitrary.arbitrary[Expr].sample\nres1: Option[org.dhallj.core.Expr] = Some(Optional (List \u003cneftfEahtuSq : Double | kg...\n```\n\nIt includes (fairly basic) support for producing both well-typed and probably-not-well-typed\nexpressions, and for generating arbitrary values of specified Dhall types:\n\n```scala\nscala\u003e import org.dhallj.testing.WellTypedExpr\nimport org.dhallj.testing.WellTypedExpr\n\nscala\u003e Arbitrary.arbitrary[WellTypedExpr].sample\nres2: Option[org.dhallj.testing.WellTypedExpr] = Some(WellTypedExpr(8436008296256993755))\n\nscala\u003e genForType(Expr.Constants.BOOL).flatMap(_.sample)\nres3: Option[org.dhallj.core.Expr] = Some(True)\n\nscala\u003e genForType(Expr.Constants.BOOL).flatMap(_.sample)\nres4: Option[org.dhallj.core.Expr] = Some(False)\n\nscala\u003e genForType(Expr.makeApplication(Expr.Constants.LIST, Expr.Constants.INTEGER)).flatMap(_.sample)\nres5: Option[org.dhallj.core.Expr] = Some([+1522471910085416508, -9223372036854775809, ...\n```\n\nThis module is currently fairly minimal, and is likely to change substantially in future releases.\n\n### dhall-javagen and dhall-prelude\n\nThe dhall-javagen module lets you take a DhallJ representation of a Dhall expression and use it to\ngenerate Java code that will build the DhallJ representation of that expression.\n\nThis is mostly a toy, but it allows us for example to distribute a \"pre-compiled\" jar containing the\nDhall Prelude:\n\n```scala\nscala\u003e import java.math.BigInteger\nimport java.math.BigInteger\n\nscala\u003e import org.dhallj.core.Expr\nimport org.dhallj.core.Expr\n\nscala\u003e val ten = Expr.makeNaturalLiteral(new BigInteger(\"10\"))\nten: org.dhallj.core.Expr = 10\n\nscala\u003e val Prelude = org.dhallj.prelude.Prelude.instance\nPrelude: org.dhallj.core.Expr = ...\n\nscala\u003e val Natural = Expr.makeFieldAccess(Prelude, \"Natural\")\nNatural: org.dhallj.core.Expr = ...\n\nscala\u003e val enumerate = Expr.makeFieldAccess(Natural, \"enumerate\")\nenumerate: org.dhallj.core.Expr = ...\n\nscala\u003e Expr.makeApplication(enumerate, ten).normalize\nres0: org.dhallj.core.Expr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n```\n\nNote that the resulting jar (which is available from Maven Central as dhall-prelude) is many times\nsmaller than either the Prelude source or the Prelude serialized as CBOR.\n\n## Developing\n\nThe project includes the currently-supported version of the Dhall language repository as a\nsubmodule, so if you want to run the acceptance test suites, you'll need to clone recursively:\n\n```bash\ngit clone --recurse-submodules git@github.com:travisbrown/dhallj.git\n```\n\nOr if you're like me and always forget to do this, you can initialize the submodule after cloning:\n\n```bash\ngit submodule update --init\n```\n\nThis project is built with [sbt][sbt], and you'll need to have sbt [installed][sbt-installation]\non your machine.\n\nWe're using the [JavaCC][javacc] parser generator for the parsing module, and we have\n[our own sbt plugin][sbt-javacc] for integrating JavaCC into our build. This plugin is open source\nand published to Maven Central, so you don't need to do anything to get it, but you will need to run\nit manually the first time you build the project (or any time you update the JavaCC grammar):\n\n```\nsbt:root\u003e javacc\nJava Compiler Compiler Version 7.0.5 (Parser Generator)\nFile \"Provider.java\" does not exist.  Will create one.\nFile \"StringProvider.java\" does not exist.  Will create one.\nFile \"StreamProvider.java\" does not exist.  Will create one.\nFile \"TokenMgrException.java\" does not exist.  Will create one.\nFile \"ParseException.java\" does not exist.  Will create one.\nFile \"Token.java\" does not exist.  Will create one.\nFile \"SimpleCharStream.java\" does not exist.  Will create one.\nParser generated with 0 errors and 1 warnings.\n[success] Total time: 0 s, completed 12-Apr-2020 08:48:53\n```\n\nAfter this is done, you can run the tests:\n\n```\nsbt:root\u003e test\n...\n[info] Passed: Total 1319, Failed 0, Errors 0, Passed 1314, Skipped 5\n[success] Total time: 36 s, completed 12-Apr-2020 08:51:07\n```\n\nNote that a few tests require the [dhall-haskell] `dhall` CLI. If you don't have it installed on\nyour machine, these tests will be skipped.\n\nThere are also a few additional slow tests that must be run manually:\n\n```\nsbt:root\u003e slow:test\n...\n[info] Passed: Total 4, Failed 0, Errors 0, Passed 4\n[success] Total time: 79 s (01:19), completed 12-Apr-2020 08:52:41\n```\n\n## Community\n\nThis project supports the [Scala code of conduct][code-of-conduct] and wants all of its channels\n(Gitter, GitHub, etc.) to be inclusive environments.\n\n## Copyright and license\n\nAll code in this repository is available under the [3-Clause BSD License][bsd-license].\n\nCopyright [Travis Brown][travisbrown] and [Tim Spence][timspence], 2020.\n\n[bsd-license]: https://opensource.org/licenses/BSD-3-Clause\n[cats-effect]: https://github.com/typelevel/cats-effect\n[cbor]: https://cbor.io/\n[circe]: https://github.com/circe/circe\n[code-of-conduct]: https://www.scala-lang.org/conduct/\n[dhall-21-0-0]: https://github.com/dhall-lang/dhall-lang/pull/1194\n[dhall-haskell]: https://github.com/dhall-lang/dhall-haskell\n[dhall-imports]: https://github.com/dhall-lang/dhall-lang/blob/master/standard/imports.md\n[dhall-json]: https://docs.dhall-lang.org/tutorials/Getting-started_Generate-JSON-or-YAML.html\n[dhall-kubernetes]: https://github.com/dhall-lang/dhall-kubernetes\n[dhall-tests]: https://github.com/dhall-lang/dhall-lang/tree/master/tests\n[dhall-lang]: https://dhall-lang.org/\n[discipline]: https://github.com/typelevel/discipline\n[graal-native-image]: https://www.graalvm.org/docs/reference-manual/native-image/\n[http4s]: https://http4s.org\n[javacc]: https://javacc.github.io/javacc/\n[jawn]: https://github.com/typelevel/jawn\n[permutive]: https://permutive.com\n[permutive-medium]: https://medium.com/permutive\n[sbt]: https://www.scala-sbt.org\n[sbt-installation]: https://www.scala-sbt.org/1.x/docs/Setup.html\n[sbt-javacc]: https://github.com/travisbrown/sbt-javacc\n[sbt-native-packager]: https://github.com/sbt/sbt-native-packager\n[scala]: https://www.scala-lang.org\n[scalacheck]: https://www.scalacheck.org/\n[snake-yaml]: https://bitbucket.org/asomov/snakeyaml/\n[spray-json]: https://github.com/spray/spray-json\n[timspence]: https://github.com/TimWSpence\n[travisbrown]: https://twitter.com/travisbrown\n","funding_links":[],"categories":["Binding"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravisbrown%2Fdhallj","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftravisbrown%2Fdhallj","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravisbrown%2Fdhallj/lists"}