
“Screw it, I'll make my own” – The story of a new programming language - chrismonsanto
http://breuleux.net/blog/my-own-language.html
======
lmm
> There is a bit of a catch-22 in language design where the more a language is
> used, the clearer it becomes which parts of it are problematic and should
> change, but the harder it gets to actually change them. To hone a language
> you must use it, but applications require that a language's features remain
> stable, robust, set in stone, and therefore as imperfect as they were at
> that moment. Furthermore, the more delays are suffered in fixing flaws or
> plugging holes, the more likely it gets that a dependency is fostered upon
> them. The options you do not explicitly and insistently leave open, tend to
> close and seal themselves before you know it.

This rings very true. I look at Ceylon and the features I'm most jealous of
are things that Scala would and should _just do_ , except for the need to
retain compatibility with 10 years of existing applications and libraries, so
instead they're enhancement proposals for the version after the version after
the next version, and in the meantime we get by with macros that more-or-less
cover the most important use cases. And Scala is relatively young as languages
go - its warts are nothing to those of, say, C++. Sometimes I wonder if
language design can only advance by new languages killing existing languages -
past a certain point it seems impossible to change a language in the ways that
it needs to be changed to become good.

~~~
akavel
A nice solution was used during development of the Go language: a tool for
_code rewriting_ (it was called "go fix"). It allowed the language authors to
quickly and easily transform large swaths of code in the standard library, and
also let everybody execute the same transformations in any third-party code.
Thus enabling rapid and extremely painless iterations. [I'm consciously
simplifying the story a bit to make it shorter and more concise, but I'm not
hurting the core message I believe.]

~~~
breuleux
I think that's a neat idea. I've thought about it, but I've never used Go
personally and I wasn't sure just how much it would help. I imagine it works
best for languages with good static properties/tools for code analysis.

~~~
lmm
I think the important cases are the ones that you can't fix by hand - the ones
where you're removing a dangerous idiom.

------
dochtman
Nice story. I have similar feelings about my own attempt, Runa
([https://github.com/djc/runa](https://github.com/djc/runa)), in particular
about just how large a language (ecosystem) has to be in order to be viable to
a few more people.

Still, just the journey is quite interesting. It makes you understand other
programming languages and their tradeoffs better, and I'm now much less afraid
of parsers and lexers and so on. :)

------
WalterBright
> it is still unsettling when you feel like you can't participate in
> discussions about programming languages without indulging into self-
> promotion

Ahem, cough, cough, er, ...

------
xjay
Curious. Are there examples of programming languages that allow spaces in
identifiers? Obviously, it would need to be designed for that.

I'm against the case-sensitive nature of some programming languages, and file
systems for that matter. While it makes sense in a computing context (faster),
you invent a new mode, just for the computer..

(Fortran was probably case-insensitive because upper-case letters were used
first, and when lower-case letters were introduced, care was taken to neatly
map them into the character set bit-wise, so one could simply clear the sixth
binary digit to turn a lower-case letter into its upper-case equivalent, then
continue the string comparison.)

Of course, with Unicode, you need a more complicated check, or you could just
ignore Unicode in the language itself for identifiers, yet allow it in
literals, data types, etc.

~~~
legulere
Case-sensitivity makes sense because it enforces uniformity of code. Case
insensitivity only matters when you want to write identifiers differently at
different locations. The only place where I see this could be useful is when
you use a library that uses a different convention.

The IMO better way to solve this is to set a convention for your programming
language and enforce it with the compiler (at least with warnings).

~~~
xjay
As you say, it's about conventions, but with a case-Sensitive system you are
more likely going to HAVE TO enforce naming conventions, because there's a
distinction now. Otherwise you'd write "MidiPort"/"MIDIPort"/"midiPort" or
what have you.

Keep in mind we wouldn't need to care about enforcing case in a style guide,
if case didn't matter, because there are no distinctions, and you'd be more
inclined to write it the natural way; no camelCase to overrule ambiguation in
writing "MIDI Port" as midiPort, or MidiPort, MIDIport, etc.

Case-sensitivity only creates unnecessary dissonance, and leads to clever uses
of that system, adding even more choice; and as we know from The Matrix, the
problem is choice. ;)

So if we keep it closer to how we would normally read and write words, I think
there would be less dissonance about that aspect of programming, or naming
files for that matter.

~~~
legulere
> Keep in mind we wouldn't need to care about enforcing case in a style guide,
> if case didn't matter, because there are no distinctions

You would still need it to get uniform code. Spaces vs. tabs also doesn't
matter but it's still in almost all style guides.

------
Learn2win
In Racket, you can use "-" and "?" in variable names and I love it.

~~~
legulere
x-y and x - y meaning different things seems like a great source of errors to
me

~~~
breuleux
It depends on a couple of factors. Personally I always write subtraction as "x
- y", so I never have any issues. Also, if undeclared variables are a compile-
time error, the compiler will (probably) complain loudly about "x-y". So you
can fix that quickly and easily, it's not too bad.

The one error that might be problematic depending on the language's semantics
is if you write something like "x.y-z" intending to subtract "z" from "x.y",
but in fact you are going to get the "y-z" property of "x". I must say that in
Earl Grey you'll unfortunately end up with "undefined" as the result of that
expression (saner languages would raise an exception on a missing property). I
have never had that issue in practice, but then again, I always space
subtraction.

~~~
Uncompetative
I don't have a problem with "x - y" and approve of hyphenated names if you
can't support spaces within names.

I had initially jumped to the conclusion that your language would use a
postfix notation and be more influenced by Forth than LISP. This is because I
assumed it's name alluded to the way that Captain Jean Luc Picard would
program his replicator.

------
vorg
> I chose to compile Earl Grey to JavaScript

Some programming languages generate code much deeper down the abstraction
stack, e.g. Haskell generating machine code, whereas others generate code to a
much shallower depth, e.g. most languages generating JavaScript. A language
generating lisp code from some syntax could even be shunting code _up_ the
abstraction stack.

How deep does the generated code need to be down the stack for some syntax to
earn the name "programming language"?

~~~
z92
If you look at the code, and can't identify it as language X, then it probably
deserves a new name.

~~~
MatthewMcDonald
This sounds pretty similar to the definition of a species.

If two organisms of appropriate gender can't reproduce with each other, then
they probably aren't the same species.

If code from two samples can't be interspersed, then it's probably not the
same language.

~~~
labster
Under that definition, Perl and Python have finally merged, given Perl 6's
Inline::Python. Peace at last!

I'd probably go with a definition more like "mutual intelligibility" like for
natural languages, but that doesn't seem right either. Sometimes I have to
turn on the subtitles for British TV.

~~~
Tiksi
Yeah, under that definition everything that supports FFI has merged into a
massive unholy mess with C. I guess if it can't be "natively"
compiled/interpreted as the same language without inlining or including, I'd
say it's a different language.

------
mikerichards
None of the languages I typically use allow hyphens in identifiers, but I find
that kebab-case to be the easiest on the eyes.

~~~
DrScump
heck, even COBOL '75 (maybe even '68) allowed hyphens in identifiers.

------
bhrgunatha
It's not surprising that changing a language would be difficult. It does,
after all, include a software component, and pretty much all large software
projects suffer the same. It can be easy to change minor technical details,
but a deep, far-reaching design decision is very often fixed in place. Even
with a good test-suite, that kind of change is rarely undertaken. At least in
my experience.

I suspect we've all worked on software that you would desperately love to
change something fundamental in the design but no matter how painful leaving
it alone is, it is preferable to live with the pain than to tear it all down.

I've known a few writers for example that say they wish they could change
their characters, but it's too late. I wonder if that's analogous.

------
itscharlieb
Very interesting account of your experience. I've been toying with the my
ideal programming language for some time and am interested. You bring up a
good point about people favoring the styles of their most recently used
language. For that reason I worry that any language I'd create would merely be
a combination of languages I've used previously and not something original.
I'm excited to take a look at your work.

------
mcnamaratw
Well that's the problem that needs solving all right.

Yet again today I have a Python project that is already (at 200 lines!)
obviously massively compressible if I had macros.

Maybe I can get there by returning functions & building up the functionality
that way, but it feels like I'm trying to scratch that spot in the middle of
my back, where I can't quite reach.

~~~
mcnamaratw
Rapid prototyping is this alternating process of building stuff up and then
boiling it down. The building up is easier in Python, but the boiling down is
easier in Lisp.

Sure would be nice to have both on tap.

------
decafbad
Unfortunately, I can't say this is unexpected:
[http://breuleux.github.io/earl-grey/repl/](http://breuleux.github.io/earl-
grey/repl/)

~~~
mbil
Are you looking for [http://breuleux.github.io/earl-
grey/repl.html](http://breuleux.github.io/earl-grey/repl.html) ?

------
cle
I'm curious, would it have been easier to change design decisions if you
hadn't bootstrapped it?

~~~
breuleux
Probably a little, but I don't think it would have made a big difference. It
takes a certain amount of code before it becomes clear that the design has a
flaw, and it's going to be the same amount of effort to adapt it, whether that
code is in the compiler or elsewhere. A bootstrapped compiler just requires a
bit more boilerplate in the transition.

