1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-13 11:16:48 +03:00
Commit Graph

1282 Commits

Author SHA1 Message Date
Jonathan Cubides
b8a016fc57
Add Makefile to hyperfine benchmarks (#2533)
This PR adds a target for our Makefile to run benchmarks using
hyperfine.
We run different commands which can be easily modified in
bench/hyperfine/Makefile.

```
make hyperfine-benchmarks
```

After running this on your terminal, checkout the generated file
bench/hyperfine/README.md for the results.

The results below are the runs using the following module.

```
module fibo;

import Stdlib.Prelude open;

fib : Nat → Nat → Nat → Nat
  | zero x1 _ := x1
  | (suc n) x1 x2 := fib n x2 (x1 + x2);

fibonacci (n : Nat) : Nat := fib n 0 1;

main : IO := printNatLn (fibonacci 50);
```

(For now, I got the following on my machine (ran in about 5min or less)
Darwin Jonathans-MacBook-Pro-2.local 22.6.0 Darwin Kernel Version
22.6.0: Fri Sep 15 13:41:28 PDT 2023;
root:xnu-8796.141.3.700.8~1/RELEASE_ARM64_T6020 arm64 arm)

- The binary without the version below is the latest commit on main.

# Hyperfine Benchmarks

## dev parse

| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `juvix-v0.4.3 dev parse fibo.juvix` | 184.3 ± 5.4 | 178.5 | 193.2 |
1.06 ± 0.04 |
| `juvix-v0.5.0 dev parse fibo.juvix` | 184.7 ± 6.9 | 179.2 | 201.3 |
1.06 ± 0.05 |
| `juvix-v0.5.1 dev parse fibo.juvix` | 174.2 ± 5.4 | 167.9 | 181.0 |
1.00 |
| `juvix-v0.5.2 dev parse fibo.juvix` | 181.3 ± 1.6 | 179.5 | 184.1 |
1.04 ± 0.03 |
| `juvix-v0.5.3 dev parse fibo.juvix` | 1185.8 ± 5.7 | 1178.4 | 1197.3 |
6.81 ± 0.21 |
| `juvix-v0.5.4 dev parse fibo.juvix` | 1308.4 ± 6.9 | 1297.6 | 1319.3 |
7.51 ± 0.23 |
| `juvix dev parse fibo.juvix` | 1311.0 ± 5.5 | 1303.2 | 1318.5 | 7.53 ±
0.23 |

## dev highlight

| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `juvix-v0.4.3 dev highlight fibo.juvix` | 770.2 ± 67.5 | 742.9 | 961.6
| 1.01 ± 0.09 |
| `juvix-v0.5.0 dev highlight fibo.juvix` | 762.7 ± 11.8 | 749.9 | 787.2
| 1.00 |
| `juvix-v0.5.1 dev highlight fibo.juvix` | 849.3 ± 9.3 | 836.5 | 863.9
| 1.11 ± 0.02 |
| `juvix-v0.5.2 dev highlight fibo.juvix` | 873.5 ± 21.1 | 855.2 | 918.9
| 1.15 ± 0.03 |
| `juvix-v0.5.3 dev highlight fibo.juvix` | 2035.9 ± 69.5 | 1946.9 |
2125.4 | 2.67 ± 0.10 |
| `juvix-v0.5.4 dev highlight fibo.juvix` | 2218.0 ± 57.3 | 2169.5 |
2316.4 | 2.91 ± 0.09 |
| `juvix dev highlight fibo.juvix` | 2206.5 ± 55.9 | 2150.4 | 2296.6 |
2.89 ± 0.09 |

## typecheck

| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `juvix-v0.4.3 typecheck fibo.juvix` | 684.1 ± 5.1 | 674.1 | 691.0 |
1.00 |
| `juvix-v0.5.0 typecheck fibo.juvix` | 695.9 ± 14.2 | 679.0 | 720.6 |
1.02 ± 0.02 |
| `juvix-v0.5.1 typecheck fibo.juvix` | 808.5 ± 18.2 | 780.8 | 848.6 |
1.18 ± 0.03 |
| `juvix-v0.5.2 typecheck fibo.juvix` | 816.0 ± 13.9 | 802.3 | 846.3 |
1.19 ± 0.02 |
| `juvix-v0.5.3 typecheck fibo.juvix` | 1934.3 ± 29.0 | 1907.3 | 1992.1
| 2.83 ± 0.05 |
| `juvix-v0.5.4 typecheck fibo.juvix` | 2106.8 ± 19.6 | 2075.6 | 2138.9
| 3.08 ± 0.04 |
| `juvix typecheck fibo.juvix` | 2135.3 ± 29.9 | 2107.4 | 2183.2 | 3.12
± 0.05 |

## compile -o /dev/null

| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `juvix-v0.4.3 compile -o /dev/null fibo.juvix` | 754.3 ± 4.9 | 745.2 |
759.8 | 1.00 ± 0.01 |
| `juvix-v0.5.0 compile -o /dev/null fibo.juvix` | 752.6 ± 3.9 | 745.2 |
757.6 | 1.00 |
| `juvix-v0.5.1 compile -o /dev/null fibo.juvix` | 845.4 ± 5.7 | 837.6 |
857.0 | 1.12 ± 0.01 |
| `juvix-v0.5.2 compile -o /dev/null fibo.juvix` | 883.7 ± 15.7 | 864.5
| 918.3 | 1.17 ± 0.02 |
| `juvix-v0.5.3 compile -o /dev/null fibo.juvix` | 1990.8 ± 12.5 |
1975.0 | 2010.4 | 2.65 ± 0.02 |
| `juvix-v0.5.4 compile -o /dev/null fibo.juvix` | 2193.9 ± 5.6 | 2182.7
| 2200.5 | 2.91 ± 0.02 |
| `juvix compile -o /dev/null fibo.juvix` | 2197.4 ± 11.6 | 2185.0 |
2226.0 | 2.92 ± 0.02 |

## eval

| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `juvix-v0.4.3 eval fibo.juvix` | 680.9 ± 5.4 | 669.7 | 687.1 | 1.00 |
| `juvix-v0.5.0 eval fibo.juvix` | 681.7 ± 5.0 | 675.0 | 689.8 | 1.00 ±
0.01 |
| `juvix-v0.5.1 eval fibo.juvix` | 772.7 ± 2.7 | 769.0 | 777.9 | 1.13 ±
0.01 |
| `juvix-v0.5.2 eval fibo.juvix` | 796.1 ± 2.7 | 791.9 | 799.5 | 1.17 ±
0.01 |
| `juvix-v0.5.3 eval fibo.juvix` | 1902.2 ± 6.5 | 1889.6 | 1913.2 | 2.79
± 0.02 |
| `juvix-v0.5.4 eval fibo.juvix` | 2101.3 ± 5.9 | 2093.1 | 2112.1 | 3.09
± 0.03 |
| `juvix eval fibo.juvix` | 2111.1 ± 17.4 | 2085.5 | 2148.3 | 3.10 ±
0.04 |

---------

Co-authored-by: Paul Cadman <git@paulcadman.dev>
2023-12-01 18:39:39 +01:00
Jan Mas Rovira
c8e7ce8afd
Remove old typechecker (#2545) 2023-12-01 16:50:37 +01:00
Paul Cadman
77b29c6963
Update to the latest juvix-stdlib (#2546)
This PR updates the juvix-stdlib submodule ref to the current
juvix-stdlib/main.

NB: The Markdown test is not stable after changes to the stdlib - the
ids (deriving from internal name ids?) will change and so the expected
file must be regenerated.
2023-12-01 15:12:54 +01:00
Jan Mas Rovira
c237f292a7
Add dependent defaults for the new typechecker (#2541)
This pr adds support for default values that depend on previous
arguments. For instance, see
[test071](ca7d0fa06d/tests/Compilation/positive/test071.juvix).
- After #2540 is implemented, we'll be able to remove the old type
checker (including the aritychecker).
2023-11-30 19:17:00 +01:00
Paul Cadman
20a95ec42d
Extract builtin definitions for loading a Package into bundled package-base package (#2535)
This PR creates a new package that's bundled with the compiler in a
similar way to the stdlib and the package description package.

## The `package-base` Package

This package is called
[package-base](ab4376cf9e/include/package-base)
and contains the minimal set of definitions required to load a Package
file.

The
[`Juvix.Builtin`](ab4376cf9e/include/package-base/Juvix/Builtin/V1.juvix)
module contains:

```
module Juvix.Builtin.V1;

import Juvix.Builtin.V1.Nat open public;
import Juvix.Builtin.V1.Trait.Natural open public;
import Juvix.Builtin.V1.String open public;
import Juvix.Builtin.V1.Bool open public;
import Juvix.Builtin.V1.Maybe open public;
import Juvix.Builtin.V1.List open public;
import Juvix.Builtin.V1.Fixity open public;
```

`Juvix.Builtin.V1.Bool` is required to support backend primitive
integers `Juvix.Builtin.V1.Trait.Natural` is required to support numeric
literals.

## The `PackageDescription.V2` module

This PR also adds a new
[`PackageDescription.V2`](ab4376cf9e/include/package/PackageDescription/V2.juvix)
type that uses the `package-base`. This is to avoid breaking existing
Package files. The Packages files in the repo (except those that test
`PackageDescription.V1`) have also been updated.

## Updating the stdlib

The standard library will be updated to use `Juvix.Builtin.*` modules in
a subsequent PR.

* Part of https://github.com/anoma/juvix/issues/2511
2023-11-30 16:22:18 +00:00
Jonathan Cubides
7de9f2f0f3
Add new case for positivity checker: type cannot occur as arg of bound var (#2542)
This PR fixes our positivity checker to support inductive definitions
with type families as type parameters. This kind of ind. type is
type-checked using the global flag `--new-type checker.`

For example, the following definition is not allowed:

```
module Evil;

type Evil (f : Type -> Type) :=
  magic : f (Evil f) -> Evil f;
```

- Closes #2540
2023-11-30 15:03:54 +01:00
Jan Mas Rovira
ca7d0fa06d
Negative tests for --new-typechecker (#2532)
Adds all existing negative tests for the new typechecker.
- Depends on #2524
2023-11-28 17:24:03 +00:00
Jan Mas Rovira
d6c1a74cec
Improve inference for --new-typechecker (#2524)
This pr applies a number of fixes to the new typechecker.
The fixes implemented are:
1. When guessing the arity of the body, we properly use the type
information of the variables in the patterns.
2. When generating wildcards, we name them properly so that they align
with the name in the type signature.
3. When compiling named applications, we inline all clauses of the form
`fun : _ := body`. This is a workaround to
https://github.com/anoma/juvix/issues/2247 and
https://github.com/anoma/juvix/issues/2517
4. I've had to ignore test027 (Church numerals). While the typechecker
passes and one can see that the types are correct, there is a lambda
where its clauses have different number of patterns. Our goal is to
support that in the near future
(https://github.com/anoma/juvix/issues/1706). This is the conflicting
lambda:
    ```
    mutual num : Nat → Num
      := λ : Nat → Num {| (zero : Nat) := czero
      | ((suc n : Nat)) {A} := csuc (num n) {A}}
    ```
5. I've added non-trivial a compilation test involving monad
transformers.
2023-11-28 16:43:14 +01:00
Jonathan Cubides
628dd23072
Fix codeblocks indentation in Markdown output (#2539)
- Closes https://github.com/anoma/juvix/issues/2528
- Closes https://github.com/anoma/juvix-docs/issues/95

After this PR is merged, this will fix the misbehaving of code blocks
within !!!/??? Environments spotted in
https://github.com/anoma/juvix-docs/issues/95. The result would be
as expected:

Already deployed, e.g. https://docs.juvix.org/0.5.4/tutorials/learn/

![screencapture-localhost-8000-reference-language-functions-2023-11-24-21_28_39](https://github.com/anoma/juvix/assets/1428088/85877b1a-0428-40b2-b900-147b3f386e8c)
2023-11-27 13:22:44 +01:00
Paul Cadman
d8027fc843
runtime Makefile: Do not resolve variables when writing a dependency file (#2538)
This is an attempt to fix a confusing situation where a user:

1. Builds the runtime with clang that does not support wasm32-wasi
2. Attempts to rebuild the runtime by passing the CC parameter pointing
to another installation of clang that does support wasm32-wasi.

In step 1. the runtime Makefile generates dependencies files which
contain the resolved value of `$(CC)`. When the user passes the correct
`CC` variable to the Makefile in step 2., the dependencies files are not
regenerated, the old value of `CC` is used in the build and the build
continues to fail.

In this PR we change the dependency file generation so that the
variables like `$(CC)` are written into the dependency file verbatim.
They are resolved when they are run in step 2. using the new value of
the CC parameter.

* Closes https://github.com/anoma/juvix/issues/2537
2023-11-27 10:14:20 +01:00
Jonathan Cubides
78bacaaff9
Fix location for aliases (#2536)
- Closes #2531
2023-11-24 19:06:14 +01:00
Jan Mas Rovira
f610518449
Add non-dependent default values to the new typechecking algorithm (#2516)
This pr adds default values (that don't depend on previous default
values) under the new `--new-typechecker` flag.
2023-11-23 11:42:58 +01:00
Paul Cadman
1c1a5b7117
Update the Juvix lock file when the Package file changes (#2522)
Adds a new version of the lock file that stores the hash (sha256 digest)
of the package file (Package.juvix, juvix.yaml) it was generated from as
a field:

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

version: 2
checksum: d05940a4d3dc0e15451d02e1294819c875ba486ee54e26865ba8d190ac7c27c3
dependencies:
- git:
    name: stdlib
    ref: f68b0614ad695eaa13ead42f3466e0a78219f826
    url: https://github.com/anoma/juvix-stdlib.git
  dependencies: []
```

The lock file is regenerated when the hash of the package file doesn't
match the value of the `checksum` field, i.e when the user updates the
package file.

Existing lock files are automatically migrated to version 2.

* Closes https://github.com/anoma/juvix/issues/2464
2023-11-22 23:21:29 +01:00
Paul Cadman
c6586a960d
Fix the global 'package' package so that modules within it can be type-checked independently (#2526)
This PR adds a Package.juvix file to the global 'package' package (that
is the package containing the `PackageDescription.{Basic, V1}` modules.

This means that users can now go-to-definition on Package.juvix types
and identifiers and navigate to fully highlighted
`PackageDescription.{Basic, V1}` modules.

* Closes https://github.com/anoma/juvix/issues/2525
2023-11-21 15:20:00 +00:00
Paul Cadman
8bbf089d63
Release 0.5.4 (#2523)
This PR updates:
- [x] Package version
- [x] Smoke test
- [x] Changelog
2023-11-17 16:47:00 +00:00
Jonathan Cubides
dd43f07905
Fix #2510 (#2512)
- Close #2510 
- Close #2518 
- Progress for #2520
2023-11-17 16:10:38 +01:00
Paul Cadman
2f4a3f809b
Run test suite in parallel (#2507)
## Overview

This PR makes the compiler pipeline thread-safe so that the test suite
can be run in parallel.

This is achieved by:
* Removing use of `{get, set, with}CurrentDir` functions.
* Adding locking around shared file resources like the the
global-project and internal build directory.

NB: **Locking is disabled for the main compiler target**, as it is
single threaded they are not required.

## Run test suite in parallel

To run the test suite in parallel you must add `--ta '+RTS -N -RTS'` to
your stack test arguments. For example:

```
stack test --fast --ta '+RTS -N -RTS'
```

The `-N` instructs the Haskell runtime to choose the number of threads
to use based on how many processors there are on your machine. You can
use `-Nn` to see the number of threads to `n`.

These flags are already [set in the
Makefile](e6dca22cfd/Makefile (L26))
when you or CI uses `stack test`.

## Locking

The Haskell package
[filelock](https://hackage.haskell.org/package/filelock) is used for
locking. File locks are used instead of MVars because Juvix code does
not control when new threads are created, they are created by the test
suite. This means that MVars created by Juvix code will have no effect,
because they are created independently on each test-suite thread.
Additionally the resources we're locking live on the filesystem and so
can be conveniently tagged by path.

### FileLock

The filelock library is wrapped in a FileLock effect:


e6dca22cfd/src/Juvix/Data/Effect/FileLock/Base.hs (L6-L8)

There is an [IO
interpreter](e6dca22cfd/src/Juvix/Data/Effect/FileLock/IO.hs (L8))
that uses filelock and an [no-op
interpreter](e6dca22cfd/src/Juvix/Data/Effect/FileLock/Permissive.hs (L7))
that just runs actions unconditionally.

### TaggedLock

To make the file locks simpler to use a TaggedLock effect is introduced:


e6dca22cfd/src/Juvix/Data/Effect/TaggedLock/Base.hs (L5-L11)

And convenience function:


e6dca22cfd/src/Juvix/Data/Effect/TaggedLock.hs (L28)

This allows an action to be locked, tagged by a directory that may or
may not exist. For example in the following code, an action is performed
on a directory `root` that may delete the directory before repopulating
the files. So the lockfile cannot be stored in the `root` itself.


e6dca22cfd/src/Juvix/Extra/Files.hs (L55-L60)

## Pipeline

As noted above, we only use locking in the test suite. The main app
target pipeline is single threaded and so locking is unnecessary. So the
interpretation of locks is parameterised so that locking can be disabled
e6dca22cfd/src/Juvix/Compiler/Pipeline/Run.hs (L64)
2023-11-16 16:19:52 +01:00
Jonathan Cubides
8616370fb2
Add MarkdownInfo entry in Module Concrete Decl and proper errors (#2515)
Remove TODO added by @janmasrovira in 
- https://github.com/anoma/juvix/pull/2513
2023-11-16 11:20:34 +01:00
Jan Mas Rovira
90200ab6de
General inductive parameters (#2506)
- Depends on #2481 

This pr allows inductive type parameters to be any type. Until now, they
had to be exactly `Type`. This allows us to define more general traits
such as the `Monad` and `Functor`, as shown in the new test.
This is only supported under the temporary `--new-typechecker` flag.

Pending work:

Update the positivity checker if necessary (@jonaprieto).
Update the necessary compilation steps in Core (@lukaszcz).
Add compilation tests.
2023-11-15 10:24:54 +01:00
Paul Cadman
7b5211664e
Add PackageDescription.Basic module Package variant (#2509)
This PR adds the `PackageDescription.Basic` module, available to
Package.juvix files.

```
module Package;

import PackageDescription.Basic open;

package : Package := basicPackage;
```

The `PackageDescription.Basic` module provides a Package type that is
translated to a Juvix Package with all default arguments. It is not
possible to customize a basic package.

A basic package does not depend on the standard library, so loads much
more quickly.

Additionally this PR:
* Adds `juvix init --basic/-b` option to generate a basic Package.juvix.
* Migrates Package.juvix files that only use default arguments, or only
customise the name field, to basic Package files.

* Closes https://github.com/anoma/juvix/issues/2508
2023-11-13 17:36:18 +00:00
Jonathan Cubides
19c2aa2437
Fix Bank Example (#2514)
While searching for any pending TODO, I came across this one and
resolved it.
2023-11-13 12:07:24 +01:00
Jan Mas Rovira
a05586e44f
Interleave arity and typechecking (#2481)
- Closes #2362 

This pr implements a new typechecking algorithm. This algorithm can be
activated using the global flag `--new-typechecker`. This flag will only
take effect on the compilation pipeline but not the repl.

The main difference between the new and old algorithm is that the new
one inserts holes during typechecking. Thus, it does not require the
arity checker pass.

The new algorithm does not yet implement default arguments. The plan is
to make the change in the following steps:
1. Merge this pr.
2. Merge #2506.
3. Implement default arguments for the new algorithm.
4. Remove the arity checker and the old algorithm.

---------

Co-authored-by: Łukasz Czajka <62751+lukaszcz@users.noreply.github.com>
2023-11-12 16:23:33 +01:00
Jan Mas Rovira
bdb0d9a662
Refactor markdown parsing (#2513) 2023-11-10 19:36:21 +01:00
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
31f519be4e
test: Run juvix format on juvix packages rather than files (#2505)
We can run `juvix format` on a whole juvix packages instead of
individual files.

This reduces the total time for `make check-format-juvix-files` from 10m
to 3m on my machine.
2023-11-08 15:54:35 +00:00
Łukasz Czajka
4f2382df32
Fix clone in subsHoles (#2504)
Fix `clone` (it was in the wrong place) introduced in
https://github.com/anoma/juvix/pull/2501
2023-11-08 15:02:21 +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
473ed259a5
Refresh bound variable ids when substituting in Internal (#2501)
* Closes #2476 

Bound variable ids need to be refreshed to maintain the invariant that
each bound variable has a unique id.
2023-11-07 15:26:18 +01: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
Paul Cadman
7f009ce14c
Cache .hie directory in CI (#2490)
We use the options in `package.yaml`.

```
         - -fhide-source-paths
         - -fwrite-ide-info -hiedir=.hie
```
If a previously available .hie directory is missing then GHC will
rebuild the whole project with reason: `[HIE file is missing]`. So we
need to cache it to take advantage of incremental builds.
2023-11-01 14:15:53 +01: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
Artem Gureev
a0bcacb0fe
Update Lisp File Printer (#2484)
Updates the compiled Lisp files for Geb usage by adding exports of the
int type as well as exporting the main entry parameter.
2023-10-31 14:18:04 +01:00
Paul Cadman
cbee146bd7
Rename Roots type to Root (#2480)
This was suggested by @jonaprieto in
https://github.com/anoma/juvix/pull/2458#discussion_r1368476371 - but we
deferred it until the Package file PR sequence was merged.
2023-10-30 14:05:52 +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
785f02ddc9
Use a versioned documentation link in the doctor output (#2475)
Previously the doctor help links would point to the Juvix documentation
dev URLs.

Now the doctor help links point to the version of the documentation
corresponding to the compiler version.

```
$ juvix doctor
> Checking for clang...
> Checking clang version...
> Checking for wasm-ld...
> Checking that clang supports wasm32...
> Checking that clang supports wasm32-wasi...
> Checking that WASI_SYSROOT_PATH is set...
  ! Environment variable WASI_SYSROOT_PATH is missing
  ! https://docs.juvix.org/0.5.2/reference/tooling/doctor/#environment-variable-wasi_sysroot_path-is-not-set
> Checking for wasmer...
> Checking latest Juvix release on Github...
```

Spotted by @agureev
2023-10-26 11:51:48 +01: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
Paul Cadman
32449e1212
Use system locale independent readFile and writeFile APIs from with-utf8 (#2473)
The problem with readFile and writeFile from text
[Data.Text.IO](https://hackage.haskell.org/package/text-2.0.2/docs/Data-Text-IO.html)
is that they use the system locale to determine the text encoding
format.

Our assumption is that all Juvix source files are UTF-8 encoded.

I cannot reproduce the issue with using the old APIs on my machine, it
can be reproduced on Arch linux. I'm not sure how to write a specific
test for this.

* Closes https://github.com/anoma/juvix/issues/2472
2023-10-26 09:13:33 +01:00