Merge branch 'cp/causal-name-lookup-index' into cp/remove-old-name-lookups

This commit is contained in:
Chris Penner 2023-02-08 12:21:53 -06:00
commit 106af7fdd2
37 changed files with 2123 additions and 1324 deletions

View File

@ -42,6 +42,8 @@ If these instructions don't work for you or are incomplete, please file an issue
The build uses [Stack](http://docs.haskellstack.org/). If you don't already have it installed, [follow the install instructions](http://docs.haskellstack.org/en/stable/README.html#how-to-install) for your platform. (Hint: `brew update && brew install stack`)
If you have not set up the Haskell toolchain before and are trying to contribute to Unison on an M1 Mac, we have [some tips specifically for you](docs/m1-mac-setup-tips.markdown/new).
```sh
$ git clone https://github.com/unisonweb/unison.git
$ cd unison
@ -49,7 +51,7 @@ $ stack --version # we'll want to know this version if you run into trouble
$ stack build --fast --test && stack exec unison
```
To run the Unison Local UI while building from source, you can use the `/dev-ui-install.sh` script. It will download the latest release of [unison-local-ui](https://github.com/unisonweb/unison-local-ui) and put it in the expected location for the unison executable created by `stack build`. When you start unison, you'll see a url where Unison Local UI is running.
To run the Unison Local UI while building from source, you can use the `/dev-ui-install.sh` script. It will download the latest release of [unison-local-ui](https://github.com/unisonweb/unison-local-ui) and put it in the expected location for the unison executable created by `stack build`. When you start unison, you'll see a url where Unison Local UI is running.
See [`development.markdown`](development.markdown) for a list of build commands you'll likely use during development.
@ -61,7 +63,7 @@ View Language Server setup instructions [here](docs/language-server.markdown).
Codebase Server
---------------
When `ucm` starts it starts a Codebase web server that is used by the
When `ucm` starts it starts a Codebase web server that is used by the
[Unison Local UI](https://github.com/unisonweb/unison-local-ui). It selects a random
port and a unique token that must be used when starting the UI to correctly
connect to the server.

View File

@ -24,10 +24,11 @@ denoted by `$CUSTOM`, then the compiler commands will look in:
for the `unison/` directory containing the library files.
The compiler commands also expect Chez Scheme to be installed
separately, and for `scheme` to be callable on the user's path. For
information on how to install, see:
separately, and for `scheme` to be callable on the user's path. The
continuation library now makes use of features in the Racket fork of
Chez. For information on how to install, see:
https://github.com/cisco/ChezScheme/blob/main/BUILDING
https://github.com/racket/ChezScheme/blob/master/BUILDING
For more information on Chez Scheme in general, see:

View File

@ -1,47 +1,259 @@
; This library is intended to contain the implementation of
; delimited continuations used in the semantics of abilities.
;
; Currently, it is a somewhat naive implementation based on call/cc.
; This has known issues that seem to still be in force even though a
; tweak has been applied that should fix certain space leaks. So, in
; the future it will likely need to be rewritten using some
; implementation specific machinery (possibly making use of
; continuation attachments as in the Racket implementation).
;
; Also, although the API includes prompts, they are currently ignored
; in `control` and `prompt` always uses the same prompt (0). This
; means that nesting handlers will not work in general, since requests
; will not be able to jump over an inner handler of unrelated
; abilities. It should be sufficient for testing simple examples in
; the mean time, though.
(library (unison cont)
(export prompt control)
(export
prompt
control)
(import (chezscheme))
(import (chezscheme)
(unison core))
(define mk (lambda (x) (raise "fell off end")))
; This implementation is based on the implementation of delimited
; continuations used in racket, and makes use of primitives added in
; the racket fork of chez scheme.
;
; The overall idea is to keep track of a meta-continuation that is
; made up of a series of captured native continuations. The native
; continuations make part of the frames of the meta-continuation,
; and these frames can be labeled with prompts to support
; multi-prompt delimited continuations. The native 'current
; continuation' makes up the portion of the meta-continuation below
; the nearest prompt.
;
; The specific racket-chez feature used is #%$call-in-continuation
; which does not seem to be available in the upstream chez. This is
; an important feature to have, because the mechanism for obtaining
; the native continuation in chez is call/cc, which leaves the
; native continuation in place. However, when we capture the native
; continuation to push it onto a frame of the meta-continuation, it
; may actually be completely eliminated from the implicit
; continuation, because we will only ever return to it by popping
; the corresponding frame of the meta=continuation.
;
; Failure to truncate the native continuation can lead to space
; leaks due to growing unreachable portions of it. The racket-chez
; feature allows us to instead repeatedly replace the implicit
; continuation with #%$null-continuation, which avoids the leak.
(define-virtual-register meta-continuation '())
; A record type representing continuation prompts.
;
; By comparing these records for pointer equality, we can make up
; fresh prompts whenever needed, without having to keep track of
; some sort of supply of prompts.
(define-record-type continuation-prompt
(fields (immutable name)))
; A frame of the meta-continuation consists of:
; 1. A prompt delimiting the portion of the meta-continuation in
; front of it.
; 2. A native continuation to resume when re-entering the given
; frame.
(define-record-type meta-frame
(fields
(immutable prompt)
(immutable resume-k)))
; A convenient abbreviation for grabbing the continuation.
(define-syntax let/cc
(syntax-rules ()
[(let/cc k e ...)
(identifier? #'k)
(call/cc (lambda (k) e ...))]))
; A wrapper around primitive operations for truncating the implicit
; continuation. `h` should be a nullary procedure that we want to
; execute in an empty continuation.
(define (call-in-empty-frame h)
(($primitive $call-in-continuation)
($primitive $null-continuation)
'() ; marks
h))
; Removes and returns the top frame of the meta-continuation.
;
; Note: this procedure assumes that the meta-continuation has
; already been checked for emptiness, and does no checking of its
; own.
(define (pop-frame!)
(let ([mf (car meta-continuation)])
(set! meta-continuation (cdr meta-continuation))
mf))
; Adds a frame to the top of the meta-continuation.
(define (push-frame! fm)
(set! meta-continuation (cons fm meta-continuation)))
; Handles returning values up the meta-continuation.
;
; Note: when we replace the native continuation with the null
; continuation, for reasons mentioned above, it's important that the
; things we run in that null continuation actually call this to
; return up the meta-continuation. Otherwise we will _actually_
; return to the null continuation, which causes a crash.
(define (yield-to-meta-continuation results)
(cond
[(null? meta-continuation)
(display "falling off end\n")
results]
[else
(let ([mf (pop-frame!)])
(($primitive $call-in-continuation)
(meta-frame-resume-k mf)
'()
(lambda ()
(if (and (pair? results) (null? (cdr results)))
(car results)
(apply values results)))))]))
; This operation corresponds roughly to `reset` in shift/reset
; delimited control. It calls (h p) in a context delimited by
; the prompt p.
;
; This is something of a helper function, as the actual `prompt`
; implementation will involve making up a fresh `p`. However,
; this common code is useful for test cases using only single
; prompt continuations.
;
; Mechanically, what this does is capture the current native
; continuation, push it on the meta-continuation with the specified
; prompt attached, and call (h p) in an empty native continuation.
(define (call-delimited-with-prompt p h)
(let/cc k
(call-in-empty-frame
(lambda ()
(let-values
([results
(let ([fm (make-meta-frame p k)])
(push-frame! fm)
(h p))])
(yield-to-meta-continuation results))))))
; Implements prompt for our multi-prompt prompt/control calculus.
;
; `prompt` makes up a fresh prompt value, and runs its body
; delimited with that value, e.g.:
;
; (prompt p ...)
;
; where `p` is a binding for the prompt value. The above is
; syntactic sugar for something like:
;
; (prompt-impl (lambda (p) ...))
(define (prompt-impl h)
((call/cc
(lambda (k)
(let ([ok mk])
(set! mk (lambda (x) (set! mk ok) (k x)))
; (h 0) <-- prompt = 0
(mk (let ([v (h 0)]) (lambda () v))))))))
(let ([p (make-continuation-prompt 'prompt)])
(call-delimited-with-prompt p h)))
; The nicer syntactic form for the above prompt implementation.
(define-syntax prompt
(syntax-rules ()
[(prompt p e ...)
(prompt-impl (lambda (p) e ...))]))
(define (control-impl h)
(call/cc
(lambda (k)
(let* ([g (lambda () (prompt p (h k)))])
(mk g)))))
; Removes the prompt from the first frame of a meta-continuation.
(define (strip-prompt mc)
(let ([mf (car mc)])
(cons (make-meta-frame #f (meta-frame-resume-k mf)) (cdr mc))))
; This funcion is used to reinstate a captured continuation. It
; should be called with:
;
; k - a native continuation to be pushed before the captured
; meta-continuation
; cc - the captured meta-continuation segment
; p - a prompt that should delimit cc
;
; `p` is used as the prompt value of the `k` frame, so shift/reset
; can be implemented by passing the same `p` that was used when `cc`
; was captured (as that means that any further `p` control effects
; in `cc` do not escape their original scope).
;
; However, we will usually be calling with p = #f, since shallow
; handlers correspond to control effects that are able to eliminate
; prompts.
;
; Note: the captured continuation `cc` is assumed to be in reverse
; order, so will be reversed back onto the meta-continuation.
(define (push-to-meta-continuation k cc p)
(push-frame! (make-meta-frame p k))
(let rec ([cc cc])
(cond
[(null? cc) #f]
[else
(push-frame! (car cc))
(rec (cdr cc))])))
; Wraps a captured continuation with a procedure that reinstates it
; upon invocation. This should be called with:
;
; ok - the captured native continuation that was captured along
; with...
; cc - the split meta-continuation
; p - a prompt associated with the captured continuation. This
; will be installed as a delimiter when the captured
; continuation is re-pushed. If no delimiting is desired,
; simply use #f, or some dummy prompt that will not be
; involved in actual control flow.
;
; Note: the captured continuation `cc` is assumed to be in reverse
; order, so will be reversed back onto the meta-continuation.
(define (make-callable-continuation ok cc p)
(lambda vals
(let/cc nk
(($primitive $call-in-continuation)
ok
'()
(lambda ()
push-to-meta-continuation nk cc p
(apply values vals))))))
; Captures the meta-continuation up to the specified prompt. The
; continuation is wrapped in a function that reinstates it when
; called. The supplied 'body' `h` is then evaluated with the
; captured continuation.
;
; This implementation is designed to support shallow ability
; handlers. This means that we actually implement what would be
; called (in delimited continuation literature) control0. This means
; that:
;
; 1. The control operator _removes_ the prompt from the
; meta-continuation. So any control effects referring to the
; same prompt will only be delimited further up the
; continuation.
; 2. The procedure reinstating the captured continuation does not
; install a delimiter, so said captured continuation is itself
; a procedure that can have control effects relevant to the
; original prompt.
;
; The reason for this is that shallow handlers are one-shot in a
; corresponding way. They only handle the first effect in their
; 'body', and handling _all_ relevant effects requires an explicitly
; recursive handler that re-installs a handling delimiter after each
; effect request.
(define (control-impl p h)
(assert (continuation-prompt? p))
(let/cc k
(let rec ([cc '()] [mc meta-continuation])
(cond
[(or (null? mc)
(eq? p (meta-frame-prompt (car mc))))
(set! meta-continuation (strip-prompt mc))
(let ([ck (make-callable-continuation k cc #f)])
(call-in-empty-frame
(lambda ()
(let-values ([results (h ck)])
(yield-to-meta-continuation results)))))]
[else (rec (cons (car mc) cc) (cdr mc))]))))
; The nicer syntactic form for the control operator.
(define-syntax control
(syntax-rules ()
[(control p k e ...)
(control-impl (lambda (k) e ...))])))
(control-impl (lambda (k) e ...))]))
; TODO: generate this as part of the main program.
; (define-init-registers init-regs)
; (init-regs)
)

109
chez-libs/unison/crypto.ss Normal file
View File

@ -0,0 +1,109 @@
(library (unison crypto)
(export
unison-FOp-crypto.HashAlgorithm.Sha1
unison-FOp-crypto.hashBytes)
(import (chezscheme)
(unison core)
(unison string)
(unison bytevector))
(define (capture-output fn)
(parameterize ((current-output-port (open-output-string)))
(fn)
(get-output-string (current-output-port))))
; if loading the dynamic library is successful, returns true
; otherwise, returns a lambda that will throw the original error
; with some helpful messaging.
(define try-load-shared (lambda (name message)
(guard (x [else (lambda ()
(printf "\n🚨🚨🚨 (crypto.ss) Unable to load shared library ~s 🚨🚨🚨\n---> ~a\n\nOriginal exception:\n" name message)
(raise x)
)])
(load-shared-object name)
#t)))
(define libcrypto (try-load-shared "libcrypto.3.dylib" "Do you have openssl installed?"))
(define libb2 (try-load-shared "libb2.dylib" "Do you have libb2 installed?"))
; if the "source" library was loaded, call (fn), otherwise returns a lambda
; that will throw the original source-library-loading exception when called.
(define (if-loaded source fn)
(case source
(#t (fn))
(else (lambda args (source)))))
(define EVP_Digest
(if-loaded libcrypto (lambda () (foreign-procedure "EVP_Digest"
(
u8* ; input buffer
unsigned-int ; length of input
u8* ; output buffer
boolean ; note: not a boolean, we just need to be able to pass NULL (0)
void* ; the EVP_MD* pointer, which holds the digest algorithm
boolean ; note: not a boolean, we just need to be able to pass NULL (0)
)
; 1 if success, 0 or -1 for failure
int))))
(define digest (lambda (text kind bits)
(let ([buffer (make-bytevector (/ bits 8))])
(if (= 1 (EVP_Digest text (bytevector-length text) buffer #f kind #f))
buffer
(error "crypto.ss digest" "libssl was unable to hash the data for some reason")))))
(define EVP_sha1 (if-loaded libcrypto (lambda () (foreign-procedure "EVP_sha1" () void*))))
(define EVP_sha256 (if-loaded libcrypto (lambda () (foreign-procedure "EVP_sha256" () void*))))
(define EVP_sha512 (if-loaded libcrypto (lambda () (foreign-procedure "EVP_sha512" () void*))))
(define EVP_sha3_256 (if-loaded libcrypto (lambda () (foreign-procedure "EVP_sha3_256" () void*))))
(define EVP_sha3_512 (if-loaded libcrypto (lambda () (foreign-procedure "EVP_sha3_512" () void*))))
(define sha1 (lambda (text) (digest text (EVP_sha1) 160)))
(define sha256 (lambda (text) (digest text (EVP_sha256) 256)))
(define sha512 (lambda (text) (digest text (EVP_sha512) 512)))
(define sha3_256 (lambda (text) (digest text (EVP_sha3_256) 256)))
(define sha3_512 (lambda (text) (digest text (EVP_sha3_512) 512)))
(define blake2b-raw
(if-loaded libb2 (lambda () (foreign-procedure "blake2b"
(
u8* ; output buffer
string ; input buffer
u8* ; input key
int ; output length
int ; input length
int ; key length
) int
))))
(define blake2s-raw
(if-loaded libb2 (lambda () (foreign-procedure "blake2s"
(
u8* ; output buffer
string ; input buffer
u8* ; input key
int ; output length
int ; input length
int ; key length
) int
))))
(define blake2s (lambda (text size)
(let ([buffer (make-bytevector (/ size 8))])
(if (= 0 (blake2s-raw buffer text #f (/ size 8) (string-length text) 0))
buffer
(error "crypto.ss blake2s" "libb2 was unable to hash the data for some reason")))))
(define blake2b (lambda (text size)
(let ([buffer (make-bytevector (/ size 8))])
(if (= 0 (blake2b-raw buffer text #f (/ size 8) (string-length text) 0))
buffer
(error "crypto.ss blake2b" "libb2 was unable to hash the data for some reason")))))
(define (unison-FOp-crypto.HashAlgorithm.Sha1) sha1)
(define (unison-FOp-crypto.hashBytes algo text)
(algo text))
)

View File

@ -101,13 +101,35 @@
unison-POp-VALU
unison-POp-VWLS
unison-POp-UPKB
unison-POp-ADDI
unison-POp-DIVI
unison-POp-EQLI
unison-POp-MODI
unison-POp-LEQI
unison-POp-POWN
unison-POp-VWRS
unison-FOp-crypto.HashAlgorithm.Sha1
unison-FOp-crypto.hashBytes
)
(import (chezscheme)
(unison core)
(unison string)
(unison crypto)
(unison bytevector))
(define unison-POp-UPKB bytevector->u8-list)
(define unison-POp-ADDI +)
(define unison-POp-DIVI /)
(define (unison-POp-EQLI a b)
(if (= a b) 1 0)
)
(define unison-POp-MODI mod)
(define unison-POp-LEQI <=)
(define unison-POp-POWN expt)
(define (reify-exn thunk)
(call/1cc
(lambda (k)
@ -145,11 +167,8 @@
(define (unison-POp-FTOT f) (number->istring f))
(define (unison-POp-IDXB n bs) (bytevector-u8-ref bs n))
(define (unison-POp-IDXS n l)
(call/1cc
(lambda (k)
(with-exception-handler
(lambda (e) (list 0))
(lambda () (list-ref l n))))))
(guard (x [else (list 0)])
(list 1 (list-ref l n))))
(define (unison-POp-IORN m n) (fxlogior m n))
(define (unison-POp-ITOT i) (signed-number->istring i))
(define (unison-POp-LEQN m n) (if (fx<= m n) 1 0))
@ -182,6 +201,12 @@
(if (null? l)
(list 0)
(list 1 (car l) (cdr l))))
(define (unison-POp-VWRS l)
(if (null? l)
(list 0)
(let ([r (reverse l)])
(list 1 (reverse (cdr l)) (car l)))))
(define (unison-POp-XORN m n) (fxxor m n))
(define (unison-POp-VALU c) (decode-value c))

View File

@ -0,0 +1,164 @@
# M1 Mac Haskell toolchain setup
If you are a newcomer to the Haskell ecosystem trying to set up your dev environment on a Mac M1 computer, welcome, you can do this! The tips in this document provide one way to get a working development setup, but are not the only path forward. If you haven't downloaded the Haskell toolchain before, our recommendation is to use GHCup. We've found that issues can arise if you mix ARM native binaries with x86 binaries to be run with Rosetta. If you're a veteran Haskell developer, much of this won't apply to you as it's likely you already have a working development environment.
Here is a working set of versions you can use to build the Unison executable:
GHC version: 8.10.7
Stack version: 2.7.5
Cabal version 3.6.2.0
Haskell language server version: 1.7.0.0
The GHC version for the project can be confirmed by looking at the `resolver` key in this project's `stack.yaml`.
## Newcomer setup tips
[Install GHCup using the instructions on their website.](https://www.haskell.org/ghcup/) Once it's installed make sure `ghcup` is on your path.
```
export PATH="$HOME/.ghcup/bin:$PATH"
```
GHCup has a nice ui for setting Haskell toolchain versions for the project. Enter `ghcup tui` to open it up and follow the instructions for installing and setting the versions there. GHCup will try to download M1 native binaries for the versions given.
Check your clang version. For [hand-wavey reasons](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/301) we recommend you use llvm version 12. See troubleshooting note below about changing your LLVM if your version is different.
```shell
$ clang --version
Homebrew clang version 12.0.1
Target: arm64-apple-darwin20.2.0
Thread model: posix
InstalledDir: /opt/homebrew/opt/llvm@12/bin
```
At the end of the process you should see something like the following for executable locations and versions.
```shell
$ which ghcup
~/.ghcup/bin/ghcup
$ ghcup --version
The GHCup Haskell installer, version 0.1.19.0
```
```bash
$ which stack
~/.ghcup/bin/stack
$ stack --version
Version 2.7.5, Git revision 717ec96c15520748f3fcee00f72504ddccaa30b5 (dirty) (163 commits) aarch64
```
```shell
$ which ghc
~/.ghcup/bin/ghc
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.10.7
```
Check which GHC version Stack thinks it's using too, for good measure:
```shell
$ stack ghc -- --version
The Glorious Glasgow Haskell Compilation System, version 8.10.7
$ stack exec -- which ghc
~/.ghcup/ghc/8.10.7/bin/ghc
```
```shell
$ which haskell-language-server-wrapper
~/.ghcup/bin/haskell-language-server-wrapper
$ haskell-language-server-wrapper
Found "...unison/hie.yaml" for "...unison/a"
Run entered for haskell-language-server-wrapper(haskell-language-server-wrapper) Version 1.7.0.0 aarch64 ghc-9.2.2
Current directory: ...unison
Operating system: darwin
Arguments: []
Cradle directory: ...unison
Cradle type: Stack
Tool versions found on the $PATH
cabal: 3.6.2.0
stack: 2.7.5
ghc: 8.10.7
```
If you're a VS Code user, you can download the Haskell extension for IDE support. You may need to configure it in `settings.json`.
```json
"haskell.manageHLS": "GHCup",
"haskell.toolchain": {
"stack": "2.7.5",
"ghc": "8.10.7",
"cabal": "recommended",
"hls": "1.7.0.0"
}
```
These setting blocks say that the VS Code extension will use GHCup for your Haskell language server distribution, and sets the versions for elements in the toolchain.
## Troubleshooting:
The VS Code extension has compiled a helpful list of troubleshooting steps here: https://github.com/haskell/vscode-haskell#troubleshooting
### "Couldn't figure out LLVM version" or "failed to compile a sanity check" errors
```
<no location info>: error:
Warning: Couldn't figure out LLVM version!
Make sure you have installed LLVM between [9 and 13)
ghc: could not execute: opt
```
Or
```
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
`gcc' failed in phase `Linker'. (Exit code: 1)
```
Try installing llvm version 12
`brew install llvm@12`
and prepend it to your path
```
export PATH="$(brew --prefix)/opt/llvm@12/bin:$PATH"
```
(The GHC version 8.10.7 mentions it supports LLVM versions up to 12. https://www.haskell.org/ghc/download_ghc_8_10_7.html)
### "GHC ABIs don't match!"
Follow the steps here:
https://github.com/haskell/vscode-haskell#ghc-abis-dont-match
We found some success telling Stack to use the system's GHC instead of managing its own version of GHC. You can try this by setting the following two configuration flags in ~/.stack/config.yaml
```
system-ghc: true
install-ghc: false
```
This is telling Stack to use the GHC executable that it finds on your $PATH. Make sure the ghc being provided is the proper version, 8.10.7, from ghcup.
Note that you may need to clean the cache for the project after this failure with `stack clean --full` if you have previously built things with a different stack distribution.
### "stack" commands like "stack build" cause a segfault:
1. Make sure your stack state is clean. `stack clean --full` removes the project's stack work directories (things in .stack-work).
2. [Wait for this bug to be fixed (or help fix this bug!)](https://github.com/commercialhaskell/stack/issues/5607)
3. Or subshell out your stack commands `$(stack commandHere)`
4. Or use bash instead of zsh
### Help! Everything is broken and I want to start over
Warning, the following will remove ghcup, configuration files, cached packages, and versions of the toolchain.
```
ghcup nuke
rm -rf ~/.ghcup
rm -rf ~/.stack
rm -rf ~/.cabal
```

43
flake.lock Normal file
View File

@ -0,0 +1,43 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1674781052,
"narHash": "sha256-nseKFXRvmZ+BDAeWQtsiad+5MnvI/M2Ak9iAWzooWBw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "cc4bb87f5457ba06af9ae57ee4328a49ce674b1b",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-22.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

105
flake.nix Normal file
View File

@ -0,0 +1,105 @@
{
description = "A common environment for unison development";
inputs = {
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11";
};
outputs = { self, flake-utils, nixpkgs }:
let
systemAttrs = flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages."${system}".extend self.overlay;
mystack = pkgs.symlinkJoin {
name = "stack";
paths = [ pkgs.stack ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = let
flags = [ "--no-nix" "--system-ghc" "--no-install-ghc" ];
add-flags =
"--add-flags '${pkgs.lib.concatStringsSep " " flags}'";
in ''
wrapProgram "$out/bin/stack" ${add-flags}
'';
};
ghc-version = "8107";
ghc = pkgs.haskell.packages."ghc${ghc-version}";
make-ormolu = p:
p.callHackageDirect {
pkg = "ormolu";
ver = "0.4.0.0";
sha256 = "0r8jb8lpaxx7wxnvxiynx2dkrfibfl8nxnjl5n4vwy0az166bbnd";
} {
ghc-lib-parser =
pkgs.haskellPackages.ghc-lib-parser_9_2_5_20221107;
Cabal = pkgs.haskellPackages.Cabal_3_6_3_0;
};
myhls = let
hp = pkgs.haskellPackages.extend hp-override;
hp-override = final: prev: {
hls-floskell-plugin =
pkgs.haskell.lib.dontCheck prev.hls-floskell-plugin;
hls-rename-plugin =
pkgs.haskell.lib.dontCheck prev.hls-rename-plugin;
haskell-language-server =
pkgs.haskell.lib.overrideCabal prev.haskell-language-server
(drv: {
configureFlags = drv.configureFlags ++ [
"-f-brittany"
"-f-fourmolu"
"-f-floskell"
"-f-stylishhaskell"
"-f-hlint"
];
});
ormolu = make-ormolu final;
};
in pkgs.haskell-language-server.override {
haskellPackages = hp;
dynamic = true;
supportedGhcVersions = [ ghc-version ];
};
myormolu = make-ormolu pkgs.haskellPackages;
nativePackages = pkgs.lib.optionals pkgs.stdenv.isDarwin (with pkgs.darwin.apple_sdk.frameworks; [ Cocoa ]);
unison-env = pkgs.mkShell {
packages = with pkgs; [
mystack
(haskell.compiler."ghc${ghc-version}".override {
useLLVM = pkgs.stdenv.isAarch64;
})
myormolu
myhls
pkg-config
zlib
] ++ nativePackages;
# workaround for https://gitlab.haskell.org/ghc/ghc/-/issues/11042
shellHook = ''
export LD_LIBRARY_PATH=${pkgs.zlib}/lib:$LD_LIBRARY_PATH
'';
};
in {
apps.repl = flake-utils.lib.mkApp {
drv =
nixpkgs.legacyPackages."${system}".writeShellScriptBin "repl" ''
confnix=$(mktemp)
echo "builtins.getFlake (toString $(git rev-parse --show-toplevel))" >$confnix
trap "rm $confnix" EXIT
nix repl $confnix
'';
};
pkgs = pkgs;
devShell = unison-env;
packages = { };
defaultPackage = self.packages."${system}".unison-env;
});
topLevelAttrs = { overlay = final: prev: { }; };
in systemAttrs // topLevelAttrs;
}

View File

@ -204,6 +204,8 @@ builtinTypesSrc =
Rename' "IO" "io2.IO",
B' "Handle" CT.Data,
Rename' "Handle" "io2.Handle",
B' "ProcessHandle" CT.Data,
Rename' "ProcessHandle" "io2.ProcessHandle",
B' "Socket" CT.Data,
Rename' "Socket" "io2.Socket",
B' "ThreadId" CT.Data,
@ -760,6 +762,13 @@ ioBuiltins =
forall1 "a" $ \a ->
a --> io (reft iot a)
),
( "IO.process.call", text --> list text --> io nat),
( "IO.process.start",
text --> list text -->
io (tuple [handle, handle, handle, phandle])),
( "IO.process.kill", phandle --> io unit),
( "IO.process.wait", phandle --> io nat),
( "IO.process.exitCode", phandle --> io (optionalt nat)),
( "validateSandboxed",
forall1 "a" $ \a -> list termLink --> a --> boolean
),
@ -955,10 +964,11 @@ iarrayt a = Type.iarrayType () `app` a
marrayt :: Type -> Type -> Type
marrayt g a = Type.marrayType () `app` g `app` a
socket, threadId, handle, unit :: Type
socket, threadId, handle, phandle, unit :: Type
socket = Type.socket ()
threadId = Type.threadId ()
handle = Type.fileHandle ()
phandle = Type.processHandle ()
unit = DD.unitType ()
tls, tlsClientConfig, tlsServerConfig, tlsSignedCert, tlsPrivateKey, tlsVersion, tlsCipher :: Type

View File

@ -13,8 +13,6 @@ module Unison.Codebase.BranchUtil
-- * Branch modifications
makeSetBranch,
makeDeleteBranch,
makeObliterateBranch,
makeAddTypeName,
makeDeleteTypeName,
makeAddTermName,
@ -24,7 +22,6 @@ module Unison.Codebase.BranchUtil
)
where
import Control.Lens
import qualified Data.Map as Map
import qualified Data.Set as Set
import Unison.Codebase.Branch (Branch, Branch0)
@ -137,18 +134,3 @@ makeDeleteTypeName (p, name) r = (p, Branch.deleteTypeName r name)
makeSetBranch ::
Path.Split -> Branch m -> (Path, Branch0 m -> Branch0 m)
makeSetBranch (p, name) b = (p, Branch.setChildBranch name b)
-- | "delete"s a branch by cons'ing an empty Branch0 onto the history at that location.
-- See also 'makeObliterateBranch'.
makeDeleteBranch ::
Applicative m =>
Path.Split ->
(Path, Branch0 m -> Branch0 m)
makeDeleteBranch (p, name) = (p, Branch.children . ix name %~ Branch.cons Branch.empty0)
-- | Erase a branch and its history
-- See also 'makeDeleteBranch'.
-- Note that this requires a AllowRewritingHistory update strategy to behave correctly.
makeObliterateBranch ::
Path.Split -> (Path, Branch0 m -> Branch0 m)
makeObliterateBranch p = makeSetBranch p Branch.empty

View File

@ -101,6 +101,7 @@ import System.Environment as SYS
( getArgs,
getEnv,
)
import System.Exit as SYS (ExitCode(..))
import System.FilePath (isPathSeparator)
import System.IO (Handle)
import System.IO as SYS
@ -123,6 +124,14 @@ import System.IO as SYS
stdout,
)
import System.IO.Temp (createTempDirectory)
import System.Process as SYS
( getProcessExitCode,
proc,
runInteractiveProcess,
terminateProcess,
waitForProcess,
withCreateProcess
)
import qualified System.X509 as X
import Unison.ABT.Normalized hiding (TTm)
import qualified Unison.Builtin as Ty (builtinTypes)
@ -1014,6 +1023,19 @@ infixr 0 -->
(-->) :: a -> b -> (a, b)
x --> y = (x, y)
start'process :: ForeignOp
start'process instr =
([BX, BX],)
. TAbss [exe, args]
. TLets Direct [hin,hout,herr,hproc] [BX,BX,BX,BX] (TFOp instr [exe, args])
. TLetD un BX (TCon Ty.unitRef 0 [])
. TLetD p3 BX (TCon Ty.pairRef 0 [hproc, un])
. TLetD p2 BX (TCon Ty.pairRef 0 [herr, p3])
. TLetD p1 BX (TCon Ty.pairRef 0 [hout, p2])
$ TCon Ty.pairRef 0 [hin, p1]
where
(exe,args,hin,hout,herr,hproc,un,p3,p2,p1) = fresh
set'buffering :: ForeignOp
set'buffering instr =
([BX, BX],)
@ -1236,6 +1258,16 @@ outMaybe maybe result =
(1, ([BX], TAbs maybe $ some maybe))
]
outMaybeNat :: Var v => v -> v -> v -> ANormal v
outMaybeNat tag result n =
TMatch tag . MatchSum $
mapFromList
[ (0, ([], none)),
(1, ([UN],
TAbs result .
TLetD n BX (TCon Ty.natRef 0 [n]) $ some n))
]
outMaybeNTup :: forall v. Var v => v -> v -> v -> v -> v -> v -> v -> ANormal v
outMaybeNTup a b n u bp p result =
TMatch result . MatchSum $
@ -1495,6 +1527,16 @@ boxBoxTo0 instr =
where
(arg1, arg2) = fresh
-- a -> b ->{E} Nat
boxBoxToNat :: ForeignOp
boxBoxToNat instr =
([BX, BX],)
. TAbss [arg1, arg2]
. TLetD result UN (TFOp instr [arg1, arg2])
$ TCon Ty.natRef 0 [result]
where
(arg1, arg2, result) = fresh
-- a -> b -> Option c
-- a -> Bool
@ -1616,6 +1658,12 @@ boxToMaybeBox =
where
(arg, maybe, result) = fresh
-- a -> Maybe Nat
boxToMaybeNat :: ForeignOp
boxToMaybeNat = inBx arg tag $ outMaybeNat tag result n
where
(arg, tag, result, n) = fresh
-- a -> Maybe (Nat, b)
boxToMaybeNTup :: ForeignOp
boxToMaybeNTup =
@ -2272,6 +2320,27 @@ declareForeigns = do
2 -> pure (Just SYS.stderr)
_ -> pure Nothing
let exitDecode ExitSuccess = 0
exitDecode (ExitFailure n) = n
declareForeign Tracked "IO.process.call" boxBoxToNat . mkForeign $
\(exe, map Util.Text.unpack -> args) ->
withCreateProcess (proc exe args) $ \_ _ _ p ->
exitDecode <$> waitForProcess p
declareForeign Tracked "IO.process.start" start'process . mkForeign $
\(exe, map Util.Text.unpack -> args) ->
runInteractiveProcess exe args Nothing Nothing
declareForeign Tracked "IO.process.kill" boxTo0 . mkForeign $
terminateProcess
declareForeign Tracked "IO.process.wait" boxToNat . mkForeign $
\ph -> exitDecode <$> waitForProcess ph
declareForeign Tracked "IO.process.exitCode" boxToMaybeNat . mkForeign $
fmap (fmap exitDecode) . getProcessExitCode
declareForeign Tracked "MVar.new" boxDirect
. mkForeign
$ \(c :: Closure) -> newMVar c

View File

@ -27,6 +27,7 @@ import qualified Data.X509 as X509
import Network.Socket (Socket)
import qualified Network.TLS as TLS (ClientParams, Context, ServerParams)
import System.Clock (TimeSpec)
import System.Process (ProcessHandle)
import System.IO (Handle)
import Unison.Reference (Reference)
import Unison.Referent (Referent)
@ -191,6 +192,8 @@ instance BuiltinForeign Bytes where foreignRef = Tagged Ty.bytesRef
instance BuiltinForeign Handle where foreignRef = Tagged Ty.fileHandleRef
instance BuiltinForeign ProcessHandle where foreignRef = Tagged Ty.processHandleRef
instance BuiltinForeign Socket where foreignRef = Tagged Ty.socketRef
instance BuiltinForeign ThreadId where foreignRef = Tagged Ty.threadIdRef

View File

@ -354,6 +354,27 @@ instance
(ustk, bstk) <- writeForeign ustk bstk b
writeForeign ustk bstk a
instance
( ForeignConvention a,
ForeignConvention b,
ForeignConvention c,
ForeignConvention d
) =>
ForeignConvention (a, b, c, d)
where
readForeign us bs ustk bstk = do
(us, bs, a) <- readForeign us bs ustk bstk
(us, bs, b) <- readForeign us bs ustk bstk
(us, bs, c) <- readForeign us bs ustk bstk
(us, bs, d) <- readForeign us bs ustk bstk
pure (us, bs, (a, b, c, d))
writeForeign ustk bstk (a, b, c, d) = do
(ustk, bstk) <- writeForeign ustk bstk d
(ustk, bstk) <- writeForeign ustk bstk c
(ustk, bstk) <- writeForeign ustk bstk b
writeForeign ustk bstk a
instance
( ForeignConvention a,
ForeignConvention b,

View File

@ -1366,29 +1366,33 @@ bprim1 !ustk !bstk UCNS i =
pure (ustk, bstk)
bprim1 !ustk !bstk TTOI i =
peekOffBi bstk i >>= \t -> case readm $ Util.Text.unpack t of
Nothing -> do
Just n
| fromIntegral (minBound :: Int) <= n,
n <= fromIntegral (maxBound :: Int) -> do
ustk <- bumpn ustk 2
poke ustk 1
pokeOff ustk 1 (fromInteger n)
pure (ustk, bstk)
_ -> do
ustk <- bump ustk
poke ustk 0
pure (ustk, bstk)
Just n -> do
ustk <- bumpn ustk 2
poke ustk 1
pokeOff ustk 1 n
pure (ustk, bstk)
where
readm ('+' : s) = readMaybe s
readm s = readMaybe s
bprim1 !ustk !bstk TTON i =
peekOffBi bstk i >>= \t -> case readMaybe $ Util.Text.unpack t of
Nothing -> do
Just n
| 0 <= n,
n <= fromIntegral (maxBound :: Word) -> do
ustk <- bumpn ustk 2
poke ustk 1
pokeOffN ustk 1 (fromInteger n)
pure (ustk, bstk)
_ -> do
ustk <- bump ustk
poke ustk 0
pure (ustk, bstk)
Just n -> do
ustk <- bumpn ustk 2
poke ustk 1
pokeOffN ustk 1 n
pure (ustk, bstk)
bprim1 !ustk !bstk TTOF i =
peekOffBi bstk i >>= \t -> case readMaybe $ Util.Text.unpack t of
Nothing -> do

View File

@ -984,13 +984,13 @@ destructuringBind = do
-- Some 42
-- vs
-- Some 42 = List.head elems
(p, boundVars, guard) <- P.try $ do
(p, boundVars) <- P.try $ do
(p, boundVars) <- parsePattern
let boundVars' = snd <$> boundVars
guard <- optional $ reserved "|" *> infixAppOrBooleanOp
P.lookAhead (openBlockWith "=")
pure (p, boundVars', guard)
pure (p, boundVars')
scrute <- block "=" -- Dwight K. Scrute ("The People's Scrutinee")
let guard = Nothing
let absChain vs t = foldr (\v t -> ABT.abs' (ann t) v t) t vs
thecase t = Term.MatchCase p (fmap (absChain boundVars) guard) $ absChain boundVars t
pure $

View File

@ -884,12 +884,10 @@ loop e = do
if hasConfirmed || insistence == Force
then do
description <- inputDescription input
Cli.stepAt
description
(Path.empty, const Branch.empty0)
Cli.updateRoot Branch.empty description
Cli.respond DeletedEverything
else Cli.respond DeleteEverythingConfirmation
DeleteTarget'Branch insistence (Just p) -> do
DeleteTarget'Branch insistence (Just p@(parentPath, childName)) -> do
branch <- Cli.expectBranchAtPath' (Path.unsplit' p)
description <- inputDescription input
absPath <- Cli.resolveSplit' p
@ -911,8 +909,12 @@ loop e = do
ppeDecl <- currentPrettyPrintEnvDecl Backend.Within
Cli.respondNumbered $ CantDeleteNamespace ppeDecl endangerments
Cli.returnEarlyWithoutOutput
Cli.stepAt description $
BranchUtil.makeDeleteBranch (Path.convert absPath)
parentPathAbs <- Cli.resolvePath' parentPath
-- We have to modify the parent in order to also wipe out the history at the
-- child.
Cli.updateAt description parentPathAbs \parentBranch ->
parentBranch
& Branch.modifyAt (Path.singleton childName) \_ -> Branch.empty
afterDelete
DisplayI outputLoc names' -> do
currentBranch0 <- Cli.getCurrentBranch0
@ -2796,7 +2798,7 @@ buildScheme main file = do
++ lns gd gen
++ [surround file]
doRunAsScheme :: HQ.HashQualified Name -> [String] -> Cli ()
doRunAsScheme :: HQ.HashQualified Name -> [String] -> Cli ()
doRunAsScheme main args = do
fullpath <- generateSchemeFile True (HQ.toString main) main
runScheme fullpath args

View File

@ -71,23 +71,27 @@ authLogin host = do
-- and it all works out fine.
redirectURIVar <- liftIO newEmptyMVar
(verifier, challenge, state) <- generateParams
let codeHandler code mayNextURI = do
let codeHandler :: (Code -> Maybe URI -> (Response -> IO ResponseReceived) -> IO ResponseReceived)
codeHandler code mayNextURI respond = do
redirectURI <- readMVar redirectURIVar
result <- exchangeCode httpClient tokenEndpoint code verifier redirectURI
putMVar authResultVar result
case result of
respReceived <- case result of
Left err -> do
Debug.debugM Debug.Auth "Auth Error" err
pure $ Wai.responseLBS internalServerError500 [] "Something went wrong, please try again."
respond $ Wai.responseLBS internalServerError500 [] "Something went wrong, please try again."
Right _ ->
case mayNextURI of
Nothing -> pure $ Wai.responseLBS found302 [] "Authorization successful. You may close this page and return to UCM."
Nothing -> respond $ Wai.responseLBS found302 [] "Authorization successful. You may close this page and return to UCM."
Just nextURI ->
pure $
respond $
Wai.responseLBS
found302
[("LOCATION", BSC.pack $ show @URI nextURI)]
"Authorization successful. You may close this page and return to UCM."
-- Wait until we've responded to the browser before putting the result,
-- otherwise the server will shut down prematurely.
putMVar authResultVar result
pure respReceived
tokens <-
Cli.with (Warp.withApplication (pure $ authTransferServer codeHandler)) \port -> do
let redirectURI = "http://localhost:" <> show port <> "/redirect"
@ -105,11 +109,11 @@ authLogin host = do
-- | A server in the format expected for a Wai Application
-- This is a temporary server which is spun up only until we get a code back from the
-- auth server.
authTransferServer :: (Code -> Maybe URI -> IO Response) -> Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
authTransferServer :: (Code -> Maybe URI -> (Response -> IO ResponseReceived) -> IO ResponseReceived) -> Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
authTransferServer callback req respond =
case (requestMethod req, pathInfo req, getQueryParams req) of
("GET", ["redirect"], (Just code, maybeNextURI)) -> do
callback code maybeNextURI >>= respond
callback code maybeNextURI respond
_ -> respond (responseLBS status404 [] "Not Found")
where
getQueryParams req = do

View File

@ -259,6 +259,9 @@ filePathRef = Reference.Builtin "FilePath"
threadIdRef = Reference.Builtin "ThreadId"
socketRef = Reference.Builtin "Socket"
processHandleRef :: Reference
processHandleRef = Reference.Builtin "ProcessHandle"
scopeRef, refRef :: Reference
scopeRef = Reference.Builtin "Scope"
refRef = Reference.Builtin "Ref"
@ -348,6 +351,9 @@ char a = ref a charRef
fileHandle :: Ord v => a -> Type v a
fileHandle a = ref a fileHandleRef
processHandle :: Ord v => a -> Type v a
processHandle a = ref a processHandleRef
threadId :: Ord v => a -> Type v a
threadId a = ref a threadIdRef

File diff suppressed because it is too large Load Diff

View File

@ -297,363 +297,375 @@ Let's try it!
222. io2.IO.openFile.impl : Text
-> FileMode
->{IO} Either Failure Handle
223. io2.IO.putBytes.impl : Handle
223. io2.IO.process.call : Text -> [Text] ->{IO} Nat
224. io2.IO.process.exitCode : ProcessHandle
->{IO} Optional Nat
225. io2.IO.process.kill : ProcessHandle ->{IO} ()
226. io2.IO.process.start : Text
-> [Text]
->{IO} ( Handle,
Handle,
Handle,
ProcessHandle)
227. io2.IO.process.wait : ProcessHandle ->{IO} Nat
228. io2.IO.putBytes.impl : Handle
-> Bytes
->{IO} Either Failure ()
224. io2.IO.ready.impl : Handle ->{IO} Either Failure Boolean
225. io2.IO.ref : a ->{IO} Ref {IO} a
226. io2.IO.removeDirectory.impl : Text
229. io2.IO.ready.impl : Handle ->{IO} Either Failure Boolean
230. io2.IO.ref : a ->{IO} Ref {IO} a
231. io2.IO.removeDirectory.impl : Text
->{IO} Either Failure ()
227. io2.IO.removeFile.impl : Text ->{IO} Either Failure ()
228. io2.IO.renameDirectory.impl : Text
232. io2.IO.removeFile.impl : Text ->{IO} Either Failure ()
233. io2.IO.renameDirectory.impl : Text
-> Text
->{IO} Either Failure ()
229. io2.IO.renameFile.impl : Text
234. io2.IO.renameFile.impl : Text
-> Text
->{IO} Either Failure ()
230. io2.IO.seekHandle.impl : Handle
235. io2.IO.seekHandle.impl : Handle
-> SeekMode
-> Int
->{IO} Either Failure ()
231. io2.IO.serverSocket.impl : Optional Text
236. io2.IO.serverSocket.impl : Optional Text
-> Text
->{IO} Either Failure Socket
232. io2.IO.setBuffering.impl : Handle
237. io2.IO.setBuffering.impl : Handle
-> BufferMode
->{IO} Either Failure ()
233. io2.IO.setCurrentDirectory.impl : Text
238. io2.IO.setCurrentDirectory.impl : Text
->{IO} Either
Failure ()
234. io2.IO.setEcho.impl : Handle
239. io2.IO.setEcho.impl : Handle
-> Boolean
->{IO} Either Failure ()
235. io2.IO.socketAccept.impl : Socket
240. io2.IO.socketAccept.impl : Socket
->{IO} Either Failure Socket
236. io2.IO.socketPort.impl : Socket ->{IO} Either Failure Nat
237. io2.IO.socketReceive.impl : Socket
241. io2.IO.socketPort.impl : Socket ->{IO} Either Failure Nat
242. io2.IO.socketReceive.impl : Socket
-> Nat
->{IO} Either Failure Bytes
238. io2.IO.socketSend.impl : Socket
243. io2.IO.socketSend.impl : Socket
-> Bytes
->{IO} Either Failure ()
239. io2.IO.stdHandle : StdHandle -> Handle
240. io2.IO.systemTime.impl : '{IO} Either Failure Nat
241. io2.IO.systemTimeMicroseconds : '{IO} Int
242. io2.IO.tryEval : '{IO} a ->{IO, Exception} a
243. unique type io2.IOError
244. io2.IOError.AlreadyExists : IOError
245. io2.IOError.EOF : IOError
246. io2.IOError.IllegalOperation : IOError
247. io2.IOError.NoSuchThing : IOError
248. io2.IOError.PermissionDenied : IOError
249. io2.IOError.ResourceBusy : IOError
250. io2.IOError.ResourceExhausted : IOError
251. io2.IOError.UserError : IOError
252. unique type io2.IOFailure
253. unique type io2.MiscFailure
254. builtin type io2.MVar
255. io2.MVar.isEmpty : MVar a ->{IO} Boolean
256. io2.MVar.new : a ->{IO} MVar a
257. io2.MVar.newEmpty : '{IO} MVar a
258. io2.MVar.put.impl : MVar a -> a ->{IO} Either Failure ()
259. io2.MVar.read.impl : MVar a ->{IO} Either Failure a
260. io2.MVar.swap.impl : MVar a -> a ->{IO} Either Failure a
261. io2.MVar.take.impl : MVar a ->{IO} Either Failure a
262. io2.MVar.tryPut.impl : MVar a
244. io2.IO.stdHandle : StdHandle -> Handle
245. io2.IO.systemTime.impl : '{IO} Either Failure Nat
246. io2.IO.systemTimeMicroseconds : '{IO} Int
247. io2.IO.tryEval : '{IO} a ->{IO, Exception} a
248. unique type io2.IOError
249. io2.IOError.AlreadyExists : IOError
250. io2.IOError.EOF : IOError
251. io2.IOError.IllegalOperation : IOError
252. io2.IOError.NoSuchThing : IOError
253. io2.IOError.PermissionDenied : IOError
254. io2.IOError.ResourceBusy : IOError
255. io2.IOError.ResourceExhausted : IOError
256. io2.IOError.UserError : IOError
257. unique type io2.IOFailure
258. unique type io2.MiscFailure
259. builtin type io2.MVar
260. io2.MVar.isEmpty : MVar a ->{IO} Boolean
261. io2.MVar.new : a ->{IO} MVar a
262. io2.MVar.newEmpty : '{IO} MVar a
263. io2.MVar.put.impl : MVar a -> a ->{IO} Either Failure ()
264. io2.MVar.read.impl : MVar a ->{IO} Either Failure a
265. io2.MVar.swap.impl : MVar a -> a ->{IO} Either Failure a
266. io2.MVar.take.impl : MVar a ->{IO} Either Failure a
267. io2.MVar.tryPut.impl : MVar a
-> a
->{IO} Either Failure Boolean
263. io2.MVar.tryRead.impl : MVar a
268. io2.MVar.tryRead.impl : MVar a
->{IO} Either
Failure (Optional a)
264. io2.MVar.tryTake : MVar a ->{IO} Optional a
265. builtin type io2.Promise
266. io2.Promise.new : '{IO} Promise a
267. io2.Promise.read : Promise a ->{IO} a
268. io2.Promise.tryRead : Promise a ->{IO} Optional a
269. io2.Promise.write : Promise a -> a ->{IO} Boolean
270. io2.Ref.cas : Ref {IO} a -> Ticket a -> a ->{IO} Boolean
271. io2.Ref.readForCas : Ref {IO} a ->{IO} Ticket a
272. builtin type io2.Ref.Ticket
273. io2.Ref.Ticket.read : Ticket a -> a
274. unique type io2.RuntimeFailure
275. unique type io2.SeekMode
276. io2.SeekMode.AbsoluteSeek : SeekMode
277. io2.SeekMode.RelativeSeek : SeekMode
278. io2.SeekMode.SeekFromEnd : SeekMode
279. builtin type io2.Socket
280. unique type io2.StdHandle
281. io2.StdHandle.StdErr : StdHandle
282. io2.StdHandle.StdIn : StdHandle
283. io2.StdHandle.StdOut : StdHandle
284. builtin type io2.STM
285. io2.STM.atomically : '{STM} a ->{IO} a
286. io2.STM.retry : '{STM} a
287. unique type io2.STMFailure
288. builtin type io2.ThreadId
289. builtin type io2.Tls
290. builtin type io2.Tls.Cipher
291. builtin type io2.Tls.ClientConfig
292. io2.Tls.ClientConfig.certificates.set : [SignedCert]
269. io2.MVar.tryTake : MVar a ->{IO} Optional a
270. builtin type io2.ProcessHandle
271. builtin type io2.Promise
272. io2.Promise.new : '{IO} Promise a
273. io2.Promise.read : Promise a ->{IO} a
274. io2.Promise.tryRead : Promise a ->{IO} Optional a
275. io2.Promise.write : Promise a -> a ->{IO} Boolean
276. io2.Ref.cas : Ref {IO} a -> Ticket a -> a ->{IO} Boolean
277. io2.Ref.readForCas : Ref {IO} a ->{IO} Ticket a
278. builtin type io2.Ref.Ticket
279. io2.Ref.Ticket.read : Ticket a -> a
280. unique type io2.RuntimeFailure
281. unique type io2.SeekMode
282. io2.SeekMode.AbsoluteSeek : SeekMode
283. io2.SeekMode.RelativeSeek : SeekMode
284. io2.SeekMode.SeekFromEnd : SeekMode
285. builtin type io2.Socket
286. unique type io2.StdHandle
287. io2.StdHandle.StdErr : StdHandle
288. io2.StdHandle.StdIn : StdHandle
289. io2.StdHandle.StdOut : StdHandle
290. builtin type io2.STM
291. io2.STM.atomically : '{STM} a ->{IO} a
292. io2.STM.retry : '{STM} a
293. unique type io2.STMFailure
294. builtin type io2.ThreadId
295. builtin type io2.Tls
296. builtin type io2.Tls.Cipher
297. builtin type io2.Tls.ClientConfig
298. io2.Tls.ClientConfig.certificates.set : [SignedCert]
-> ClientConfig
-> ClientConfig
293. io2.TLS.ClientConfig.ciphers.set : [Cipher]
299. io2.TLS.ClientConfig.ciphers.set : [Cipher]
-> ClientConfig
-> ClientConfig
294. io2.Tls.ClientConfig.default : Text
300. io2.Tls.ClientConfig.default : Text
-> Bytes
-> ClientConfig
295. io2.Tls.ClientConfig.versions.set : [Version]
301. io2.Tls.ClientConfig.versions.set : [Version]
-> ClientConfig
-> ClientConfig
296. io2.Tls.decodeCert.impl : Bytes
302. io2.Tls.decodeCert.impl : Bytes
-> Either Failure SignedCert
297. io2.Tls.decodePrivateKey : Bytes -> [PrivateKey]
298. io2.Tls.encodeCert : SignedCert -> Bytes
299. io2.Tls.encodePrivateKey : PrivateKey -> Bytes
300. io2.Tls.handshake.impl : Tls ->{IO} Either Failure ()
301. io2.Tls.newClient.impl : ClientConfig
303. io2.Tls.decodePrivateKey : Bytes -> [PrivateKey]
304. io2.Tls.encodeCert : SignedCert -> Bytes
305. io2.Tls.encodePrivateKey : PrivateKey -> Bytes
306. io2.Tls.handshake.impl : Tls ->{IO} Either Failure ()
307. io2.Tls.newClient.impl : ClientConfig
-> Socket
->{IO} Either Failure Tls
302. io2.Tls.newServer.impl : ServerConfig
308. io2.Tls.newServer.impl : ServerConfig
-> Socket
->{IO} Either Failure Tls
303. builtin type io2.Tls.PrivateKey
304. io2.Tls.receive.impl : Tls ->{IO} Either Failure Bytes
305. io2.Tls.send.impl : Tls -> Bytes ->{IO} Either Failure ()
306. builtin type io2.Tls.ServerConfig
307. io2.Tls.ServerConfig.certificates.set : [SignedCert]
309. builtin type io2.Tls.PrivateKey
310. io2.Tls.receive.impl : Tls ->{IO} Either Failure Bytes
311. io2.Tls.send.impl : Tls -> Bytes ->{IO} Either Failure ()
312. builtin type io2.Tls.ServerConfig
313. io2.Tls.ServerConfig.certificates.set : [SignedCert]
-> ServerConfig
-> ServerConfig
308. io2.Tls.ServerConfig.ciphers.set : [Cipher]
314. io2.Tls.ServerConfig.ciphers.set : [Cipher]
-> ServerConfig
-> ServerConfig
309. io2.Tls.ServerConfig.default : [SignedCert]
315. io2.Tls.ServerConfig.default : [SignedCert]
-> PrivateKey
-> ServerConfig
310. io2.Tls.ServerConfig.versions.set : [Version]
316. io2.Tls.ServerConfig.versions.set : [Version]
-> ServerConfig
-> ServerConfig
311. builtin type io2.Tls.SignedCert
312. io2.Tls.terminate.impl : Tls ->{IO} Either Failure ()
313. builtin type io2.Tls.Version
314. unique type io2.TlsFailure
315. builtin type io2.TVar
316. io2.TVar.new : a ->{STM} TVar a
317. io2.TVar.newIO : a ->{IO} TVar a
318. io2.TVar.read : TVar a ->{STM} a
319. io2.TVar.readIO : TVar a ->{IO} a
320. io2.TVar.swap : TVar a -> a ->{STM} a
321. io2.TVar.write : TVar a -> a ->{STM} ()
322. io2.validateSandboxed : [Term] -> a -> Boolean
323. unique type IsPropagated
324. IsPropagated.IsPropagated : IsPropagated
325. unique type IsTest
326. IsTest.IsTest : IsTest
327. unique type Link
328. builtin type Link.Term
329. Link.Term : Term -> Link
330. Link.Term.toText : Term -> Text
331. builtin type Link.Type
332. Link.Type : Type -> Link
333. builtin type List
334. List.++ : [a] -> [a] -> [a]
335. List.+: : a -> [a] -> [a]
336. List.:+ : [a] -> a -> [a]
337. List.at : Nat -> [a] -> Optional a
338. List.cons : a -> [a] -> [a]
339. List.drop : Nat -> [a] -> [a]
340. List.empty : [a]
341. List.size : [a] -> Nat
342. List.snoc : [a] -> a -> [a]
343. List.take : Nat -> [a] -> [a]
344. metadata.isPropagated : IsPropagated
345. metadata.isTest : IsTest
346. builtin type MutableArray
347. MutableArray.copyTo! : MutableArray g a
317. builtin type io2.Tls.SignedCert
318. io2.Tls.terminate.impl : Tls ->{IO} Either Failure ()
319. builtin type io2.Tls.Version
320. unique type io2.TlsFailure
321. builtin type io2.TVar
322. io2.TVar.new : a ->{STM} TVar a
323. io2.TVar.newIO : a ->{IO} TVar a
324. io2.TVar.read : TVar a ->{STM} a
325. io2.TVar.readIO : TVar a ->{IO} a
326. io2.TVar.swap : TVar a -> a ->{STM} a
327. io2.TVar.write : TVar a -> a ->{STM} ()
328. io2.validateSandboxed : [Term] -> a -> Boolean
329. unique type IsPropagated
330. IsPropagated.IsPropagated : IsPropagated
331. unique type IsTest
332. IsTest.IsTest : IsTest
333. unique type Link
334. builtin type Link.Term
335. Link.Term : Term -> Link
336. Link.Term.toText : Term -> Text
337. builtin type Link.Type
338. Link.Type : Type -> Link
339. builtin type List
340. List.++ : [a] -> [a] -> [a]
341. List.+: : a -> [a] -> [a]
342. List.:+ : [a] -> a -> [a]
343. List.at : Nat -> [a] -> Optional a
344. List.cons : a -> [a] -> [a]
345. List.drop : Nat -> [a] -> [a]
346. List.empty : [a]
347. List.size : [a] -> Nat
348. List.snoc : [a] -> a -> [a]
349. List.take : Nat -> [a] -> [a]
350. metadata.isPropagated : IsPropagated
351. metadata.isTest : IsTest
352. builtin type MutableArray
353. MutableArray.copyTo! : MutableArray g a
-> Nat
-> MutableArray g a
-> Nat
-> Nat
->{g, Exception} ()
348. MutableArray.freeze : MutableArray g a
354. MutableArray.freeze : MutableArray g a
-> Nat
-> Nat
->{g} ImmutableArray a
349. MutableArray.freeze! : MutableArray g a
355. MutableArray.freeze! : MutableArray g a
->{g} ImmutableArray a
350. MutableArray.read : MutableArray g a
356. MutableArray.read : MutableArray g a
-> Nat
->{g, Exception} a
351. MutableArray.size : MutableArray g a -> Nat
352. MutableArray.write : MutableArray g a
357. MutableArray.size : MutableArray g a -> Nat
358. MutableArray.write : MutableArray g a
-> Nat
-> a
->{g, Exception} ()
353. builtin type MutableByteArray
354. MutableByteArray.copyTo! : MutableByteArray g
359. builtin type MutableByteArray
360. MutableByteArray.copyTo! : MutableByteArray g
-> Nat
-> MutableByteArray g
-> Nat
-> Nat
->{g, Exception} ()
355. MutableByteArray.freeze : MutableByteArray g
361. MutableByteArray.freeze : MutableByteArray g
-> Nat
-> Nat
->{g} ImmutableByteArray
356. MutableByteArray.freeze! : MutableByteArray g
362. MutableByteArray.freeze! : MutableByteArray g
->{g} ImmutableByteArray
357. MutableByteArray.read16be : MutableByteArray g
363. MutableByteArray.read16be : MutableByteArray g
-> Nat
->{g, Exception} Nat
358. MutableByteArray.read24be : MutableByteArray g
364. MutableByteArray.read24be : MutableByteArray g
-> Nat
->{g, Exception} Nat
359. MutableByteArray.read32be : MutableByteArray g
365. MutableByteArray.read32be : MutableByteArray g
-> Nat
->{g, Exception} Nat
360. MutableByteArray.read40be : MutableByteArray g
366. MutableByteArray.read40be : MutableByteArray g
-> Nat
->{g, Exception} Nat
361. MutableByteArray.read64be : MutableByteArray g
367. MutableByteArray.read64be : MutableByteArray g
-> Nat
->{g, Exception} Nat
362. MutableByteArray.read8 : MutableByteArray g
368. MutableByteArray.read8 : MutableByteArray g
-> Nat
->{g, Exception} Nat
363. MutableByteArray.size : MutableByteArray g -> Nat
364. MutableByteArray.write16be : MutableByteArray g
369. MutableByteArray.size : MutableByteArray g -> Nat
370. MutableByteArray.write16be : MutableByteArray g
-> Nat
-> Nat
->{g, Exception} ()
365. MutableByteArray.write32be : MutableByteArray g
371. MutableByteArray.write32be : MutableByteArray g
-> Nat
-> Nat
->{g, Exception} ()
366. MutableByteArray.write64be : MutableByteArray g
372. MutableByteArray.write64be : MutableByteArray g
-> Nat
-> Nat
->{g, Exception} ()
367. MutableByteArray.write8 : MutableByteArray g
373. MutableByteArray.write8 : MutableByteArray g
-> Nat
-> Nat
->{g, Exception} ()
368. builtin type Nat
369. Nat.* : Nat -> Nat -> Nat
370. Nat.+ : Nat -> Nat -> Nat
371. Nat./ : Nat -> Nat -> Nat
372. Nat.and : Nat -> Nat -> Nat
373. Nat.complement : Nat -> Nat
374. Nat.drop : Nat -> Nat -> Nat
375. Nat.eq : Nat -> Nat -> Boolean
376. Nat.fromText : Text -> Optional Nat
377. Nat.gt : Nat -> Nat -> Boolean
378. Nat.gteq : Nat -> Nat -> Boolean
379. Nat.increment : Nat -> Nat
380. Nat.isEven : Nat -> Boolean
381. Nat.isOdd : Nat -> Boolean
382. Nat.leadingZeros : Nat -> Nat
383. Nat.lt : Nat -> Nat -> Boolean
384. Nat.lteq : Nat -> Nat -> Boolean
385. Nat.mod : Nat -> Nat -> Nat
386. Nat.or : Nat -> Nat -> Nat
387. Nat.popCount : Nat -> Nat
388. Nat.pow : Nat -> Nat -> Nat
389. Nat.shiftLeft : Nat -> Nat -> Nat
390. Nat.shiftRight : Nat -> Nat -> Nat
391. Nat.sub : Nat -> Nat -> Int
392. Nat.toFloat : Nat -> Float
393. Nat.toInt : Nat -> Int
394. Nat.toText : Nat -> Text
395. Nat.trailingZeros : Nat -> Nat
396. Nat.xor : Nat -> Nat -> Nat
397. structural type Optional a
398. Optional.None : Optional a
399. Optional.Some : a -> Optional a
400. builtin type Pattern
401. Pattern.capture : Pattern a -> Pattern a
402. Pattern.isMatch : Pattern a -> a -> Boolean
403. Pattern.join : [Pattern a] -> Pattern a
404. Pattern.many : Pattern a -> Pattern a
405. Pattern.or : Pattern a -> Pattern a -> Pattern a
406. Pattern.replicate : Nat -> Nat -> Pattern a -> Pattern a
407. Pattern.run : Pattern a -> a -> Optional ([a], a)
408. builtin type Ref
409. Ref.read : Ref g a ->{g} a
410. Ref.write : Ref g a -> a ->{g} ()
411. builtin type Request
412. builtin type Scope
413. Scope.array : Nat ->{Scope s} MutableArray (Scope s) a
414. Scope.arrayOf : a
374. builtin type Nat
375. Nat.* : Nat -> Nat -> Nat
376. Nat.+ : Nat -> Nat -> Nat
377. Nat./ : Nat -> Nat -> Nat
378. Nat.and : Nat -> Nat -> Nat
379. Nat.complement : Nat -> Nat
380. Nat.drop : Nat -> Nat -> Nat
381. Nat.eq : Nat -> Nat -> Boolean
382. Nat.fromText : Text -> Optional Nat
383. Nat.gt : Nat -> Nat -> Boolean
384. Nat.gteq : Nat -> Nat -> Boolean
385. Nat.increment : Nat -> Nat
386. Nat.isEven : Nat -> Boolean
387. Nat.isOdd : Nat -> Boolean
388. Nat.leadingZeros : Nat -> Nat
389. Nat.lt : Nat -> Nat -> Boolean
390. Nat.lteq : Nat -> Nat -> Boolean
391. Nat.mod : Nat -> Nat -> Nat
392. Nat.or : Nat -> Nat -> Nat
393. Nat.popCount : Nat -> Nat
394. Nat.pow : Nat -> Nat -> Nat
395. Nat.shiftLeft : Nat -> Nat -> Nat
396. Nat.shiftRight : Nat -> Nat -> Nat
397. Nat.sub : Nat -> Nat -> Int
398. Nat.toFloat : Nat -> Float
399. Nat.toInt : Nat -> Int
400. Nat.toText : Nat -> Text
401. Nat.trailingZeros : Nat -> Nat
402. Nat.xor : Nat -> Nat -> Nat
403. structural type Optional a
404. Optional.None : Optional a
405. Optional.Some : a -> Optional a
406. builtin type Pattern
407. Pattern.capture : Pattern a -> Pattern a
408. Pattern.isMatch : Pattern a -> a -> Boolean
409. Pattern.join : [Pattern a] -> Pattern a
410. Pattern.many : Pattern a -> Pattern a
411. Pattern.or : Pattern a -> Pattern a -> Pattern a
412. Pattern.replicate : Nat -> Nat -> Pattern a -> Pattern a
413. Pattern.run : Pattern a -> a -> Optional ([a], a)
414. builtin type Ref
415. Ref.read : Ref g a ->{g} a
416. Ref.write : Ref g a -> a ->{g} ()
417. builtin type Request
418. builtin type Scope
419. Scope.array : Nat ->{Scope s} MutableArray (Scope s) a
420. Scope.arrayOf : a
-> Nat
->{Scope s} MutableArray (Scope s) a
415. Scope.bytearray : Nat
421. Scope.bytearray : Nat
->{Scope s} MutableByteArray (Scope s)
416. Scope.bytearrayOf : Nat
422. Scope.bytearrayOf : Nat
-> Nat
->{Scope s} MutableByteArray
(Scope s)
417. Scope.ref : a ->{Scope s} Ref {Scope s} a
418. Scope.run : (∀ s. '{g, Scope s} r) ->{g} r
419. structural type SeqView a b
420. SeqView.VElem : a -> b -> SeqView a b
421. SeqView.VEmpty : SeqView a b
422. Socket.toText : Socket -> Text
423. unique type Test.Result
424. Test.Result.Fail : Text -> Result
425. Test.Result.Ok : Text -> Result
426. builtin type Text
427. Text.!= : Text -> Text -> Boolean
428. Text.++ : Text -> Text -> Text
429. Text.drop : Nat -> Text -> Text
430. Text.empty : Text
431. Text.eq : Text -> Text -> Boolean
432. Text.fromCharList : [Char] -> Text
433. Text.fromUtf8.impl : Bytes -> Either Failure Text
434. Text.gt : Text -> Text -> Boolean
435. Text.gteq : Text -> Text -> Boolean
436. Text.lt : Text -> Text -> Boolean
437. Text.lteq : Text -> Text -> Boolean
438. Text.patterns.anyChar : Pattern Text
439. Text.patterns.charIn : [Char] -> Pattern Text
440. Text.patterns.charRange : Char -> Char -> Pattern Text
441. Text.patterns.digit : Pattern Text
442. Text.patterns.eof : Pattern Text
443. Text.patterns.letter : Pattern Text
444. Text.patterns.literal : Text -> Pattern Text
445. Text.patterns.notCharIn : [Char] -> Pattern Text
446. Text.patterns.notCharRange : Char -> Char -> Pattern Text
447. Text.patterns.punctuation : Pattern Text
448. Text.patterns.space : Pattern Text
449. Text.repeat : Nat -> Text -> Text
450. Text.reverse : Text -> Text
451. Text.size : Text -> Nat
452. Text.take : Nat -> Text -> Text
453. Text.toCharList : Text -> [Char]
454. Text.toLowercase : Text -> Text
455. Text.toUppercase : Text -> Text
456. Text.toUtf8 : Text -> Bytes
457. Text.uncons : Text -> Optional (Char, Text)
458. Text.unsnoc : Text -> Optional (Text, Char)
459. ThreadId.toText : ThreadId -> Text
460. todo : a -> b
461. structural type Tuple a b
462. Tuple.Cons : a -> b -> Tuple a b
463. structural type Unit
464. Unit.Unit : ()
465. Universal.< : a -> a -> Boolean
466. Universal.<= : a -> a -> Boolean
467. Universal.== : a -> a -> Boolean
468. Universal.> : a -> a -> Boolean
469. Universal.>= : a -> a -> Boolean
470. Universal.compare : a -> a -> Int
471. Universal.murmurHash : a -> Nat
472. unsafe.coerceAbilities : (a ->{e1} b) -> a ->{e2} b
473. builtin type Value
474. Value.dependencies : Value -> [Term]
475. Value.deserialize : Bytes -> Either Text Value
476. Value.load : Value ->{IO} Either [Term] a
477. Value.serialize : Value -> Bytes
478. Value.value : a -> Value
423. Scope.ref : a ->{Scope s} Ref {Scope s} a
424. Scope.run : (∀ s. '{g, Scope s} r) ->{g} r
425. structural type SeqView a b
426. SeqView.VElem : a -> b -> SeqView a b
427. SeqView.VEmpty : SeqView a b
428. Socket.toText : Socket -> Text
429. unique type Test.Result
430. Test.Result.Fail : Text -> Result
431. Test.Result.Ok : Text -> Result
432. builtin type Text
433. Text.!= : Text -> Text -> Boolean
434. Text.++ : Text -> Text -> Text
435. Text.drop : Nat -> Text -> Text
436. Text.empty : Text
437. Text.eq : Text -> Text -> Boolean
438. Text.fromCharList : [Char] -> Text
439. Text.fromUtf8.impl : Bytes -> Either Failure Text
440. Text.gt : Text -> Text -> Boolean
441. Text.gteq : Text -> Text -> Boolean
442. Text.lt : Text -> Text -> Boolean
443. Text.lteq : Text -> Text -> Boolean
444. Text.patterns.anyChar : Pattern Text
445. Text.patterns.charIn : [Char] -> Pattern Text
446. Text.patterns.charRange : Char -> Char -> Pattern Text
447. Text.patterns.digit : Pattern Text
448. Text.patterns.eof : Pattern Text
449. Text.patterns.letter : Pattern Text
450. Text.patterns.literal : Text -> Pattern Text
451. Text.patterns.notCharIn : [Char] -> Pattern Text
452. Text.patterns.notCharRange : Char -> Char -> Pattern Text
453. Text.patterns.punctuation : Pattern Text
454. Text.patterns.space : Pattern Text
455. Text.repeat : Nat -> Text -> Text
456. Text.reverse : Text -> Text
457. Text.size : Text -> Nat
458. Text.take : Nat -> Text -> Text
459. Text.toCharList : Text -> [Char]
460. Text.toLowercase : Text -> Text
461. Text.toUppercase : Text -> Text
462. Text.toUtf8 : Text -> Bytes
463. Text.uncons : Text -> Optional (Char, Text)
464. Text.unsnoc : Text -> Optional (Text, Char)
465. ThreadId.toText : ThreadId -> Text
466. todo : a -> b
467. structural type Tuple a b
468. Tuple.Cons : a -> b -> Tuple a b
469. structural type Unit
470. Unit.Unit : ()
471. Universal.< : a -> a -> Boolean
472. Universal.<= : a -> a -> Boolean
473. Universal.== : a -> a -> Boolean
474. Universal.> : a -> a -> Boolean
475. Universal.>= : a -> a -> Boolean
476. Universal.compare : a -> a -> Int
477. Universal.murmurHash : a -> Nat
478. unsafe.coerceAbilities : (a ->{e1} b) -> a ->{e2} b
479. builtin type Value
480. Value.dependencies : Value -> [Term]
481. Value.deserialize : Bytes -> Either Text Value
482. Value.load : Value ->{IO} Either [Term] a
483. Value.serialize : Value -> Bytes
484. Value.value : a -> Value
.builtin> alias.many 94-104 .mylib

View File

@ -74,7 +74,7 @@ The `builtins.merge` command adds the known builtins to a `builtin` subnamespace
63. Value/ (5 terms)
64. bug (a -> b)
65. crypto/ (12 terms, 1 type)
66. io2/ (126 terms, 30 types)
66. io2/ (131 terms, 31 types)
67. metadata/ (2 terms)
68. todo (a -> b)
69. unsafe/ (1 term)

View File

@ -81,6 +81,8 @@ test> Int.tests.conversions =
fromText "+0" == Some +0,
fromText "a8f9djasdlfkj" == None,
fromText "3940" == Some +3940,
fromText "1000000000000000000000000000" == None,
fromText "-1000000000000000000000000000" == None,
toFloat +9394 == 9394.0,
toFloat -20349 == -20349.0
]
@ -150,6 +152,8 @@ test> Nat.tests.conversions =
toText 10 == "10",
fromText "ooga" == None,
fromText "90" == Some 90,
fromText "-1" == None,
fromText "100000000000000000000000000" == None,
unsnoc "abc" == Some ("ab", ?c),
uncons "abc" == Some (?a, "bc"),
unsnoc "" == None,

View File

@ -74,6 +74,8 @@ test> Int.tests.conversions =
fromText "+0" == Some +0,
fromText "a8f9djasdlfkj" == None,
fromText "3940" == Some +3940,
fromText "1000000000000000000000000000" == None,
fromText "-1000000000000000000000000000" == None,
toFloat +9394 == 9394.0,
toFloat -20349 == -20349.0
]
@ -139,6 +141,8 @@ test> Nat.tests.conversions =
toText 10 == "10",
fromText "ooga" == None,
fromText "90" == Some 90,
fromText "-1" == None,
fromText "100000000000000000000000000" == None,
unsnoc "abc" == Some ("ab", ?c),
uncons "abc" == Some (?a, "bc"),
unsnoc "" == None,

View File

@ -47,11 +47,15 @@ Deleting the root namespace should require confirmation if not forced.
```ucm
.> delete.namespace .
.> delete.namespace .
-- Should have an empty history
.> history .
```
Deleting the root namespace shouldn't require confirmation if forced.
```ucm
.> delete.namespace.force .
-- Should have an empty history
.> history .
```

View File

@ -86,6 +86,11 @@ Deleting the root namespace should require confirmation if not forced.
undo, or `builtins.merge` to restore the absolute basics to
the current path.
-- Should have an empty history
.> history .
☝️ The namespace . is empty.
```
Deleting the root namespace shouldn't require confirmation if forced.
@ -96,4 +101,9 @@ Deleting the root namespace shouldn't require confirmation if forced.
undo, or `builtins.merge` to restore the absolute basics to
the current path.
-- Should have an empty history
.> history .
☝️ The namespace . is empty.
```

View File

@ -33,14 +33,6 @@ ex2 tup = match tup with
(a, b, (c,d)) -> c + d
```
Syntactically, the left-hand side of the bind can be any pattern and can even include guards, for instance, see below. Because a destructuring bind desugars to a regular pattern match, pattern match coverage will eventually cause this to not typecheck:
```unison:hide
ex3 =
Some x | x > 10 = Some 19
x + 1
```
## Corner cases
Destructuring binds can't be recursive: the left-hand side bound variables aren't available on the right hand side. For instance, this doesn't typecheck:

View File

@ -71,14 +71,6 @@ ex2 tup = match tup with
(also named ex1)
```
Syntactically, the left-hand side of the bind can be any pattern and can even include guards, for instance, see below. Because a destructuring bind desugars to a regular pattern match, pattern match coverage will eventually cause this to not typecheck:
```unison
ex3 =
Some x | x > 10 = Some 19
x + 1
```
## Corner cases
Destructuring binds can't be recursive: the left-hand side bound variables aren't available on the right hand side. For instance, this doesn't typecheck:

View File

@ -22,15 +22,15 @@ The deleted namespace shouldn't appear in `ls` output.
## history
The history of the namespace should still exist if requested explicitly.
The history of the namespace should be empty.
```ucm
.> history mynamespace
```
Merging an empty namespace should still copy its history if it has some.
Merging an empty namespace should be a no-op
```ucm
```ucm:error
.empty> history
.empty> merge .mynamespace
.empty> history

View File

@ -47,24 +47,15 @@ The deleted namespace shouldn't appear in `ls` output.
```
## history
The history of the namespace should still exist if requested explicitly.
The history of the namespace should be empty.
```ucm
.> history mynamespace
Note: The most recent namespace hash is immediately below this
message.
⊙ 1. #nvh8d4j0fm
- Deletes:
x
□ 2. #i52j9fd57b (start of history)
☝️ The namespace .mynamespace is empty.
```
Merging an empty namespace should still copy its history if it has some.
Merging an empty namespace should be a no-op
```ucm
☝️ The namespace .empty is empty.
@ -75,20 +66,13 @@ Merging an empty namespace should still copy its history if it has some.
.empty> merge .mynamespace
Nothing changed as a result of the merge.
⚠️
The namespace .mynamespace doesn't exist.
.empty> history
Note: The most recent namespace hash is immediately below this
message.
⊙ 1. #nvh8d4j0fm
- Deletes:
x
□ 2. #i52j9fd57b (start of history)
☝️ The namespace .empty is empty.
```
Add and then delete a term to add some history to a deleted namespace.

View File

@ -23,7 +23,7 @@ Technically, the definitions all exist, but they have no names. `builtins.merge`
.foo> ls
1. builtin/ (415 terms, 63 types)
1. builtin/ (420 terms, 64 types)
```
And for a limited time, you can get even more builtin goodies:
@ -35,7 +35,7 @@ And for a limited time, you can get even more builtin goodies:
.foo> ls
1. builtin/ (587 terms, 81 types)
1. builtin/ (592 terms, 82 types)
```
More typically, you'd start out by pulling `base.

View File

@ -49,7 +49,8 @@ y = "hello"
Notice that `master` now has the definition of `y` we wrote.
We can also delete the fork if we're done with it. (Don't worry, it's still in the `history` and can be resurrected at any time.)
We can also delete the fork if we're done with it. (Don't worry, even though the history at that path is now empty,
it's still in the `history` of the parent namespace and can be resurrected at any time.)
```ucm
.> delete.namespace .feature1

View File

@ -96,7 +96,8 @@ y = "hello"
Notice that `master` now has the definition of `y` we wrote.
We can also delete the fork if we're done with it. (Don't worry, it's still in the `history` and can be resurrected at any time.)
We can also delete the fork if we're done with it. (Don't worry, even though the history at that path is now empty,
it's still in the `history` of the parent namespace and can be resurrected at any time.)
```ucm
.> delete.namespace .feature1
@ -105,29 +106,20 @@ We can also delete the fork if we're done with it. (Don't worry, it's still in t
.> history .feature1
Note: The most recent namespace hash is immediately below this
message.
⊙ 1. #hsbtlt2og6
- Deletes:
y
□ 2. #q95r47tc4l (start of history)
☝️ The namespace .feature1 is empty.
.> history
Note: The most recent namespace hash is immediately below this
message.
⊙ 1. #ut7mk2guld
⊙ 1. #492bge1qkb
- Deletes:
feature1.y
⊙ 2. #oaneanmrn8
⊙ 2. #qdsgea37fc
+ Adds / updates:
@ -138,26 +130,26 @@ We can also delete the fork if we're done with it. (Don't worry, it's still in t
Original name New name(s)
feature1.y master.y
⊙ 3. #m6o57p1elr
⊙ 3. #ppkkh269f7
+ Adds / updates:
feature1.y
⊙ 4. #ep8ckbhnqt
⊙ 4. #u8aiheqfug
> Moves:
Original name New name
x master.x
⊙ 5. #t7aklphn43
⊙ 5. #es9cmc7kok
+ Adds / updates:
x
□ 6. #l6lcr63iti (start of history)
□ 6. #jo7t8m4dft (start of history)
```
To resurrect an old version of a namespace, you can learn its hash via the `history` command, then use `fork #namespacehash .newname`.

View File

@ -58,7 +58,9 @@ b.termInB = 11
.history> update
```
Now, if we soft-delete a namespace, but move another over it we expect the history to be replaced, and we expect the history from the source to be wiped out.
Deleting a namespace should not leave behind any history,
if we move another to that location we expect the history to simply be the history
of the moved namespace.
```ucm
.history> delete.namespace b

View File

@ -150,7 +150,9 @@ b.termInB = 11
b.termInB : Nat
```
Now, if we soft-delete a namespace, but move another over it we expect the history to be replaced, and we expect the history from the source to be wiped out.
Deleting a namespace should not leave behind any history,
if we move another to that location we expect the history to simply be the history
of the moved namespace.
```ucm
.history> delete.namespace b
@ -267,7 +269,7 @@ I should be able to move the root into a sub-namespace
.> ls
1. root/ (592 terms, 82 types)
1. root/ (597 terms, 83 types)
.> history
@ -276,13 +278,13 @@ I should be able to move the root into a sub-namespace
□ 1. #o2vkdh7ltv (start of history)
□ 1. #bn675bbtpm (start of history)
```
```ucm
.> ls .root.at.path
1. builtin/ (587 terms, 81 types)
1. builtin/ (592 terms, 82 types)
2. existing/ (1 term)
3. happy/ (3 terms, 1 type)
4. history/ (1 term)
@ -292,7 +294,7 @@ I should be able to move the root into a sub-namespace
Note: The most recent namespace hash is immediately below this
message.
⊙ 1. #i0lk1c81v7
⊙ 1. #vor04lbt72
- Deletes:
@ -303,7 +305,7 @@ I should be able to move the root into a sub-namespace
Original name New name
existing.a.termInA existing.b.termInA
⊙ 2. #64lmvl3fbe
⊙ 2. #tk3qtdeoov
+ Adds / updates:
@ -315,26 +317,26 @@ I should be able to move the root into a sub-namespace
happy.b.termInA existing.a.termInA
history.b.termInA existing.a.termInA
⊙ 3. #1upc23ts8h
⊙ 3. #r971i7m95i
+ Adds / updates:
existing.a.termInA existing.b.termInB
⊙ 4. #hp3nttbbeu
⊙ 4. #6qh988adub
> Moves:
Original name New name
history.a.termInA history.b.termInA
⊙ 5. #3vt487avqa
⊙ 5. #g19mlrid0i
- Deletes:
history.b.termInB
⊙ 6. #cng5456u5h
⊙ 6. #n0a5seofan
+ Adds / updates:
@ -345,13 +347,13 @@ I should be able to move the root into a sub-namespace
Original name New name(s)
happy.b.termInA history.a.termInA
⊙ 7. #6s6rta6dft
⊙ 7. #i3nsbtl7kc
+ Adds / updates:
history.a.termInA history.b.termInB
⊙ 8. #ri5k67h719
⊙ 8. #a2u0kep087
> Moves:
@ -361,7 +363,7 @@ I should be able to move the root into a sub-namespace
happy.a.T.T2 happy.b.T.T2
happy.a.termInA happy.b.termInA
⊙ 9. #5lhn2nqa5u
⊙ 9. #g18uf760mb
+ Adds / updates:
@ -371,7 +373,7 @@ I should be able to move the root into a sub-namespace
happy.a.T.T
⊙ 10. #2oljit38kd
⊙ 10. #2edl4803r1
+ Adds / updates:
@ -383,7 +385,7 @@ I should be able to move the root into a sub-namespace
⊙ 11. #95soup1m3q
⊙ 11. #qcd5obbuv8
```

File diff suppressed because it is too large Load Diff

View File

@ -59,17 +59,17 @@ y = 2
most recent, along with the command that got us there. Try:
`fork 2 .old`
`fork #c50ilio6t7 .old` to make an old namespace
`fork #2b8npf0tu2 .old` to make an old namespace
accessible again,
`reset-root #c50ilio6t7` to reset the root namespace and
`reset-root #2b8npf0tu2` to reset the root namespace and
its history to that of the
specified namespace.
When Root Hash Action
1. now #r1ojo66sp7 add
2. now #c50ilio6t7 add
3. now #k0vh8qed2b builtins.merge
1. now #j967usn5hk add
2. now #2b8npf0tu2 add
3. now #lv9og66mct builtins.merge
4. #sg60bvjo91 history starts here
Tip: Use `diff.namespace 1 7` to compare namespaces between

View File

@ -13,7 +13,7 @@ Let's look at some examples. We'll start with a namespace with just the builtins
□ 1. #61h5m6vr8d (start of history)
□ 1. #a2uij441jg (start of history)
.> fork builtin builtin2
@ -42,21 +42,21 @@ Now suppose we `fork` a copy of builtin, then rename `Nat.+` to `frobnicate`, th
Note: The most recent namespace hash is immediately below this
message.
⊙ 1. #h3t1td6j70
⊙ 1. #2orc0vqqcv
> Moves:
Original name New name
Nat.frobnicate Nat.+
⊙ 2. #hof2b14ggf
⊙ 2. #fk0nmiqqgk
> Moves:
Original name New name
Nat.+ Nat.frobnicate
□ 3. #61h5m6vr8d (start of history)
□ 3. #a2uij441jg (start of history)
```
If we merge that back into `builtin`, we get that same chain of history:
@ -71,21 +71,21 @@ If we merge that back into `builtin`, we get that same chain of history:
Note: The most recent namespace hash is immediately below this
message.
⊙ 1. #h3t1td6j70
⊙ 1. #2orc0vqqcv
> Moves:
Original name New name
Nat.frobnicate Nat.+
⊙ 2. #hof2b14ggf
⊙ 2. #fk0nmiqqgk
> Moves:
Original name New name
Nat.+ Nat.frobnicate
□ 3. #61h5m6vr8d (start of history)
□ 3. #a2uij441jg (start of history)
```
Let's try again, but using a `merge.squash` (or just `squash`) instead. The history will be unchanged:
@ -106,7 +106,7 @@ Let's try again, but using a `merge.squash` (or just `squash`) instead. The hist
□ 1. #61h5m6vr8d (start of history)
□ 1. #a2uij441jg (start of history)
```
The churn that happened in `mybuiltin` namespace ended up back in the same spot, so the squash merge of that namespace with our original namespace had no effect.
@ -485,13 +485,13 @@ This checks to see that squashing correctly preserves deletions:
Note: The most recent namespace hash is immediately below this
message.
⊙ 1. #v3tbgssvfo
⊙ 1. #9ijnd9ip7o
- Deletes:
Nat.* Nat.+
□ 2. #61h5m6vr8d (start of history)
□ 2. #a2uij441jg (start of history)
```
Notice that `Nat.+` and `Nat.*` are deleted by the squash, and we see them deleted in one atomic step in the history.