1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-15 10:03:22 +03:00
Commit Graph

480 Commits

Author SHA1 Message Date
Jonathan Cubides
bd16d3ef2a
Add support for Literate Juvix Markdown (#2448)
This PR adds an initial support for Literate Juvix Markdown files, files
with the extension `.juvix.md`.

Here is a small example of such a file: `Test.juvix.md`.

<pre>
# This is a heading
Lorem ...

```juvix
module Test;

type A := a;

fun : A -> A 
 | _ := a;
```
Other text
</pre>


This initial support enables users to execute common commands such as
typechecking, compilation, and HTML generation. Additionally, a new
command called `markdown` has been introduced. This command replaces
code blocks marked with the juvix attribute with their respective HTML
output, much like the output we obtain when running `juvix html`. In
this version, comments are ignored in the output, including judoc
blocks.

- We intend to use this new feature in combination with this Python
plugin (https://github.com/anoma/juvix-mkdocs) to enhance our
documentation site.



https://github.com/anoma/juvix/assets/1428088/a0c17f36-3d76-42cc-a571-91f885866874


## Future work

Open as issues once this PR is merged, we can work on the following:

- Support imports of Juvix Markdown modules (update the path resolver to
support imports of Literate Markdown files)
- Support (Judoc) comments in md Juvix blocks
- Support Markdown in Judoc blocks
- Update Text editor support, vscode extension and emacs mode (the
highlighting info is a few characters off in the current state)



- Closes #1839 
- Closes #1719
2023-11-10 13:55:36 +01:00
Paul Cadman
68d4314c78
Migrate all Juvix projects from juvix.yaml to Package.juvix in the repository (#2503)
This PR:

* Modifies entry point `_entryPointBuildDir` to use the `BuildDir` type
instead of `SomeBase Dir`. This allows delayed resolution of the default
build directory which was useful for the Package -> Concrete translation
point below.
* Modifies `juvix dev root` to render the current package as a
Package.juvix file.
* Modifies the Package -> Concrete translation to recognise default
arguments. So, for example, an empty `juvix.yaml` file will be
translated into the following (instead of the `name`, `version`, and
`dependencies` arguments being populated).

        
        module Package;

        import Stdlib.Prelude open;
        import PackageDescription.V1 open;

        package : Package := defaultPackage;
        
* Adds a temporary command (removed when juvix.yaml support is removed)
`juvix dev migrate-juvix-yaml` that translates `juvix.yaml` into an
equivalent `Package.juvix` in the current project.
* Adds a temporary script `migrate-juvix-yaml.sh` (removed when
juvix.yaml support is removed) which can be run in the project to
translate all Juvix projects in the repository.
* Actually translate all of the `juvix.yaml` files to `Package.juvix`
using the script.

* Part of https://github.com/anoma/juvix/issues/2487
2023-11-07 18:11:02 +00:00
Łukasz Czajka
5948a38a54
Named arguments syntax with function definitions (#2494)
* Closes #2365
* Implements the syntax `f@{x1 := def1; ...; xn := defn}` and `f@?{x1 :=
def1; ..; xn := defn}`. Each definition inside the `@{..}` is an
ordinary function definition. The `@?` version allows partial
application (not all explicit named arguments need to be provided). This
subsumes the old record creation syntax.
2023-11-07 12:02:22 +01:00
Paul Cadman
9690aadf53
Update file walker to use Package.juvix to detect a Juvix package (#2502)
The file walker `RecurseFilter` indictates if the the walker recurses
into
a directory which contains a Juvix project.

Previously the file walker would detect juvix.yaml. It now detects both
juvix.yaml and Package.juvix.

* Part of https://github.com/anoma/juvix/issues/2487
2023-11-06 15:34:27 +00:00
Paul Cadman
e8a5d20d07
Add -n/--non-interactive option to juvix init (#2500)
When moving to Package.juvix, the package configuration file cannot be
empty. So it's convenient to have a quick way to create a Package.juvix
file (previously you could run `touch juvix.yaml`.

This PR adds the `-n / --non-interactive` option to `juvix init`. This
will create a default `Package.juvix`, using the name of the current
directory to populate the package name.

Similarly for the interactive version of juvix init, if the name of the
current directory is not a valid Juvix module then a fallback name is
used instead.

For example:
```
$ mkdir /tmp/new-package
$ cd /tmp/new-package
$ juvix init -n
$ cat Package.juvix
module Package;

import PackageDescription.V1 open;

package : Package :=
  defaultPackage
    {name := "new-package";
     version := mkVersion 0 0 0;
     dependencies := [defaultStdlib]};
```

* Part of https://github.com/anoma/juvix/issues/2487
2023-11-06 13:56:20 +00:00
Paul Cadman
511e99f217
Use Package.juvix in the global project (#2499)
## Global package configuration

This PR updates the global-project to use `Package.juvix` instead of
`juvix.yaml`.

The global package gets the following `Package.juvix`:

```
module Package;

import PackageDescription.V1 open;

package : Package :=
  defaultPackage
    {name := "global-juvix-package";
     version := mkVersion 0 0 0;
     dependencies := [defaultStdlib]};
```

## juvix clean --global

This PR also adds an option `-g/--global` to `juvix clean` that removes
the `$XDG_CONFIG_HOME/juvix/VERSION` directory.

## Testing notes

If you've already run Juvix 0.5.3 you'll need to run `juvix clean -g`
before you'll use the new global project. This will not be an issue for
users of Juvix 0.5.4 (as this version of Juvix will never generate
juvix.yaml in the global project).

Part of:
* https://github.com/anoma/juvix/issues/2487
2023-11-06 11:49:43 +00:00
Paul Cadman
9d75dcac96
Normalise paths on ResolverCache set and lookup (#2498)
Paths are used as keys in the PathResolver ResolverCache. These paths
must be normalised because a path may have a different representation
when it is used to set an entry in the cache and when it is used to
lookup from the cache.

Path normalisation is also used in the REPL before a directory is
compared with the standard library path.

* Closes https://github.com/anoma/juvix/issues/2497
2023-11-06 09:45:26 +00:00
Jonathan Cubides
ee45ddf8c2
Fix #2495 (#2496)
- Closes #2495
2023-11-03 21:23:57 +01:00
Jonathan Cubides
47c8df11f1
Fix remove unexpected whitespaces introduced by formatting (#2489)
- Closes #2059
2023-11-03 12:51:45 +01:00
Paul Cadman
145f20fc68
Update juvix init to generate Package.juvix instead of juvix.yaml (#2483)
`juvix init` now generates a `Package.juvix` file in the current
directory instead of a `juvix.yaml` file. It uses the prompts from the
user to fill in the name and version options.

### Validity check

After the file is generated, the Juvix project in the current directory
is loaded to check that the generated file is valid.

### Version support

Each version of the PackageDescription module must have a corresponding
[PackageDescriptionType](c39c27000c/src/Juvix/Compiler/Pipeline/Package/Loader/Versions.hs (L12))
which defines:

* The path relative to `include/package` that the file exists at (e.g
`PackageDescription/V1.juvix`)
* The name of the Package type in the file (e.g `Package`)
* A function that translates a Package type into a Concrete function
definition that represents the code that is generated in the
`Package.juvix`
* A function that returns a Bool that determines if the generated
function definition depends on the standard library. (i.e that the
standard library needs to be imported by Package.juvix).

The last point is necessary because in the V1 spec, the `SemVer` type
uses `Maybe` to encode the release and meta components of the of the
version:

```
package : Package :=
  defaultPackage
    {name := "dd";
     version := mkVersion 1 2 3 {just "prerel"} {just "meta"}};
```

So if the user specifies a release or meta component in their version -
then the standard library needs to be imported to provide the `just`
constructor. If the user only specifies major, minor and patch
components then the standard library does not need to be imported.

* Closes https://github.com/anoma/juvix/issues/2485
2023-11-03 09:54:44 +00:00
Łukasz Czajka
485f6e7920
Literal casting (#2457)
* Closes #2453 
* Closes #2432
* Any nonnegative literal `n` is replaced with `fromNat {_} {{_}} n`
where `fromNat` is the builtin conversion function defined in the
`Natural` trait in `Stdlib.Trait.Natural`.
* Any negative literal `-n` is replaced with `fromInt {_} {{_}} -n`
where `fromInt` is the builtin conversion function defined in the
`Integral` trait in `Stdlib.Trait.Integral`.
* Before resolving instance holes, it is checked whether the type holes
introduced for `fromNat` and `fromInt` have been inferred. If not, an
attempt is made to unify them with `Nat` or `Int`. This allows to
type-check e.g. `1 == 1` (there is no hint in the context as to what the
type of `1` should be, so it is decided to be `Nat` after inferring the
hole fails).
2023-11-03 10:01:03 +01:00
Paul Cadman
8c5bf822ed
Bump version to 0.5.3 (#2492)
This PR updates:
- [x] Package version
- [x] Smoke test
- [x] Changelog
2023-11-01 16:18:33 +00:00
Jonathan Cubides
21d5034e60
Fix formatting for all Juvix files in tests folder (#2404)
In this PR, we ran the Juvix formatter so that we can now freely run
`make format`, `make check`, or `make pre-commit` without any unexpected
file changes.

This goes after:

- https://github.com/anoma/juvix/pull/2486
2023-10-31 18:36:34 +01:00
Jonathan Cubides
89d35637ac
Fix #2479 (#2486)
Fix formatting for as-patterns inside implicit patterns.
2023-10-31 16:57:27 +01:00
Paul Cadman
9bfe20e323
Version the PackageDescription module (#2478)
This PR adds a version number to the module name of the
`PackageDescription` module. This allows us to change the Package file
format in a backwards compatible way in the future.

Now the simplest Package.juvix file looks like:

```
module Package;

import PackageDescription.V1 open;

package : Package := defaultPackage;
```

## Adding new versions

The idea is that new versions of the PackageDescription format will be
added as files of the form:
include/package/PackageDescription/Vx.juvix

The correspondence between a version of the PackageDescription file and
the package type name is recorded in
[`packageDescriptionTypes`](9ba869d836/src/Juvix/Compiler/Pipeline/Package/Loader.hs (L15)).

The `package` identifier type must come from **one** of the versions
of the PackageDescription module.

* Closes https://github.com/anoma/juvix/issues/2452
2023-10-30 11:33:36 +00:00
Paul Cadman
2e727cc337
Format long list literals by splitting using pre-comma multiline (#2477)
### Example of nested list formatting using the new method:

```
l : List (List Int) :=
  [ [1; 2; 3]
  ; longLongLongListArg
  ; [ longLongLongListArg
    ; longLongLongListArg
    ; longLongLongListArg
    ; longLongLongListArg
    ]
  ; longLongLongListArg
  ];
```

* Closes https://github.com/anoma/juvix/issues/2466
2023-10-30 10:09:48 +01:00
Paul Cadman
0a8799a344
Use a Juvix source file to define a package (#2434)
Depends on:
* ~~https://github.com/anoma/juvix/pull/2459~~
* https://github.com/anoma/juvix/pull/2462

This PR is part of a series implementing:
* https://github.com/anoma/juvix/issues/2336

This PR adds the package file loading function, including a file
evaluation effect. It integrates this with the existing `readPackage`
function and adds tests / smoke tests.

## Package.juvix format

Instead of `juvix.yaml` (which is still supported currently) users can
now place a `Package.juvix` file in the root of their project. The
simplest `Package.juvix` file you can write is:

```
module Package;

import PackageDescription open;

package : Package := defaultPackage;
```

The
[PackageDescription](35b2f618f0/include/package/PackageDescription.juvix)
module defines the `Package` type. Users can use "go-to definition" in
their IDE from the Package file to see the documentation and
definitions.

Users may also import `Stdlib.Prelude` in their Package file. This is
loaded from the global project. No other module imports are supported.

Notes:
* If a directory contains both `Package.juvix` and `juvix.yaml` then
`Package.juvix` is used in preference.

## Default stdlib dependency

The `Dependency` type has a constructor called `defaultStdlib`. This
means that any project can use the compiler builtin standard library
dependency. With `juvix.yaml` this dependency is only available when the
`dependencies` field is unspecified.

```
module Package;

import PackageDescription open;

package : Package := defaultPackage { dependencies := [defaultStdlib] };
```

## Validation

As well as the standard type checking validation that the Juvix compiler
provides additional validation is made on the file.

* The Package module must contain the identifier `package` and it must
have type `Package` that's obtained from the global `PackageDescription`
module.
* Every dependency specified in the Package.juvix must be unique.

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

## Examples

### Package with name and version

```
module Package;

import PackageDescription open;

package : Package :=
  defaultPackage {name := "a-package";
                  version := mkVersion 0 1 0};
```

### Package with GitHub dependency

```
module Package;

import PackageDescription open;

package : Package :=
  defaultPackage {name := "a-package";
                  version := mkVersion 0 1 0;
                  dependencies := [defaultStdlib;
                                   github (org := "anoma";
                                           repo := "juvix-containers";
                                           ref := "v0.7.1")]};
```

## Package with main and buildDir fields

```
module Package;

import Stdlib.Prelude open;
import PackageDescription open;

package : Package :=
  defaultPackage {name := "a-package";
                  version := mkVersion 0 1 0;
                  dependencies := [defaultStdlib;
                                   github (org := "anoma";
                                           repo := "juvix-containers";
                                           ref := "v0.7.1")];
                  buildDir := just "/tmp/build";
                  main := just "HelloWorld.juvix"
                };

```
2023-10-27 12:35:20 +01:00
Jan Mas Rovira
0943a4ab92
Dependent default values (#2446)
- Closes #2445
2023-10-27 10:19:07 +02:00
Paul Cadman
9a4c09ac77
Add missing juvix.yaml files to test project roots (#2474)
If you have `juvix.yaml` file in a parent of the juvix source directory
in your filesystem then some Compilation tests will fail. This is
because the tests assume that the project root will be in the test
directory.

This PR just adds `juvix.yaml` files to those test directories to avoid
this issue.

Spotted by @agureev
2023-10-26 10:41:23 +01:00
Łukasz Czajka
ef1148beaa
Fix precedence inconsistency bug (#2470)
Precedence inconsistency was not always correctly detected.
2023-10-25 16:13:27 +02:00
Paul Cadman
27aaf9d9f9
Add dependency on expressions in function default arguments (#2462)
Closes:
* https://github.com/anoma/juvix/issues/2461
2023-10-24 11:02:24 +02:00
Paul Cadman
8e6c1c8f07
Use JuvixError instead of Text for errors in Package file loading (#2459)
Depends on:
*  https://github.com/anoma/juvix/pull/2458

This PR is part of a series implementing:
* https://github.com/anoma/juvix/issues/2336

In attempt to make the main PR:
* https://github.com/anoma/juvix/pull/2434
easier to review.

This PR introduces standard JuvixError handling for errors related to
the loading of the juvix.yaml file. Before this PR errors were thrown as
Text and then communicated to the user using the `error` function.
2023-10-23 19:01:36 +01:00
Jonathan Cubides
c6b3b95db3
Add new flags to the Html backend (#2447)
This PR adds `--prefix-id`, `--no-path`, and `only-code` flags to the
HTML backend to manipulate the hyperlinks on the resulting HTML output
and the output itself by only keeping the content of the body in the
Html.

As a usage case, we can support `juvix-standalone` blocks, as
demonstrated in

- https://github.com/anoma/juvix-docs/pull/80
2023-10-23 16:22:04 +02:00
Łukasz Czajka
cdfb35aaac
Arithmetic simplification (#2454)
Simplifies arithmetic expressions in the Core optimization phase,
changing e.g. `(x - 1) + 1` to `x`. Such expressions appear as a result
of compiling pattern matching on natural numbers.
2023-10-23 11:47:17 +02:00
Paul Cadman
c1c2a06922
Process $root/Package.juvix using a special PathResolver (#2451)
The special PathResolver puts files from the global package stdlib and
files from the global package description files in scope of the
$root/Package.juvix module.

Currently this means that PackageDescription module is in scope for the
module so that the user can write:

```
module Package;

import Stdlib.Prelude open;
import PackageDescription open;

package : Package :=
  mkPackageDefault
    (name := "foo")
    { version := mkVersion 0 1 0
    ; dependencies :=
      [ github "anoma" "juvix-stdlib" "adf58a7180b361a022fb53c22ad9e5274ebf6f66"
      ; github "anoma" "juvix-containers" "v0.7.1"]};
```
2023-10-23 10:08:44 +02:00
Łukasz Czajka
272b93e595
Constant folding (#2450)
* Closes #2154 
* Evaluates closed applications with value arguments when the result
type is zero-order. For example, `3 + 4` is evaluated to `7`, and `id 3`
is evaluated to `3`, but `id id` is not evaluated because the target
type is not zero-order (it's a function type).
2023-10-20 12:03:56 +02:00
Łukasz Czajka
cbd8253afd
Instance coercions (#2444)
* Closes #2426 

A coercion from trait `T` to `T'` can be declared with the syntax
```
coercion instance
coeName {A} {{T A}} : T' A := ...
```
Coercions can be seen as instances with special resolution rules.

Coercion resolution rules
-------------------------
* If a non-coercion instance can be applied in a single instance
resolution step, no coercions are considered. No ambiguity results if
there exists some coercion which could be applied, but a non-coercion
instance exists - the non-coercion instances have priority.
* If no non-coercion instance can be applied in a single resolution
step, all minimal coercion paths which lead to an applicable
non-coercion instance are considered. If there is more than one,
ambiguity is reported.

Examples
----------

The following type-checks because:
1. There is no non-coercion instance found for `U String`.
2. There are two minimal coercion paths `U` <- `U1` and `U` <- `U2`, but
only one of them (`U` <- `U2`) ends in an applicable non-coercion
instance (`instU2` for `U2 String`).

```
trait
type U A := mkU {pp : A -> A};

trait
type U1 A := mkU1 {pp : A -> A};

trait
type U2 A := mkU2 {pp : A -> A};

coercion instance
fromU1toU {A} {{U1 A}} : U A :=
  mkU@{
    pp := U1.pp
  };

coercion instance
fromU2toU {A} {{U2 A}} : U A :=
  mkU@{
    pp := U2.pp
  };

instance
instU2 : U2 String := mkU2 id;

main : IO := printStringLn (U.pp "X")
```

The following results in an ambiguity error because:
1. There is no non-coercion instance found for `T Unit`.
2. There are two minimal coercion paths `T` <- `T1` and `T` <- `T2`,
both of which end in applicable non-coercion instances.

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

trait
type T1 A := mkT1 { pp : A → A };

trait
type T2 A := mkT2 { pp : A → A };

instance
unitT1 : T1 Unit := mkT1 (pp := λ{_ := unit});

instance
unitT2 : T2 Unit := mkT2 (pp := λ{_ := unit});

coercion instance
fromT1toT {A} {{T1 A}} : T A := mkT@{
  pp := T1.pp
};

coercion instance
fromT2toT {A} {{T2 A}} : T A := mkT@{
  pp := T2.pp
};

main : Unit := T.pp unit;
```

The following type-checks, because there exists a non-coercion instance
for `T2 String`, so the coercion `fromT1toT2` is ignored during instance
resolution.

```
trait
type T1 A := mkT1 {pp : A -> A};

trait
type T2 A := mkT2 {pp : A -> A};

instance
instT1 {A} : T1 A :=
  mkT1@{
    pp := id
  };

coercion instance
fromT1toT2 {A} {{M : T1 A}} : T2 A :=
  mkT2@{
    pp := T1.pp {{M}}
  };

instance
instT2 : T2 String :=
  mkT2@{
    pp (s : String) : String := s ++str "!"
  };

main : String := T2.pp "a";
```
2023-10-19 16:00:31 +02:00
Łukasz Czajka
c3bcf40db1
Case value inlining (#2441)
* Introduces the `inline: case` pragma which causes an identifier to be
inlined if it is matched on. This is necessary to support GEB without
compromising optimization for other targets.
* Adapts to the new commits in
https://github.com/anoma/juvix-stdlib/pull/86
2023-10-12 18:59:47 +02:00
Jan Mas Rovira
81f8339625
Allow syntax operator in the rhs of a record declaration (#2442)
- Closes #2431.
2023-10-11 16:59:06 +02:00
Jan Mas Rovira
a5516a5a08
Add default arguments (#2408) 2023-10-10 23:28:06 +02:00
Łukasz Czajka
407a74004c
Fix instance axiom bug (#2439)
* Closes #2438
2023-10-10 15:55:17 +02:00
Łukasz Czajka
60a191b786
Numeric, ordering and equality traits (#2433)
* Adapts to https://github.com/anoma/juvix-stdlib/pull/86
* Adds a pass in `toEvalTransformations` to automatically inline all
record projection functions, regardless of the optimization level. This
is necessary to ensure that arithmetic operations and comparisons on
`Nat` or `Int` are always represented directly with the corresponding
built-in Core functions. This is generally highly desirable and required
for the Geb target.
* Adds the `inline: always` pragma which indicates that a function
should always be inlined during the mandatory inlining phase, regardless
of optimization level.
2023-10-09 18:25:01 +02:00
Jan Mas Rovira
0e4c27b74f
Add constructor wildcards (#2437)
- Closes #2402.

Changes:
1. Allow the definition of empty record types.
2. Introduce the _constructor wildcard_ pattern. That is, a pattern of
the form `constr@{}` that matches the constructor `constr` regardless of
its number of arguments.
2023-10-09 14:14:30 +02:00
Artem Gureev
e7f5a83da3
Update Geb backend (#2436)
Changes in the printing of Lambda terms necessary for the use of the Juvix
Geb backend, changing the names of binary operations, adding a
constructor for natural numbers. Appropriately changes tests when
necessary.

---------

Co-authored-by: Jonathan Cubides <jonathan.cubides@uib.no>
2023-10-06 17:37:08 +02:00
Jan Mas Rovira
28c404348a
Ignore instance arguments in the termination checker (#2435)
- Fixes #2414
2023-10-06 12:09:15 +02:00
Łukasz Czajka
34b5a14935
Improve the specialisation optimisation (#2417)
* Closes #2416 
* Closes #2401 
* Avoids generating identical specialisations by keeping a
specialisation signature for each specialised function application.
* Allows to specialise on a per-trait or per-instance basis:
```
{-# specialize: true #-}
trait
type Natural N := mkNatural {
  + : N -> N -> N;
  * : N -> N -> N;
  fromNat : Nat -> N;
};
```
or
```
{-# specialize: true #-}
instance
naturalNatI : Natural Nat := ...
```
* The above `specialize: bool` pragma actually works with any type or
function. To be able to simultaneously specify the boolean
specialisation flag and specialisation arguments, one can use
`specialize-args: [arg1, .., argn]` which works like `specialize: [arg1,
.., argn]`.
2023-10-05 10:12:48 +02:00
Paul Cadman
b049f931b2
Bump version to 0.5.2 (#2425)
This PR updates:
- [x] Package version
- [x] Smoke test
- [x] Changelog
2023-10-04 13:54:15 +01:00
Łukasz Czajka
6b38543ae3
Fix bug in instance termination checking (#2423)
* Closes #2421
2023-10-04 12:00:48 +02:00
Paul Cadman
76d69b5ef3
Add juvix dependencies update command (#2419)
This PR adds a new command `juvix dependencies update` that fetches all
dependencies in a project and updates the project lock file.

Currently the only way to update the lock file is to delete it and
generate a new one.

## CLI Docs

```
juvix dependencies --help
Usage: juvix dependencies COMMAND

  Subcommands related to dependencies

Available options:
  -h,--help                Show this help text

Available commands:
  update                   Fetch package dependencies and update the lock file
```

## Example

A project containing the following `juvix.yaml`

```yaml
dependencies:
  - .juvix-build/stdlib/
  - git:
      url: https://github.com/anoma/juvix-test
      ref: v0.6.0
      name: test
main: Example.juvix
name: example
version: 1.0.0
```

compile to generate the lockfile: `juvix compile`

```yaml
# This file was autogenerated by Juvix version 0.5.1.
# Do not edit this file manually.

dependencies:
- path: .juvix-build/stdlib/
  dependencies: []
- git:
    name: test
    ref: a94c61749678ff57556ee6e4cb1f8fbbddbc4ab1
    url: https://github.com/anoma/juvix-test
  dependencies:
  - git:
      name: stdlib
      ref: 4facf14d9b2d06b81ce1be1882aa9050f768cb45
      url: https://github.com/anoma/juvix-stdlib
    dependencies: []
```

Now update the test dependency version:

```yaml
- .juvix-build/stdlib/
- git:
   url: https://github.com/anoma/juvix-test
   ref: v0.6.1
   name: test
main: Example.juvix
name: example
version: 1.0.0
```

And run `juvix dependencies update`

Now the lockfile has updated to the hash of v0.6.1:

```yaml
# This file was autogenerated by Juvix version 0.5.1.
# Do not edit this file manually.

dependencies:
- path: .juvix-build/stdlib/
  dependencies: []
- git:
    name: test
    ref: a7ac74cac0db92e0b5e349f279d797c3788cdfdd
    url: https://github.com/anoma/juvix-test
  dependencies:
  - git:
      name: stdlib
      ref: 4facf14d9b2d06b81ce1be1882aa9050f768cb45
      url: https://github.com/anoma/juvix-stdlib
    dependencies: []
```

---------

Co-authored-by: Jonathan Cubides <jonathan.cubides@uib.no>
2023-10-03 18:09:13 +02:00
Jan Mas Rovira
9d9631aa26
Allow open statements in let expressions (#2395)
- Closes #2185
2023-10-02 23:13:45 +02:00
Jan Mas Rovira
76b58f090f
Fix for crash with wildcard used in type definition (#2405)
- Closes #2292.

Holes are now allowed in the type of inductive parameters.
If the type is unsupported, a user error is thrown.
2023-10-02 18:58:21 +02:00
Paul Cadman
dad3963c00
Add package lockfile support (#2388)
This PR adds lock file support to the compiler pipeline. The lock file
is generated whenever a compiler pipeline command (`juvix {compile,
typecheck, repl}`) is run.

The lock file contains all the information necessary to reproduce the
whole dependency source tree. In particular for git dependencies,
branch/tag references are resolved to git hash references.

## Lock file format

The lock file is a YAML `juvix.lock.yaml` file written by the compiler
alongside the package's `juvix.yaml` file.

```
LOCKFILE_SPEC: { dependencies: { DEPENDENCY_SPEC, dependencies: LOCKFILE_SPEC }
DEPENDENCY_SPEC: PATH_SPEC | GIT_SPEC
PATH_SPEC: { path: String }
GIT_SPEC: { git: {url: String, ref: String, name: String } }
```

## Example

Consider a project containing the following `juvix.yaml`:

```yaml
dependencies:
- .juvix-build/stdlib/
- git:
   url: https://github.com/anoma/juvix-containers
   ref: v0.7.1
   name: containers
name: example
version: 1.0.0
```

After running `juvix compile` the following lockfile `juvix.lock.yaml`
is generated.

```yaml
# This file was autogenerated by Juvix version 0.5.1.
# Do not edit this file manually.

dependencies:
- path: .juvix-build/stdlib/
  dependencies: []
- git:
    name: containers
    ref: 3debbc7f5776924eb9652731b3c1982a2ee0ff24
    url: https://github.com/anoma/juvix-containers
  dependencies:
  - git:
      name: stdlib
      ref: 4facf14d9b2d06b81ce1be1882aa9050f768cb45
      url: https://github.com/anoma/juvix-stdlib
    dependencies: []
  - git:
      name: test
      ref: a7ac74cac0db92e0b5e349f279d797c3788cdfdd
      url: https://github.com/anoma/juvix-test
    dependencies:
    - git:
        name: stdlib
        ref: 4facf14d9b2d06b81ce1be1882aa9050f768cb45
        url: https://github.com/anoma/juvix-stdlib
      dependencies: []
```

For subsequent runs of the juvix compile pipeline, the lock file
dependency information is used.

 ## Behaviour when package file and lock file are out of sync

If a dependency is specified in `juvix.yaml` that is not present in the
lock file, an error is raised.

Continuing the example above, say we add an additional dependency:

```
dependencies:
- .juvix-build/stdlib/
- git:
     url: https://github.com/anoma/juvix-containers
     ref: v0.7.1
     name: containers
- git:
     url: https://github.com/anoma/juvix-test
     ref: v0.6.1
     name: test
name: example
version: 1.0.0
```

`juvix compile` will throw an error:

```
/Users/paul/tmp/lockfile/dep/juvix.yaml:1:1: error:
The dependency test is declared in the package's juvix.yaml but is not declared in the lockfile: /Users/paul/tmp/lockfile/dep/juvix.lock.json
Try removing /Users/paul/tmp/lockfile/dep/juvix.lock.yaml and then run Juvix again.
```

Closes:
* https://github.com/anoma/juvix/issues/2334
2023-10-02 17:51:14 +02:00
Łukasz Czajka
5fc0f33bb4
Add Partial trait (#2409)
Adds a Partial trait to the standard library, similar to the one in
PureScript:

https://book.purescript.org/chapter6.html#nullary-type-classes

This enables using partial functions in an encapsulated manner and
without depending on the Debug module.

Adds a trait:

```
trait
type Partial := mkPartial {
   fail : {A : Type} -> String -> A
};

runPartial {A} (f : {{Partial}} -> A) : A := f {{mkPartial Debug.failwith}};
```
2023-10-02 15:14:40 +02:00
Jonathan Cubides
0230a7b848
Fix minor: case and error message (#2407)
Co-authored-by: Paul Cadman <git@paulcadman.dev>
2023-09-29 16:28:59 +02:00
Łukasz Czajka
5642c82a0e
Update benchmarks (#2415)
* Small style improvements
* Update `mapfun.juvix` to use `Int` instead of `Nat` so that it is
semantically equivalent to the other implementations.
* Adapt to #2396
2023-09-29 15:55:52 +02:00
Łukasz Czajka
1260853583
Improve closure calls in the runtime (#2396)
* Closes #1653 

The running time improvement is 20-30% on benchmarks dominated by
closure calls.
2023-09-29 14:20:00 +02:00
Łukasz Czajka
7c3b70459b
Fix delay instance resolution (#2393)
* Closes #2348
2023-09-29 13:08:05 +02:00
Łukasz Czajka
e4a5ca7399
Record creation syntax with function definitions (#2369)
* Closes #2280 
* Record creation syntax uses normal function definition syntax like at
the top-level or in lets.
* It is now allowed to omit the result type annotation in function
definitions (the `: ResultType` part) with `_` inserted by default. This
is allowed only for simple definitions of the form `x := value` in lets
and record creation, but not at the top level.
2023-09-28 17:07:38 +02:00
Jonathan Cubides
f9e27b52f7
Update pre-commit to check JSON formatting (#2400) 2023-09-28 14:55:35 +02:00
Jan Mas Rovira
27df3949f5
Add nodes with no edges to the dependency graph (#2390)
- Closes #2373 

Consider this:
```
let 
 x : _ := 0
in ...
```
When translating the let to internal, we build the dependency graph and
then use that to group definitions in mutually recursive blocks. Since
`x` has no edge, it was not being added to the dependency graph, so it
was not being translated to Internal, thus crashing later during
inference.
2023-09-26 13:17:50 +02:00