1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-01 00:04:58 +03:00
Commit Graph

87 Commits

Author SHA1 Message Date
Łukasz Czajka
fe90da58ed
Error for an instance subsumed by other instances (#2375)
* Closes #2372
2023-09-21 11:12:49 +01:00
Łukasz Czajka
c5d8641142
Error on local instances (#2376)
* Closes #2374

---------

Co-authored-by: Paul Cadman <git@paulcadman.dev>
2023-09-21 10:34:28 +01:00
Jan Mas Rovira
8daca2ba0a
New fixity/iterator syntax (#2332)
- Closes #2330
- Closes #2329 

This pr implements the syntax changes described in #2330. It drops
support for the old yaml-based syntax.
Some valid examples:
```
syntax iterator for {init := 1; range := 1};

syntax fixity cons := binary {assoc := right};
syntax fixity cmp := binary;
syntax fixity cmp := binary {}; -- debatable whether we want to accept empty {} or not. I think we should
```
# Future work
This pr creates an asymmetry between iterators and operators
definitions. Iterators definition do not require a constructor. We could
add it to make it homogeneous, but it looks a bit redundant:
```
syntax iterator for := mkIterator {init := 1; range := 1};
```

We could consider merging iterator and fixity declarations with this
alternative syntax.
```
syntax XXX for := iterator {init := 1; range := 1};

syntax XXX cons := binary {assoc := right};
```
where `XXX` is a common keyword. Suggestion by @lukaszcz XXX = declare

---------

Co-authored-by: Łukasz Czajka <62751+lukaszcz@users.noreply.github.com>
Co-authored-by: Lukasz Czajka <lukasz@heliax.dev>
2023-09-14 10:57:38 +02:00
Paul Cadman
327cfaa0f6
Remove duplicated implicit pattern check from scoper (#2357)
This PR removes the CaseBranchImplicit error from the scoper. This error
is already handled in the arity/typechecker with a good error message:

 The arity checker error message for

```
   case b of {
      | {{true}} := false
```
is 

```
Expected an explicit pattern but found an implicit instance pattern: {{true}}
```

* Closes https://github.com/anoma/juvix/issues/2356
2023-09-13 12:16:05 +02:00
Jan Mas Rovira
73e2cf0fa8
Small refactor for traits (#2345)
This pr simplifies parsing by removing `FunctionParameterUnnamed`. It
also removes ghost wildcards introduced during parsing.

It also introduces an error for double braced atoms `{{x}}` that are not
on the left of an arrow `->`
2023-09-08 17:22:21 +02:00
Łukasz Czajka
08f123fa3d
Traits (#2320)
* Closes #1646 

Implements a basic trait framework. A simple instance search mechanism
is included which fails if there is more than one matching instance at
any step.

Example usage:
```
import Stdlib.Prelude open hiding {Show; mkShow; show};

trait
type Show A :=
  mkShow {
    show : A → String
  };

instance
showStringI : Show String := mkShow (show := id);

instance
showBoolI : Show Bool := mkShow (show := λ{x := if x "true" "false"});

instance
showNatI : Show Nat := mkShow (show := natToString);

showList {A} : {{Show A}} → List A → String
  | nil := "nil"
  | (h :: t) := Show.show h ++str " :: " ++str showList t;

instance
showListI {A} {{Show A}} : Show (List A) := mkShow (show := showList);

showMaybe {A} {{Show A}} : Maybe A → String
  | (just x) := "just (" ++str Show.show x ++str ")"
  | nothing := "nothing";

instance
showMaybeI {A} {{Show A}} : Show (Maybe A) := mkShow (show := showMaybe);

main : IO :=
  printStringLn (Show.show true) >>
  printStringLn (Show.show false) >>
  printStringLn (Show.show 3) >>
  printStringLn (Show.show [true; false]) >>
  printStringLn (Show.show [1; 2; 3]) >>
  printStringLn (Show.show [1; 2]) >>
  printStringLn (Show.show [true; false]) >>
  printStringLn (Show.show [just true; nothing; just false]) >>
  printStringLn (Show.show [just [1]; nothing; just [2; 3]]) >>
  printStringLn (Show.show "abba") >>
  printStringLn (Show.show ["a"; "b"; "c"; "d"]);
```

It is possible to manually provide an instance and to match on implicit
instances:
```
f {A} : {{Show A}} -> A -> String
  | {{mkShow s}} x -> s x;

f' {A} : {{Show A}} → A → String
  | {{M}} x := Show.show {{M}} x;
```

The trait parameters in instance types are checked to be structurally
decreasing to avoid looping in the instance search. So the following is
rejected:
```
type Box A := box A;

trait
type T A := mkT { pp : A → A };

instance
boxT {A} : {{T (Box A)}} → T (Box A) := mkT (λ{x := x});
```
We check whether each parameter is a strict subterm of some trait
parameter in the target. This ordering is included in the finite
multiset extension of the subterm ordering, hence terminating.
2023-09-08 12:16:43 +02:00
Jan Mas Rovira
34719bbc4d
Report termination errors after typechecking (#2318)
- Closes #2293.
- Closes #2319 

I've added an effect for termination. It keeps track of which functions
failed the termination checker, which is run just after translating to
Internal. During typechecking, non-terminating functions are not
normalized. After typechecking, if there is at least one function which
failed the termination checker, an error is reported.
Additionally, we now properly check for termination of functions defined
in a let expression in the repl.
2023-08-30 16:38:59 +02:00
Jan Mas Rovira
ef16b45ca6
Aliasing (#2301)
- Closes #2188.

This pr introduces a new syntactical statement for defining aliases:
```
syntax alias newName := oldName;
```
where `oldName` can be any name in the expression namespace. Fixity and
module aliases are not supported at the moment.

- The `newName` does not inherit the fixity of `oldName`. We have agreed
that the goal is to inherit the fixity of `oldName` except if `newName`
has a fixity statement, but this will be done in a separate pr as it
requires #2310.
2023-08-25 15:28:58 +02:00
Łukasz Czajka
2baad15a41 Remove old function syntax (#2305)
* Enables new function syntax in local let-declarations
* Closes #2251
2023-08-24 16:24:47 +02:00
Jan Mas Rovira
5194e7c2cd
Check that type functions are supported (#2306)
- Closes #2297 

When the type of function definition is of the form `... -> Type` it has
to have only one clause and no pattern matching.
2023-08-23 13:18:57 +02:00
Łukasz Czajka
8095e52c21
Check for incomparable precedences (#2289)
Give an error when there are two operators with incomparable precedences
instead of linearising the ordering arbitrarily.
2023-08-16 16:33:29 +02:00
Łukasz Czajka
b5a3b0088e
Error on duplicate keys in YAML (#2290)
* Closes #2285
2023-08-11 09:22:22 +01:00
Łukasz Czajka
eebe961321
User-friendly operator declaration syntax (#2270)
* Closes #1964 

Adds the possibility to define operator fixities. They live in a
separate namespace. Standard library defines a few in
`Stdlib.Data.Fixity`:
```

syntax fixity rapp {arity: binary, assoc: right};
syntax fixity lapp {arity: binary, assoc: left, same: rapp};
syntax fixity seq {arity: binary, assoc: left, above: [lapp]};

syntax fixity functor {arity: binary, assoc: right};

syntax fixity logical {arity: binary, assoc: right, above: [seq]};
syntax fixity comparison {arity: binary, assoc: none, above: [logical]};

syntax fixity pair {arity: binary, assoc: right};
syntax fixity cons {arity: binary, assoc: right, above: [pair]};

syntax fixity step {arity: binary, assoc: right};
syntax fixity range {arity: binary, assoc: right, above: [step]};

syntax fixity additive {arity: binary, assoc: left, above: [comparison, range, cons]};
syntax fixity multiplicative {arity: binary, assoc: left, above: [additive]};

syntax fixity composition {arity: binary, assoc: right, above: [multiplicative]};
```

The fixities are identifiers in a separate namespace (different from
symbol and module namespaces). They can be exported/imported and then
used in operator declarations:
```
import Stdlib.Data.Fixity open;

syntax operator && logical;
syntax operator || logical;
syntax operator + additive;
syntax operator * multiplicative;
```
2023-08-09 18:15:51 +02:00
Jan Mas Rovira
98b3621ae1
Record patterns (#2271)
- Closes #2269 

Example:
```
type Sum (A B : Type) :=
  | inj1 {
      fst : A;
      snd : B
    }
  | inj2 {
      fst : A;
      snd2 : B
    };

sumSwap {A B : Type} : Sum A B -> Sum B A
  | inj1@{fst; snd := y} := inj2 y fst
  | inj2@{snd2 := y; fst := fst} := inj1 y fst;
```
2023-08-08 16:01:20 +02:00
Jan Mas Rovira
f7382caeac
Record updates (#2263)
- Closes #1642.

This pr introduces syntax for convenient record updates.
Example:
```
type Triple (A B C : Type) :=
  | mkTriple {
      fst : A;
      snd : B;
      thd : C;
    };

main : Triple Nat Nat Nat;
main :=
  let
    p : Triple Nat Nat Nat := mkTriple 2 2 2;
    p' :
      Triple Nat Nat Nat :=
        p @Triple{
          fst := fst + 1;
          snd := snd * 3
        };
    f : Triple Nat Nat Nat -> Triple Nat Nat Nat := (@Triple{fst := fst * 10});
  in f p';
```
We write `@InductiveType{..}` to update the contents of a record. The
`@` is used for parsing. The `InductiveType` symbol indicates the type
of the record update. Inside the braces we have a list of `fieldName :=
newValue` items separated by semicolon. The `fieldName` is bound in
`newValue` with the old value of the field. Thus, we can write something
like `p @Triple{fst := fst + 1;}`.

Record updates `X@{..}` are parsed as postfix operators with higher
priority than application, so `f x y @X{q := 1}` is equivalent to `f x
(y @X{q := 1})`.

It is possible the use a record update with no argument by wrapping the
update in parentheses. See `f` in the above example.
2023-08-07 12:35:36 +02:00
Łukasz Czajka
22de9d0233
Disallow iterators with zero ranges (#2267)
* Closes #2265
2023-08-03 11:43:59 +02:00
Jan Mas Rovira
2d666fd82c
Named arguments (#2250)
- closes #1991 

This pr implements named arguments as described in #1991. It does not
yet implement optional arguments, which should be added in a later pr as
they are not required for record syntax.

# Syntax Overview

Named arguments are a convenient mehcanism to provide arguments, where
we give the arguments by name instead of by position. Anything with a
type signature can have named arguments, i.e. functions, types,
constructors and axioms.

For instance, if we have (note that named arguments can also appear on
the rhs of the `:`):
```
fun : {A B : Type} (f : A -> B) : (x : A) -> B := ... ;
```
With the traditional positional application, we would write
```
fun suc zero
```
With named arguments we can write the following:
1. `fun (f := suc) (x := zero)`.
2. We can change the order: `fun (x := zero) (f := suc)`.
3. We can group the arguments: `fun (x := zero; f := suc)`.
4. We can partially apply functions with named arguments: `fun (f :=
suc) zero`.
5. We can provide implicit arguments analogously (with braces): `fun {A
:= Nat; B := Nat} (f := suc; x := zero)`.
6. We can skip implicit arguments: `fun {B := Nat} (f := suc; x :=
zero)`.

What we cannot do:
1. Skip explicit arguments. E.g. `fun (x := zero)`.
2. Mix explicit and implicit arguments in the same group. E.g. `fun (A
:= Nat; f := suc)`
3. Provide explicit and implicit arguments in different order. E.g. `fun
(f := suc; x := zero) {A := Nat}`.
2023-07-18 10:32:34 +01:00
Jan Mas Rovira
9ad2d71001
Format juvix files using new function syntax (#2245) 2023-07-11 17:22:07 +02:00
Jan Mas Rovira
2c8a364143
New syntax for function definitions (#2243)
- Closes #2060
- Closes #2189


- This pr adds support for the syntax described in #2189. It does not
drop support for the old syntax.

It is possible to automatically translate juvix files to the new syntax
by using the formatter with the `--new-function-syntax` flag. E.g.

```
juvix format --in-place --new-function-syntax
```
# Syntax changes
Type signatures follow this pattern:
```
f (a1 : Expr) .. (an : Expr) : Expr
```
where each `ai` is a non-empty list of symbols. Braces are used instead
of parentheses when the argument is implicit.

Then, we have these variants:
1. Simple body. After the signature we have `:= Expr;`.
2. Clauses. The function signature is followed by a non-empty sequence
of clauses. Each clause has the form:
```
| atomPat .. atomPat := Expr
```
# Mutual recursion
Now identifiers **do not need to be defined before they are used**,
making it possible to define mutually recursive functions/types without
any special syntax.
There are some exceptions to this. We cannot forward reference a symbol
`f` in some statement `s` if between `s` and the definition of `f` there
is one of the following statements:
1. Local module
2. Import statement
3. Open statement

I think it should be possible to drop the restriction for local modules
and import statements
2023-07-10 19:57:55 +02:00
Łukasz Czajka
e9284b3ef6
Iterator syntax (#2126)
* Closes #1992 

A function identifier `fun` can be declared as an iterator with
```
syntax iterator fun;
```
For example:
```haskell
syntax iterator for;
for : {A B : Type} -> (A -> B -> A) -> A -> List B -> List A;
for f acc nil := acc;
for f acc (x :: xs) := for (f acc x) xs;
```
Iterator application syntax allows for a finite number of initializers
`acc := a` followed by a finite number of ranges `x in xs`. For example:
```
for (acc := 0) (x in lst) acc + x
```
The number of initializers plus the number of ranges must be non-zero.

An iterator application
```
fun (acc1 := a1; ..; accn := an) (x1 in b1; ..; xk in bk) body
```
gets desugared to
```
fun \{acc1 .. accn x1 .. xk := body} a1 .. an b1 .. bk
```
The `acc1`, ..., `accn`, `x1`, ..., `xk` can be patterns.

The desugaring works on a purely syntactic level. Without further
restrictions, it is not checked if the number of initializers/ranges
matches the type of the identifier. The restrictions on the number of
initializers/ranges can be specified in iterator declaration:
```
syntax iterator fun {init: n, range: k};
syntax iterator for {init: 1, range: 1};
syntax iterator map {init: 0, range: 1};
```
The attributes (`init`, `range`) in between braces are parsed as YAML to
avoid inventing and parsing a new attribute language. Both attributes
are optional.
2023-05-30 15:30:11 +02:00
Jonathan Cubides
2148d174f5
Add VampIR to the CI (#2096)
This PR:

- Makes `vamp-ir` available in the CI (pre-release 0.1.2)
- [Use a setup-wasmer action to install
`wasmer`](https://github.com/marketplace/actions/setup-wasmer)
- Fixes cache option value for `jaxxstorm/action-install-gh-release`'s
usages

Adds support for:

- #2103 


Related: 

- https://github.com/anoma/vamp-ir/issues/90

---------

Co-authored-by: Jan Mas Rovira <janmasrovira@gmail.com>
2023-05-22 19:49:36 +02:00
Łukasz Czajka
6bfe727a0e
Add syntax keyword (#2107)
* Closes #2007
2023-05-22 12:50:07 +02:00
Jan Mas Rovira
ab83749a86
Scope check symbols inside using {..} and hiding {..} (#2108)
- Closes #2089 

Now the symbols inside `using {..}` and `hiding {..}` are properly
scoped, which means that they will be properly colored and will have
goto information. If the referenced module does not contain a symbol in
the list, an error will be thrown.
2023-05-22 11:41:13 +02:00
Jonathan Cubides
e2f2d0a2f4
Fix Makefile target bugs for formatting and type Checking Juvix files (#2057)
This PR resolves a few bugs in the Makefile targets for formatting and
type checking Juvix files, which were preventing the capture of type
checking errors for our examples and bad formatting for all the Juvix
files in the repository. With this PR, our code should now be clean, and
we can expect every file to be properly formatted and type checked.

Changes made:

- [x] Updated `make format-juvix-files`
- [x] Updated `make check-format-juvix-files`
- [x] Formatted all Juvix files
- [x] Comment a fragment in `examples/milestone/Bank/Bank.juvix`

In the future, we will drastically simplify the Makefile once we improve
the `format` and the `type check` command for example posted here:

- #2066 
- #2087 

Related:

- #2063 
- #2040 (due to some typechecking errors we're not capturing before)
- #2105
- https://github.com/anoma/juvix/issues/2059
2023-05-19 17:33:56 +02:00
Jan Mas Rovira
d135f74cf8
Add dangling judoc error (#2099) 2023-05-16 15:39:43 +02:00
Łukasz Czajka
c31e373c88
Add: pragma support (#1997)
* Closes #1965 
* Implements the `unroll` pragma to control the unrolling depth on a
per-function basis.
* Implements parsing of the `inline` pragma.

---------

Co-authored-by: janmasrovira <janmasrovira@gmail.com>
2023-04-26 15:26:13 +02:00
Paul Cadman
f61e612c54
Fix dependencies suggestion in missing module error (#2024)
If an import statement to a missing module occurs when parsing in a
project with no dependencies the error message has the following form:

```
The module Foo does not exist.
It should be in /Users/paul/heliax/juvix-2023/tests/negative/NoDependencies/Foo.juvix
or in one of the dependencies:
```

This PR changes this error message to the `or in one of the
dependencies:` line is omitted from the error message when there are no
dependencies in the project.

This commit also adds a negative parse error test for missing module.
2023-04-22 18:15:38 +01:00
Paul Cadman
ea09ec3068
Add builtin integer type to the surface language (#1948)
This PR adds a builtin integer type to the surface language that is
compiled to the backend integer type.

## Inductive definition

The `Int` type is defined in the standard library as:

```
builtin int
type Int :=
  | --- ofNat n represents the integer n
    ofNat : Nat -> Int
  | --- negSuc n represents the integer -(n + 1)
    negSuc : Nat -> Int;
```

## New builtin functions defined in the standard library

```
intToString : Int -> String;
+ : Int -> Int -> Int;
neg : Int -> Int;
* : Int -> Int -> Int;
- : Int -> Int -> Int;
div : Int -> Int -> Int;
mod : Int -> Int -> Int;

== : Int -> Int -> Bool;
<= : Int -> Int -> Bool;
< : Int -> Int -> Bool;
```

Additional builtins required in the definition of the other builtins:

```
negNat : Nat -> Int;
intSubNat : Nat -> Nat -> Int;
nonNeg : Int -> Bool;
```

## REPL types of literals

In the REPL, non-negative integer literals have the inferred type `Nat`,
negative integer literals have the inferred type `Int`.

```
Stdlib.Prelude> :t 1
Nat
Stdlib.Prelude> :t -1
Int
:t let x : Int := 1 in x
Int
```

## The standard library Prelude

The definitions of `*`, `+`, `div` and `mod` are not exported from the
standard library prelude as these would conflict with the definitions
from `Stdlib.Data.Nat`.

Stdlib.Prelude
```
open import Stdlib.Data.Int hiding {+;*;div;mod} public;
```

* Closes https://github.com/anoma/juvix/issues/1679
* Closes https://github.com/anoma/juvix/issues/1984

---------

Co-authored-by: Lukasz Czajka <lukasz@heliax.dev>
2023-04-13 08:16:49 +01:00
Łukasz Czajka
1eadbc4f81
Remove the old C backend (#1862)
* Depends on PR #1832 
* Closes #1799 
* Removes Backend.C.Translation.FromInternal
* Removes `foreign` and `compile` blocks
* Removes unused test files
* Removes the old C runtime
* Removes other dead code
2023-03-14 17:22:32 +01:00
janmasrovira
098c256da8
Allow shadowing local variables with let function definitions (#1847)
Co-authored-by: Paul Cadman <git@paulcadman.dev>
2023-02-22 10:26:54 +01:00
Łukasz Czajka
c1d85c451e
Give proper errors for incorrect application of lazy builtins (#1830)
* Closes #1828
2023-02-10 19:21:46 +01:00
janmasrovira
3c33916034
Remove braces from let expressions (#1790) 2023-02-01 19:22:43 +01:00
janmasrovira
38622b28d1
Allow type signatures to have a body (#1785)
- Closes #1637.

A function type signature is now allowed to have a body. This is valid
for both top level and let definitions.
```
not : Bool -> Bool := λ {
 | true := false
 | false := true
};
```
2023-01-31 08:46:53 +00:00
janmasrovira
0193a33d4c
Fix inference loop (#1726) 2023-01-17 13:28:38 +01:00
janmasrovira
f7205915a5
Typecheck let expressions (#1712) 2023-01-17 09:41:07 +01:00
janmasrovira
3b452e7d76
Fix #1693 (#1708) 2023-01-09 18:56:28 +01:00
Jonathan Cubides
3fbc9c7c55
Change syntax for ind. data types and forbid the empty data type (#1684)
Closes #1644 #1635
2023-01-03 13:49:04 +01:00
Murray
5cea26ac7f
Improve As-Pattern parsing (#1603)
* Allow naming nullary constructors without using parentheses
* Negative test cases
2022-11-03 10:02:22 +01:00
janmasrovira
803d2008d9
remove ≔ from the language and replace it by := (#1563)
* remove ≔ from the language and replace it by :=

* revert accidental changes in juvix input mode

* update stdlib submodule

* rename ℕ by Nat in the tests and examples

* fix shell tests
2022-09-30 10:55:32 +10:00
janmasrovira
9e0bbf7351
Replace -> by := in lambda syntax (#1533) 2022-09-14 14:31:28 +02:00
janmasrovira
ccce5a4a31
Disallow tab characters as spaces (#1523) 2022-09-07 13:59:41 +02:00
Jonathan Cubides
01a44e436d
Refactor (#1420)
* Big refactor in process

* remove unnecessary functions from the prelude

* remove comments
2022-08-03 13:20:40 +02:00
janmasrovira
39a300eaa2
Support type aliases (#1404)
* add a simple positive test

* add lambda expressions to microjuvix language

* add basic normalization of type aliases

* fix test name

* normalize only functions on types

* normalize when matching

* fix type of inductive names

* improve detection of normalizing functions

* remove obsolete comment

* match constructor return type

* add test for issue 1333

* fix existing tests

* use lambda case

* add strong normalization

* Add test cases for type aliases and another fix

Co-authored-by: Jonathan Cubides <jonathan.cubides@uib.no>
2022-07-25 12:30:18 +02:00
Jonathan Cubides
423ccec70a
Add positivity check for inductive types (#1393)
* w.i.p

* Added strict positivity condition for datatypes w.i.p

* Add negative test for str.postivity check

* Add some revisions

* the branch is back to feet

* w.i.p add lots of traces to check alg.

* Add more test and revisions

* Add negative and positive test to the new flag and the keyword

* Fix shell tests.

* Make pre-commit happy

* Fix rebase conflicts

* Make pre-commit happy

* Add shell test, rename keyword, fix error msg

* Revert change

* Necessary changes

* Remove wrong unless

* Move the positivity checker to its own folder

* Add missing juvix.yaml

* Add a negative test thanks to jan

* make some style changes

* Make ormolu happy

* Remove unnecessary instance of Show

Co-authored-by: Jan Mas Rovira <janmasrovira@gmail.com>
2022-07-23 09:27:12 +02:00
janmasrovira
e939f8fe9f
Keep qualified names (#1392)
* keep qualified names

* add comment

* add pretty field to Abstract Name

* add test

* Add shell test

* Add another test

* fix shell test

Co-authored-by: Jonathan Cubides <jonathan.cubides@uib.no>
2022-07-21 15:54:08 +02:00
Łukasz Czajka
e19fbf489f
Implement some error messages (#1396) (#1400)
* Implement error message for double braces
* Implement error message for implicit pattern on the left of an application
* Implement error message for constructor expected on the left of an application 

Co-authored-by: Jan Mas Rovira <janmasrovira@gmail.com>
2022-07-20 16:24:03 +02:00
janmasrovira
a8f4acaca2
Curly braces are allowed nested in patterns (#1380) 2022-07-20 10:33:52 +02:00
janmasrovira
32059965a9
Type checking fails when the type of a pattern is not given by the signature (#1378)
* infer hole in type from pattern

* refactor

* fix error message

* format

* fix matching of identifiers

* improve error message
2022-07-15 17:57:04 +02:00
Jonathan Cubides
d11605ab1e
Check all the type parameter names are different when declaring an inductive type (#1377)
* Fix #1334

* Rename error type
2022-07-15 10:58:49 +02:00
Jonathan Cubides
3b3ea45da9
Rename MiniJuvix to Juvix (#259)
* Renaming MiniJuvix to Juvix

* Make Ormolu happy

* Make Hlint happy

* Remove redundant imports

* Fix shell tests and add target ci to our Makefile

* Make pre-commit happy
2022-07-08 13:59:45 +02:00