4 ms·
The core point, to me, seemed to be about limiting factors in language extension. To allow something like: my_if (points <= 100, printf ("%D", points), error
by tmtvl 1y ago
The core point, to me, seemed to be about limiting factors in language extension. To allow something like:
my_if (points <= 100, printf ("%D", points), error ("Invalid point total"));
Where the various parameters are lazily evaluated.
Or like:
frobnicate (frazzle: foo, frozzle: bar, frizzle: baz);
Where frazzle, frozzle, and frizzle are position-independent keyword variables.
Allowing those in C would require a modicum of effort, while other languages make these kinds of syntax extension fairly easy.
- PaulHoule 1y agoIn languages like Java (or C) you can build S-expression like structures like so Variable<Integer> x = newVariable(); Expression<Integer> = add(x,literal(5)); x.set(15); System.out.println(eval(x)) // prints "20" and it is not that hard to either serialize these to code or run them in a tree-walking interpreter where quote() and eval() imply an extended language where you can write functions that work on Expression<Expression<X>>. Type erasure causes some problems in Java that make you sometimes write a type you shouldn't have to and you do have to unerase types in method names which is a little ugly but it works. I did some experiments towards this to convince myself it would work https://github.com/paulhoule/ferocity/blob/main/ferocity0/src/test/java/com/ontology2/ferocity/TestFierceStrings.java https://github.com/paulhoule/ferocity/blob/main/ferocity0/sr... had I really kept at it I would have bootstrapped by developing a ferocity0 which was sufficient to write a code generator that could generate stubs for the Java stdlib + a persistent collections library and then write a ferocity1 in ferocity0, and if necessary ferocity(N+1) in ferocityN until it supported "all" of Java, though "all" might have omitted some features like "var" that are both sugar and use type inference that ferocity would struggle with -- if you need sugar in this system you implement it with metaprogramming. The idea is that certain projects would benefit from balls-to-the-walls metaprogramming and the code compression you get would compensate for the code getting puffed up. My guess is a lot of people would see it as an unholy mating of the worst of Java and Common Lisp. However, I'm certain it would be good for writing code generators.
- molteanu 1y agoThe solution, which I often seen in practice, is to eventually write code generators, which is what Lisp macros are, after all. I've seen it in C and wrote a big piece about it that was posted here some time ago[1], about the extra tools, code generators, special formats and standards employed and needed to make up for C's deficiencies (in respect to meta-programming, at least). Everywhere I see code generators it means a feature is lacking in the main language used for the project. Then you bring in other tools to make up for that deficiency. Only, usually, we don't call that deficiency, since we are used to things being that way. It is called day-to-day business. I think that's what I've tried to convey in the article. [1] https://news.ycombinator.com/item?id=41066544 https://news.ycombinator.com/item?id=41066544
- PaulHoule 1y agoI don't see code generation as a bad smell at all. At my job we use the JooQ code generator which is well integrated with maven and either IntellJ IDEA or Eclipse so autcompletion "just works". In modern Java you can pack up a code generator as a maven plugin [1] and put something in your POM that runs the generator. It's easy. There are other ways to hook the compiler too, see the controversial https://projectlombok.org/ https://projectlombok.org/ Lisp does come closest to a "language construction set" that lets you bend a language to your will. I think a compiler could be built for a language that looks more conventional that would be just as malleable, maybe even more malleable, but a generation of system programmers were traumatized by slow C++ builds and want to have nothing to do with a compiler which could be slow, even if you could make up for the slowness by having dramatically less code. [1] A maven plugin is just a Java class which can do everything in the ordinary Java way which gets dependencies injected by the maven runtime. It's a common rookie mistake to try to solve problems by writing XML. I mean, if you can write a POM that makes existing plugins do what you want go right ahead, but if you can't just write your own plugin.
- molteanu 1y ago> I don't see code generation as a bad smell at all. Well, exactly! > At my job we use the JooQ code generator... And in Lisp one would use the...Lisp code generator. That is, the macro. And the beauty of it is that it doesn't work with pure strings but 'understands', parses, manipulates the code as expressions in its own language. That is, it has at its disposal the entire language for manipulating those expressions. And I think that is one of the "aha" moments. At least, it was for me. When you realize the reason for having those code generators, regardless of the project and language, in the first place. That is, something missing from the language. Some extra feature that can't be implemented. Some solution that works really close to 99%, but not beyond. Something that one would like to express, but can't. Some piece of code that you want to be parameterized like you would a function, some piece of code that you want to use in multiple places but you don't want to write the same boilerplate or copy/paste it all over the place with the risk that when you modify something, you'll need to modify in all those places. Or some piece of code that you want to be auto-generated when you build/deploy/etc. The examples are countless. The world of meta-programming offers enough of them. The article gives the control statements as an example, as a hint to build the appetite, as is suggested in the intro, in fact.