Previously when using `run.compiled`, `Debug.toText` was not attempting
to decompile closures, which generally led to pretty terrible output.
This changes the prety-printing for `run.compiled` to work similarly to
the pretty-printer for `run` but with empty name mappings for types and
terms.
Testing and example output
==========================
I couldn't figure out how to test this change. I don't see any examples
of calling `run.compiled` and capturing output, and `Debug.toText`
inside a transcript acts as the pretty-printer in `run` as opposed to
`run.compiled`. But I did some manual testing with the following `main`
method:
```unison
main = do
Debug.trace "output" (1, "foo", -1, -3.2, 0xsabba, ["one", "two"], [-2.1, +3.4], [0xsabba, 0xsdeadbeef])
```
Previous output
---------------
```
trace: output
DataB2 #2lg4a 3276800 (DataU1 ##Nat 1310720 1) (DataB2 #2lg4a 3276800 (Foreign (Wrap ##Text "foo")) (DataB2 #2lg4a 3276800 (DataU1 ##Int 983040 (-1)) (DataB2 #2lg4a 3276800 (DataU1 ##Float 589824 (-4608983858650965606)) (DataB2 #2lg4a 3276800 (Foreign (Wrap ##Bytes _)) (DataB2 #2lg4a 3276800 (Foreign (Wrap ##Sequence _)) (DataB2 #2lg4a 3276800 (Foreign (Wrap ##Sequence _)) (DataB2 #2lg4a 3276800 (Foreign (Wrap ##Sequence _)) (Enum #00nv2 3342336))))))))
```
New output
----------
```
(1,
"foo",
-1,
-3.2,
0xsabba,
["one", "two"],
[-2.1, 3.4],
[0xsabba, 0xsdeadbeef])
```
Fixes#3938
I wasn't really sure of the right way to test this. I added a test to
`builtin-tests` that was previously failing and now succeeds. I wasn't
sure whether I should include specific ability constructor
hashes/indexes in the test, so I just tested that it doesn't throw an
exception. This test also doesn't seem to run with `stack test` and
needs me to explicitly call
`./unison-src/builtin-tests/interpreter-tests.sh` but it seems like that
is a thing?
Anyway it seems to work:
```
.> cd .tmp service_calls
.tmp>
✅
~/code/unison/scratch.u changed.
Now evaluating any watch expressions (lines starting with `>`)... Ctrl+C cancels.
1 | > Link.Term.toText (termLink abort)
⧩
"#b589mbg492brf3k3t0lg706d7ob88jqslgmja9gkrimv4137utuittc2r9l1tgvhrl40f71c99m39ch48gubbjhn5vf2pf5evjsinn8#0"
.tmp>
✅
~/code/unison/scratch.u changed.
Now evaluating any watch expressions (lines starting with `>`)... Ctrl+C cancels.
1 | > Link.Term.toText (termLink Store.get)
⧩
"#fmj3l8nggpfuh0ueuhr2rcka4s91ihufqiq6rocn25vsnni3v8rtjjteq79d398shvrfvbmhhoc7amhoh9lmdlghhiirl81sodj3ti0#1"
.tmp>
✅
~/code/unison/scratch.u changed.
Now evaluating any watch expressions (lines starting with `>`)... Ctrl+C cancels.
1 | > Link.Term.toText (termLink Store.put)
⧩
"#fmj3l8nggpfuh0ueuhr2rcka4s91ihufqiq6rocn25vsnni3v8rtjjteq79d398shvrfvbmhhoc7amhoh9lmdlghhiirl81sodj3ti0#0"
```
* Add migration to fix bad primary key in scoped_type_lookup
* Drop indexes before creating new ones.
* Remove "on conflict do nothing" when building name lookups
* Change Migration 8 to 9 to be a pure sql migration
* Include schema version in backup and use vacuum into
* Allow specifying not to backup on migration
* Add ability to copy codebase safely (for share migrations)
* Set migration strategies
* Create dir to copy into if missing
* Ormolu
* ormolu
- The existing code was assuming that only references involved in `Pack`
instructions were relevant, but this only preserves data type and
request information. We need to remember types used in handlers, or
else we will think that remote requests are coming from distinct
abilities than the ones we are handling.
In certain cases this will change the failure message from something
like `resolve: unhandled ability request: 1561` to `resolve: unhandled
ability request: #ifg08` where `#ifg08` is the has of the ability that
was unhandled. At this stage we don't have convenient access to the
actual constructor within the ability that was not handled.
I haven't added tests because I don't really know how to set them up.
But it's not really a big deal if there's a regression in this error
message, so I'm not sure whether they'd be worth the trouble.
Resolves#3791
Delegate to the runtime's Socket equality, which I believe uses pointer
equality.
I tested this by running the following code, which no longer gives an
error after this change:
```
main = do
socket = Socket.client (HostName "www.google.com") (Port "http")
socket === socket
```
This improves the error message when there is a type mismatch in
equality checks of `Foreign`. The `Eq.==` error message now matches the
style of error message provided for `compare` on the `Ord` instance.
- Renames callProcess to process.call since there will be several
related functions now.
- Adds a ProcessHandle type for references to asynchronous processes
- Add start, kill, wait and exitCode for interactive processes.
* start spawns a new process with the given command and arguments,
returning Handles for the in, out and error streams of the process,
and a ProcessHandle referencing it
* kill kills a process given a ProcessHandle
* wait blocks on a process to finish and returns the exit code
* exitCode does a non-blocking query for the exit code of the process.
It returns `None` if the process is still running.
- This allows calling out to an external executable with specified
arguments. The executable is searched for in the path according to
some platform specific rules. The call is blocking, and the exit
code is returned.
- Note: this is _not_ the sort of external call that involves a shell
as an intermediary.
- This sort of call is supported by both Haskell and racket. Chez seems
to only have the shell-based external call, so it might be necessary
to wrap a foreign library for it (otherwise the arguments would have
to be escaped, which seems like a bad idea). Nevertheless, it seems
like the right API to expose.
- Opening a fully interactive, asynchronous process is left for future
work.
- This reworks the Debug.trace machinery to allow getting just the
text that would be shown for a value. Instead of carrying a tracing
function in the runtime, a function that generates the (annotated)
text is used, and the logic for printing it is moved to the runtime
itself.
- Also, a primitive instruction is available for getting at the text. It
has three possible results:
* None - the tracer is completely off
* Some (Left txt) - an 'ugly' textual representation
* Some (Right txt) - a 'pretty' textual representation
In GHC, CAS returns both a Boolean and the current value of the IORef,
which can be used to retry a failed CAS.
This strategy is more efficient than returning a Boolean only because
it uses a single call to cmpxchg in assembly (see [1]) to avoid an
extra read per CAS iteration, however it's not supported in Scheme.
Therefore, we adopt the more common signature that only returns a
Boolean, which doesn't even suffer from spurious failures because GHC
issues loads of mutable variables with memory_order_acquire (see [2])
Incidentally, this also works around the lack of support for compound
direct lets in our interpreter.
[1]: https://github.com/ghc/ghc/blob/master/rts/PrimOps.cmm#L697
[2]: https://github.com/ghc/ghc/blob/master/compiler/GHC/StgToCmm/Prim.hs#L285
* WIP: fix up anns for bindings, blocks, etc.
* Working annotations for lets
* Add nesting tests
* Fix nesting tests
* Fix annotations on let-rec blocks
* Fix bad test src
* Skip destructuring binds test for now.
* Remove debugging
* Better fallbacks for finding ref nodes
* Transcript updates
* Fix bad 'contains'
* Rewrite letrec and let combinators to avoid requiring semigroup
* Don't include block openers in the block itself.
We don't want things like '=' or '->' to be part of a block
* Re-run transcripts
* Remove redundant constraint
What was `pull.silent` is now also `pull`.
What was `pull` is now `pull.verbose`.
Resolves#3566.
Before this change, the `Verbosity` type (which I believe was only used
for variations of pulling code) was either `Silent` or `Default`. This
is awkward because silent became the new default. So I changed it to
`Silent` or `Verbose` and filled in default values as needed.
I retained the verbose functionality for `debug.pull-exhaustive` because
if you are in the state that you need that command, some extra output
about what is happening might be useful.
- It seems that there are situations where implementing foreign
equality as:
promote ((==) @ T)
(where `promote` wraps the inputs with coercions) can cause memory
faults. This is _not_ because the runtime is (currently) erroneously
coercing between distinct types (at least in the test case used to
find this error). Rather, it has something to do with `unsafeCoerce`
causing invalid GHC to generate some invalid code, whether via
optimization or otherwise.
It seems that separating out the equality test into its own,
noinline function prevents the issue. So, that has been done for all
cases. It is actually quite difficult to find simple code that
triggers the issue, however, so it is difficult to say whether this
definitively fixes the problem.
- The check was looking for occurrences of `f x y z ...` to make sure it
was safe to eliminate variables that had been added by enclosure.
However, it wasn't finding occurrences of `f` by itself, because that
is not considered an application by the predicate that was being used.
- I also made the 'fix-up' code default to not eliminating any variables
when there are *no* subsequent occurrences of `f`. Previously this
would allow eliminating as many variables as possible. However, this
can produce ill-scoped definitions. Avoiding this would require
knowing which variables are in scope when reducing an unused
definition, but that would require a more complicated rewriting
process than is currently used.