2017-04-19 12:16:50 +03:00
|
|
|
# Duet
|
2017-04-18 12:01:37 +03:00
|
|
|
|
2019-11-15 18:59:20 +03:00
|
|
|
A tiny language, a subset of Haskell (with type classes) aimed at aiding teachers teach Haskell
|
2017-05-08 12:45:59 +03:00
|
|
|
|
2019-11-15 18:24:28 +03:00
|
|
|
## Usage
|
2018-05-24 14:32:08 +03:00
|
|
|
|
2019-11-15 18:24:28 +03:00
|
|
|
This comes as a library and as a program capable of running Duet programs.
|
2018-05-24 14:32:08 +03:00
|
|
|
|
2017-05-08 12:48:18 +03:00
|
|
|
```
|
2019-11-15 18:24:28 +03:00
|
|
|
$ duet --help
|
|
|
|
Duet interpreter
|
2017-05-08 12:52:20 +03:00
|
|
|
|
2019-11-15 18:24:28 +03:00
|
|
|
Usage: duet [--version] [--help] COMMAND
|
|
|
|
This is the interpreter for the Duet mini-Haskell educational language
|
2017-05-08 12:52:20 +03:00
|
|
|
|
2019-11-15 18:24:28 +03:00
|
|
|
Available options:
|
|
|
|
--version Show version
|
|
|
|
--help Show this help text
|
2017-05-08 12:52:20 +03:00
|
|
|
|
2019-11-15 18:24:28 +03:00
|
|
|
Available commands:
|
|
|
|
run Run the given program source
|
2017-05-08 12:52:20 +03:00
|
|
|
```
|
2019-11-15 18:32:21 +03:00
|
|
|
|
2019-11-15 18:55:03 +03:00
|
|
|
## Run
|
|
|
|
|
|
|
|
The help for this command:
|
|
|
|
|
|
|
|
```
|
|
|
|
Usage: duet run FILEPATH [--main NAME] [--concise] [-n|--steps steps]
|
|
|
|
Run the given program source
|
|
|
|
|
|
|
|
Available options:
|
|
|
|
-h,--help Show this help text
|
|
|
|
FILEPATH The .hs file to interpret
|
|
|
|
--main NAME The main value to run
|
|
|
|
--concise Concise view
|
2019-11-15 18:56:16 +03:00
|
|
|
-n,--steps steps Maximum number of steps to run (default: 100)
|
2019-11-15 18:55:03 +03:00
|
|
|
```
|
|
|
|
|
|
|
|
Running code in Duet literally performs one substitution step at
|
|
|
|
time. For example, evaluating `(\x -> x + 5) (2 * 3)`, we get:
|
|
|
|
|
|
|
|
``` haskell
|
|
|
|
[1]
|
|
|
|
(\x -> x + 5) (2 * 3)
|
|
|
|
[2]
|
|
|
|
(2 * 3) + 5
|
|
|
|
[3]
|
|
|
|
6 + 5
|
|
|
|
[4]
|
|
|
|
11
|
|
|
|
```
|
|
|
|
|
|
|
|
Note that this demonstrates basic argument application and non-strictness.
|
|
|
|
|
2019-11-15 18:47:33 +03:00
|
|
|
Example `integers.hs`:
|
2019-11-15 18:32:21 +03:00
|
|
|
|
|
|
|
```haskell
|
|
|
|
main = 3 + ((2 + -3) - 3)
|
|
|
|
```
|
|
|
|
|
|
|
|
Output for this program:
|
|
|
|
|
|
|
|
``` haskell
|
|
|
|
$ duet run examples/integers.hs
|
|
|
|
[1]
|
|
|
|
3 + ((2 + -3) - 3)
|
|
|
|
[2]
|
|
|
|
3 + (-1 - 3)
|
|
|
|
[3]
|
|
|
|
3 + -4
|
|
|
|
[4]
|
|
|
|
-1
|
|
|
|
```
|
2019-11-15 18:44:50 +03:00
|
|
|
|
|
|
|
## Differences from Haskell
|
|
|
|
|
|
|
|
See also the next section for a complete example using all the
|
|
|
|
available syntax.
|
|
|
|
|
2019-11-15 18:57:46 +03:00
|
|
|
* Duet is non-strict, but is not lazy. There is no sharing and no
|
|
|
|
thunks.
|
|
|
|
* No `module` or `import` module system whatsoever.
|
2019-11-15 18:44:50 +03:00
|
|
|
* No `let` syntax, no parameters in definitions e.g. `f x = ..` you
|
2019-11-15 18:49:26 +03:00
|
|
|
must use a lambda. Representing `let` in the stepper presents a
|
|
|
|
design challenge not currently met.
|
2019-11-15 18:44:50 +03:00
|
|
|
* Kinds `*` are written `Type`: e.g. `class Functor (f :: Type -> Type)`.
|
|
|
|
* Kind inference is not implemented, so if you want a kind other than
|
|
|
|
`Type` (aka `*` in Haskell), you have to put a kind signature on the
|
|
|
|
type variable.
|
|
|
|
* Indentation is stricter, a case's alts must be at a column larger
|
|
|
|
than the `case`.
|
|
|
|
* Infix operators are stricter: an infix operator must have spaces
|
|
|
|
around it. You **cannot** have more than one operator without
|
|
|
|
parentheses, therefore operator precedence does not come into play
|
2019-11-15 18:51:53 +03:00
|
|
|
in Duet (this is intentional). This also permits you to write `-5`
|
|
|
|
without worrying about where it rests.
|
2019-11-15 18:44:50 +03:00
|
|
|
* Superclasses are not supported.
|
|
|
|
* Operator definitions are not supported.
|
|
|
|
* There is only `Integer` and `Rational` number types: they are
|
|
|
|
written as `1` or `1.0`.
|
2019-11-15 18:47:07 +03:00
|
|
|
* Any `_` or `_foo` means "hole" and the interpreter does not touch
|
|
|
|
them, it continues performing rewrites without caring. This is good
|
|
|
|
for teaching.
|
2019-11-15 18:44:50 +03:00
|
|
|
* There is no standard `Prelude`. The only defined base types are:
|
|
|
|
* String
|
|
|
|
* Char
|
|
|
|
* Integer
|
|
|
|
* Rational
|
|
|
|
* Bool
|
|
|
|
* You don't need a `Show` instance to inspect values; the interpreter
|
2019-11-15 18:49:26 +03:00
|
|
|
shows them as they are, including lambdas.
|
2019-11-15 18:44:50 +03:00
|
|
|
|
2019-11-15 18:50:55 +03:00
|
|
|
View `examples/syntax-buffet.hs` for an example featuring all the
|
|
|
|
syntax supported in Duet.
|