On Monday, 13 June 2011 at 20:02, Benjohn Barnes wrote:
• I strongly feel that languages "do well" when they come with batteries included. The particular metric of do well I'm thinking of is getting widely adopted and used by loving developers.
I believe there are several key parts to the "batteries included" feel of a language ecosystem:
One of them is that it has to be easy to create a library and share it with others; otherwise a sufficiently large body of libraries won't be created. This has been the main motivation behind Black Hole: It could make it feasible to write and share libraries with non-trivial dependency graphs.
But I have realized that simply making it possible to share code easily isn't sufficient. Some important issues here are
1) R5RS, being a minimal language, simply doesn't provide enough syntax (ie macros). The special forms are so few that each developer has to choose between using vanilla R5RS, which is often painful (the syntax for multiple values for instance), or creating his own set of base macros, which leads to loads of separate and suboptimal designs of things that should be core language constructs.
This works well for isolated projects with few dependencies to other libraries, but it seriously hurts code readability when sharing libraries.
2) R5RS has a culture of not incorporating things into the language until it is known that the particular design is arguably the best possible. This works well when it is acceptable to have many different approaches to the same problems until they're solved, but it seriously hurts the ability to share code.
If one wants to make a "batteries included" system, this design philosophy simply doesn't work. It is necessary to incorporate things before they are perfectly worked out, and then improve things incrementally. (Of course this doesn't make careful design less important.)
The minimalistic, don't-add-until-perfect, way of things has left R5RS with several important (for projects that need "batteries included") holes in its core functionality, for instance a module system, unwind-protect, complete I/O, threads and even simple things like a basic set of list functions (fold, where are you?).
3) Most "batteries included" languages nowadays come with a relatively large standard library, and rarely encourage multiple language implementations like Scheme does. I think discouraging multiple implementations of the language is an important ingredient to make a batteries included language work.
There can be more than one language implementation, but there has to exist an obvious default. Ruby, Python, Java, PHP, .NET, and to some extent C/C++/ObjC all do this.
4) I have argued that making it easy to share code isn't enough to give the language a "batteries included" feel: To get there, we'd have to change the whole language philosophy to the extent that we'd have a new language, complete with its own syntax, semantics, feel and culture.
Yet I think it's important to remember that, for some applications, Scheme's simplicity and smallness are really nice. Examples of this are education and embedded apps.
The people who currently use Scheme now probably use it because it actually fits what they are trying to do. Changing the language this much would change the target audience of the language so much that I can't see how Scheme could evolve into a batteries included language.
----
Racket matches what I have described above fairly well, but it has some design choices that I haven't (yet?) been able to come to terms with.
I am investigating the possibility to create my own Lisp based on these ideas, but I don't know yet if it would just hurt things by segmenting the Lisp world even further, or could help by contributing some new ideas and thoughts. I think that I at least know enough about Scheme and Lisp to be able to avoid repeating most historical mistakes though.
/Per