4 ms·
I don't think you're missing much. Yeah, the main point seems to be that if your language has closures, you suddenly can express a lot of things that were out o
by Jach 1y ago
I don't think you're missing much. Yeah, the main point seems to be that if your language has closures, you suddenly can express a lot of things that were out of reach before. Not a new insight. But there's another point I think that is hinted at on the topic of control abstractions. Or at least I'm reminded of the topic. It's better and more succinctly and explicitly talked about in an early chapter of the free book Patterns of Software: https://dreamsongs.com/Files/PatternsOfSoftware.pdf https://dreamsongs.com/Files/PatternsOfSoftware.pdf
The extra point might be that more languages should facilitate defining your own control abstractions just as they support defining your own data abstractions. Functions are one way of making data abstractions, but languages often provide multiple ways. Closures are one way of doing a type of control abstraction (involving such things as delayed or multiple evaluation), but there are other ways too. For some reason we see value and a need for defining our own data abstractions, but not so much for control abstractions, even though (according to the book) once they were often co-designed, like Fortran's arrays and DO loop. And for some reason even in the few languages that do support making your own control abstractions, like Lisp, you'll still find users who disapprove of doing so, claiming all you need are the standard existing methods like looping, map/reduce style functions, and some non-local exits.
- PaulHoule 1y agoThere's closures and there's being able to transform the expression tree. Graham's On Lisp is a really interesting book https://paulgraham.com/onlisptext.html https://paulgraham.com/onlisptext.html which is allegedly about programming with macros but I'd say 80% of the time he implements something with closures and then makes a macro-based implementation that peforms better. That 80% can be done in Python and the other 20% you wouldn't want to do in Python because Python already has those features... And if you wanted to implement meta-objects in Python you would do it Pythonically. Graham unfortunately doesn't work any examples that involve complex transformations on the expression trees because these are hard and if you want to work that hard you're better off looking at the Dragon book. You can work almost all the examples in Norvig's Common Lisp book https://www.amazon.com/Paradigms-Artificial-Intelligence-Programming-Studies/dp/1558601910 https://www.amazon.com/Paradigms-Artificial-Intelligence-Pro... in Python and today Norvig would advocate that you do.
- Jtsummers 1y agoNorvig put PAIP up on Github a while ago: https://github.com/norvig/paip-lisp https://github.com/norvig/paip-lisp
- smcameron 1y agoThere's an upside to C's limitations. Several times I've seen expressed the notion that "every big Lisp project uses its own dialect of Lisp". This is less true in C, I think, because it doesn't have the power (ignoring preprocessor abuse, which does happen, see Bourne shell source[1]). C++ has a bit more power, and there we see projects tend to use their own subset of C++. In both Lisp, and C++, taking some isolated snippet from a codebase, you can't quite really be sure what it's doing without reading the rest of the program because of what might be called the "excessive" power of the languages. In C, it is much more likely that you can look at an isolated snippet of code from some codebase and be reasonably sure about what it is doing, and be able to extract this snippet more or less as-is, and re-use it in some other, unrelated code base. At least, this has been my experience, ymmv. [1] https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh
- molteanu 1y agoWell, yes, an often heard, and reasonable argument. But then what happens in a reasonably sized C project is that other tools are brought in to fill the gaps. Tools like code generators (see some other comments on this post), for example, which are necessarily written in a different language and, most importantly, come with their own terminology and way of doing things. Which, in the end, becomes an extra mental load, the kind that you've rightly mentioned. Only you've partitioned or spread that load horizontally in multiple little pieces as opposed to building abstractions on top of each other. Or, each piece of code is understandable by itself, but one has to read dozens of such "little islands" to make sense of what the code is achieving since, by necessity, you need to have many such pieces to achieve something meaningful. The alternative being the abstraction pyramid which does more with less code. The downside being, there is an upfront investment in understanding those abstraction layers before one can juggle with them, so to speak. In your example, the upfront investment is less so, but every-time you must do something meaningful, including reading the code, you pay the penalty of not having powerful enough tools. As an example: engineers go to universities to study calculus, physics and material science so that, with these, they can better plan and build a highway (let's say). There is a huge upfront investment in that, let's say 16 years of study. Versus, use our shovels and buckets and start building right away. That is easy to learn. You learn it in a day. You start building right away. Everyone can supervise and, thus, understand the work because it is straightforward. 1 day upfront investment. But the later will advance at a horrible pace. There is no way to visualize what you're doing. There is no study beforehand. Maybe the hill will collapse and you need to start over. Maybe the two ends of the road will not meet where you'd expect to. Maybe the materials crack after a week. Maybe the road is not even, so you start over. Etc, etc.