5 ms·
We definitely don't have Linus's streak of user-interface malice. (Git-related mental carnage has taken its toll on many urbit developers as well, alas.) What
by juped 11y ago
We definitely don't have Linus's streak of user-interface malice. (Git-related mental carnage has taken its toll on many urbit developers as well, alas.)
What you suggest reminds me of Lisp's infamous "M-expressions", but worse, because the lack of reserved words in Hoon is the most immediate tangible benefit of our syntax. We're homoiconic, and syntax looks unambiguously like syntax (and is actually extremely regular).
It's difficult to make the assertion that there really isn't much of a learning curve stick in a HN comment, unfortunately - it's based on experience learning the system myself, and helping others learn it on talk. It hasn't been anything syntax-related that trips up people actually learning the language, certainly - it's just something superficial that's easy to comment on on websites, as we've all seen around Lisp or Perl or even Python (whitespace-indented blocks).
To answer you directly, runes are the tag in the tagged union that is the type of our AST, not any kind of identifier. (Perl would probably let you assign pieces of syntax to identifiers, of course...) For example, if you have the following Hoon:
|= a=@
?~ a
~| %decrement-underflow !!
=| b=@
|- ^- @
?: =(+(b) a)
b
$(b +(b))
the associated AST (a noun of type ++twig) is
[ %brts
p=[%bark p=%a q=[%axil p=[%atom p=~.]]]
q
[ %wtsz
p=[%.y p=~ q=~[%a]]
q
[ %sgbr
p
[ %dtzz
p=%tas
q=2.663.495.029.034.430.894.880.199.458.246.708.989.383.632.228
]
q=[%zpzp ~]
]
r
[ %tsbr
p=[%bark p=%b q=[%axil p=[%atom p=~.]]]
q
[ %brhp
p
[ %kthp
p=[%axil p=[%atom p=~.]]
q
[ %wtcl
p=[%dtts p=[%dtls p=[%cnzz p=~[%b]]] q=[%cnzz p=~[%a]]]
q=[%cnzz p=~[%b]]
r=[%cnts p=~[%$] q=~[[p=~[%b] q=[%dtls p=[%cnzz p=~[%b]]]]]]
]
]
]
]
]
]
(To get this, I just ran ++ream, our compiler's frontend, on that code sample.) It would be as simple as dropping in an alternate parser there that looked for, e.g., 'if' rather than '?:', which isn't actually hard because our parser combinators are really easy to use. (The actual Hoon parser is very old and due for a cleanup, unfortunately, but conceptually is not very complicated.)
I wouldn't endorse it myself, but perhaps in the future of the project someone will find it a useful thing to do and do it. It would definitely clash with the language's design sensibilities in a way that "use English" doesn't clash with Perl's - Hoon is somewhat more picky (though, what language isn't?).
Edit: I completely forgot that I was going to include a hypothetical version of the above with keywords. Here:
defgate a=@
nil? a
error %decrement-underflow
dim b=@
runtrap cast-to @
if inc(b) == a
b
replace b with inc(b) in this
(The keywords are silly, but please imagine better ones.)
- mst 11y agoActually, hoon syntax reminds me of a coffescriptish set of M-expressions for a language designed by APL developers who were told to use digraphs to get around the users' use of teletypes (edited after juped replied to add: I think juped did, but everybody else, please do read that as if said with an indulgent smile rather than a sneer, I -am- a perl hacker after all). If anything, I could probably do fine with an S-expr-ish form - [ gate [a=@] [ [nil? a [ error %decrement-underflow ] [ let [b=@] [ [runtrap [cast-to @]] [if [= [+ b 1] a ] b [ recur b=[+ b 1] ] ] ] ] ] ] but what's perhaps more interesting to you is the fact that I'd managed to remember 'wutcol' for ?:, which then meant that when I saw %wtcl in the output I immediately identified that branch and my brain started reverse engineering it without any real 'wtf' time, leading me to wonder if forcing people into the pronounced names earlier somehow might also help. A more actually M-expression style might be gate {{a @}} { nil? a { error %decrement-underflow } { set b @ runtrap [cast-to @] if {inc(b) == a} { b } { recur a=inc(b) } } } which would probably be quite trivial to implement in Tcl, though I think losing the tall/wide principle would be an impediment to learning in a way that named runes I suspect wouldn't be. I'm afraid you're in error about 'use English' though - to many of us it absolutely does clash with the sensibilities of the language and frankly I find it intensely grating (please do reconsider my words in that light to see if they change meaning to you, if you have a moment to do so). I would fully expect somebody who knows hoon reasonable well to find this just as grating, in the same way I'm sure a trick cyclist would find riding a bike with training wheels grating. But that doesn't mean training wheels can't be useful, even so.
- juped 11y agoYeah - we are homoiconic (twigs are nouns), but we aren't actually Lisp. I think with training wheels it probably pays off to be excessively empirical. See the situation in Haskell where the only reason "map" only maps over lists and not generic Functors is that people were afraid to put the word "Functor" on a newbie's screen - but many newbies are in fact confused by "map" and "fmap" both existing! So holding one's nose and accepting something inelegant for that reason should probably be done if and only if it works. So far, we haven't actually had any issue with digraph runes in particular, and I think there's a number of reasons why. I think in practice a lot of what we actually do is aggressively subset the language - which is okay, because a great deal of the runes are in fact compiler-level macros. While we can't put this in any documentation because it would hold us to too much, the character choices in runes are actually designed to have patterns that are easy to remember in them. For instance, %-, %+, and %^ are 1, 2, and 3-ary "function application", respectively, and %. is %- with the order of its children reversed. Analogously, :-, :+, and :^ build 2, 3, and 4-tuples, respectively, and :_ is :- with the order of its children reversed (a minor irregularity because :. is somewhat awkward, especially when your comments start with ::). Finally, ?. is "unless" - it's ?: with the "then" and "else" branches reversed. So a new Hoon programmer might learn |=, along with the fact that | runes make cores, and ?:, along with the fact that ? runes are conditionals, and already be able to sorta-read the decrement gate given above. Another sort of training wheel we have is that some of our concepts can masquerade as more familiar ones. For example, many people, including you, read the irregular form for %=, or "evaluate with changes" (seen above as "$(b +(b))") as "recursion", because most of the time you see it explicitly in simpler code it is actually being used to recurse. The reason this turns out not to be a huge deal is because there's basically no non-pathological case where %=ing $ (which is actually not syntax, but an empty name, in the code above referring to the |- trap that it's inside) is not recursion, making it an intermediate-level topic (and it's a higher-level topic that, at the lower level, %= is basically the most fundamental operation we do). It's not surprising that you could remember %wtcl easily - a lot of people associate verbally. I do, and Curtis has made it clear that he named the punctuation because he does. The weird names make it less of a subconscious thing than it is with, say, "char *argv[]" or "s->len", and also mean that Hoon programmers in the same office can talk quickly and unambiguously (it does feel silly at first, I admit). The biggest insight of the syntax, though, (in my opinion, which is not necessarily shared), is that fixed-arity syntactic forms let us avoid both code that tries to escape off the right edge of the screen and unsightly piles of closing brackets, because most syntax trees are greatly unbalanced. Something really prosaic that feeds into this is just the fact that all the runes are two characters wide, giving Hoon that surprisingly easy to scan "imperative" feel. You might be able to find four-character keywords (without cheating and using wtcl etc, naturally!) and make this work, of course.