Hacker News new | ask | show | jobs
by yarvin9 3671 days ago
Hoon is mainly built on a fixed set of hardwired, built-in macros. This is how I can be so confident about not needing anything like gensyms (what eliminates gensyms is having a subject which is navigated geometrically, not symbolically).

The advantage of fixing the set of hardwired macros is that, when reading code, everyone knows exactly what every line is doing, without having to indirect through the local macro environment. Macros are the first step toward a DSL.

DSLs are always and everywhere a bad idea. They may make code slightly cleaner or better-looking. In exchange, they add a level of indirection to the task of trying to understand it. This is the source of the nickname "write-only code," a common failure mode in FP. Write-only code can also be created by extravagant and pointless use of higher-order or non-strict programming, both of which complicate the task of reading code.

For instance, Hoon has a rune (keyword or digraph) for a 2-tuple, a 3-tuple, a 4-tuple, but not for a 5-tuple or up. Why? The 4-tuple cons pulled its weight, the 5-tuple didn't. For every special form you add to Hoon's fixed, limited set, you're imposing a cost on anyone who has to learn Hoon.

I hope you can see the UI advantage to functional programming in an environment of controlled evaluation complexity. IMHO, too much of FP is a world in which every program is its own language.

Which one is right? Actually, I feel it's possible that the only real language is K, and the rest of us are just phonies.

1 comments

> everyone knows exactly what every line is doing

At least, until you start to define functions, whereby a line now says "something happens according to a definition elsewhere which is just invoked here".

Oh wait, that's also what a piece of syntax or macro also says, pretty much.

> I hope you can see the UI advantage to functional programming in an environment of controlled evaluation complexity

What I do know is that big programs written in C can be pretty difficult to understand, even though most of their bulk hardly uses much more than what's covered by the operator precedence table on page 53 of Kernighan and Ritchie, 2nd ed. A lot of that has to do with the fact that foo_bar(ptr_widget, 42, gadget_struct) can mean anything whatsoever, even though it isn't a special operator or macro call. The small assurance that three word-sized chunks are passed somewhere by value doesn't actually buy a whole lot of understanding.

(Brain* * * * * * has a nice, small, inextensible set of operators. Does it help?)

The dictionary you have to comprehend is not that of the language, but of the language, plus that of the code base written in it. What good is it if some language has 20 entities rather than 30, if the code base you're grappling with has 10,000.

The difference between a language with symbolic names, and a language with names and macros, is a difference between one level of indirection, and two levels of indirection. My view is that one is hard enough.

Macros aren't functions. A function call is one thing. A macro can expand to arbitrary code. This code may contain function calls or other symbols.

Before you can even interpret these symbols, you have to expand the macros in your head. This is two steps, rather than one. Expanding is not tracing. This extra step is why whoever is reading your code is so easily tempted to give up and writes it again herself, with her own macro language.

I was not comparing FP to C. If you look at actual Hoon code, it's pretty comparable in size to other functional languages, and also in clarity once you learn to read it. Obviously C is much fatter and harder to understand (and has macros, of course).

A function can contain arbitrary code behind the call. It can be a remote procedure call to a server, such that it is impossible to reverse-engineer what it does, beyond black-box testing.