The codebase manager lets you make changes to your codebase and explore the definitions it contains, but it also listens for changes to any file ending in
.uin the current directory. When any such file is saved (which we call a "scratch file"), Unison parses and typechecks that file. Let's try this out.
ucmterminal running and open up a file,
foo.u,or whatever you like) in your preferred text editor (if you want syntax highlighting for Unison files,follow this linkfor instructions on setting up your editor).
Now put the following in your scratch file:
square : Nat -> Nat square x = use Nat * x * x
This defines a function called
square.It takes an argument called
xand it returns
xmultiplied by itself.
When you save the file, Unison replies:
✅ I found and typechecked these definitions in ~/unisoncode/scratch.u. If you do an `add` or `update` , here's how your codebase would change: ⍟ These new definitions are ok to `add`: square : Nat -> Nat Now evaluating any watch expressions (lines starting with `>`)… Ctrl+C cancels.
It typechecked the
squarefunction and tells us that
squareis "ok to
add."We'll do that shortly, but first, let's try calling our function right in the
scratch.ufile, just by starting a line with
square : Nat -> Nat square x = use Nat * x * x > square 4
And Unison prints:
6 | > square 4 ⧩ 16
6 |is the line number from the file. The
> square 4on line 6 of the file, starting with a
>is called a "watch expression", and Unison uses these watch expressions instead of having a separate read-eval-print-loop (REPL). The code you are editing can be run interactively as you go, with a full text editor at your disposal, with the same definitions all in scope, without needing to switch to a separate tool.
use Nat *is ause clausewhich specifies which "*" operator we want to use. This one is from the
Natnamespace in our
lib.basestandard library. Use clauses mean we can refer to
Natand can refer to
*without prefixing it
Question:do we really want to reevaluate all watch expressions on every file save? What if they're expensive? Luckily, Unison keeps a cache of results for expressions it evaluates, keyed by the hash of the expression, and you can clear this cache at any time without ill effects. If a result for a hash is in the cache, Unison returns that instead of evaluating the expression again. So you can think of and use your
.uscratch files a bit like spreadsheets, which only recompute the minimal amount when dependencies change.
Let's try out a few more examples:
-- A comment, ignored by Unison > List.reverse [1,2,3,4] > 4 + 6 > 5.0 / 2.0 > not true
✅ ~/unisoncode/scratch.u changed. Now evaluating any watch expressions (lines starting with `>`)… Ctrl+C cancels. 6 | > List.reverse [1,2,3,4] ⧩ [4, 3, 2, 1] 7 | > 4 + 6 ⧩ 10 8 | > 5.0 / 2.0 ⧩ 2.5 9 | > not true ⧩ false
A function which is deterministic will always return the same result for the given set of input values.