gelisam / klister

an implementation of stuck macros
BSD 3-Clause "New" or "Revised" License
134 stars 11 forks source link

Klister

Klister [TyDe 2020, video] is a programming language, a research prototype which combines features from Racket, ML, and a strict Haskell into a single language. It is named after its most distinguishing feature, "stuck macros" [Compose NYC 2019_], as "Klister" is Danish for "adhesive".

.. _TyDe 2020: http://davidchristiansen.dk/pubs/tyde2020-predictable-macros-abstract.pdf .. _video: https://www.youtube.com/watch?v=FyeWwYfqTHo .. _Compose NYC 2019: https://www.youtube.com/watch?v=nUvKoG_V_U0

::

lang "prelude.kl"

-- do notation is not builtin syntax, it's implemented as a library! (import "monad.kl")

-- An effectful action whose inferred type is (-> String (IO Unit)) (defun putStrLn (str) (write stdout (string-append str "\n")))

-- "run" is like main, except you can have more than one. (run -- Klister doesn't have type classes yet, so "do" needs an explicit -- dictionary argument. (do io-monad (putStrLn "hello") (putStrLn "world")))

You can run the above program using either stack or cabal::

$ cabal run klister -- run examples/hello.kl
hello
world

Features

Features we borrow from Racket:

.. _Custom syntax: examples/lambda-case.kl .. _easy-to-override hygiene: examples/anaphoric-if.kl .. _Custom languages: examples/rpn.kl .. _Syntax objects: TODO: link to a short example which explains that in Racket, syntax objects are introduced via #'(...), whereas in Klister they are introduced via '(...). Also explain that Klister does not have unannotated s-expressions. And the relationship between Syntax and Syntax-Contents. .. _module system: TODO: write a short example demonstrating macros which generate macros. Maybe define-syntax-rules.kl? Let's also take the opportunity to document the meta, import, and export primitives.

Features we borrow from ML:

.. _algebraic datatypes: TODO: write a small example defining and matching on an algebraic type. Perhaps Either? Let's also take the opportunity to demonstrate polymorphic functions on Either.

Features we borrow from Haskell:

.. _monads: TODO: link to monad.kl's Monad definition, and add a comment there highlighting the inferred type, especially the higher-kinded type variable.

Features which make Klister special (but not necessarily unique; see the bibliography_ for languages with similar features):

.. _bibliography: bibliography.rst .. _Type-providing macros: TODO: write a small example demonstrating this feature. .. _Type-aware macros: TODO: write a small example demonstrating this feature. .. _Stuck macros: TODO: write a small example demonstrating this feature. Maybe the traverse-traverse-id example from Compose NYC 2019? .. _Problem-aware macros: TODO: write a small example demonstrating all the different problems one can write a macro for.

Cool things which can be built using the above features:

.. _Custom type-driven code generation: TODO: write a small example demonstrating the feature. Perhaps the traverse-traverse-id example again? .. _custom type systems: TODO: write an example #lang in which functions are not curried, writing copious comments. .. _custom implicit terms: TODO: improve the comments in the implicit-conversion example, then link to it.

While we think Klister demonstrates some neat ideas, there are some limitations which make Klister an impractical choice for most real-life projects. If you want to help make Klister a more practical language, please reach out_!

.. _reach out: https://github.com/gelisam/klister/issues/new

Here are the most prominent Racket features which are missing from Klister:

.. _local-expand: https://github.com/gelisam/klister/issues/144#issuecomment-1133964551 .. _Syntax parameters: https://github.com/gelisam/klister/issues/105

Here are the most prominent Haskell features which are missing from Klister:

.. _Type classes: https://github.com/gelisam/klister/issues/167 .. _Type annotations containing foralls: https://github.com/gelisam/klister/issues/60

Here are the most prominent features which Racket and Haskell both have but which are missing from Klister:

.. _examples: https://github.com/gelisam/klister/tree/main/examples .. _FFI: https://github.com/gelisam/klister/issues/165 .. _Expanding modules separately: https://github.com/gelisam/klister/issues/118

Guide and Reference

The Klister Guide consists of the various commented examples linked from the above feature list, plus the extra information in the sub-sections below.

The Klister Reference covers every identifier in the "prelude.kl" language, but doesn't currently say much about each. It consists of a list of examples showing how to use the macros, and a list of type signatures documenting how to use the values and functions.

.. _list of examples: examples/primitives-documentation.kl .. _list of type signatures: examples/primitives-documentation.golden

Imports



The ``import`` form will search for modules in the same directory as the
importing module, and in directories listed in the ``KLISTERPATH`` environment
variable, a ``:``-separated list of directories.

Setting ``KLISTERPATH`` is needed for all tests to pass, as some rely on modules
from the ``examples`` directory;

::

  $ cabal test

  Test suite klister-tests: RUNNING...
  All tests
    Golden tests
      keyword-used-incorrectly:                          FAIL
        ...
        +Module not found: keyword-test.kl
        +Searched in directory at /.../examples/failing-examples
        +And on $KLISTERPATH:
        ...
      wrong-keyword:                                     FAIL
        ...
        +Module not found: keyword-test.kl
        +Searched in directory at /.../examples/failing-examples
        +And on $KLISTERPATH:
        ...
      bound-vs-free:                                     FAIL
        ...
        +Module not found: do.kl
        +Searched in directory at /.../examples/failing-examples
        +And on $KLISTERPATH:
        ...

  3 out of 132 tests failed
  Test suite klister-tests: FAIL

::

  $ KLISTERPATH=examples cabal test
  ...
  Test suite klister-tests: PASS