mirror of
https://github.com/unisonweb/unison.git
synced 2024-09-11 10:35:57 +03:00
Update the transcripts with cmark
`cmark`’s pretty-printer matches our output pretty well, with a few differences: - it puts a space between the fence and the info string for in code blocks; - it prefers `-` over `*` for bulleted lists (as do I) and it indents them; - it `\`-escapes certain chars very conservatively; - it prefers indented/unfenced code blocks if there is no info string; and - it prefers `*` over `_` (unlike any sane person). This also shows how the change fixes a number of issues: - fix2158-1.output.md also illustrates how this change fixes #1809; - alias-many.output.md and input-parse-errors.output.md show how fenced code blocks without an info string would use the beginning of the content as the info string; - transcripts-round-trip/main.output.md shows how output blocks for generated `unison` stanzas (which could contain nested fenced blocks) might not have long-enough fences; and - error-messages.output.md and generic-parse-errors.output.md show how Unison errors were reported on the wrong line number (and thus the printed error lines were also incorrect).
This commit is contained in:
parent
9e2fa2bbe7
commit
1dc181b99a
@ -1,4 +1,3 @@
|
||||
|
||||
## Structural find and replace
|
||||
|
||||
Here's a scratch file with some rewrite rules:
|
||||
|
@ -30,7 +30,7 @@ So we can see the pretty-printed output:
|
||||
definitions currently in this namespace.
|
||||
|
||||
```
|
||||
```unison:added-by-ucm scratch.u
|
||||
````` unison:added-by-ucm scratch.u
|
||||
structural ability Abort where abort : {Abort} a
|
||||
|
||||
structural ability Ask a where ask : {Ask a} a
|
||||
@ -766,7 +766,7 @@ UUID.randomUUIDBytes = do
|
||||
|
||||
(|>) : a -> (a ->{e} b) ->{e} b
|
||||
a |> f = f a
|
||||
```
|
||||
`````
|
||||
|
||||
This diff should be empty if the two namespaces are equivalent. If it's nonempty, the diff will show us the hashes that differ.
|
||||
|
||||
@ -795,7 +795,7 @@ x = ()
|
||||
definitions currently in this namespace.
|
||||
|
||||
```
|
||||
```unison:added-by-ucm scratch.u
|
||||
```` unison:added-by-ucm scratch.u
|
||||
explanationOfThisFile : Text
|
||||
explanationOfThisFile =
|
||||
"""
|
||||
@ -815,7 +815,7 @@ sloppyDocEval =
|
||||
1 + 1
|
||||
```
|
||||
}}
|
||||
```
|
||||
````
|
||||
|
||||
These are currently all expected to have different hashes on round trip.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Test for code serialization operations.
|
||||
|
||||
Define a function, serialize it, then deserialize it back to an actual
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
Unison documentation is written in Unison and has some neat features:
|
||||
|
||||
* The documentation type provides a rich vocabulary of elements that go beyond markdown, including asides, callouts, tooltips, and more.
|
||||
* Docs may contain Unison code which is parsed and typechecked to ensure validity. No more out of date examples that don't compile or assume a bunch of implicit context!
|
||||
* Embeded examples are live and can show the results of evaluation. This uses the same evaluation cache as Unison's scratch files, allowing Unison docs to function like well-commented spreadsheets or notebooks.
|
||||
* Links to other definitions are typechecked to ensure they point to valid definitions. The links are resolved to hashes and won't be broken by name changes or moving definitions around.
|
||||
* Docs can be included in other docs and you can assemble documentation programmatically, using Unison code.
|
||||
* There's a powerful textual syntax for all of the above, which we'll introduce next.
|
||||
- The documentation type provides a rich vocabulary of elements that go beyond markdown, including asides, callouts, tooltips, and more.
|
||||
- Docs may contain Unison code which is parsed and typechecked to ensure validity. No more out of date examples that don't compile or assume a bunch of implicit context\!
|
||||
- Embeded examples are live and can show the results of evaluation. This uses the same evaluation cache as Unison's scratch files, allowing Unison docs to function like well-commented spreadsheets or notebooks.
|
||||
- Links to other definitions are typechecked to ensure they point to valid definitions. The links are resolved to hashes and won't be broken by name changes or moving definitions around.
|
||||
- Docs can be included in other docs and you can assemble documentation programmatically, using Unison code.
|
||||
- There's a powerful textual syntax for all of the above, which we'll introduce next.
|
||||
|
||||
## Introduction
|
||||
|
||||
@ -769,3 +769,4 @@ scratch/main> display doc.guide
|
||||
|
||||
```
|
||||
🌻 THE END
|
||||
|
||||
|
@ -36,6 +36,7 @@ some subtyping.
|
||||
|
||||
However, the ability handling was just processing rows in whatever
|
||||
order they occurred, and during inference it happened that `g`
|
||||
occurred in the row before `Async t g. Processing the stricter parts
|
||||
occurred in the row before `Async t g`. Processing the stricter parts
|
||||
first is better, becauase it can solve things more precisely and avoid
|
||||
ambiguities relating to subtyping.
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
This tests a case where a function was somehow discarding abilities.
|
||||
|
||||
|
||||
``` unison
|
||||
structural ability Trivial where
|
||||
trivial : ()
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Tests a former error due to bad calling conventions on delay.impl
|
||||
|
||||
``` unison
|
||||
|
@ -38,7 +38,7 @@ go = do
|
||||
|
||||
|
||||
```
|
||||
This comes from issue #3513
|
||||
This comes from issue \#3513
|
||||
|
||||
``` unison
|
||||
(<<) : (b ->{e} c) -> (a ->{e} b) -> a ->{e} c
|
||||
|
@ -177,7 +177,7 @@ Note that the universal versions of `hash` and `hmac` are currently unimplemente
|
||||
```
|
||||
## Hashing tests
|
||||
|
||||
Here are some test vectors (taken from [here](https://www.di-mgt.com.au/sha_testvectors.html) and [here](https://en.wikipedia.org/wiki/BLAKE_(hash_function))) for the various hashing algorithms:
|
||||
Here are some test vectors (taken from [here](https://www.di-mgt.com.au/sha_testvectors.html) and [here](https://en.wikipedia.org/wiki/BLAKE_\(hash_function\))) for the various hashing algorithms:
|
||||
|
||||
``` unison
|
||||
ex alg input expected = checks [hashBytes alg (ascii input) == fromHex expected]
|
||||
|
@ -9,7 +9,6 @@ MVars are the building block on which many other concurrency
|
||||
primitives can be built, such as Futures, Run at most once initializer
|
||||
blocks, Queues, etc.
|
||||
|
||||
|
||||
``` unison
|
||||
eitherCk : (a -> Boolean) -> Either e a -> Boolean
|
||||
eitherCk f = cases
|
||||
|
@ -16,14 +16,13 @@ socketAccept = compose reraise socketAccept.impl
|
||||
This section tests functions in the IO builtin related to binding to
|
||||
TCP server socket, as to be able to accept incoming TCP connections.
|
||||
|
||||
```builtin
|
||||
.io2.IO.serverSocket : Optional Text -> Text ->{io2.IO} Either Failure io2.Socket
|
||||
|
||||
```
|
||||
builtin.io2.IO.serverSocket : Optional Text -> Text ->{io2.IO} Either Failure io2.Socket
|
||||
```
|
||||
|
||||
This function takes two parameters, The first is the Hostname. If None
|
||||
is provided, We will attempt to bind to 0.0.0.0 (All ipv4
|
||||
addresses). We currently only support IPV4 (we should fix this!)
|
||||
addresses). We currently only support IPV4 (we should fix this\!)
|
||||
The second is the name of the port to bind to. This can be
|
||||
a decimal representation of a port number between 1-65535. This can be
|
||||
a named port like "ssh" (for port 22) or "kermit" (for port 1649),
|
||||
|
@ -1,5 +1,6 @@
|
||||
Loops that access a shared counter variable, accessed in transactions.
|
||||
Some thread delaying is just accomplished by counting in a loop.
|
||||
|
||||
``` unison
|
||||
count : Nat -> ()
|
||||
count = cases
|
||||
|
@ -54,7 +54,7 @@ scratch/main> add
|
||||
Tip: Use `help filestatus` to learn more.
|
||||
|
||||
```
|
||||
---
|
||||
-----
|
||||
|
||||
``` unison
|
||||
y = 42
|
||||
|
@ -1,4 +1,4 @@
|
||||
Test for new Text -> Bytes conversions explicitly using UTF-8 as the encoding
|
||||
Test for new Text -\> Bytes conversions explicitly using UTF-8 as the encoding
|
||||
|
||||
Unison has function for converting between `Text` and a UTF-8 `Bytes` encoding of the Text.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Some random ability stuff to ensure things work.
|
||||
|
||||
``` unison
|
||||
|
@ -31,7 +31,7 @@ scratch/main> add
|
||||
ability Channels
|
||||
|
||||
```
|
||||
Now we update the ability, changing the name of the constructor, _but_, we simultaneously
|
||||
Now we update the ability, changing the name of the constructor, *but*, we simultaneously
|
||||
add a new top-level term with the same name as the constructor which is being
|
||||
removed from Channels.
|
||||
|
||||
@ -89,7 +89,7 @@ scratch/main> update.old patch thing
|
||||
ability Channels
|
||||
|
||||
```
|
||||
If however, `Channels.send` and `thing` _depend_ on `Channels`, updating them should succeed since it pulls in the ability as a dependency.
|
||||
If however, `Channels.send` and `thing` *depend* on `Channels`, updating them should succeed since it pulls in the ability as a dependency.
|
||||
|
||||
``` unison
|
||||
unique ability Channels where
|
||||
|
@ -47,6 +47,7 @@ scratch/main> run is2even
|
||||
```
|
||||
it errors if the desired result name conflicts with a name in the
|
||||
unison file
|
||||
|
||||
```ucm
|
||||
scratch/main> add.run is2even
|
||||
|
||||
@ -57,6 +58,7 @@ scratch/main> add.run is2even
|
||||
|
||||
```
|
||||
otherwise, the result is successfully persisted
|
||||
|
||||
```ucm
|
||||
scratch/main> add.run foo.bar.baz
|
||||
|
||||
@ -223,6 +225,7 @@ x = 50
|
||||
|
||||
```
|
||||
this saves 2 to xres, rather than 100
|
||||
|
||||
```ucm
|
||||
scratch/main> add.run xres
|
||||
|
||||
|
@ -3,7 +3,7 @@ test> foo : [Test.Result]
|
||||
foo = []
|
||||
```
|
||||
|
||||
Apparently when we add a test watch, we add a type annotation to it, even if it already has one. We don't want this to happen though!
|
||||
Apparently when we add a test watch, we add a type annotation to it, even if it already has one. We don't want this to happen though\!
|
||||
|
||||
```ucm
|
||||
scratch/main> add
|
||||
|
@ -1,17 +1,14 @@
|
||||
The `alias.many` command can be used to copy definitions from the current namespace into your curated one.
|
||||
The names that will be used in the target namespace are the names you specify, relative to the current namespace:
|
||||
|
||||
```scratch
|
||||
/main> help alias.many
|
||||
scratch/main> help alias.many
|
||||
|
||||
alias.many (or copy)
|
||||
`alias.many <relative1> [relative2...] <namespace>` creates aliases `relative1`, `relative2`, ...
|
||||
in the namespace `namespace`.
|
||||
`alias.many foo.foo bar.bar .quux` creates aliases `.quux.foo.foo` and `.quux.bar.bar`.
|
||||
|
||||
```
|
||||
|
||||
Let's try it!
|
||||
Let's try it\!
|
||||
|
||||
```ucm
|
||||
scratch/main> alias.many List.adjacentPairs List.all List.any List.chunk List.chunksOf List.dropWhile List.first List.init List.intersperse List.isEmpty List.last List.replicate List.splitAt List.tail List.takeWhile mylib
|
||||
@ -62,4 +59,5 @@ scratch/main> find-in mylib
|
||||
|
||||
|
||||
```
|
||||
Thanks, `alias.many!
|
||||
Thanks, `alias.many`\!
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
|
||||
This tests a variable related bug in the ANF compiler.
|
||||
|
||||
The nested let would get flattened out, resulting in:
|
||||
|
||||
bar = result
|
||||
|
||||
which would be handled by renaming. However, the _context_ portion of
|
||||
which would be handled by renaming. However, the *context* portion of
|
||||
the rest of the code was not being renamed correctly, so `bar` would
|
||||
remain in the definition of `baz`.
|
||||
|
||||
|
@ -103,7 +103,7 @@ ex thing =
|
||||
4201
|
||||
|
||||
```
|
||||
Here's another example, showing that bindings cannot reference bindings declared in blocks nested in the _body_ (the final expression) of a block:
|
||||
Here's another example, showing that bindings cannot reference bindings declared in blocks nested in the *body* (the final expression) of a block:
|
||||
|
||||
``` unison
|
||||
ex thing =
|
||||
@ -137,7 +137,7 @@ ex thing =
|
||||
```
|
||||
### Blocks can define one or more functions which are recursive or mutually recursive
|
||||
|
||||
We call these groups of definitions that reference each other in a block _cycles_. For instance:
|
||||
We call these groups of definitions that reference each other in a block *cycles*. For instance:
|
||||
|
||||
``` unison
|
||||
sumTo n =
|
||||
@ -253,7 +253,7 @@ ex n =
|
||||
ex : n -> r
|
||||
|
||||
```
|
||||
Just don't try to run it as it's an infinite loop!
|
||||
Just don't try to run it as it's an infinite loop\!
|
||||
|
||||
### Cyclic definitions in a block don't have access to any abilities
|
||||
|
||||
@ -279,7 +279,7 @@ ex n =
|
||||
|
||||
|
||||
```
|
||||
### The _body_ of recursive functions can certainly access abilities
|
||||
### The *body* of recursive functions can certainly access abilities
|
||||
|
||||
For instance, this works fine:
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
We can display the guide before and after adding it to the codebase:
|
||||
|
||||
```ucm
|
||||
|
@ -153,6 +153,7 @@ test> Nat.tests.conversions =
|
||||
```
|
||||
|
||||
## `Boolean` functions
|
||||
|
||||
``` unison
|
||||
test> Boolean.tests.orTable =
|
||||
checks [
|
||||
@ -345,6 +346,7 @@ test> checks [
|
||||
```
|
||||
|
||||
Other list functions
|
||||
|
||||
``` unison
|
||||
test> checks [
|
||||
List.take bigN [1,2,3] == [1,2,3],
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
This should render as `Bytes.fromList [1,2,3,4]`, not `##Bytes.fromSequence [1,2,3,4]`:
|
||||
|
||||
``` unison
|
||||
|
@ -72,4 +72,5 @@ scratch/main> view inner.ping
|
||||
```
|
||||
The bug here is that `inner.ping` still refers to `pong` by name. But if we properly identified the nameless (in the
|
||||
context that the update was applied) `pong` as an implicit term to include in the new `ping`'s cycle, then `ping` would
|
||||
be left referring to a nameless thing (namely, `pong`, but updated to refer to the new `ping).
|
||||
be left referring to a nameless thing (namely, `pong`, but updated to refer to the new `ping`).
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
First we'll set up two libraries, and then we'll use them in some projects and show what `names` are deep-loaded for them.
|
||||
|
||||
Our two "libraries":
|
||||
|
||||
``` unison
|
||||
text.a = 1
|
||||
text.b = 2
|
||||
@ -12,6 +13,7 @@ http.z = 8
|
||||
```
|
||||
|
||||
Our `app1` project includes the text library twice and the http library twice as direct dependencies.
|
||||
|
||||
```ucm
|
||||
scratch/app1> fork text lib.text_v1
|
||||
|
||||
@ -39,6 +41,7 @@ scratch/app1> delete.namespace http
|
||||
|
||||
```
|
||||
As such, we see two copies of `a` and two copies of `x` via these direct dependencies.
|
||||
|
||||
```ucm
|
||||
scratch/app1> names a
|
||||
|
||||
@ -59,6 +62,7 @@ scratch/app1> names x
|
||||
```
|
||||
Our `app2` project includes the `http` library twice as direct dependencies, and once as an indirect dependency via `webutil`.
|
||||
It also includes the `text` library twice as indirect dependencies via `webutil`
|
||||
|
||||
```ucm
|
||||
scratch/app2> fork http lib.http_v1
|
||||
|
||||
@ -91,6 +95,7 @@ scratch/app2> delete.namespace text
|
||||
```
|
||||
Now we see two copies of `x` via direct dependencies on `http`, and one copy of `a` via indirect dependency on `text` via `webutil`.
|
||||
We see neither the second indirect copy of `a` nor the indirect copy of `x` via webutil because we already have names for them.
|
||||
|
||||
```ucm
|
||||
scratch/app2> names a
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
# Delete namespace dependents check
|
||||
|
||||
This is a regression test, previously `delete.namespace` allowed a delete as long as the deletions had a name _anywhere_ in your codebase, it should only check the current project branch.
|
||||
This is a regression test, previously `delete.namespace` allowed a delete as long as the deletions had a name *anywhere* in your codebase, it should only check the current project branch.
|
||||
|
||||
``` unison
|
||||
sub.dependency = 123
|
||||
|
@ -1,7 +1,9 @@
|
||||
### `debug.file`
|
||||
|
||||
I can use `debug.file` to see the hashes of the last typechecked file.
|
||||
|
||||
Given this .u file:
|
||||
|
||||
``` unison
|
||||
structural type outside.A = A Nat outside.B
|
||||
structural type outside.B = B Int
|
||||
@ -30,7 +32,9 @@ scratch/main> debug.file
|
||||
This will help me make progress in some situations when UCM is being deficient or broken.
|
||||
|
||||
### `dependents` / `dependencies`
|
||||
|
||||
But wait, there's more. I can check the dependencies and dependents of a definition:
|
||||
|
||||
```ucm
|
||||
scratch/main> add
|
||||
|
||||
@ -110,3 +114,4 @@ scratch/main> dependents d
|
||||
|
||||
```
|
||||
We don't have an index for dependents of constructors, but iirc if you ask for that, it will show you dependents of the structural type that provided the constructor.
|
||||
|
||||
|
@ -58,14 +58,14 @@ b2.abc = 23
|
||||
```
|
||||
Things we want to test:
|
||||
|
||||
* Diffing identical namespaces
|
||||
* Adds, removes, updates
|
||||
* Adds with multiple names
|
||||
* Moved and copied definitions
|
||||
* Moves that have more that 1 initial or final name
|
||||
* ... terms and types
|
||||
* New patches, modified patches, deleted patches, moved patches
|
||||
* With and without propagated updates
|
||||
- Diffing identical namespaces
|
||||
- Adds, removes, updates
|
||||
- Adds with multiple names
|
||||
- Moved and copied definitions
|
||||
- Moves that have more that 1 initial or final name
|
||||
- ... terms and types
|
||||
- New patches, modified patches, deleted patches, moved patches
|
||||
- With and without propagated updates
|
||||
|
||||
``` unison
|
||||
fromJust = 1
|
||||
@ -489,43 +489,44 @@ Updates: -- 1 to 1
|
||||
|
||||
New name conflicts: -- updates where RHS has multiple hashes (excluding when RHS=LHS)
|
||||
|
||||
1. foo#jk19sm5bf8 : Nat - do we want to force a hashqualified? Arya thinks so
|
||||
1. foo\#jk19sm5bf8 : Nat - do we want to force a hashqualified? Arya thinks so
|
||||
↓
|
||||
2. ┌ foo#0ja1qfpej6 : Nat
|
||||
3. └ foo#jk19sm5bf8 : Nat
|
||||
2. ┌ foo\#0ja1qfpej6 : Nat
|
||||
3. └ foo\#jk19sm5bf8 : Nat
|
||||
|
||||
Resolved name conflicts: -- updates where LHS had multiple hashes and RHS has one
|
||||
|
||||
4. ┌ bar#0ja1qfpej6 : Nat
|
||||
5. └ bar#jk19sm5bf8 : Nat
|
||||
4. ┌ bar\#0ja1qfpej6 : Nat
|
||||
5. └ bar\#jk19sm5bf8 : Nat
|
||||
↓
|
||||
6. bar#jk19sm5bf8 : Nat
|
||||
6. bar\#jk19sm5bf8 : Nat
|
||||
|
||||
## Display issues to fixup
|
||||
|
||||
- [d] Do we want to surface new edit conflicts in patches?
|
||||
- [t] two different auto-propagated changes creating a name conflict should show
|
||||
- \[d\] Do we want to surface new edit conflicts in patches?
|
||||
- \[t\] two different auto-propagated changes creating a name conflict should show
|
||||
up somewhere besides the auto-propagate count
|
||||
- [t] Things look screwy when the type signature doesn't fit and has to get broken
|
||||
- \[t\] Things look screwy when the type signature doesn't fit and has to get broken
|
||||
up into multiple lines. Maybe just disallow that?
|
||||
- [d] Delete blank line in between copies / renames entries if all entries are 1 to 1
|
||||
- \[d\] Delete blank line in between copies / renames entries if all entries are 1 to 1
|
||||
see todo in the code
|
||||
- [x] incorrectly calculated bracket alignment on hashqualified "Name changes" (delete.output.md)
|
||||
- [x] just handle deletion of isPropagated in propagate function, leave HandleInput alone (assuming this does the trick)
|
||||
- [x] might want unqualified names to be qualified sometimes:
|
||||
- [x] if a name is updated to a not-yet-named reference, it's shown as both an update and an add
|
||||
- [x] similarly, if a conflicted name is resolved by deleting the last name to
|
||||
- \[x\] incorrectly calculated bracket alignment on hashqualified "Name changes" (delete.output.md)
|
||||
- \[x\] just handle deletion of isPropagated in propagate function, leave HandleInput alone (assuming this does the trick)
|
||||
- \[x\] might want unqualified names to be qualified sometimes:
|
||||
- \[x\] if a name is updated to a not-yet-named reference, it's shown as both an update and an add
|
||||
- \[x\] similarly, if a conflicted name is resolved by deleting the last name to
|
||||
a reference, I (arya) suspect it will show up as a Remove
|
||||
- [d] Maybe group and/or add headings to the types, constructors, terms
|
||||
- [x] add tagging of propagated updates to test propagated updates output
|
||||
- [x] missing old names in deletion ppe (delete.output.md) (superseded by \#1143)
|
||||
- [x] delete.term has some bonkers output
|
||||
- [x] Make a decision about how we want to show constructors in the diff
|
||||
- [x] 12.patch patch needs a space
|
||||
- [x] This looks like garbage
|
||||
- [x] Extra 2 blank lines at the end of the add section
|
||||
- [x] Fix alignment issues with buildTable, convert to column3M (to be written)
|
||||
- [x] adding an alias is showing up as an Add and a Copy; should just show as Copy
|
||||
- [x] removing one of multiple aliases appears in removes + moves + copies section
|
||||
- [x] some overlapping cases between Moves and Copies^
|
||||
- [x] Maybe don't list the type signature twice for aliases?
|
||||
- \[d\] Maybe group and/or add headings to the types, constructors, terms
|
||||
- \[x\] add tagging of propagated updates to test propagated updates output
|
||||
- \[x\] missing old names in deletion ppe (delete.output.md) (superseded by \#1143)
|
||||
- \[x\] delete.term has some bonkers output
|
||||
- \[x\] Make a decision about how we want to show constructors in the diff
|
||||
- \[x\] 12.patch patch needs a space
|
||||
- \[x\] This looks like garbage
|
||||
- \[x\] Extra 2 blank lines at the end of the add section
|
||||
- \[x\] Fix alignment issues with buildTable, convert to column3M (to be written)
|
||||
- \[x\] adding an alias is showing up as an Add and a Copy; should just show as Copy
|
||||
- \[x\] removing one of multiple aliases appears in removes + moves + copies section
|
||||
- \[x\] some overlapping cases between Moves and Copies^
|
||||
- \[x\] Maybe don't list the type signature twice for aliases?
|
||||
|
||||
|
@ -510,6 +510,7 @@ test2 = [:
|
||||
|
||||
```
|
||||
View is fine.
|
||||
|
||||
```ucm
|
||||
scratch/main> view test2
|
||||
|
||||
@ -521,6 +522,7 @@ scratch/main> view test2
|
||||
|
||||
```
|
||||
But note it's not obvious how display should best be handling this. At the moment it just does the simplest thing:
|
||||
|
||||
```ucm
|
||||
scratch/main> display test2
|
||||
|
||||
|
@ -43,11 +43,11 @@ Syntax:
|
||||
|
||||
`[:` starts a documentation block; `:]` finishes it. Within the block:
|
||||
|
||||
* Links to definitions are done with `@List`. `\@` (and `\:]`) if you want to escape.
|
||||
* `@[signature] List.take` expands to the type signature of `List.take`
|
||||
* `@[source] List.map` expands to the full source of `List.map`
|
||||
* `@[include] someOtherDoc`, inserts a value `someOtherDoc : Doc` here.
|
||||
* `@[evaluate] someDefinition` expands to the result of evaluating `someDefinition`, which must be a pre-existing definition in the codebase (can't be an arbitrary expression).
|
||||
- Links to definitions are done with `@List`. `\@` (and `\:]`) if you want to escape.
|
||||
- `@[signature] List.take` expands to the type signature of `List.take`
|
||||
- `@[source] List.map` expands to the full source of `List.map`
|
||||
- `@[include] someOtherDoc`, inserts a value `someOtherDoc : Doc` here.
|
||||
- `@[evaluate] someDefinition` expands to the result of evaluating `someDefinition`, which must be a pre-existing definition in the codebase (can't be an arbitrary expression).
|
||||
|
||||
### An example
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
If `foo#old` exists in old, and `foo#new` exists in new, you might think `upgrade old new` would rewrite references to
|
||||
`#old` with references to `#new`. And it will... !!unless!! `#old` still exists in new.
|
||||
`#old` with references to `#new`. And it will... \!\!unless\!\! `#old` still exists in new.
|
||||
|
||||
``` unison
|
||||
lib.old.foo = 18
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
up = 0xs0123456789abcdef
|
||||
down = 0xsfedcba9876543210
|
||||
|
@ -16,7 +16,6 @@ mytest = [Ok "ok"]
|
||||
|
||||
```
|
||||
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in /private/tmp/scratch.u.
|
||||
|
@ -5,6 +5,7 @@ mynamespace.x = 1
|
||||
```
|
||||
|
||||
The deleted namespace shouldn't appear in `ls` output.
|
||||
|
||||
```ucm
|
||||
scratch/main> ls
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
The Unison codebase, when first initialized, contains no definitions in its namespace.
|
||||
|
||||
Not even `Nat` or `+`!
|
||||
Not even `Nat` or `+`\!
|
||||
|
||||
BEHOLD!!!
|
||||
BEHOLD\!\!\!
|
||||
|
||||
```ucm
|
||||
scratch/main> ls
|
||||
@ -37,4 +37,5 @@ scratch/main> ls lib
|
||||
2. builtinsio/ (643 terms, 92 types)
|
||||
|
||||
```
|
||||
More typically, you'd start out by pulling `base.
|
||||
More typically, you'd start out by pulling `base`.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
This file contains programs with parse errors and type errors, for visual inspection of error message quality and to check for regressions or changes to error reporting.
|
||||
|
||||
## Parse errors
|
||||
@ -212,7 +211,8 @@ foo = match 1 with
|
||||
|
||||
I got confused here:
|
||||
|
||||
3 |
|
||||
2 | 2 -- no right-hand-side
|
||||
|
||||
|
||||
I was surprised to find an end of section here.
|
||||
I was expecting one of these instead:
|
||||
@ -258,7 +258,8 @@ x = match Some a with
|
||||
|
||||
I got confused here:
|
||||
|
||||
7 |
|
||||
6 | 2
|
||||
|
||||
|
||||
I was surprised to find an end of section here.
|
||||
I was expecting one of these instead:
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
When an error is encountered in a `unison:hide:all` block
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
When an error is encountered in a `unison:hide:all` block
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
Dangerous scary words!
|
||||
Dangerous scary words\!
|
||||
|
||||
When an expected error is not encountered in a `ucm:hide:all` block
|
||||
then the transcript parser should print the stanza
|
||||
@ -12,6 +11,7 @@ scratch/main> history
|
||||
```
|
||||
|
||||
|
||||
|
||||
🛑
|
||||
|
||||
The transcript was expecting an error in the stanza above, but did not encounter one.
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
Dangerous scary words!
|
||||
Dangerous scary words\!
|
||||
|
||||
When an error is encountered in a `ucm:hide:all` block
|
||||
then the transcript parser should print the stanza
|
||||
@ -12,6 +11,7 @@ scratch/main> move.namespace foo bar
|
||||
```
|
||||
|
||||
|
||||
|
||||
🛑
|
||||
|
||||
The transcript failed due to an error in the stanza above. The error is:
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
Dangerous scary words!
|
||||
Dangerous scary words\!
|
||||
|
||||
When an expected error is not encountered in a `ucm:hide` block
|
||||
then the transcript parser should print the stanza
|
||||
@ -12,6 +11,7 @@ scratch/main> history
|
||||
```
|
||||
|
||||
|
||||
|
||||
🛑
|
||||
|
||||
The transcript was expecting an error in the stanza above, but did not encounter one.
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
Dangerous scary words!
|
||||
Dangerous scary words\!
|
||||
|
||||
When an error is encountered in a `ucm:hide` block
|
||||
then the transcript parser should print the stanza
|
||||
@ -12,6 +11,7 @@ scratch/main> move.namespace foo bar
|
||||
```
|
||||
|
||||
|
||||
|
||||
🛑
|
||||
|
||||
The transcript failed due to an error in the stanza above. The error is:
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
When an expected error is not encountered in a `unison:hide:all:error` block
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
When an error is encountered in a `unison:hide:all` block
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
When an expected error is not encountered in a `unison:hide:error` block
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
### Transcript parser hidden errors
|
||||
|
||||
When an error is encountered in a `unison:hide` block
|
||||
|
@ -1,6 +1,7 @@
|
||||
We were seeing an issue where (it seemed) that every namespace that was visited during a propagate would get a new history node, even when it didn't contain any dependents.
|
||||
|
||||
Example:
|
||||
|
||||
``` unison
|
||||
a = "a term"
|
||||
X.foo = "a namespace"
|
||||
@ -16,6 +17,7 @@ scratch/main> add
|
||||
|
||||
```
|
||||
Here is an update which should not affect `X`:
|
||||
|
||||
``` unison
|
||||
a = "an update"
|
||||
```
|
||||
@ -30,6 +32,7 @@ scratch/main> update
|
||||
|
||||
```
|
||||
As of the time of this writing, the history for `X` should be a single node, `#4eeuo5bsfr`;
|
||||
|
||||
```ucm
|
||||
scratch/main> history X
|
||||
|
||||
@ -42,6 +45,7 @@ scratch/main> history X
|
||||
|
||||
```
|
||||
however, as of release/M1i, we saw an extraneous node appear. If your `ucm` is fixed, you won't see it below:
|
||||
|
||||
```ucm
|
||||
scratch/main> history #7nl6ppokhg
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
Previously, the `alias.term` and `alias.type` would fail if the source argument was hash-only, and there was no way to create an alias for a definition that didn't already have a name. Also, the `replace.term` and `replace.type` _only_ worked on hashes, and they had to be _full_ hashes.
|
||||
Previously, the `alias.term` and `alias.type` would fail if the source argument was hash-only, and there was no way to create an alias for a definition that didn't already have a name. Also, the `replace.term` and `replace.type` *only* worked on hashes, and they had to be *full* hashes.
|
||||
|
||||
With this PR, the source of an alias can be a short hash (even of a definition that doesn't currently have a name in the namespace) along with a name or hash-qualified name from the current namespace as usual.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
```ucm
|
||||
scratch/main> builtins.merge
|
||||
|
||||
|
@ -13,9 +13,9 @@ foo.bar = 23
|
||||
|
||||
Suffix-based name resolution prefers to use names locally defined in the current file, then checks for matches in the codebase. Here are the precise rules, which will be explained below with examples:
|
||||
|
||||
* If a symbol, `s`, is a suffix of exactly one definition `d` in the file, then `s` refers to `d`.
|
||||
* Otherwise, if `s` is a suffix of exactly one definition `d` in the codebase, then `s` refers to `d`.
|
||||
* Otherwise, if `s` is a suffix of multiple definitions in the file or the codebase, then (at least for terms) type-directed name resolution will be attempted to figure out which definition `s` refers to.
|
||||
- If a symbol, `s`, is a suffix of exactly one definition `d` in the file, then `s` refers to `d`.
|
||||
- Otherwise, if `s` is a suffix of exactly one definition `d` in the codebase, then `s` refers to `d`.
|
||||
- Otherwise, if `s` is a suffix of multiple definitions in the file or the codebase, then (at least for terms) type-directed name resolution will be attempted to figure out which definition `s` refers to.
|
||||
|
||||
## Example 1: local file term definitions shadow codebase term definitions
|
||||
|
||||
@ -32,7 +32,7 @@ baz = bar ++ ", world!"
|
||||
|
||||
## Example 2: any locally unique term suffix shadows codebase term definitions
|
||||
|
||||
This should also typecheck, using the file's `oog.bar`. This shows you can refer to a definition in the file by any suffix that is unique to definitions in the file (even if that suffix may match other definitions in the _codebase_). See example 4 below for overriding this behavior.
|
||||
This should also typecheck, using the file's `oog.bar`. This shows you can refer to a definition in the file by any suffix that is unique to definitions in the file (even if that suffix may match other definitions in the *codebase*). See example 4 below for overriding this behavior.
|
||||
|
||||
``` unison
|
||||
use Text ++
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
structural ability Ask where ask : Nat
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
structural ability CLI where
|
||||
print : Text ->{CLI} ()
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
printLine : Text ->{IO} ()
|
||||
printLine msg =
|
||||
@ -18,8 +17,8 @@ main3 _ = printLine "🦄 ☁️ 🌈"
|
||||
|
||||
Testing a few variations here:
|
||||
|
||||
* Should be able to run annotated and unannotated main functions in the current file.
|
||||
* Should be able to run annotated and unannotated main functions from the codebase.
|
||||
- Should be able to run annotated and unannotated main functions in the current file.
|
||||
- Should be able to run annotated and unannotated main functions from the codebase.
|
||||
|
||||
```ucm
|
||||
scratch/main> run main1
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
structural type One a = One a
|
||||
unique type Woot a b c = Woot a b c
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
``` unison
|
||||
structural ability Exception where raise : Failure -> x
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Tests for a case where bad eta reduction was causing erroneous watch
|
||||
output/caching.
|
||||
|
||||
|
@ -37,3 +37,4 @@ fail because the type was invalid.
|
||||
|
||||
The fix was to avoid dropping certain existential variables out of
|
||||
scope.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
This should not typecheck - the inline `@eval` expression uses abilities.
|
||||
|
||||
``` unison
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
This transcript checks that updates to data types propagate successfully to dependent types and dependent terms that do pattern matching. First let's create some types and terms:
|
||||
|
||||
``` unison
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Tests an issue where pattern matching matrices involving built-in
|
||||
types was discarding default cases in some branches.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Checks a corner case with type checking involving destructuring binds.
|
||||
|
||||
The binds were causing some sequences of lets to be unnecessarily
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
This tests an issue where ability variables were being defaulted over
|
||||
eagerly. In general, we want to avoid collecting up variables from the
|
||||
use of definitions with types like:
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Tests that delaying an un-annotated higher-rank type gives a normal
|
||||
type error, rather than an internal compiler error.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Tests for a loop that was previously occurring in the type checker.
|
||||
|
||||
``` unison
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Tests for an ability failure that was caused by order dependence of
|
||||
checking wanted vs. provided abilities. It was necessary to re-check
|
||||
rows until a fixed point is reached.
|
||||
|
@ -1,9 +1,8 @@
|
||||
|
||||
Tests an issue with a lack of generality of handlers.
|
||||
|
||||
In general, a set of cases:
|
||||
|
||||
{ e ... -> k }
|
||||
{ e ... -\> k }
|
||||
|
||||
should be typed in the following way:
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Tests a variable capture problem.
|
||||
|
||||
After pattern compilation, the match would end up:
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
loop : List Nat -> Nat -> List Nat
|
||||
loop l = cases
|
||||
|
@ -1,6 +1,6 @@
|
||||
This bugfix addresses an issue where embedded Unison code in UCM was expected to be present in the active codebase when the `display` command was used render `Doc` values.
|
||||
|
||||
First, a few \[hidden] definitions necessary for typechecking a simple Doc2.
|
||||
First, a few \[hidden\] definitions necessary for typechecking a simple Doc2.
|
||||
|
||||
```ucm
|
||||
scratch/main> add
|
||||
@ -18,6 +18,7 @@ scratch/main> add
|
||||
|
||||
```
|
||||
Next, define and display a simple Doc:
|
||||
|
||||
``` unison
|
||||
README = {{
|
||||
Hi
|
||||
@ -32,10 +33,8 @@ scratch/main> display README
|
||||
```
|
||||
Previously, the error was:
|
||||
|
||||
```
|
||||
⚙️ Processing stanza 5 of 7.ucm: PE [("die",SrcLoc {srcLocPackage = "unison-parser-typechecker-0.0.0-He2Hp1llokT2nN4MnUfUXz", srcLocModule = "Unison.Runtime.Interface", srcLocFile = "src/Unison/Runtime/Interface.hs", srcLocStartLine = 118, srcLocStartCol = 18, srcLocEndLine = 118, srcLocEndCol = 60})] Lit
|
||||
AnnotatedText (fromList [Segment {segment = "Unknown term reference: #4522d", annotation = Nothing}])
|
||||
|
||||
```
|
||||
|
||||
but as of this PR, it's okay.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
Also fixes #1519 (it's the same issue).
|
||||
Also fixes \#1519 (it's the same issue).
|
||||
|
||||
```ucm
|
||||
scratch/main> builtins.merge
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Tests ability checking in scenarios where one side is concrete and the other is
|
||||
a variable. This was supposed to be covered, but the method wasn't actually
|
||||
symmetric, so doing `equate l r` might work, but not `equate r l`.
|
||||
|
@ -1,5 +1,6 @@
|
||||
Tests cases that produced bad decompilation output previously. There
|
||||
are three cases that need to be 'fixed up.'
|
||||
|
||||
1. lambda expressions with free variables need to be beta reduced
|
||||
2. let defined functions need to have arguments removed and
|
||||
occurrences rewritten.
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Array comparison was indexing out of bounds.
|
||||
|
||||
``` unison
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
unique type codebase.Foo = Foo
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
foo =
|
||||
_ = 1
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
debug a = match Debug.toText a with
|
||||
None -> ""
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
unique type Foo = Foo
|
||||
unique type sub.Foo =
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
Tests an improvement to type checking related to abilities.
|
||||
|
||||
`foo` below typechecks fine as long as all the branches are _checked_
|
||||
`foo` below typechecks fine as long as all the branches are *checked*
|
||||
against their expected type. However, it's annoying to have to
|
||||
annotate them. The old code was checking a match by just synthesizing
|
||||
and subtyping, but we can instead check a match by pushing the
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
``` unison
|
||||
structural ability X t where
|
||||
x : t -> a -> a
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
Add `List.zonk` to the codebase:
|
||||
|
||||
``` unison
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
See [this ticket](https://github.com/unisonweb/unison/issues/849).
|
||||
|
||||
``` unison
|
||||
|
@ -79,7 +79,7 @@ scratch/main> view x y z
|
||||
y + 2
|
||||
|
||||
```
|
||||
Uh oh! `z` is still referencing the old version. Just to confirm:
|
||||
Uh oh\! `z` is still referencing the old version. Just to confirm:
|
||||
|
||||
``` unison
|
||||
test> t1 = if z == 3 then [Fail "nooo!!!"] else [Ok "great"]
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
First we'll add a definition:
|
||||
|
||||
``` unison
|
||||
@ -67,3 +66,4 @@ scratch/main> add
|
||||
|
||||
```
|
||||
Previously, this would fail because the hashing algorithm was being given one big let rec block whose binding order was normalized.
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
If an argument is required but doesn't have a fuzzy resolver, the command should just print the help.
|
||||
|
||||
|
||||
```ucm
|
||||
-- The second argument of move.term is a 'new-name' and doesn't have a fuzzy resolver
|
||||
scratch/main> move.term
|
||||
|
@ -78,7 +78,8 @@ x = "hi
|
||||
|
||||
I got confused here:
|
||||
|
||||
2 |
|
||||
1 | x = "hi
|
||||
|
||||
|
||||
I was surprised to find an end of input here.
|
||||
I was expecting one of these instead:
|
||||
@ -98,7 +99,8 @@ y : a
|
||||
|
||||
I got confused here:
|
||||
|
||||
2 |
|
||||
1 | y : a
|
||||
|
||||
|
||||
I was surprised to find an end of section here.
|
||||
I was expecting one of these instead:
|
||||
|
@ -1,25 +1,21 @@
|
||||
|
||||
# Hello!
|
||||
# Hello\!
|
||||
|
||||
This markdown file is also a Unison transcript file. Transcript files are an easy way to create self-documenting Unison programs, libraries, and tutorials.
|
||||
|
||||
The format is just a regular markdown file with some fenced code blocks that are typechecked and elaborated by `ucm`. For example, you can call this transcript via:
|
||||
|
||||
```
|
||||
$ ucm transcript hello.md
|
||||
|
||||
```
|
||||
|
||||
This runs it on a freshly generated empty codebase. Alternately `ucm transcript.fork --codebase /path/to/code hello.md` runs the transcript on a freshly generated copy of the provided codebase. Do `ucm help` to learn more about usage.
|
||||
|
||||
Fenced code blocks of type `unison` and `ucm` are treated specially:
|
||||
|
||||
* `ucm` blocks are executed, and the output is interleaved into the output markdown file after each command, replacing the original `ucm` block.
|
||||
* `unison` blocks are typechecked, and a `ucm` block with the output of typechecking and execution of the file is inserted immediately afterwards.
|
||||
- `ucm` blocks are executed, and the output is interleaved into the output markdown file after each command, replacing the original `ucm` block.
|
||||
- `unison` blocks are typechecked, and a `ucm` block with the output of typechecking and execution of the file is inserted immediately afterwards.
|
||||
|
||||
Take a look at [the elaborated output](hello.output.md) to see what this file looks like after passing through the transcript runner.
|
||||
|
||||
## Let's try it out!!
|
||||
## Let's try it out\!\!
|
||||
|
||||
In the `unison` fenced block, you can give an (optional) file name (defaults to `scratch.u`), like so:
|
||||
|
||||
@ -31,7 +27,6 @@ x = 42
|
||||
|
||||
```
|
||||
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in myfile.u.
|
||||
@ -76,7 +71,7 @@ Doing `unison:hide:all` hides the block altogether, both input and output - this
|
||||
|
||||
## Expecting failures
|
||||
|
||||
Sometimes, you have a block which you are _expecting_ to fail, perhaps because you're illustrating how something would be a type error. Adding `:error` to the block will check for this. For instance, this program has a type error:
|
||||
Sometimes, you have a block which you are *expecting* to fail, perhaps because you're illustrating how something would be a type error. Adding `:error` to the block will check for this. For instance, this program has a type error:
|
||||
|
||||
``` unison
|
||||
hmm : .builtin.Nat
|
||||
|
@ -966,3 +966,4 @@ scratch/main> help-topic testcache
|
||||
|
||||
```
|
||||
We should add a command to show help for hidden commands also.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
This transcript does some testing of higher-rank types. Regression tests related to higher-rank types can be added here.
|
||||
|
||||
In this example, a higher-rank function is defined, `f`. No annotation is needed at the call-site of `f`, because the lambda is being checked against the polymorphic type `forall a . a -> a`, rather than inferred:
|
||||
|
@ -5,6 +5,7 @@ x = 55
|
||||
```
|
||||
|
||||
`handleNameArg` parse error in `add`
|
||||
|
||||
```ucm
|
||||
scratch/main> add .
|
||||
|
||||
@ -42,8 +43,8 @@ scratch/main> add 2
|
||||
|
||||
```
|
||||
todo:
|
||||
```haskell
|
||||
|
||||
``` haskell
|
||||
SA.Name name -> pure name
|
||||
SA.NameWithBranchPrefix (Left _) name -> pure name
|
||||
SA.NameWithBranchPrefix (Right prefix) name -> pure $ Path.prefixNameIfRel (Path.AbsolutePath' prefix) name
|
||||
@ -56,7 +57,6 @@ todo:
|
||||
SA.SearchResult mpath result ->
|
||||
maybe (Left "can’t find a name from the numbered arg") pure . HQ.toName $ searchResultToHQ mpath result
|
||||
otherNumArg -> Left . I.Formatted $ wrongStructuredArgument "a name" otherNumArg
|
||||
|
||||
```
|
||||
|
||||
aliasMany: skipped -- similar to `add`
|
||||
@ -75,18 +75,17 @@ You can run `help update` for more information on using
|
||||
|
||||
```
|
||||
aliasTerm
|
||||
```scratch
|
||||
/main> alias.term ##Nat.+ Nat.+
|
||||
|
||||
```
|
||||
scratch/main> alias.term ##Nat.+ Nat.+
|
||||
|
||||
aliasTermForce,
|
||||
aliasType,
|
||||
|
||||
|
||||
todo:
|
||||
```alias
|
||||
Many,
|
||||
|
||||
```
|
||||
|
||||
aliasMany,
|
||||
api,
|
||||
authLogin,
|
||||
back,
|
||||
@ -202,6 +201,5 @@ upgradeCommitInputPattern,
|
||||
view,
|
||||
viewGlobal,
|
||||
viewReflog
|
||||
|
||||
```
|
||||
|
||||
|
@ -374,6 +374,7 @@ scratch/main> io.test testAppend
|
||||
|
||||
```
|
||||
### SystemTime
|
||||
|
||||
``` unison
|
||||
testSystemTime : '{io2.IO} [Result]
|
||||
testSystemTime _ =
|
||||
@ -578,6 +579,7 @@ testGetArgs.runMeWithTwoArgs = 'let
|
||||
```
|
||||
|
||||
Test that they can be run with the right number of args.
|
||||
|
||||
```ucm
|
||||
scratch/main> add
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
## A type param cannot have conflicting kind constraints within a single decl
|
||||
|
||||
conflicting constraints on the kind of `a` in a product
|
||||
|
||||
``` unison
|
||||
unique type T a = T a (a Nat)
|
||||
```
|
||||
@ -17,6 +17,7 @@ unique type T a = T a (a Nat)
|
||||
|
||||
```
|
||||
conflicting constraints on the kind of `a` in a sum
|
||||
|
||||
``` unison
|
||||
unique type T a
|
||||
= Star a
|
||||
@ -37,6 +38,7 @@ unique type T a
|
||||
|
||||
Successfully infer `a` in `Ping a` to be of kind `* -> *` by
|
||||
inspecting its component-mate `Pong`.
|
||||
|
||||
``` unison
|
||||
unique type Ping a = Ping Pong
|
||||
unique type Pong = Pong (Ping Optional)
|
||||
@ -58,6 +60,7 @@ unique type Pong = Pong (Ping Optional)
|
||||
```
|
||||
Catch the conflict on the kind of `a` in `Ping a`. `Ping` restricts
|
||||
`a` to `*`, whereas `Pong` restricts `a` to `* -> *`.
|
||||
|
||||
``` unison
|
||||
unique type Ping a = Ping a Pong
|
||||
unique type Pong = Pong (Ping Optional)
|
||||
@ -75,6 +78,7 @@ unique type Pong = Pong (Ping Optional)
|
||||
|
||||
```
|
||||
Successful example between mutually recursive type and ability
|
||||
|
||||
``` unison
|
||||
unique type Ping a = Ping (a Nat -> {Pong Nat} ())
|
||||
unique ability Pong a where
|
||||
@ -96,6 +100,7 @@ unique ability Pong a where
|
||||
|
||||
```
|
||||
Catch conflict between mutually recursive type and ability
|
||||
|
||||
``` unison
|
||||
unique type Ping a = Ping (a -> {Pong Nat} ())
|
||||
unique ability Pong a where
|
||||
@ -114,6 +119,7 @@ unique ability Pong a where
|
||||
|
||||
```
|
||||
Consistent instantiation of `T`'s `a` parameter in `S`
|
||||
|
||||
``` unison
|
||||
unique type T a = T a
|
||||
|
||||
@ -137,6 +143,7 @@ unique type S = S (T Nat)
|
||||
Delay kind defaulting until all components are processed. Here `S`
|
||||
constrains the kind of `T`'s `a` parameter, although `S` is not in
|
||||
the same component as `T`.
|
||||
|
||||
``` unison
|
||||
unique type T a = T
|
||||
|
||||
@ -158,6 +165,7 @@ unique type S = S (T Optional)
|
||||
|
||||
```
|
||||
Catch invalid instantiation of `T`'s `a` parameter in `S`
|
||||
|
||||
``` unison
|
||||
unique type T a = T a
|
||||
|
||||
@ -178,6 +186,7 @@ unique type S = S (T Optional)
|
||||
## Checking annotations
|
||||
|
||||
Catch kind error in type annotation
|
||||
|
||||
``` unison
|
||||
test : Nat Nat
|
||||
test = 0
|
||||
@ -195,6 +204,7 @@ test = 0
|
||||
|
||||
```
|
||||
Catch kind error in annotation example 2
|
||||
|
||||
``` unison
|
||||
test : Optional -> ()
|
||||
test _ = ()
|
||||
@ -212,6 +222,7 @@ test _ = ()
|
||||
|
||||
```
|
||||
Catch kind error in annotation example 3
|
||||
|
||||
``` unison
|
||||
unique type T a = T (a Nat)
|
||||
|
||||
@ -231,6 +242,7 @@ test _ = ()
|
||||
|
||||
```
|
||||
Catch kind error in scoped type variable annotation
|
||||
|
||||
``` unison
|
||||
unique type StarStar a = StarStar (a Nat)
|
||||
unique type Star a = Star a
|
||||
@ -256,6 +268,7 @@ test _ =
|
||||
## Effect/type mismatch
|
||||
|
||||
Effects appearing where types are expected
|
||||
|
||||
``` unison
|
||||
unique ability Foo where
|
||||
foo : ()
|
||||
@ -276,6 +289,7 @@ test _ = ()
|
||||
|
||||
```
|
||||
Types appearing where effects are expected
|
||||
|
||||
``` unison
|
||||
test : {Nat} ()
|
||||
test _ = ()
|
||||
|
@ -29,6 +29,7 @@ scratch/main> debug.lsp-name-completion foldMap
|
||||
|
||||
```
|
||||
Should still find the term which has a matching hash to a better name if the better name doesn't match.
|
||||
|
||||
```ucm
|
||||
scratch/main> debug.lsp-name-completion transitive_same_hash.foldMap
|
||||
|
||||
|
@ -30,18 +30,21 @@ contains both additions.
|
||||
## Basic merge: two unconflicted adds
|
||||
|
||||
Alice's adds:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "alices foo"
|
||||
```
|
||||
|
||||
Bob's adds:
|
||||
|
||||
``` unison
|
||||
bar : Text
|
||||
bar = "bobs bar"
|
||||
```
|
||||
|
||||
Merge result:
|
||||
|
||||
```ucm
|
||||
project/alice> merge /bob
|
||||
|
||||
@ -61,12 +64,14 @@ project/alice> view foo bar
|
||||
If Alice and Bob also happen to add the same definition, that's not a conflict.
|
||||
|
||||
Alice's adds:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "alice and bobs foo"
|
||||
```
|
||||
|
||||
Bob's adds:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "alice and bobs foo"
|
||||
@ -76,6 +81,7 @@ bar = "bobs bar"
|
||||
```
|
||||
|
||||
Merge result:
|
||||
|
||||
```ucm
|
||||
project/alice> merge /bob
|
||||
|
||||
@ -95,18 +101,21 @@ project/alice> view foo bar
|
||||
Updates that occur in one branch are propagated to the other. In this example, Alice updates `foo`, while Bob adds a new dependent `bar` of the original `foo`. When Bob's branch is merged into Alice's, her update to `foo` is propagated to his `bar`.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "old foo"
|
||||
```
|
||||
|
||||
Alice's updates:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "new foo"
|
||||
```
|
||||
|
||||
Bob's adds:
|
||||
|
||||
``` unison
|
||||
bar : Text
|
||||
bar = foo ++ " - " ++ foo
|
||||
@ -119,6 +128,7 @@ project/bob> display bar
|
||||
|
||||
```
|
||||
Merge result:
|
||||
|
||||
```ucm
|
||||
project/alice> merge /bob
|
||||
|
||||
@ -146,6 +156,7 @@ We classify something as an update if its "syntactic hash"—not its normal Unis
|
||||
Let's see an example. We have `foo`, which depends on `bar` and `baz`. Alice updates `bar` (propagating to `foo`), and Bob updates `baz` (propagating to `foo`). When we merge their updates, both updates will be reflected in the final `foo`.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "foo" ++ " - " ++ bar ++ " - " ++ baz
|
||||
@ -158,6 +169,7 @@ baz = "old baz"
|
||||
```
|
||||
|
||||
Alice's updates:
|
||||
|
||||
``` unison
|
||||
bar : Text
|
||||
bar = "alices bar"
|
||||
@ -170,6 +182,7 @@ project/alice> display foo
|
||||
|
||||
```
|
||||
Bob's updates:
|
||||
|
||||
``` unison
|
||||
baz : Text
|
||||
baz = "bobs baz"
|
||||
@ -182,6 +195,7 @@ project/bob> display foo
|
||||
|
||||
```
|
||||
Merge result:
|
||||
|
||||
```ucm
|
||||
project/alice> merge /bob
|
||||
|
||||
@ -210,6 +224,7 @@ project/alice> display foo
|
||||
Of course, it's also possible for Alice's update to propagate to one of Bob's updates. In this example, `foo` depends on `bar` which depends on `baz`. Alice updates `baz`, propagating to `bar` and `foo`, while Bob updates `bar` (to something that still depends on `foo`), propagating to `baz`. The merged result will have Alice's update to `foo` incorporated into Bob's updated `bar`, and both updates will propagate to `baz`.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "old foo" ++ " - " ++ bar
|
||||
@ -228,6 +243,7 @@ project/main> display foo
|
||||
|
||||
```
|
||||
Alice's updates:
|
||||
|
||||
``` unison
|
||||
baz : Text
|
||||
baz = "alices baz"
|
||||
@ -240,6 +256,7 @@ project/alice> display foo
|
||||
|
||||
```
|
||||
Bob's updates:
|
||||
|
||||
``` unison
|
||||
bar : Text
|
||||
bar = "bobs bar" ++ " - " ++ baz
|
||||
@ -252,6 +269,7 @@ project/bob> display foo
|
||||
|
||||
```
|
||||
Merge result:
|
||||
|
||||
```ucm
|
||||
project/alice> merge /bob
|
||||
|
||||
@ -282,18 +300,21 @@ project/alice> display foo
|
||||
We don't currently consider "update + delete" a conflict like Git does. In this situation, the delete is just ignored, allowing the update to proceed.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "old foo"
|
||||
```
|
||||
|
||||
Alice's updates:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "alices foo"
|
||||
```
|
||||
|
||||
Bob's changes:
|
||||
|
||||
```ucm
|
||||
project/bob> delete.term foo
|
||||
|
||||
@ -301,6 +322,7 @@ project/bob> delete.term foo
|
||||
|
||||
```
|
||||
Merge result:
|
||||
|
||||
```ucm
|
||||
project/alice> merge /bob
|
||||
|
||||
@ -319,6 +341,7 @@ In a future version, we'd like to give the user a warning at least.
|
||||
Library dependencies don't cause merge conflicts, the library dependencies are just unioned together. If two library dependencies have the same name but different namespace hashes, then the merge algorithm makes up two fresh names.
|
||||
|
||||
Alice's adds:
|
||||
|
||||
``` unison
|
||||
lib.alice.foo : Nat
|
||||
lib.alice.foo = 17
|
||||
@ -331,6 +354,7 @@ lib.bothDifferent.baz = 19
|
||||
```
|
||||
|
||||
Bob's adds:
|
||||
|
||||
``` unison
|
||||
lib.bob.foo : Nat
|
||||
lib.bob.foo = 20
|
||||
@ -343,6 +367,7 @@ lib.bothDifferent.baz = 21
|
||||
```
|
||||
|
||||
Merge result:
|
||||
|
||||
```ucm
|
||||
project/alice> merge bob
|
||||
|
||||
@ -392,7 +417,7 @@ project/alice> merge /bob
|
||||
project/alice was already up-to-date with project/bob.
|
||||
|
||||
```
|
||||
## No-op merge (Bob < Alice)
|
||||
## No-op merge (Bob \< Alice)
|
||||
|
||||
If Bob is behind Alice, then merging Bob into Alice looks like this.
|
||||
|
||||
@ -413,6 +438,7 @@ project/main> branch bob
|
||||
|
||||
```
|
||||
Alice's addition:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "foo"
|
||||
@ -432,7 +458,7 @@ project/alice> merge /bob
|
||||
project/alice was already up-to-date with project/bob.
|
||||
|
||||
```
|
||||
## Fast-forward merge (Bob > Alice)
|
||||
## Fast-forward merge (Bob \> Alice)
|
||||
|
||||
If Bob is ahead of Alice, then merging Bob into Alice looks like this.
|
||||
|
||||
@ -453,6 +479,7 @@ project/main> branch bob
|
||||
|
||||
```
|
||||
Bob's addition:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "foo"
|
||||
@ -496,12 +523,14 @@ This can cause merge failures due to out-of-scope identifiers, and the user may
|
||||
In this example, Alice deletes `foo`, while Bob adds a new dependent of `foo`.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "foo"
|
||||
```
|
||||
|
||||
Alice's delete:
|
||||
|
||||
```ucm
|
||||
project/alice> delete.term foo
|
||||
|
||||
@ -509,6 +538,7 @@ project/alice> delete.term foo
|
||||
|
||||
```
|
||||
Bob's new code that depends on `foo`:
|
||||
|
||||
``` unison
|
||||
bar : Text
|
||||
bar = foo ++ " - " ++ foo
|
||||
@ -546,7 +576,6 @@ bar =
|
||||
use Text ++
|
||||
foo ++ " - " ++ foo
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Merge failure: type error
|
||||
@ -556,18 +585,21 @@ It may be Alice's and Bob's changes merge together cleanly in the sense that the
|
||||
In this example, Alice updates a `Text` to a `Nat`, while Bob adds a new dependent of the `Text`. Upon merging, propagating Alice's update to Bob's dependent causes a typechecking failure.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "foo"
|
||||
```
|
||||
|
||||
Alice's update:
|
||||
|
||||
``` unison
|
||||
foo : Nat
|
||||
foo = 100
|
||||
```
|
||||
|
||||
Bob's new definition:
|
||||
|
||||
``` unison
|
||||
bar : Text
|
||||
bar = foo ++ " - " ++ foo
|
||||
@ -599,7 +631,6 @@ bar =
|
||||
use Text ++
|
||||
foo ++ " - " ++ foo
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Merge failure: simple term conflict
|
||||
@ -608,6 +639,7 @@ Alice and Bob may disagree about the definition of a term. In this case, the con
|
||||
are presented to the user to resolve.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "old foo"
|
||||
@ -617,6 +649,7 @@ bar = "old bar"
|
||||
```
|
||||
|
||||
Alice's changes:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "alices foo"
|
||||
@ -675,7 +708,6 @@ qux =
|
||||
use Text ++
|
||||
"alices qux depends on alices foo" ++ foo
|
||||
|
||||
|
||||
```
|
||||
|
||||
```ucm
|
||||
@ -693,16 +725,19 @@ project/merge-bob-into-alice> view bar baz
|
||||
Ditto for types; if the hashes don't match, it's a conflict. In this example, Alice and Bob do different things to the same constructor. However, any explicit changes to the same type will result in a conflict, including changes that could concievably be merged (e.g. Alice and Bob both add a new constructor, or edit different constructors).
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
unique type Foo = MkFoo Nat
|
||||
```
|
||||
|
||||
Alice's changes:
|
||||
|
||||
``` unison
|
||||
unique type Foo = MkFoo Nat Nat
|
||||
```
|
||||
|
||||
Bob's changes:
|
||||
|
||||
``` unison
|
||||
unique type Foo = MkFoo Nat Text
|
||||
```
|
||||
@ -734,7 +769,6 @@ type Foo = MkFoo Nat Nat
|
||||
-- project/bob
|
||||
type Foo = MkFoo Nat Text
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Merge failure: type-update + constructor-rename conflict
|
||||
@ -742,16 +776,19 @@ type Foo = MkFoo Nat Text
|
||||
We model the renaming of a type's constructor as an update, so if Alice updates a type and Bob renames one of its constructors (even without changing its structure), we consider it a conflict.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
unique type Foo = Baz Nat | Qux Text
|
||||
```
|
||||
|
||||
Alice's changes `Baz Nat` to `Baz Nat Nat`
|
||||
|
||||
``` unison
|
||||
unique type Foo = Baz Nat Nat | Qux Text
|
||||
```
|
||||
|
||||
Bob's renames `Qux` to `BobQux`:
|
||||
|
||||
``` unison
|
||||
unique type Foo = Baz Nat | BobQux Text
|
||||
```
|
||||
@ -783,7 +820,6 @@ type Foo = Baz Nat Nat | Qux Text
|
||||
-- project/bob
|
||||
type Foo = Baz Nat | BobQux Text
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Merge failure: constructor-rename conflict
|
||||
@ -791,11 +827,13 @@ type Foo = Baz Nat | BobQux Text
|
||||
Here is another example demonstrating that constructor renames are modeled as updates.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
unique type Foo = Baz Nat | Qux Text
|
||||
```
|
||||
|
||||
Alice's rename:
|
||||
|
||||
```ucm
|
||||
project/alice> move.term Foo.Baz Foo.Alice
|
||||
|
||||
@ -803,6 +841,7 @@ project/alice> move.term Foo.Baz Foo.Alice
|
||||
|
||||
```
|
||||
Bob's rename:
|
||||
|
||||
```ucm
|
||||
project/bob> move.term Foo.Qux Foo.Bob
|
||||
|
||||
@ -836,7 +875,6 @@ type Foo = Qux Text | Alice Nat
|
||||
-- project/bob
|
||||
type Foo = Bob Text | Baz Nat
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Merge failure: non-constructor/constructor conflict
|
||||
@ -844,12 +882,14 @@ type Foo = Bob Text | Baz Nat
|
||||
A constructor on one side can conflict with a regular term definition on the other.
|
||||
|
||||
Alice's additions:
|
||||
|
||||
``` unison
|
||||
my.cool.thing : Nat
|
||||
my.cool.thing = 17
|
||||
```
|
||||
|
||||
Bob's additions:
|
||||
|
||||
``` unison
|
||||
unique ability my.cool where
|
||||
thing : Nat -> Nat
|
||||
@ -883,7 +923,6 @@ my.cool.thing = 17
|
||||
-- project/bob
|
||||
ability my.cool where thing : Nat ->{cool} Nat
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Merge failure: type/type conflict with term/constructor conflict
|
||||
@ -891,17 +930,20 @@ ability my.cool where thing : Nat ->{cool} Nat
|
||||
Here's a subtle situation where a new type is added on each side of the merge, and an existing term is replaced with a constructor of one of the types.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
Foo.Bar : Nat
|
||||
Foo.Bar = 17
|
||||
```
|
||||
|
||||
Alice adds this type `Foo` with constructor `Foo.Alice`:
|
||||
|
||||
``` unison
|
||||
unique type Foo = Alice Nat
|
||||
```
|
||||
|
||||
Bob adds the type `Foo` with constructor `Foo.Bar`, replacing the original `Foo.Bar` term:
|
||||
|
||||
```ucm
|
||||
project/bob> delete.term Foo.Bar
|
||||
|
||||
@ -913,6 +955,7 @@ unique type Foo = Bar Nat Nat
|
||||
```
|
||||
|
||||
These won't cleanly merge.
|
||||
|
||||
```ucm
|
||||
project/alice> merge bob
|
||||
|
||||
@ -944,7 +987,6 @@ type Foo = Alice Nat
|
||||
-- project/bob
|
||||
type Foo = Bar Nat Nat
|
||||
|
||||
|
||||
```
|
||||
|
||||
Here's a more involved example that demonstrates the same idea.
|
||||
@ -1019,7 +1061,6 @@ Foo.Bar.Hello = 18
|
||||
-- project/bob
|
||||
type Foo.Bar = Baz Nat | Hello Nat Nat
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Merge algorithm quirk: add/add unique types
|
||||
@ -1031,6 +1072,7 @@ which is a parse error.
|
||||
We will resolve this situation automatically in a future version.
|
||||
|
||||
Alice's additions:
|
||||
|
||||
``` unison
|
||||
unique type Foo = Bar
|
||||
|
||||
@ -1039,6 +1081,7 @@ alice _ = 18
|
||||
```
|
||||
|
||||
Bob's additions:
|
||||
|
||||
``` unison
|
||||
unique type Foo = Bar
|
||||
|
||||
@ -1084,7 +1127,6 @@ alice _ = 18
|
||||
bob : Foo -> Nat
|
||||
bob _ = 19
|
||||
|
||||
|
||||
```
|
||||
|
||||
## `merge.commit` example (success)
|
||||
@ -1093,12 +1135,14 @@ After merge conflicts are resolved, you can use `merge.commit` rather than `swit
|
||||
"commit" your changes.
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "old foo"
|
||||
```
|
||||
|
||||
Alice's changes:
|
||||
|
||||
``` unison
|
||||
foo : Text
|
||||
foo = "alices foo"
|
||||
@ -1142,7 +1186,6 @@ foo = "alices foo"
|
||||
foo : Text
|
||||
foo = "bobs foo"
|
||||
|
||||
|
||||
```
|
||||
|
||||
Resolve conflicts and commit:
|
||||
@ -1219,6 +1262,7 @@ There are a number of conditions under which we can't perform a merge, and the u
|
||||
If `foo` and `bar` are aliases in the nearest common ancestor, but not in Alice's branch, then we don't know whether to update Bob's dependents to Alice's `foo` or Alice's `bar` (and vice-versa).
|
||||
|
||||
Original branch:
|
||||
|
||||
``` unison
|
||||
foo : Nat
|
||||
foo = 100
|
||||
@ -1228,6 +1272,7 @@ bar = 100
|
||||
```
|
||||
|
||||
Alice's updates:
|
||||
|
||||
``` unison
|
||||
foo : Nat
|
||||
foo = 200
|
||||
@ -1237,6 +1282,7 @@ bar = 300
|
||||
```
|
||||
|
||||
Bob's addition:
|
||||
|
||||
``` unison
|
||||
baz : Text
|
||||
baz = "baz"
|
||||
@ -1271,6 +1317,7 @@ conflict involving a builtin, we can't perform a merge.
|
||||
One way to fix this in the future would be to introduce a syntax for defining aliases in the scratch file.
|
||||
|
||||
Alice's branch:
|
||||
|
||||
```ucm
|
||||
project/alice> alias.type lib.builtins.Nat MyNat
|
||||
|
||||
@ -1278,6 +1325,7 @@ project/alice> alias.type lib.builtins.Nat MyNat
|
||||
|
||||
```
|
||||
Bob's branch:
|
||||
|
||||
``` unison
|
||||
unique type MyNat = MyNat Nat
|
||||
```
|
||||
@ -1301,6 +1349,7 @@ project/alice> merge /bob
|
||||
Each naming of a decl may not have more than one name for each constructor, within the decl's namespace.
|
||||
|
||||
Alice's branch:
|
||||
|
||||
``` unison
|
||||
unique type Foo = Bar
|
||||
```
|
||||
@ -1312,6 +1361,7 @@ project/alice> alias.term Foo.Bar Foo.some.other.Alias
|
||||
|
||||
```
|
||||
Bob's branch:
|
||||
|
||||
``` unison
|
||||
bob : Nat
|
||||
bob = 100
|
||||
@ -1337,6 +1387,7 @@ project/alice> merge /bob
|
||||
Each naming of a decl must have a name for each constructor, within the decl's namespace.
|
||||
|
||||
Alice's branch:
|
||||
|
||||
``` unison
|
||||
unique type Foo = Bar
|
||||
```
|
||||
@ -1348,6 +1399,7 @@ project/alice> delete.term Foo.Bar
|
||||
|
||||
```
|
||||
Bob's branch:
|
||||
|
||||
``` unison
|
||||
bob : Nat
|
||||
bob = 100
|
||||
@ -1371,6 +1423,7 @@ project/alice> merge /bob
|
||||
A decl cannot be aliased within the namespace of another of its aliased.
|
||||
|
||||
Alice's branch:
|
||||
|
||||
``` unison
|
||||
structural type A = B Nat | C Nat Nat
|
||||
structural type A.inner.X = Y Nat | Z Nat Nat
|
||||
@ -1387,6 +1440,7 @@ project/alice> names A
|
||||
|
||||
```
|
||||
Bob's branch:
|
||||
|
||||
``` unison
|
||||
bob : Nat
|
||||
bob = 100
|
||||
@ -1406,6 +1460,7 @@ project/alice> merge /bob
|
||||
Constructors may only exist within the corresponding decl's namespace.
|
||||
|
||||
Alice's branch:
|
||||
|
||||
```ucm
|
||||
project/alice> add
|
||||
|
||||
@ -1419,6 +1474,7 @@ project/alice> alias.term Foo.Bar AliasOutsideFooNamespace
|
||||
|
||||
```
|
||||
Bob's branch:
|
||||
|
||||
```ucm
|
||||
project/bob> add
|
||||
|
||||
@ -1445,12 +1501,14 @@ project/alice> merge bob
|
||||
By convention, `lib` can only namespaces; each of these represents a library dependencies. Individual terms and types are not allowed at the top level of `lib`.
|
||||
|
||||
Alice's branch:
|
||||
|
||||
``` unison
|
||||
lib.foo : Nat
|
||||
lib.foo = 1
|
||||
```
|
||||
|
||||
Bob's branch:
|
||||
|
||||
``` unison
|
||||
bob : Nat
|
||||
bob = 100
|
||||
@ -1470,7 +1528,7 @@ project/alice> merge /bob
|
||||
```
|
||||
## LCA precondition violations
|
||||
|
||||
The LCA is not subject to most precondition violations, which is good, because the user can't easily manipulate it!
|
||||
The LCA is not subject to most precondition violations, which is good, because the user can't easily manipulate it\!
|
||||
|
||||
Here's an example. We'll delete a constructor name from the LCA and still be able to merge Alice and Bob's stuff
|
||||
together.
|
||||
@ -1608,7 +1666,6 @@ project/alice> merge /bob
|
||||
|
||||
### Delete one alias and update the other
|
||||
|
||||
|
||||
``` unison
|
||||
foo = 17
|
||||
bar = 17
|
||||
@ -1715,7 +1772,6 @@ project/alice> merge /bob
|
||||
```
|
||||
### Delete a constructor
|
||||
|
||||
|
||||
``` unison
|
||||
type Foo = Bar | Baz
|
||||
```
|
||||
@ -1814,7 +1870,6 @@ project/main> view Foo
|
||||
|
||||
This test demonstrates a bug.
|
||||
|
||||
|
||||
In the LCA, we have `foo` with dependent `bar`, and `baz`.
|
||||
|
||||
``` unison
|
||||
@ -1968,7 +2023,6 @@ bar =
|
||||
use Nat +
|
||||
foo + foo
|
||||
|
||||
|
||||
```
|
||||
|
||||
But `bar` was put into the scratch file instead.
|
||||
|
@ -1,6 +1,5 @@
|
||||
# Tests for `move.namespace`
|
||||
|
||||
|
||||
## Moving the Root
|
||||
|
||||
I should be able to move the root into a sub-namespace
|
||||
@ -57,7 +56,7 @@ foo = 1
|
||||
□ 1. #08a6hgi6s4 (start of history)
|
||||
|
||||
```
|
||||
I should be able to move a sub namespace _over_ the root.
|
||||
I should be able to move a sub namespace *over* the root.
|
||||
|
||||
```ucm
|
||||
-- Should request confirmation
|
||||
|
@ -78,7 +78,6 @@ somewhere.y = 2
|
||||
```
|
||||
`names.global` searches from the root, and absolutely qualifies results
|
||||
|
||||
|
||||
```ucm
|
||||
-- We can search by suffix and find all definitions in the codebase named 'x', and each of their aliases respectively.
|
||||
.some> names.global x
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Basics
|
||||
|
||||
## non-exhaustive patterns
|
||||
|
||||
``` unison
|
||||
unique type T = A | B | C
|
||||
|
||||
@ -51,6 +53,7 @@ test = cases
|
||||
|
||||
```
|
||||
## redundant patterns
|
||||
|
||||
``` unison
|
||||
unique type T = A | B | C
|
||||
|
||||
@ -95,6 +98,7 @@ test = cases
|
||||
# Uninhabited patterns
|
||||
|
||||
match is complete without covering uninhabited patterns
|
||||
|
||||
``` unison
|
||||
unique type V =
|
||||
|
||||
@ -119,6 +123,7 @@ test = cases
|
||||
|
||||
```
|
||||
uninhabited patterns are reported as redundant
|
||||
|
||||
``` unison
|
||||
unique type V =
|
||||
|
||||
@ -158,6 +163,7 @@ test = cases
|
||||
# Guards
|
||||
|
||||
## Incomplete patterns due to guards should be reported
|
||||
|
||||
``` unison
|
||||
test : () -> ()
|
||||
test = cases
|
||||
@ -201,6 +207,7 @@ test = cases
|
||||
|
||||
```
|
||||
## Complete patterns with guards should be accepted
|
||||
|
||||
``` unison
|
||||
test : Optional Nat -> Nat
|
||||
test = cases
|
||||
@ -227,6 +234,7 @@ test = cases
|
||||
|
||||
Uncovered patterns are only instantiated as deeply as necessary to
|
||||
distinguish them from existing patterns.
|
||||
|
||||
``` unison
|
||||
unique type T = A | B | C
|
||||
|
||||
@ -282,6 +290,7 @@ test = cases
|
||||
## Non-exhaustive
|
||||
|
||||
Nat
|
||||
|
||||
``` unison
|
||||
test : Nat -> ()
|
||||
test = cases
|
||||
@ -302,6 +311,7 @@ test = cases
|
||||
|
||||
```
|
||||
Boolean
|
||||
|
||||
``` unison
|
||||
test : Boolean -> ()
|
||||
test = cases
|
||||
@ -324,6 +334,7 @@ test = cases
|
||||
## Exhaustive
|
||||
|
||||
Nat
|
||||
|
||||
``` unison
|
||||
test : Nat -> ()
|
||||
test = cases
|
||||
@ -345,6 +356,7 @@ test = cases
|
||||
|
||||
```
|
||||
Boolean
|
||||
|
||||
``` unison
|
||||
test : Boolean -> ()
|
||||
test = cases
|
||||
@ -368,6 +380,7 @@ test = cases
|
||||
# Redundant
|
||||
|
||||
Nat
|
||||
|
||||
``` unison
|
||||
test : Nat -> ()
|
||||
test = cases
|
||||
@ -386,6 +399,7 @@ test = cases
|
||||
|
||||
```
|
||||
Boolean
|
||||
|
||||
``` unison
|
||||
test : Boolean -> ()
|
||||
test = cases
|
||||
@ -406,6 +420,7 @@ test = cases
|
||||
# Sequences
|
||||
|
||||
## Exhaustive
|
||||
|
||||
``` unison
|
||||
test : [()] -> ()
|
||||
test = cases
|
||||
@ -427,6 +442,7 @@ test = cases
|
||||
|
||||
```
|
||||
## Non-exhaustive
|
||||
|
||||
``` unison
|
||||
test : [()] -> ()
|
||||
test = cases
|
||||
@ -529,6 +545,7 @@ test = cases
|
||||
## Uninhabited
|
||||
|
||||
`Cons` is not expected since `V` is uninhabited
|
||||
|
||||
``` unison
|
||||
unique type V =
|
||||
|
||||
@ -559,6 +576,7 @@ final element is `false`, while the fourth pattern matches when the
|
||||
first element is `true`. However, the only possible list length at
|
||||
the third or fourth clause is 1, so the first and final element must
|
||||
be equal. Thus, the pattern match is exhaustive.
|
||||
|
||||
``` unison
|
||||
test : [Boolean] -> ()
|
||||
test = cases
|
||||
@ -582,6 +600,7 @@ test = cases
|
||||
|
||||
```
|
||||
This is the same idea as above but shows that fourth match is redundant.
|
||||
|
||||
``` unison
|
||||
test : [Boolean] -> ()
|
||||
test = cases
|
||||
@ -607,6 +626,7 @@ first and third element are true. The third matches lists of length 4
|
||||
or greater where the final 4 elements are `true, false, true, false`.
|
||||
The list must be exactly of length 4 to arrive at the second or third
|
||||
clause, so the third pattern is redundant.
|
||||
|
||||
``` unison
|
||||
test : [Boolean] -> ()
|
||||
test = cases
|
||||
@ -665,6 +685,7 @@ transitive type dependencies of references that appear in the expression.
|
||||
|
||||
This test ensures that we have fetched the `T` type although there is
|
||||
no data decl reference to `T` in `witht`.
|
||||
|
||||
``` unison
|
||||
witht : Unit
|
||||
witht = match unit2t () with
|
||||
|
@ -1,6 +1,5 @@
|
||||
Regression test for https://github.com/unisonweb/unison/pull/2377
|
||||
|
||||
|
||||
``` unison
|
||||
structural ability Ab where
|
||||
a: Nat -> ()
|
||||
|
@ -1,8 +1,6 @@
|
||||
We had bugs in the calling conventions for both send and terminate which would
|
||||
cause pattern matching on the resulting (Right ()) would cause a runtime error.
|
||||
|
||||
|
||||
|
||||
``` unison
|
||||
use builtin.io2.Tls newClient send handshake terminate
|
||||
|
||||
|
@ -128,7 +128,7 @@ unique type UserType = UserType Nat
|
||||
unique type RecordWithUserType = { a : Text, b : Record4, c : UserType }
|
||||
```
|
||||
|
||||
If you `view` or `edit` it, it _should_ be treated as a record type, but it does not (which is a bug)
|
||||
If you `view` or `edit` it, it *should* be treated as a record type, but it does not (which is a bug)
|
||||
|
||||
```ucm
|
||||
scratch/main> view RecordWithUserType
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user