Skip to content

Commit 86d9303

Browse files
authored
Merge pull request #142 from exercism/unison-upgrade
The Unison upgrade
2 parents a74cc45 + 4e7849f commit 86d9303

File tree

174 files changed

+2776
-2662
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+2776
-2662
lines changed

docs/INSTALLATION.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Installation Options
44

5-
The current Unison release is available for Mac OS X, 64-bit Linux, and Windows users! We hope that if you are trying out Unison you'll come talk to us in the Exercism forum or in the [Unison language slack](http://unison-lang.org/slack). Come ask questions, and report issues you might encounter! We want you to have a welcoming and positive experience when getting started! 😊
5+
The current Unison release is available for Mac OS X, 64-bit Linux, and Windows users! We hope that if you are trying out Unison you'll come talk to us in the Exercism forum or in the [Unison Discord](https://unison-lang.org/discord). Come ask questions, and report issues you might encounter! We want you to have a welcoming and positive experience when getting started! 😊
66

77
Unison can be downloaded with [homebrew](https://brew.sh/), [Nix](https://github.com/ceedubs/unison-nix/#usage), or directly via packaged binaries. All of these download options are described in the [Installation instructions page of our website](https://www.unison-lang.org/learn/quickstart/#installation-options). Once you have the UCM installed, head back here!
88

docs/LEARNING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ For reference material, the [Unison language reference](https://www.unison-lang.
88

99
You may want to familiarize yourself with [Unison Share](https://share.unison-lang.org/), Unison's repository for public libraries and projects. The documentation for the standard library, [`base`](https://share.unison-lang.org/@unison/code/latest/namespaces/public/base/latest), contains helpful usage information.
1010

11-
👋 If you're ever stuck, we're happy to help. The #beginner-friendly channel in [the official Unison slack](http://unison-lang.org/slack) is filled with friendly people.
11+
👋 If you're ever stuck, we're happy to help. The #beginner-friendly channel in [the official Unison Discord server](https://unison-lang.org/discord) is filled with friendly people.

docs/RESOURCES.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44

55
* [The Unison language documentation](https://www.unison-lang.org/learn/fundamentals/values-and-functions/terms/) is a great place to learn core Unison concepts
66
* [Unison Share](https://share.unison-lang.org/) is the repository where we host public libraries and code
7-
* You can always ask questions in [the Unison slack](http://unison-lang.org/slack)
7+
* You can always ask questions in [the Unison Discord](https://unison-lang.org/discord)
88
* [The Unison Blog](https://www.unison-lang.org/blog/) contains language updates and special topics
99
* An article about using [Unison's Remote ability to implement a Spark-like library](https://www.unison-lang.org/articles/distributed-datasets/)
1010

1111
## Videos
1212

13-
* [YOW! Lambda Jam 2021](https://www.youtube.com/watch?v=DF6zt0Q-pz4), by Rúnar Bjarnason
13+
* [YOW! Lambda Jam 2021 - Part 1](https://www.youtube.com/watch?v=Adu75GJ0w1o), and [Part 2](https://www.youtube.com/watch?v=gy44CTCce0o), by Rúnar Bjarnason
1414
* [Scale By the Bay 2019](https://www.youtube.com/watch?v=IvENPX0MAZ4), by Paul Chiusano
1515
* This is a 32 minute talk that briefly covers the core ideas of Unison and talks about Unison's approach to refactoring.
1616
* [Strange Loop 2019](https://www.youtube.com/watch?v=gCWtkvDQ2ZI), by Paul Chiusano
1717
* This is a longer (40 min) introduction to the core ideas of Unison and probably the best talk to start with.
1818
* [Scale By the Bay 2018](https://www.youtube.com/watch?v=v7L-5AQQkbM), by Paul Chiusano.
1919
* [Lambda World 2018](https://www.youtube.com/watch?v=rp_Eild1aq8), by Rúnar Bjarnason also presented at [Øredev 2018](https://vimeo.com/311512465).
2020
* [Scala World 2017](https://www.youtube.com/watch?v=knqlWboqf_U), by Paul Chiusano.
21-
* [Full Stack Fest](https://www.youtube.com/watch?v=f6yA3t0dO-k) 2016, by Paul Chiusano
21+
* [Full Stack Fest](https://www.youtube.com/watch?v=f6yA3t0dO-k) 2016, by Paul Chiusano

docs/TESTS.md

+11-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Writing Unison code is as simple as opening your terminal of choice and running the `ucm` command in the directory where you'll be writing your Unison code. Then you can use your favorite text editor to create or open a file with a `.u` suffix, like `scratch.u` or `hello.u`. The bulk of your workflow will be navigating between the running `ucm` command line instance and your `.u` file. The UCM automatically listens to changes in your `.u` suffixed file upon saving the file.
1010

11-
In lieu of a directory structure, Unison codebases are organized via "namespaces". You'll be exploring the standard library's namespace, called `base`, for useful functions and data types, and you'll be creating your own as you write Unison code. In the UCM, navigation in the codebase is done with the [`ls`](https://www.unison-lang.org/learn/ucm-commands/#ls), [`cd`](https://www.unison-lang.org/learn/ucm-commands/#cd), and [`view`](https://www.unison-lang.org/learn/ucm-commands/#view) commands—they're used for listing namespace content, moving throughout the namespace tree, and viewing source code, respectively.
11+
In lieu of a directory structure, Unison codebases are organized via "namespaces". You'll be exploring the standard library's namespace, called `base`, for useful functions and data types, and you'll be creating your own as you write Unison code. In the UCM, navigation in the codebase is done with the [`ls`](https://www.unison-lang.org/learn/ucm-commands/#ls) and [`view`](https://www.unison-lang.org/learn/ucm-commands/#view) commands—they're used for listing namespace content and viewing source code, respectively.
1212

1313
While you can navigate and view your codebase via the UCM CLI, you may also want to see a nice graphical representation of your work. You can do that by issuing the [`ui`](https://www.unison-lang.org/learn/ucm-commands/#ui) command in the UCM CLI. It will open a browser window with a view of the code in your codebase. The local codebase UI is also a great way to explore functions in our standard library, called `base`, which might be useful in accomplishing the exercises. [Read more about the local codebase UI here](https://www.unison-lang.org/learn/tooling/local-codebase-u-i/).
1414

@@ -18,21 +18,22 @@
1818

1919
### Quick overview
2020

21-
1. With the UCM watching the exercise directory, make your changes in the `<myFileName>.u` file
22-
2. Save the `<myFileName>.u` file
23-
3. If the file typechecks, run the `add` or `update` UCM commands
21+
1. Create a new project using command [`project.create`](https://www.unison-lang.org/docs/tour/#part-2-tour) and provide the name for it (e.g. `project.create hello-world`)
22+
2. With the UCM watching the exercise directory, make your changes in the `<myFileName>.u` file
23+
3. Save the `<myFileName>.u` file
24+
4. If the file typechecks, run the `add` or `update` UCM commands
2425

2526
* If the file does not typecheck, make changes to the code in your `<myFileName>.u` file until it compiles
26-
4. Run the `load <myFileName>.test.u` command in the UCM cli to bring the tests into scope and run them
27+
5. Run the `load <myFileName>.test.u` command in the UCM cli to bring the tests into scope and run them
2728

2829
### Detailed walk through
2930

30-
If you're working on an Exercism problem on the command line, most likely you'll be implementing your solution in the directory named after the given exercise. For example, if the exercise is `hello-world`, you should open the `ucm` from the command line after having `cd`'ed into `~/exercism/unison/hello-world`. Make your implementation changes in the `hello.u` file, and when you're satisfied with your implementation, enter the `add` or `update` command in the Unison codebase manager CLI (UCM) to add your work from the file into the codebase.
31+
If you're working on an Exercism problem on the command line, most likely you'll be implementing your solution in the directory named after the given exercise. For example, if the exercise is `hello-world`, you should open the `ucm` from the command line after having `cd`'ed into `~/exercism/unison/hello-world` and create a project in the `ucm` (e.g. `project.create hello-world`). Make your implementation changes in the `hello.u` file, and when you're satisfied with your implementation, enter the `add` or `update` command in the Unison codebase manager CLI (UCM) to add your work from the file into the codebase.
3132

32-
The file that contains the tests for each exercise is suffixed `.test.u`. You'll want to use the `load` command in the UCM to bring the tests into scope and run them. The `load` command takes a file path as its argument. Here's what that might look like for the hello world exercise:
33+
The file that contains the tests for each exercise is suffixed `.test.u`. You'll want to use the `load` command in the UCM to bring the tests into scope and run them. The `load` command takes a file path as its argument. Here's what that might look like for the hello world exercise and `hello-world` project:
3334

3435
```
35-
.> load hello.test.u
36+
hello-world/main> load hello.test.u
3637
```
3738

3839
You should see a message from the UCM about the terms that were brought into scope and, importantly, the result of running the test:
@@ -63,7 +64,7 @@
6364
6465
hello : Text
6566
66-
.> update
67+
hello-world/main> update
6768
6869
⍟ I've updated these names to your new definition:
6970
@@ -73,7 +74,7 @@
7374
Next we can re-load our tests to see if anything changed!
7475

7576
```
76-
.> load hello.test.u
77+
hello-world/main> load hello.test.u
7778
Now evaluating any watch expressions (lines starting with `>`)... Ctrl+C cancels.
7879
7980
@@ -91,7 +92,6 @@
9192
* If the old definition has any dependents, update will automatically propagate the change if possible, or create a [`todo`](https://www.unison-lang.org/learn/usage-topics/workflow-how-tos/resolve-conflicts/) item for future refactoring.
9293
* [`load`](https://www.unison-lang.org/learn/ucm-commands/#load): Parses, typechecks and evaluates the given `.u` suffixed scratch file. Once typechecked and evaluated, you can add the terms to your codebase.
9394
* [`ls`](https://www.unison-lang.org/learn/ucm-commands/#ls): Lists the contents of a namespace
94-
* [`cd`](https://www.unison-lang.org/learn/ucm-commands/#cd): Navigates into the given namespace, creating the namespace if it does not exist
9595
* [`view`](https://www.unison-lang.org/learn/ucm-commands/#view): View the source code of a given Unison definition
9696
* [`ui`](https://www.unison-lang.org/learn/ucm-commands/#ui): Opens the local codebase UI
9797
* `exit`: Closes the UCM

docs/WORKFLOW.md

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ The UCM will show the results of evaluating the expression upon saving the file.
1414

1515
For a more in-depth Exercism workflow, here's a [walk-through video][walk-through-vid] of implementing and testing an Exercism problem.
1616

17+
```exercism/caution
18+
The walk-through video shows workflow for the older version of Unison. See new workflow [here](https://exercism.org/docs/tracks/unison/tests) with new project workflow.
19+
```
20+
1721
## Codebase organization
1822

1923
A Unison codebase is organized by "namespaces." Namespaces function a bit like directories in a file system, except instead of containing files, they contain your Unison types and functions. Namespace paths are separated by dots, `.`. For example, we can refer to the `Text` namespace in the `base` namespace with `base.Text`.
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
[
22
{
33
"name": "lasagna.test.ex1",
4-
"test_code": "lasagna.test.ex1 = test.expect (expectedMinutesInOven === 40)"
4+
"test_code": "let\n Test.expect (expectedMinutesInOven === 40)"
55
},
66
{
77
"name": "lasagna.test.ex2",
8-
"test_code": "lasagna.test.ex2 = test.expect (preparationTimeInMinutes 5 === 10)"
8+
"test_code": "let\n Test.expect (preparationTimeInMinutes 5 === 10)"
99
},
1010
{
1111
"name": "lasagna.test.ex3",
12-
"test_code": "lasagna.test.ex3 = test.expect (elapsedTimeInMinutes 3 20 === 26)"
12+
"test_code": "let\n Test.expect (elapsedTimeInMinutes 3 20 === 26)"
1313
}
14-
]
14+
]
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Testing transcript
22

33
```ucm
4-
.> load ./lasagna.u
5-
.> add
6-
.> load ./lasagna.test.u
7-
.> add
8-
.> move.term lasagna.tests tests
4+
scratch/main> load ./lasagna.u
5+
scratch/main> add
6+
scratch/main> load ./lasagna.test.u
7+
scratch/main> add
8+
scratch/main> move.term lasagna.tests tests
99
```
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,50 @@
11
[
22
{
3-
"name": "pacmanRules.test.ex1",
4-
"test_code": "pacmanRules.test.ex1 = let\n\tTest.label \"eatGhost, ghost gets eaten\" <| expect (eatGhost true true)"
3+
"name": "eatGhost, ghost gets eaten",
4+
"test_code": "let\n Test.label.deprecated \"eatGhost, ghost gets eaten\" <| expect (eatGhost true true)"
55
},
66
{
7-
"name": "pacmanRules.test.ex2",
8-
"test_code": "pacmanRules.test.ex2 = let\n\tTest.label \"eatGhost, ghost does not get eaten because no power pellet active\" <| expect (eatGhost false true === false)"
7+
"name": "eatGhost, ghost does not get eaten because no power pellet active",
8+
"test_code": "let\n Test.label.deprecated \"eatGhost, ghost does not get eaten because no power pellet active\" <| expect (eatGhost false true === false)"
99
},
1010
{
11-
"name": "pacmanRules.test.ex3",
12-
"test_code": "pacmanRules.test.ex3 = let\n\tTest.label \"eatGhost, ghost does not get eaten because not touching ghost\" <| expect (eatGhost true false === false)"
11+
"name": "eatGhost, ghost does not get eaten because not touching ghost",
12+
"test_code": "let\n Test.label.deprecated \"eatGhost, ghost does not get eaten because not touching ghost\" <| expect (eatGhost true false === false)"
1313
},
1414
{
15-
"name": "pacmanRules.test.ex4",
16-
"test_code": "pacmanRules.test.ex4 = let\n\tTest.label \"score, score when eating dot\" <| expect (score false true)"
15+
"name": "score, score when eating dot",
16+
"test_code": "let\n Test.label.deprecated \"score, score when eating dot\" <| expect (score false true)"
1717
},
1818
{
19-
"name": "pacmanRules.test.ex5",
20-
"test_code": "pacmanRules.test.ex5 = let\n\tTest.label \"score, score when eating power pellet\" <| expect (score true false)"
19+
"name": "score, score when eating power pellet",
20+
"test_code": "let\n Test.label.deprecated \"score, score when eating power pellet\" <| expect (score true false)"
2121
},
2222
{
23-
"name": "pacmanRules.test.ex6",
24-
"test_code": "pacmanRules.test.ex6 = let\n\tTest.label \"score, no score when nothing eaten\" <| expect (score false false === false )"
23+
"name": "score, no score when nothing eaten",
24+
"test_code": "let\n Test.label.deprecated \"score, no score when nothing eaten\" <| expect (score false false === false )"
2525
},
2626
{
27-
"name": "pacmanRules.test.ex7",
28-
"test_code": "pacmanRules.test.ex7 = let\n\tTest.label \"lose if touching a ghost without a power pellet active\" <| expect (lose false true)"
27+
"name": "lose if touching a ghost without a power pellet active",
28+
"test_code": "let\n Test.label.deprecated \"lose if touching a ghost without a power pellet active\" <| expect (lose false true)"
2929
},
3030
{
31-
"name": "pacmanRules.test.ex8",
32-
"test_code": "pacmanRules.test.ex8 = let\n\tTest.label \"don't lose if touching a ghost with a power pellet active\" <| expect (lose true true === false)"
31+
"name": "don't lose if touching a ghost with a power pellet active",
32+
"test_code": "let\n Test.label.deprecated \"don't lose if touching a ghost with a power pellet active\" <| expect (lose true true === false)"
3333
},
3434
{
35-
"name": "pacmanRules.test.ex9",
36-
"test_code": "pacmanRules.test.ex9 = let\n\tTest.label \"don't lose if not touching a ghost\" <| expect (lose true false === false)"
35+
"name": "don't lose if not touching a ghost",
36+
"test_code": "let\n Test.label.deprecated \"don't lose if not touching a ghost\" <| expect (lose true false === false)"
3737
},
3838
{
39-
"name": "pacmanRules.test.ex10",
40-
"test_code": "pacmanRules.test.ex10 = let\n\tTest.label \"win if all dots eaten\" <| expect (win true false false)"
39+
"name": "win if all dots eaten",
40+
"test_code": "let\n Test.label.deprecated \"win if all dots eaten\" <| expect (win true false false)"
4141
},
4242
{
43-
"name": "pacmanRules.test.ex11",
44-
"test_code": "pacmanRules.test.ex11 = let\n\tTest.label \"don't win if all dots eaten, but touching a ghost\" <| expect (win true false true === false)"
43+
"name": "don't win if all dots eaten, but touching a ghost",
44+
"test_code": "let\n Test.label.deprecated \"don't win if all dots eaten, but touching a ghost\" <| expect (win true false true === false)"
4545
},
4646
{
47-
"name": "pacmanRules.test.ex12",
48-
"test_code": "pacmanRules.test.ex12 = let\n\tTest.label \"win if all dots eaten and touching a ghost with a power pellet active\" ,| expect (win true true true)"
47+
"name": "win if all dots eaten and touching a ghost with a power pellet active",
48+
"test_code": "let\n Test.label.deprecated \"win if all dots eaten and touching a ghost with a power pellet active\" <| expect (win true true true)"
4949
}
50-
]
50+
]
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Testing transcript
22

33
```ucm
4-
.> load ./pacmanRules.u
5-
.> add
6-
.> load ./pacmanRules.test.u
7-
.> add
8-
.> move.term pacmanRules.tests tests
4+
scratch/main> load ./pacmanRules.u
5+
scratch/main> add
6+
scratch/main> load ./pacmanRules.test.u
7+
scratch/main> add
8+
scratch/main> move.term pacmanRules.tests tests
99
```

exercises/concept/pacman-rules/pacmanRules.test.u

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
pacmanRules.test.ex1 = let
2-
Test.label "eatGhost, ghost gets eaten" <| expect (eatGhost true true)
2+
Test.label.deprecated "eatGhost, ghost gets eaten" <| expect (eatGhost true true)
33

44
pacmanRules.test.ex2 = let
5-
Test.label "eatGhost, ghost does not get eaten because no power pellet active" <| expect (eatGhost false true === false)
5+
Test.label.deprecated "eatGhost, ghost does not get eaten because no power pellet active" <| expect (eatGhost false true === false)
66

77
pacmanRules.test.ex3 = let
8-
Test.label "eatGhost, ghost does not get eaten because not touching ghost" <| expect (eatGhost true false === false)
8+
Test.label.deprecated "eatGhost, ghost does not get eaten because not touching ghost" <| expect (eatGhost true false === false)
99

1010
pacmanRules.test.ex4 = let
11-
Test.label "score, score when eating dot" <| expect (score false true)
11+
Test.label.deprecated "score, score when eating dot" <| expect (score false true)
1212

1313
pacmanRules.test.ex5 = let
14-
Test.label "score, score when eating power pellet" <| expect (score true false)
14+
Test.label.deprecated "score, score when eating power pellet" <| expect (score true false)
1515

1616
pacmanRules.test.ex6 = let
17-
Test.label "score, no score when nothing eaten" <| expect (score false false === false )
17+
Test.label.deprecated "score, no score when nothing eaten" <| expect (score false false === false )
1818

1919
pacmanRules.test.ex7 = let
20-
Test.label "lose if touching a ghost without a power pellet active" <| expect (lose false true)
20+
Test.label.deprecated "lose if touching a ghost without a power pellet active" <| expect (lose false true)
2121

2222
pacmanRules.test.ex8 = let
23-
Test.label "don't lose if touching a ghost with a power pellet active" <| expect (lose true true === false)
23+
Test.label.deprecated "don't lose if touching a ghost with a power pellet active" <| expect (lose true true === false)
2424

2525
pacmanRules.test.ex9 = let
26-
Test.label "don't lose if not touching a ghost" <| expect (lose true false === false)
26+
Test.label.deprecated "don't lose if not touching a ghost" <| expect (lose true false === false)
2727

2828
pacmanRules.test.ex10 = let
29-
Test.label "win if all dots eaten" <| expect (win true false false)
29+
Test.label.deprecated "win if all dots eaten" <| expect (win true false false)
3030

3131
pacmanRules.test.ex11 = let
32-
Test.label "don't win if all dots eaten, but touching a ghost" <| expect (win true false true === false)
32+
Test.label.deprecated "don't win if all dots eaten, but touching a ghost" <| expect (win true false true === false)
3333

3434
pacmanRules.test.ex12 = let
35-
Test.label "win if all dots eaten and touching a ghost with a power pellet active" <| expect (win true true true)
35+
Test.label.deprecated "win if all dots eaten and touching a ghost with a power pellet active" <| expect (win true true true)
3636

3737
test> pacmanRules.tests = runAll [
3838
pacmanRules.test.ex1,

0 commit comments

Comments
 (0)