Earlier quoted context omitted.
Now suppose three of you are working on the same project, and each brings their own code generator like this. You can take Common Lisp macros from multiple sources and use them in the same expression, in any pattern of nesting.
In principle. Most people find somebody else's metaprogramming-heavy Common Lisp difficult to work with. When you look at classic programs from the golden age of AI you find they either rewrote their Lisp prototype in C++ for speed or the Lisp program (like an expert system shell) is much smaller than you imagine possible but it looks like the engine of a UFO.
The plan-execute pattern
41–50 of 81 posts
Re: The plan-execute pattern
#42Earlier quoted context omitted.
>What makes Scheme and other homoiconic languages special is that the code that is currently executing can be manipulated live like any other data structure I think I know Scheme well, and I don't catch your meaning. Most Scheme implementations are compilers that output a machine-language executable. How can this executable be "manipulated live" in a way that differs from an executable produced by any other language?…
> the code that is currently executing can be manipulated live Typically when people say this about Lisp, they mean that they can redefine functions and objects live, having all the code adapt to use the new definitions, or when their code hits an error, they can not only redefine functions and objects live, but also examine the state of the call stack and change the values of variables live, and then let the code ru…
Re: The plan-execute pattern
#43However, when I later revisited the design of Ninja I found that removing the separate planning phase better reflected the dynamic nature of how builds end up working out, where you discover information during the build that impacts what work you have planned. See the "Single pass" discussion in my design notes[2], which includes some negatives of the change.
If the author reads this, in [2] I made a Rust-based Ninja rewrite that has some similar data structures to those in the blog post, you might find it interesting!
[1] https://github.com/ninja-build/ninja/blob/dcefb838534a56b262... [2] https://neugierig.org/software/blog/2022/03/n2.html
Re: The plan-execute pattern
#44"I feel uneasy about design patterns. On the one hand, my university class on design patterns revived my interest in programming. On the other hand, I find most patterns in the Gang of Four book to be irrelevant to my daily work; they solve problems that a choice of programming language or paradigm creates." My relationship with design patterns changed when I stopped viewing them as prescriptive and started viewing t…
Descriptive of the kinds of workarounds that a lack of proper abstraction capabilities made necessary in ancient Java.
Furthermore, the purpose of design patterns is not to introduce anything new, it’s to provide a catalog of repeatedly occurring existing patterns in software development, including the respective situations each pattern is applicable in, and their individual benefits and drawbacks. An important motivation was to name each pattern, so that when one software engineer says “builder”, the other engineers know what it means. Previously developers encountered certain patterns sooner or later, but didn’t know what to call each pattern, or each developer invented their own names, or meant different things by the same name.
The set of relevant patterns will change over time to some extent as software development changes, but that is orthogonal to the concept of design patterns. It’s a mistake to think of design patterns as specifically the set of 23 GoF patterns. Though some GoF patterns are unlikely to ever become irrelevant, like Adapter, Decorator, Composite, Proxy, Interpreter, Strategy.
Re: The plan-execute pattern
#45"I feel uneasy about design patterns. On the one hand, my university class on design patterns revived my interest in programming. On the other hand, I find most patterns in the Gang of Four book to be irrelevant to my daily work; they solve problems that a choice of programming language or paradigm creates." My relationship with design patterns changed when I stopped viewing them as prescriptive and started viewing t…
Re: The plan-execute pattern
#46"I feel uneasy about design patterns. On the one hand, my university class on design patterns revived my interest in programming. On the other hand, I find most patterns in the Gang of Four book to be irrelevant to my daily work; they solve problems that a choice of programming language or paradigm creates." My relationship with design patterns changed when I stopped viewing them as prescriptive and started viewing t…
Descriptive of the kinds of workarounds that a lack of proper abstraction capabilities made necessary in ancient Java.
Look, I'm glad you work in a language where you don't need to describe those things any more, but the vast majority of people still do. And for that group of people, understanding that "Design Patterns" is a dictionary, not a recipe book, is a really important thing.
Re: The plan-execute pattern
#47This is a similar pattern to Terraform, correct? (Plan/Apply). I like this pattern, however, when implementing it into automation it presents a conundrum. Often, code will be checked into a repository with a "plan" attached to it. Great. Merge after plan is approved, then automation executes the plan. However, lots of providers will only show errors on the "execute" phase (e.g., on apply, "resource already exists" er…
Re: The plan-execute pattern
#48Earlier quoted context omitted.
> the code that is currently executing can be manipulated live Typically when people say this about Lisp, they mean that they can redefine functions and objects live, having all the code adapt to use the new definitions, or when their code hits an error, they can not only redefine functions and objects live, but also examine the state of the call stack and change the values of variables live, and then let the code ru…
But that can't be "what makes Scheme and other homoiconic languages special".
[0]: https://texdraft.github.io/lisp-compiler/internals.html
Re: The plan-execute pattern
#49Earlier quoted context omitted.
Descriptive of the kinds of workarounds that a lack of proper abstraction capabilities made necessary in ancient Java.
Or any other major commercially used language right now? Look, I'm glad you work in a language where you don't need to describe those things any more, but the vast majority of people still do. And for that group of people, understanding that "Design Patterns" is a dictionary, not a recipe book, is a really important thing.
It's not a bad book if you read it as positive account rather than a normative prescription, I have the dead tree version on my bookshelf, but it's also a narrow, historically-informed perspective. Nothing about patterns is a fundamental concept that persists across languages (or even time), unlike things like SICP, algorithms, CS concepts, etc.
Re: The plan-execute pattern
#50Earlier quoted context omitted.
But that can't be "what makes Scheme and other homoiconic languages special".
I suppose that, if I'm asked "What is something that makes homoiconic languages special?" and the answer can't be that it makes macros easy, then I would say it's that it's easy to write an interpreter for that language in the language itself, because the data structures that form the syntactic structure of the language are themselves first-class objects. That's why the interpreter from the appendix of the LISP 1.5 m…
Scheme was the first language with lexical scoping of variables, and after Scheme was published in 1975, most new languages have had lexical scope and most languages used now (Java, C#, Javascript, Rust) have it. I think the qualities you describe make it easier to experiment with (Lisp-like) languages and language implementations, which is why lexical scope appeared in a Lisp-like first. Also, I think the concept of a "closure" appeared first in discussions about Lisp (maybe as part of the same discussions that led to lexical scope). Ditto I think continuations and continution-passing style. Also the interpreter you refer to in Appendix A of the Lisp 1.5 manual had a subtle problem or area for improvement around functions appearing as arguments to functions, and the Lisp's community's discovery of that and solution to that seems to have been incorporated into other languages, probably first the early functional languages like Miranda, then on to Javascript, etc.