7 ms·
Fwiw, I think what's important about homoiconicity isn't so much that the language uses "boring" data structures for its (intermediate?) syntax tree, but that t
by zenhack 7y ago
Fwiw, I think what's important about homoiconicity isn't so much that the language uses "boring" data structures for its (intermediate?) syntax tree, but that the both the syntax itself and the representation of the syntax as an AST is simple and obvious.
Haskell has TemplateHaskell, which can be used for macro-like things, but it's substantially less ergonomic, not because Haskell isn't "homoiconic", but because the grammer is actually really complex and non-obvious. There's tons of little things that you don't think about when writing Haskell code, but you have to deal with when manipulating it. For example:
https://hackage.haskell.org/package/template-haskell-2.15.0.0/docs/Language-Haskell-TH-Syntax.html#t:SourceStrictness https://hackage.haskell.org/package/template-haskell-2.15.0....
That's a node in the AST that stands for something that is at most one character in the source text, and usually zero. So code manipulating this stuff gets really verbose and clunky. It's still powerful, but it's not the same.
As a side project, I'm actually working on an ML-family language with a macro system. It still has a more traditional ML-style syntax, but it is simple so working with it should be comparatively ergonomic. In an ML you wouldn't frequently want to be working with loosely defined data structures anyway; the first thing you'll do is convert it to a more strongly typed form that captures what you really want to be manipulating.
- hinkley 7y agoI hope I stay active in the industry long enough for people with influence to start talking about Human Factors as they apply to development tools. Ten years ago I thought that might be right around now, but today I'd still say ten years from now. I might be in my fusion powered self-driving car waiting for that boat to come in. When I'm digging through a large body of code looking for subtle bugs, I want the code to be boring but not bland. By that I mean, yes, all of the bits should be obvious, because I'm having to contend with the cartesian product of all of the bits. But if everything is self-similar top to bottom, there are no landmarks. It becomes very easy to get 'lost' in the code and have trouble telling if the next candidate for debugging is 'up', 'down' or sideways in the call stack. Fractals are really cool to look at, but they're murder for navigation purposes.
- coldtea 7y ago>Fractals are really cool to look at, but they're murder for navigation purposes. Are they? They imply that the structure is self-similar, which is a good trait for a structure, and makes it easy to read it at any level and get what's going on. That's what trees are, lists of lists are, strings of characters are, etc. >But if everything is self-similar top to bottom, there are no landmarks. The specific functions called at each level are the landmarks.
- hinkley 7y agoWhat specific functions? That's my point. If you go all in on recursive design, all the functions, variables, and object names are the same all the way up and down your graph. There are no specific functions. It's all grey goo.
- thom 7y agoForgive my failing imagination, but can you give some concrete examples of what you’re describing?
- tabtab 7y agoI cannot speak for the others here, but with languages like say JavaScript, the symbols usually represent something. {...} will usually represent a block of code. "[...]" will usually represent an array-like index. With Lisp you don't have such visual cues; you have to read the function name and perform a mental translation (lookup) of that function name to "find" a purpose in order to know what the "parenthesized unit" is. Thus, it's more mental steps to compute the general meaning of the code. One is mentally searching (mapping) on name, not visual appearance. Lisp fans seem to perform this lookup faster than average. Whether it's because they've been doing it for so long or they have an inborn knack is unknown. It would make a fascinating area of research. I tried to get the hang of name-based fast recognition, but was progressing too slow for my comfort.
- 7y ago
- zozbot234 7y ago> but that the both the syntax itself and the representation of the syntax as an AST is simple and obvious. The PLT literature is full of programming languages with simple and easily-serialized syntax. It's not all about LISP or Church's lambda calculus or whatever, there's plenty more out there. As one example, the bit of Haskell syntax you mention is only "complex and non-obvious" because the Haskell community has yet to internalize the ideas that PLT research has come up with, as to how laziness and strictness should be specified, interact etc. in a programming language (i.e. polarity, focusing, call-by-push-value).
- tome 7y ago> the Haskell community has yet to internalize the ideas that PLT research has come up with, as to how laziness and strictness should be specified Could you how those ideas should be used in practice? I'm a Haskell programmer and vaguely familiar with the ideas you mention but it's not clear to me exactly how they fit into a practical language.
- haecceity 7y agoMy experience with dsl in rust is that they’re hard to use because you can’t use the types to read the source code. Because the dsl can do funny things to the types. I guess powerful macro systems are useful in complex languages but maybe we shouldn’t rely on it too much?