daml/compiler/damlc
Sofia Faro 1bd117bcec
Inline typeclass projections. (#5759)
* Inline typeclasses and apply projections.

This draft PR:

* adds a Subst module for substitution within LF expressions.
  This implementation piggybacks on the existing type
  substition. But there are not enough tests yet.
* passes World data into the simplifier, in order to have
  have the ability to inline functions (selectively)
* inlines typeclass dictionaries and projection functions
* beta reduces type lambdas (which are just ignored by
  speedy afaik)
* beta reduces lambdas that are passed units or dictionaries
* runs the simplifier twice so it has a change to
  perform the inlining, reduction, AND projection
  -- this is probably avoidable by sequencing the
  simplifier steps in a specific order, but running
  the simplifier twice is simple enough for now.
* together, these fix #5748 (see result on a toy module)

TODO:

* add lots of tests for Subst
* run this on a benchmark to see how big of a difference it makes.
* reduce the jankiness of running the simplifier twice.

Results:

DAML input:

```
module Main where

hello : Int
hello = 10 + 30
```

Original DAML-LF output:

```
module Main where
    @location(7:0-7:5)
    def hello : Int64 =
      a284919a95c4a515cd1efac0d89be302d0e9d61e692a2176128c871ad8067e36:GHC.Num:+
        @Int64
        a284919a95c4a515cd1efac0d89be302d0e9d61e692a2176128c871ad8067e36:GHC.Num:$fAdditiveInt
        10
        30
```

Current DAML-LF output:

```
 module Main where
    @location(7:0-7:5)
    def hello : Int64 = ADD_INT64 10 30
```

changelog_begin
changelog_end

* Update copyright header

* Lint

* More direct typeclass simplification

* extendWorldSelf + getTypeClassDictionary

* Fix visual

* Fix visual comment

* Disable cross-module inlining for incremental builds

* Cleanup subst/freevars.

* copyright header

* Alpha equivalence for LF expressions.

* copyright header

* lots of tests

* fix comment

* Apply review suggestions
2020-05-11 16:48:27 +00:00
..
daml-compiler Inline typeclass projections. (#5759) 2020-05-11 16:48:27 +00:00
daml-doc Update Bazel 2.0.0 --> 2.1.0 (#5651) 2020-05-11 11:47:54 +02:00
daml-doctest replace DAML Authors with DA in copyright headers (#5228) 2020-03-27 01:26:10 +01:00
daml-ide Fix handling of packages in damlc visual (#5789) 2020-05-04 11:34:33 +02:00
daml-ide-core Inline typeclass projections. (#5759) 2020-05-11 16:48:27 +00:00
daml-lf-conversion replace DAML Authors with DA in copyright headers (#5228) 2020-03-27 01:26:10 +01:00
daml-opts Serialize package metadata and stop parsing packages twice (#5607) 2020-04-17 17:05:32 +02:00
daml-package-config Refactor mkConfFile (#5546) 2020-04-15 12:18:31 +02:00
daml-preprocessor Turn warnings for module name/record name mismatches into errors (#5266) 2020-03-30 10:21:53 +00:00
daml-prim-src Split standard library docs up one page per module. (#5636) 2020-04-22 13:23:46 +01:00
daml-rule-types Move GHC session to a Shake rule (#5517) 2020-04-09 17:11:40 +02:00
daml-stdlib-src fix splitOn when sep appears at end (#5872) 2020-05-07 15:01:12 +02:00
daml-visual Inline typeclass projections. (#5759) 2020-05-11 16:48:27 +00:00
exe replace DAML Authors with DA in copyright headers (#5228) 2020-03-27 01:26:10 +01:00
ide-debug-driver replace DAML Authors with DA in copyright headers (#5228) 2020-03-27 01:26:10 +01:00
lib/DA/Cli Clarify documentation around --project-root (#5832) 2020-05-05 11:10:51 +02:00
pkg-db replace DAML Authors with DA in copyright headers (#5228) 2020-03-27 01:26:10 +01:00
stable-packages New command: daml ledger fetch-dar (#5225) 2020-03-27 18:04:14 +00:00
tests fix splitOn when sep appears at end (#5872) 2020-05-07 15:01:12 +02:00
base-hoogle-template.txt daml-docs: Generate Hoogle database with anchor table from generating docs. (#5704) 2020-04-23 16:12:48 +01:00
base-md-template.md damldocs: Switch to mustache templates. (#2373) 2019-08-02 13:52:38 +00:00
base-rst-index-template.rst Split standard library docs up one page per module. (#5636) 2020-04-22 13:23:46 +01:00
base-rst-template.rst Split standard library docs up one page per module. (#5636) 2020-04-22 13:23:46 +01:00
BUILD.bazel Fix ./fmt.sh check (#5718) 2020-04-24 12:04:14 +00:00
README.md daml-docs: Generate Hoogle database with anchor table from generating docs. (#5704) 2020-04-23 16:12:48 +01:00
util.bzl Split up repl tests to make them faster (#5450) 2020-04-07 10:22:15 +02:00

Code layout

The following list is ordered topologicaly based on the dependency graph.

daml-preprocessor

daml-preprocessor contains the DAML preprocessor which runs our version of the record-dot-preprocessor and the preprocessor for generating Generic instances. The preprocessor also performs a few additional checks, e.g., that you do not import internal modules.

daml-opts

daml-opts contains two libraries: daml-opt-types and daml-opts.

daml-opt-types contains the Options type which controls the various flags affecting most damlc commands. Most of the options can be controlled via command line flags.

daml-opts contains the conversion from damlcs Options type to ghcides IdeOptions type. This is in a separate package to avoid making everything depend on daml-preprocessor.

daml-lf-conversion

daml-lf-conversion handles the conversion from GHCs Core to DAML-LF.

daml-ide-core

daml-ide-core is a wrapper around ghcide that adds DAML-specific rules such as rules for producing DAML-LF.

daml-doc

daml-doc contains our variant of haddock.

daml-ide

daml-ide contains the LSP layer of the IDE and wraps the corresponding LSP layer in ghcide and adds custom handlers such as those for scenario results.

daml-compiler

daml-compiler contains the implementation of a few top-level damlc commands, e.g., upgrade.

lib

lib is all of damlc but packaged as a library since that can be more convenient for tests.

exe

This is a tiny wrapper around lib to produce the damlc executable.

Developing

When working on the compiler:

da-ghcid //compiler/damlc/tests:integration-dev --reload=compiler/damlc/tests/daml-test-files --test=":main --pattern="
bazel run //compiler/damlc/tests:integration-dev -- --pattern=
bazel run damlc -- compile $PWD/MyDaml12File.daml

When working on the IDE via the test suite:

bazel run //compiler/damlc/tests:shake -- --pattern=
da-ghcid //compiler/damlc/tests:shake --test=":main --pattern="

The above commands do not execute scenarios. To do that, use a command like

bazel run damlc test $PWD/compiler/damlc/tests/bond-trading/Test.daml

At the moment, commands relying on ghc-pkg, e.g., damlc build do not work via bazel run. For testing, install the SDK with daml-sdk-head and then use daml-head damlc.

Updating daml-doc's golden tests

Run

bazel run //compiler/damlc/tests:daml-doc -- --accept

to accept the current documentation as new golden files.

Documentation

Standard library docs are exposed under the bazel rules which you can build with:

bazel build //compiler/damlc:daml-base-docs

This creates a tarball containing RST (ReStructured Text) docs, and a hoogle database.

DAML Packages and Database

A DAML project is compiled to a DAML package and can be distributed as a DAML archive (DAR). This is essentially a zip archive containing the DAML source code of the library together with the compiled .dalf file. The damlc package loading mechanism is based on GHC's package database and uses the same .conf file format. GHC's package database is documented at https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/packages.html.

Loading packages

damlc loads packages from a package database given by the option --package-db. It creates a map from package name to DAML-LF file from all the contained .dalf files in this directory and links the created DAML-LF against these packages. It uses the .hi interface files created upon installation of the packages for type checking.

Base packages

Currently a package database is provided together with the damlc Bazel rule and bazel run damlc loads this database by default. This package database is also bundled in the damlc-dist.tar.gz tarball included in the SDK.

Building the package database

The package database that comes with damlc and the above archives can be build with

bazel build //compiler/damlc/pkg-db:pkg-db