https://www.youtube.com/watch?v=_ahvzDzKdB0
or as PDF:
https://www.cs.virginia.edu/~evans/cs655/readings/steele.pdf
https://www.youtube.com/watch?v=_ahvzDzKdB0
or as PDF:
https://www.cs.virginia.edu/~evans/cs655/readings/steele.pdf
It is like designing a workshop. You only have so much space within arms reach. Here you place your most frequently used and valuable tools. You can "grow your language" by adding tools but they can't replace what you have in this limited and privileged position - instead, new tools have to go in cupboards or on another table. The new tools will have higher friction than the first priority tools you added.
Maybe you can have a workshop where you imagine a tool and it appears in your hand thereby removing the constraint of "tools within reach" but I think this then makes it too ephemeral and abstract. It is the constraints that makes a language tactile and ergonomic - remove the constraints and you have no structure at all.
In this case, the "tools within reach" are your core keywords and syntax. Growing features via libraries or syntactic extensions generally incur more ceremony and less elegance. Having totally flexible syntax extensions/keywords doesn't solve the problem, it just moves up a level abstraction/generality and means you have given your users the "design a language" problem instead of solving it for them.
This is an interesting observation that reminds me of
> In Lisp, you don't just write your program down toward the language, you also build the language up toward your program.
from Paul Graham's "Programming Bottom-Up". Some people would consider it an advantage being allowed to fold the "design a language problem" into the overall problem.
More, I think this is just a matter of degree, not kind.
As soon as you have something as apparently simple as named procedures, you're really writing a DSL, albeit very coarsely, for your business problem. Add named record types. Add textual macros. Add operator overloading. Add Lisp-style macros. At every point where the language allows a word on the screen to stand in for something larger, you're giving the programmer the power to design a language for their problem domain.
> We need to put tools for language growth in the hands of the users.
Guy's previos work with Common Lisp is epitome of this. There are three kind of macros in the language: reader macros, macros and compiler macros. They give the tools for the user to extend the language. There is just 25 or so core primitives in the 'core' language and the runtime. The rest 900+ functions and symbols are basically the standard library (the fact that they are slapped into the same package and they extend the core in a ways that other languages can't hides the simplicity of the language somewhat).
The creator has repeated this philosophy a few times:
> There is very little reason for an Elixir v2.0 with breaking changes. The language was designed to be extensible and if we need to do major changes to the language to improve the language itself, then we failed at the foundation.
https://elixirforum.com/t/what-would-you-like-to-see-in-elix...
> A big language does not only fragment the community and makes it harder to learn but it is also harder to maintain. It is also why the language was designed to be extensible: so the community could build what is necessary without a push to make everything part of the language.
https://elixirforum.com/t/questions-about-property-testing-s...
> We also understand there is a limited amount of features we can add to the language before making the journey too long or the language too big. Adding something now means not including something else later. As an exercise, let’s see a counter example of when we didn’t add something to the language: GenStage. [...]
https://elixirforum.com/t/questions-about-property-testing-s...