Skip to content

dancewithheart/agda2scala

Repository files navigation

CI

An experimental Agda backend that generates Scala 2 or Scala 3 source files.

Currently supported:

  • ✅ Sum types / ADTs (also polymorphic ADTs like Maybe[A], List[A])
  • ✅ Product types (records) (with polymorphic parameters)
  • ✅ Simple and polymorphic functions (e.g. id[A])
  • ✅ Literals: Int/Nat, Bool, String (subset)
  • 🚧 Pattern matching (match / cases) – planned
  • 🚧 Mapping Agda stdlib names to Scala stdlib (Nat, List, pairs) – planned / partial

Basic usage:

cabal run -- agda2scala ./examples/adts.agda

compile following Agda code:

module examples.adts where

-- sum types
data Rgb : Set where
  Red : Rgb
  Green : Rgb
  Blue : Rgb
{-# COMPILE AGDA2SCALA Rgb #-}

-- polymorphic ADT

data List (X : Set) : Set where
  []   : List X
  _::_ : X -> List X -> List X
{-# COMPILE AGDA2SCALA List #-}

-- literals String

hello : String
hello = "Hello World!"
{-# COMPILE AGDA2SCALA hello #-}

into Scala code:

package examples

object adts:
  enum Rgb:
    case Red
    case Green
    case Blue

  enum List[X]:
    case Nil extends List[Nothing]
    case Cons[X](x0: X, x1: List[X]) extends List[X]

  def hello(): String = "Hello World!"

More Agda examples

Identifier mapping

Agda constructor names are not always valid Scala identifiers (e.g. []). We apply a small mapping table for common constructors and then sanitize the result:

  • []Nil
  • _∷_ / _::_ / _cons_Cons
  • _,_Pair

See Agda.Compiler.Scala.NamePolicy.

Working with source code

  • continuous compilation loop using entr
find -name '*.hs' | entr cabal test all

or using ghcid

ghcid
  • Build
cabal build all
  • Run tests
cabal test all
cabal test agda2scala-test
cabal test agda2scala-hedgehog
  • Simple way to run Scala backend
cabal run -- agda2scala --help
cabal run -- agda2scala ./examples/adts.agda
  • Generate Scala2 output
cabal run -- agda2scala --compile --no-main --out-dir=scala2/src/main/scala ./examples/adts.agda
  • Generate Scala3 (dotty) output
cabal run -- agda2scala --compile --no-main --scala-dialect=Scala3 --out-dir=scala3/src/main/scala ./examples/adts.agda
cabal run -- agda2scala --help
cabal run -- agda2scala ./examples/adts.agda
cabal run -- agda2scala --compile --no-main --out-dir=scala2/src/main/scala ./examples/adts.agda
  • format code
fourmolu -i $(find src app test -name '*.hs')
cabal-fmt -i agda2scala.cabal
hlint src app test

end-to-end tests

There are Scala 3 and Scala 2 projects for code generated from Agda examples

They have unit tests, that use code generated from examples.

                agda2scala                
                (generate)                     sbt test
Agda examples ==============> src/main/scala <============ src/test/scala

checks:
* compile Agda examples
* run Scala unit tests that calls Scala code

Those tests are run on CI - Github Actions

Generate Scala 2 code from Agda examples and running tests:

cabal run -- agda2scala --compile --no-main --out-dir=scala2/src/main/scala ./examples/adts.agda
cd scala2
sbt ~test

generate Scala 3 code:

cabal run -- agda2scala --compile --no-main --scala-dialect=Scala3 --out-dir=scala3/src/main/scala ./examples/adts.agda
cd scala3
sbt ~test

Resources

About

Scala 2 and Scala 3 backend for Agda

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors