urbit / developers.urbit.org

Website for the Urbit Foundation's developer program
https://developers.urbit.org
16 stars 56 forks source link

document second syntax for `+*` #218

Closed drbeefsupreme closed 2 years ago

drbeefsupreme commented 2 years ago

+* is pretty cursed. I discovered today that it has two syntaxes. These are both valid:

|_  a=*
+*  this  .
+*  that  [foo]  @
--
|%
++  foo  ~
+*  bar  [baz]  @
--

Right now, the docs say that you can only use +* in a door, and only at the beginning of the core, before the rest of the arms. This turns out not to be the case - there is a second syntax for +* that works in doors as well as |% and |@. I couldn't find anywhere in the kernel where it is used, but it is found here: https://github.com/urbit/urbit/blob/master/pkg/base-dev/lib/language-server/complete.hoon#L6-L7

The compact explanation for why this is happening: the first +* in |_ is parsed using +wasp. It gets thrown into its own particular spot in the AST as the alas in %brcb, and the later modifications to the real arms are performed in +open:ap. Any subsequent invocations of +* in a |_, or for |% and |@ are parsed by +boog, and unlike the first +* in a door, these are "real arms".

Unfortunately this second syntax doesn't seem to desugar nicely - it involves a %made spec, which isn't produced any other way. It seems to mostly work like |$ though, with an additional annotation. When the %made spec travels through the compiler, it ends up as a %made %note which then ends up in a %hint type. This doesn't happen with |$. But these yield the same output:

=<  ((foo @) ['asdf' 2])
|%
+*  foo  [bar]  [a=cord b=bar]
--
> [a='asdf' b=2]
=<  ((foo @) ['asdf' 2])
|%
++  foo  |$  [bar]  [a=cord b=bar]
--
> [a='asdf' b=2]
drbeefsupreme commented 2 years ago

OK, maybe this shouldn't be documented since it sounds like it shouldn't exist based on comments in the other thread.

drbeefsupreme commented 2 years ago

Yeah nevermind, I should have made the other issue first and realized this is deprecated syntax.