A coroutine is a computation that can `yield`, suspending itself and passing control back up to the caller. It can then be resumed at the caller's leisure.
An function with an effect (in this sense) is a function which can ask a handler to `perform` some effect for it. This suspends the function and passes control to whichever handler is in scope for that call, allowing that handler to resume the function at its leisure.
I suspect that you're misunderstanding what is meant by effect, because despite buzz about them and backend support for them in OCaml 5, they aren't yet implemented with syntax and type-level support in any mainstream languages I'm aware of.
By making effects explicit, you reap the benefit of being able to write non-effectful code.
Depending on what your language tracked as an effect, you could make your business-logic always terminate, or perform no allocations, if you had effects for Mutation/GeneralRecursion/Allocation.
But no, I certainly don't understand the function->handler control flow here. It has to be handler->function, otherwise you've got two handlers!
a function will return to it's call site (or diverge), a handler doesn't necessarily have to resume from where it was invoked. There is also (sort of) dynamic scoping, where you don't have to thread the handlers through calls.
Not sure why but everything below the hero section on your homepage is displaying as just grey background to me on Firefox, even with enhanced tracking protection and adblock off. In the console the only error is `Uncaught ReferenceError: tippy is not defined`.
Checked on a private window; it happens only when I say no to inessential cookies. Being in California might also have something to do with it, because according to the logs that sets something to opt in mode.
I have to say that I was a little disappointed by this article. It doesn’t really demonstrate Kap as solving any of the issues that spreadsheets have, and it doesn’t really address many of the reasons people like spreadsheets.
Spreadsheets are reactive and stateless and allow you to move seamlessly from data storage to computation on that data. This is really just a calculator REPL that can ingest tabular data easily. I’d be more interested if they’d innovated more with the interface — maybe something node-based?
At the point when you've written a term which is incidentally equivalent to another, the Unison codebase manager tool tells you that you're adding a term that is identical and lists its name. You can still technically perform the addition if you really want at that point, but most folks don't want two aliases for the same function floating around. If you do end up adding it, updating A would also update B. Think of the function name as metadata and the actual implementation as the identity of the function.
Is the term merely the hash of its contents, or does it also include the module space? If it's just the hash of its contents, how do you deal with functions which have the same implementation now but shouldn't always - e. g.:
If they hash to the same thing and I update `serviceA.requiredHeaders` (because the vendor changed from `X-API-KEY` to `X-VENDOR-API-KEY`) do I have to know that these are two different services in order to review the change and untangle these two methods or is there a way to mark these as "structurally equivalent but semantically distinct"?
Yes this is unfortunately a problem that comes up with our current system. We had to solve this early on by distinguishing "unique" types form "structural" types. For types it is obvious that you want to make sure that these types generate a unique hash, even if they are the same structure:
type UserName = UserName Text
type Password = Password Text
since the entire point in introducing types here is to actually declare them as different from one another.
But for other it might actually be beneficial to recognize that they are the same type, for example:
type Optional a = None | Some a
type Maybe a = Nothing | Just a
To allow for both, you can prefix type with either "structural" or "unique" depending on what behavior you want (unique is the default). We have tossed around the idea of also introducing unique terms which would let you terms like yours as unique terms that should be salted, and let the current behavior of "structural"? terms be the default. The reality is that this hasn't been such a big problem that it has made it to the top of our list yet ;)
(Sorry for replying late to this but) that seems kind of inconvenient! And what if I'm using two libraries which happen to export functions with identical ASTs, and one updates? I guess usually meaningful nominal types will ensure that that doesn't happen but it seems like a nightmare to deal with in the event that it does.
for us, A and B are the same Term since they have the same hash, they are just two different alias for that hash, so if you update either, you are effectively updating both.
In fact if you had the function:
double x = x + x
and you were to rewrite it to be:
double addend = addend + addend
Unison would say "this is the same function, no update needed" as it produces the same AST
It's roughly the same, no? It emulates a non-deterministic Turing machine and gives the same results, just taking much longer. But runtime isn't everything! I think that if you're programming in a nondeterministic style, you're programming as if you have a NTM, whether or not you're actually running the code on one.
Also, surely NTMs are only physically unrealizable if P!=NP, and so whether or not NTMs could exist is an open question.
Yes, the cool thing here is just to use higher order to provides the user non-determinism seaminglessly within Python while in prolog this is a built in feature.