1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-14 08:27:03 +03:00
Commit Graph

1330 Commits

Author SHA1 Message Date
Ł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
Paul Cadman
7b000eba0c
Fixes behaviour of default stdlib when internal-build-flag is set (#2283)
The mechanism for using `--internal-build-flag` to set the build
directory for the default stdlib location already existed, it was just
unused (Nothing always passed in, instead of the entry point):


11ebc4acde/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/PathResolver.hs (L128)

This PR fixes that issue, adds some smoke tests to check the behaviour
of the stdlib dependency.

* Closes https://github.com/anoma/juvix/issues/2273

The issue with what to do with relative stdlib dependency paths when
`--internal-build-flag` is set remains open:
https://github.com/anoma/juvix/issues/2274
2023-08-09 16:12:44 +01:00
Paul Cadman
e0aadef298
Prettyprint aggregate ADT constructor types with parentheses (#2284)
This PR fixes an issue with formatting ADT definitions.

Previously the pretty printer would remove required parentheses from
aggregate constructor arguments: `type t (A : Type) := c A (t A) ` ->
`type t (A : Type) := c A t A`.

We now handle this in the same way as patterns.

* https://github.com/anoma/juvix/issues/2277
2023-08-09 09:48:58 +01:00
Łukasz Czajka
9718433a89
Enable builtin list syntax in the standard library (#2282) 2023-08-08 17:33:43 +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
Paul Cadman
18b664aa53
Fix benchmark wasmer command (#2268)
The benchmark run has been failing since the latest release of wasmer.


https://github.com/anoma/juvix-nightly-builds/actions/runs/5746121923/job/15575622923

wasmer no longer supports the --disable-cache option and there's no
equivalent that I can find in the new CLI.
2023-08-03 13:44:36 +01:00
Łukasz Czajka
22de9d0233
Disallow iterators with zero ranges (#2267)
* Closes #2265
2023-08-03 11:43:59 +02:00
Jan Mas Rovira
f38123c550
Adt syntax (#2262)
- merge #2260  first

Allows constructors to be defined using Haskell-like Adt syntax.
E.g.
```
module Adt;

type Bool :=
  | true
  | false;

type Pair (A B : Type) :=
  | mkPair A B;

type Nat :=
  | zero
  | suc Nat;
```

---------

Co-authored-by: Paul Cadman <git@paulcadman.dev>
2023-08-01 13:39:43 +01:00
Jan Mas Rovira
4a6a7e6540
Add field projections for records (#2260)
- Closes #2258 

# Overview
When we define a type with a single constructor and one ore more fields,
a local module is generated with the same name as the inductive type.
This module contains a projection for every field. Projections can be
used as any other function.

E.g. If we have
```
type Pair (A B : Type) := mkPair {
 fst : A;
 snd : B;
};
```
Then we generate
```
module Pair;
 fst {A B : Type} : Pair A B -> A
  | (mkPair a b) := a;

 snd : {A B : Type} : Pair A B -> B
  | (mkPair a b) := b;
end;
```
2023-08-01 09:46:22 +01:00
Łukasz Czajka
3c5cc744ec
Don't print pragmas in documentation (#2266)
* Fixes #2187
2023-07-31 14:33:05 +02:00
Łukasz Czajka
70dea79181
Minor refactor and script update (#2261)
* Updates the `cntlines.sh` script to take into account the removal of
Abstract.
* Moves the VampIR runtime to `runtime/src/vampir`.
2023-07-27 17:57:20 +02:00
Jan Mas Rovira
65b000999d
Separate modules namespace (#2257) 2023-07-26 09:59:50 +02:00
Jonathan Cubides
d27da6f17c
Bump version to v0.4.2 🎉 (#2259)
This PR updates:

- package version 
- smoke test 
- changelog

---------

Co-authored-by: Paul Cadman <git@paulcadman.dev>
2023-07-25 10:35:26 +02:00
Jan Mas Rovira
e79159b21e
Add record declaration syntax (#2254)
- Closes #1641 

This pr adds the option to declare constructors with fields. E.g.
```
type Pair (A B : Type) :=
  | mkPair {
      fst : A;
      snd : B
    };
```
Which is desugared to
```
type Pair (A B : Type) :=
  | mkPair :  (fst : A) -> (snd : B) -> Pair A B;
```
making it possible to write ` mkPair (fst := 1; snd := 2)`.


Mutli-constructor types are also allowed to have fields.
2023-07-24 16:56:13 +02:00
Jan Mas Rovira
ea652e5279
Refactor deriving statements in Concrete.Language (#2256)
Deriving instances was a pita because of the extensive use of type
families. I have refactored the code to make it easier to work with
2023-07-19 15:39:23 +01:00
Jan Mas Rovira
49a0bc0496
Rename inductive constructor (#2255)
Rename `InductiveConstructorDef` -> `ConstructorDef` in `Concrete` so
that it is consistent with `Internal` and its field names
2023-07-18 12:50:30 +01: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
9fdf848e3e
Typcheck imports before statements (#2253)
- closes #2248
2023-07-11 12:26:52 +02:00
Jan Mas Rovira
366afb5dad
Parse many consecutive - as a comment (#2240)
- Closes #2190
2023-07-11 11:35:33 +02:00
Łukasz Czajka
bf6603eb33
Update to GEB version 0.3.2 (#2244)
GEB 0.3.2 introduces the following changes.
* The STLC frontend no longer requires full type information in terms.
The syntax of the terms changed.
* An error node has been introduced which allows to compile Juvix `fail`
nodes.

The following features required for compilation from Juvix are still
missing in GEB.
* Modular arithmetic types ([GEB issue
#61](https://github.com/anoma/geb/issues/61)).
* Functor/algebra iteration to implement bounded inductive types ([GEB
issue #62](https://github.com/anoma/geb/issues/62)).
2023-07-11 11:02:48 +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
Jan Mas Rovira
0cc689a2ef
Add syntax for builtin list (#2239)
- Depends on #2219 
- Closes #1643 

This pr introduces a `list` as a new builtin so that we can use syntax
sugar both in expressions and patterns. E.g. it is now possible to write
`[1; 2; 3;]`.
2023-07-03 13:24:56 +02:00
Łukasz Czajka
ff940b427e
Local pragmas improvements (#2236)
* Fixes the indices in `inline` and `specialize` for local lambda-lifted
identifiers.
* Adds the `specialize-by` pragma which allows to specialize a local
function by some of its free variables, or specialize arguments by name.
For example:
```
funa : {A : Type} -> (A -> A) -> A -> A;
funa {A} f a :=
  let
    {-# specialize-by: [f] #-}
    go : Nat -> A;
    go zero := a;
    go (suc n) := f (go n);
  in go 10;
```
If `funa` is inlined, then `go` will be specialized by the actual
argument substituted for `f`.
2023-06-30 16:59:29 +02:00
Jan Mas Rovira
d69d8c6eca
Remove abstract (#2219)
- Closes #2002 
- Closes #1690 
- Closes #2224
- Closes #2237
2023-06-30 15:01:46 +02:00
Jan Mas Rovira
38028d2dff
Fix bug in aritychecker (#2238)
When inserting wildcards on the LHS of a clause, we were reusing the
same variable, which is wrong. Now fresh variables are generated.

- Closes #2235
2023-06-29 17:25:30 +02:00
Łukasz Czajka
39ef069bfc
Fold lets when the bound variable occurs at most once (#2231)
For example, convert
```
let x := f a b c in
g x
```
to
```
g (f a b c)
```
2023-06-29 13:02:10 +02:00
Łukasz Czajka
b4347bdd23
Numeric range types (#2232)
* Closes #2145
2023-06-28 17:24:08 +02:00
Łukasz Czajka
755f02ab4c
Fix bug in computeTypeInfo (#2234)
* Closes #2233
2023-06-28 16:08:12 +02:00
Łukasz Czajka
5b44b2e654
Use specialization pragmas in the standard library (#2230)
* Adds `specialize` pragmas for folds, maps, etc.
* Fixes two bugs in `specializeArgs`
2023-06-27 15:37:11 +02:00
Łukasz Czajka
2fff65030b
Case folding (#2229)
Fold constant cases, i.e., convert
```
case C a b
| A := ..
| B x := ..
| C x y := M
```
to
```
let x := a;
     y := b;
in
M
```
2023-06-27 12:29:26 +02:00
Łukasz Czajka
7c039d687b
Specialization optimisation (#2164)
* Closes #2147 

Adds a `specialize` pragma which allows to specify (explicit) arguments
considered for specialization. Whenever a function is applied to a
constant known value for the specialized argument, a new version of the
function will be created with the argument pasted in. For example, the
code

```juvix
{-# specialize: [1] #-}
mymap : {A B : Type} -> (A -> B) -> List A -> List B;
mymap f nil := nil;
mymap f (x :: xs) := f x :: mymap f xs;

main : Nat;
main := length (mymap λ{x := x + 3} (1 :: 2 :: 3 :: 4 :: nil));
```

will be transformed into code equivalent to

```juvix
mymap' : (Nat -> Nat) -> List Nat -> List Nat;
mymap' f nil := nil;
mymap' f (x :: xs) := λ{x := x + 3} x :: mymap' xs;

main : Nat;
main := length (mymap' (1 :: 2 :: 3 :: 4 :: nil));
```
2023-06-26 16:49:19 +02:00
Łukasz Czajka
82a86ace45
Fix de Bruijn indices in LetRecs (#2227)
* Closes #2226 

For the program
```juvix
module letrec;

import Stdlib.Prelude open;

myfun : {A : Type} -> (A -> A) -> A -> A;
myfun {A} f a :=
      let
        go : Nat -> A -> A;
        go' : Nat -> A -> A;

        go zero a := a;
        go (suc n) a := f (go' n a);

        go' zero a := a;
        go' (suc n) a := f (go n a);
      in
      go 5 a;

main : Nat;
main := myfun ((+) 1) 7;
```
after translating to Core and lambda-lifting we got the incorrect
indices in types of the let-bindings.
```
def myfun : Π A : Type, (A$0 → A$1) → A$1 → A$2 :=
  λ(A : Type)
    λ(f : A$0 → A$1)
      λ(a : A$1)
        let go' : Int → a$1 → a$2 := go'_9 A$2 f$1 in
        let go : Int → a$2 → a$3 := go_10 A$3 f$2 in
        go$0 5 a$2;
```
The indices have been corrected in this PR.
2023-06-26 12:05:51 +02:00
Paul Cadman
4ab201f1ac
Bump version to 0.4.1 and update CHANGELOG (#2225)
This PR prepares the 0.4.1 release.

* Bump version in package.yaml
* Update version smoke test
* Updates CHANGELOG

NB: The links in the changelog will not work until we create the release
tag.
2023-06-23 12:39:27 +01:00
Veronika Romashkina
9840878413
Remove Subtree sections, all collapse all button (#2213)
- Resolves #2198

<img width="700" alt="Screenshot 2023-06-20 at 14 09 21"
src="https://github.com/anoma/juvix/assets/8126674/f5ebb89e-5f2a-41fe-8495-13b1ec4aea02">
2023-06-23 11:31:59 +01:00
Łukasz Czajka
f77e05513f
Lifting calls out of cases for the VampIR backend (#2218)
* Closes #2200 

For example,

```
def power' : Int → Int → Int → Int :=
  λ(acc : Int)
    λ(a : Int)
      λ(b : Int)
        if = b 0 then acc else if = (% b 2) 0 then power' acc (* a a) (/ b 2) else power' (* acc a) (* a a) (/ b 2);
```

is transformed into

```
def power' : Int → Int → Int → Int :=
  λ(acc : Int)
    λ(a : Int)
      λ(b : Int)
        if = b 0 then acc else let _X : Bool := = (% b 2) 0 in
        power' (if _X then acc else * acc a) (* a a) (/ b 2);
```
2023-06-23 10:55:19 +01:00
Łukasz Czajka
8201cb828c
The public pragma (#2223)
* Closes #2217
2023-06-22 18:31:53 +02:00
Łukasz Czajka
f7118d485c
Local pragmas (#2222)
* Closes #2196
2023-06-22 16:23:36 +02:00
Paul Cadman
1b30c75657
Build and cache smoke binary keyed using icu4c version (#2221)
This PR replaces fetching a precompiled binary of smoke with a
build/cache for macOS smoke tests on CI.

smoke dynamically links to icu4c, so a cached binary of smoke will break
when brew bumps the icu4c version. In this PR we use the icu4c version
in the cache key of the smoke build to avoid this issue.

NB: The smoke build cannot be done as a separate job because the smoke
binary must be built using exactly the same version of the macos-12
runner image as the smoke testing step to make sure that the icu4c
versions match.

Motivation for doing this is this failure:
https://github.com/anoma/juvix/actions/runs/5325094406/jobs/9645334642

which uses this release of the runner image
https://github.com/actions/runner-images/releases/tag/macOS-12%2F20230618.1

which contains the updated brew version of icu4c.

20230618.1 is currently a prerelease, but will start to run on more jobs
shortly.

```
2023-06-20T17:10:13.2222310Z Copied executables to /Users/runner/.local/bin:
2023-06-20T17:10:13.2223440Z - juvix
2023-06-20T17:10:13.5312790Z dyld[90256]: Library not loaded: '/usr/local/opt/icu4c/lib/libicuuc.72.dylib'
2023-06-20T17:10:13.5331930Z   Referenced from: '/Users/runner/hostedtoolcache/jonaprieto/smoke/latest/darwin-x64/smoke'
2023-06-20T17:10:13.5333610Z   Reason: tried: '/usr/local/opt/icu4c/lib/libicuuc.72.dylib' (no such file), '/usr/local/lib/libicuuc.72.dylib' (no such file), '/usr/lib/libicuuc.72.dylib' (no such file), '/usr/local/Cellar/icu4c/73.2/lib/libicuuc.72.dylib' (no such file), '/usr/local/lib/libicuuc.72.dylib' (no such file), '/usr/lib/libicuuc.72.dylib' (no such file)
2023-06-20T17:10:13.5334690Z make[1]: *** [smoke-only] Abort trap: 6
2023-06-20T17:10:13.5335310Z make: *** [smoke] Error 2
2023-06-20T17:10:13.5363170Z ##[error]Process completed with exit code 2.
```
2023-06-22 10:10:31 +02:00
Łukasz Czajka
5f35178575
Switch to Halo2 for VampIR backend tests (#2216)
* Closes #2214
2023-06-21 13:08:19 +02:00
Łukasz Czajka
c47320bb13
Use equality instead of less-equal when translating matching on Nats (#2215)
* Closes #2211
2023-06-20 15:39:53 +01:00
Łukasz Czajka
afbee7f14d
Fix isNegative in the VampIR runtime (#2212)
* Closes #2206
2023-06-20 15:34:50 +02:00
Veronika Romashkina
02e2f9f2dd
Use juvix-installer in CodeSpaces, install vamp-ir (#2210)
- Closes #2113
- Install `vamp-ir`.

---------

Co-authored-by: Jonathan Cubides <jonathan.cubides@uib.no>
2023-06-20 14:19:27 +02:00
Łukasz Czajka
50553758c2
Improve iterator formatting and syntax (#2204)
* Closes #2202
2023-06-20 13:21:46 +02:00
Jan Mas Rovira
6fb7bbff2d
Move termination checker to Internal (#2209)
- Closes #2203
2023-06-20 11:02:37 +02:00
Paul Cadman
5f3fdb9c08
Support juvix format with no argument to format a project (#2208)
When `juvix format` is invoked from some directory within a juvix
project then the formatter is run on all the files contained in the
project.

If `juvix format` is run from some directory outside of a Juvix project
then an error is reported. The user gets the same error as they would
get if
`juvix format` was run with a directory argument that is not within a
Juvix project.

* Closes https://github.com/anoma/juvix/issues/2087
2023-06-20 06:32:17 +01:00
Paul Cadman
fa4c92c7a5
Propogate formatter results when traversing subdirs (#2207)
Previously if a project looked like (where `Unformatted.juvix` contains
unformatted code, and `Formatted.juvix` is fully formatted):

```
Dir
|- juvix.yaml
|- Unformatted.juvix
|- Subdir
   |- Formatted.juvix
```

and the user ran `juvix format Dir/` then the command would return exit
code 0 instead of exit code 1. This is because only the result from
formatting files within `Subdir` was used, the result from `Dir` was
discarded.

This PR fixes this, the results of formatting all subdirectories in a
project are combined appropriately.
2023-06-19 18:42:28 +01:00
Paul Cadman
7840f9fa79
Always print source of formatted file unless --check is specified (#2205)
This PR was already merged in https://github.com/anoma/juvix/pull/2173,
but main was subsequently forced pushed as part of the 0.4.0 release and
these changes were erased by mistake.

This PR changes the behaviour of the formatter when run on files that
are already formatted. Previously the source of a file that was already
formatted was not output by the formatter.

After this PR, the formatter always outputs the contents of a formatted
file (when used on a single file, and if the --check option is not
specified).

If the `format: false` pragma is set then the source is echoed verbatim,
without highlighting (because it's not possible to get the highlighting
without the formatting).

This probably helps implementing the formatter in the vscode extension,
see https://github.com/anoma/vscode-juvix/issues/98
2023-06-19 15:14:59 +01:00