Andrej Bauer maintains a “programming languages zoo” of languages like this: http://plzoo.andrej.com
> The Programming Languages Zoo is a collection of miniature programming languages which demonstrates various concepts and techniques used in programming language design and implementation. It is a good starting point for those who would like to implement their own programming language, or just learn how it is done.
The PL Zoo is a great resource, but that's not exactly what the blog post is advocating for. PL Zoo is meant for students studying the implementation and design of programming languages.
What the blog author is describing, on the other hand, is a small language for teaching the use and application of certain programming techniques.
It's a very promising idea, one that I may try to bring to life for something tricky, like monads or maybe Rust's ownership system.
I'm very fond of small, specific and simple languages without sacrificing inherent complexity. For me, that includes IP adresses, UUIDs, timestamps, URIs, println formatting, et cetera.
It's a shame though that we don't represent them as such in the current state of affairs but choose to implement them separately in every language. Can we have a fast, universal, feature complete parser generator that is natively supported in our mainstream languages?
For instance, think adding an ANTLR grammar into a .NET project and then be able to just do `var ipAddress = ip"127.0.0.1";` and get full editor support with that.
By the way, there are these things JetBrains MPS and Eclipse Xtext, which are metaprogramming environments, allowing you to define DSLs and actually get IDE support for features you add. Rather heavyweight compared to just grammar, or to Lisp macros, but apparently you get more in return, seeing as grammar and macros don't teach your editors about the semantics of the new entities.
I’d love if it were ANTLR. I think it already has much in the way of support for multiple languages (I’m still working on a Dart port, and I encountered someone who has ported it to D).
At the end of the day, I guess it might just boil down to surrounding tooling.
Scheme sounds like it's pretty close to what the author is describing. It's a very small and simple core that you can build on, and even create mini languages on top of. The macro system allows you to pretty much express any idea without having to change the core language. As a bonus the runtime is interactive allowing you to explore ideas and see the results immediately.
Lua always seemed somehow "right" to me (despite its numerous flaws, including one-based indexing), just like s-expressions somehow are just the right format for many kinds of data. You look at it and "just know". You understand it, the computer understands it effortlessly, and if you remove any element it stops making sense.
One thing both of these have in common is that they are slightly different from mainstream ideas (e.g. C, Python, JSON, XML). Not so different it becomes alien, but different enough to make you approach it with a different state of mind.
I have spent limited time with Lua - mostly just fiddling with pico-8. My experience has been that it's fairly easy to get used to, but occasionally annoying. For example, it doesn't interact nicely with modular arithmetic the way 0-based indexing does.
If you store a 2d array in a 1d one, it's natural to try/use x+200*y or such. With 0-based indexing it just works. With 1-based indexing, it's more complicated. If you do any modulus-based array access, 1-based indexing makes it more complicated. Basically, a world with 0-based indexing results in simpler math than a world with 1-based indexing, making it the better choice.
Because Lua is often used as an extension language of C++ which has 0-based indexing: it's really painful for programmers to switch from one indexing to another.
I tend to consider one-based indexing Lua's only flaw, in fact. In particular for the LuaJIT dialect, since I'm less satisfied with the new paradigm for environments.
I worked through the CTM book[0] a while ago and I think this was the general approach taken using the Oz programming language. Each programming paradigm was split into a kernel language that would demonstrate specific programming features. I'd highly recommend trying it out.
I really like the diagram they use to split up the languages + paradigms[1]
But instead it's almost the opposite. Bentley's original use of the little language term was about optimizing the languages for specific tasks. Not about building them around explaining a single concept
> XL features programmer-reconfigurable syntax and semantics. Compiler plug-ins can be used to add new features to the language. A base set of plug-ins implements a relatively standard imperative language. Programmers can write their own plug-ins to implement application-specific notations, which can then be used as readily as built-in language features.
> XL is defined at four different levels: XL0 defines how an input text is transformed into a parse tree. XL1 defines a base language with features comparable to C++. XL2 defines the standard library, which includes common data types and operators. XLR defines a dynamic runtime for XL based on XL0.
> XL has no primitive types nor keywords. All useful operators and data types, like integers or addition, are defined in the standard library (XL2). XL1 is portable between different execution environments. There is no such guarantee for XL2: if a particular CPU does not implement floating-point multiplication, the corresponding operator definition may be missing from the standard library, and using a floating-point multiply may result in a compile-time error.
Frankly, I'm not sure if this is much different from implementing a language with a parser generator, but apparently the ‘semantics plugins’ are written in a version of the language itself, instead of something like the eternal C[++].
Hmm. I wanted to offer a course based on Idris this time around, and found that I would have to cover a lot of Haskell to get to the main parts of Idris. As I was about to teach this semester, somebody pointed out the new book "The Little Typer", along the lines of "The Little Lisper" and "The Little Schemer". Looks like Pie is a toy language in "The Little Typer". Pie looks promising - I'll dig in and spend a weekend on it :)
What an interesting idea. Sort of, isolate out a graph of concepts from a language, and pull it out into its own language.
I do wonder why the author believes you need a separate language for this. Why not a DSL, or even a regular library in your popular language of choice (Scala, Haskell, JS, etc.).
Is that a reasonable approach too? Or is some part of the toy language approach lost without perfect domain-specific syntax, or because of parts of your host language leaking in?
As a developer who loves Ruby, the article (or possibly someone's comment above about making a mini-language around monads) reminded me of an excellent talk I heard lately that implemented a DSL/object model for monads in Ruby, and refactored some moderately sticky problems to use them. Still didn't convince me that they were the One Holy Way to do my next project, but got it a whole lot closer to a tool in my toolbox.
I think the reasoning behind implementing these small languages on their own would be twofold: one, unless you're very careful, you end up with lots of context and approach and style inherited from your host language. You can write non-rubyish Ruby, but only to a degree...and anyone using it who's moderately familiar with the language is likely to break your artificial constraints. And for many of the programming concepts perhaps best demonstrated in isolation, they're divergent enough to be hard to implement well in a 'traditional' host language.
Libraries sometimes cannot do what new languages can, or can only mimic it in a very very cumbersome way, I think this is why the author advocates for separate languages, rather than libraries.
The other thing that a separate language allows is for the author to remove every distraction that a host lanauge might have, and really streamline and emphasise the concepts they’re trying to show, and those concepts only.
Brainfuck certainly is small. I think it might also be an example of what I had in mind. Brainfuck could be a little language for the idea of a Turing machine. Perhaps by writing Brainfuck programs, one better understands the mechanics of the Turing machine.
When I first read the title, I thought the article was about awk. After all the definitive book about awk has a whole chapter on little languages. In that context, little languages means languages with specialized applications, and not general-purpose.
> The Programming Languages Zoo is a collection of miniature programming languages which demonstrates various concepts and techniques used in programming language design and implementation. It is a good starting point for those who would like to implement their own programming language, or just learn how it is done.