Please see the disclaimer.

Assumed Audience: Programmers.

Discuss on Hacker News and Reddit.

Epistemic Status: Confident-ish.

Introduction

So I saw “A Decade of Developing a Programming Language” and read it.

Yeah, I changed the title capitalization. Deal with it.

Then I saw “A Response to ‘A Decade of Developing a Programming Language’” and realized that such posts are hype right now.

So I’ll hop on that train.

History

In late 2012, I was getting fed up with C++ in college, so I decided to develop my own language.

Eleven years later, it is still under wraps. Sigh…

But I’m close!

So yeah, I’ve also spent a decade developing a language.

And I did write a comment on Hacker News for the first, but it is better as a blog post.

Items from the Original

First, let’s critique items from the original.

Avoid Gradual Typing

Absolutely.

I had gradual typing and abandoned it. Gradual typing is not as good as simple Go-like inference, and that simple inference is easy to implement and takes care of 95% of the “problem.”

However, you also need one or more dynamic typing escape hatches. When I implemented a config file format by tweaking JSON, I had to implement dynamic typing in C.

Avoid Self-Hosting Your Compiler

It depends.

You probably should avoid it by default, unless your language is just so much better than the original. Rust is an example of this (compared to C++).

I’m writing in C, and I want memory safety, so bootstrapping makes sense for me.

Avoid Writing Your Own Code Generator, Linker, etc.

This is excellent advice! Use the standard tools. You’ll get free stuff, like excellent debuggers and such.

Of course, me being me, I’m breaking it. :) I am trying a different distribution method, where you distribute an LLVM-like IR, and the end machine then generates the machine code on first run. In that case, there’s no linker necessary, but I do have to write my own code generator. Fun.

So the original post is right, but so is the response.

Avoid Bike Shedding About Syntax

Yes, absolutely.

However! The response post is also right.

Syntax is the user interface of a programming language.

The best treatment of UI is to have a bevevolent dictator (BDFL) with taste and with good listening skills make decisions by fiat.

Both of those traits are important.

First, they must have good taste or they can’t make any design good.

Second, they must listen because users are more important than art. If the users struggle with the UI, then the BDFL should change the UI to meet the users where they are at.

Third, they need to make decisions by fiat because bike shedding can be endless and stifling.

Do this right, and your UI’s will be consistent (because one good designer controls them) but user-friendly.

Programming language syntax should operate the same way: have a BDFL with those traits that has all power.

Yes, they should listen, so some bike shedding will happen. And should happen.

And then, at some point, the BDFL should decide that he’s listened enough and make a decision.

For my part, I bikeshedded a lot, but the syntax still changed after that because I didn’t listen.

Cross-Platform Support Is a Challenge

Yes, in more ways than one.

First, you have to somehow generate code for all of the platforms, then you have to make sure your library works on all of the platforms too.

However, I agree more with the response that doing so upfront does improve the design.

I have a good API for multiplexing items (a replacement for async stuff, really), and it arose out of studying the Windows and POSIX API’s and figuring out something that would work on both.

Compiler Books Aren’t Worth the Money

Yes, but please do read Crafting Interpreters.

Anyway, getting a simple parser and bytecode generator (or LLVM codegen) is the simple part of making a language. Then you need to make it robust, and no one talks about that.

Maybe I should write a blogpost about that once my language stabilizes.

Growing a Language Is Hard

Yes, absolutely. He mentioned two ways it needs to grow: libraries and users.

You can design a language to be easy to grow via libraries. See “Growing a Language” by Guy Steele.

I went the extra mile with this, and user code can add its own keywords and lexing code. So growing my language is “easy.”

That’s not to say that getting here was easy; it was excruciating because the design to do so took me years of learning to figure out and implement.

This is the biggest reason my language is not available yet.

But growing the userbase? That’s hard. You need to have a plan, and the best plan is to solve a massive pain point, or multiple. I’m targeting multiple.

First, I’m targeting shell; my language can shell out as easily as shells, or even more easily, but it’s a proper language with strong static type checking. If there are people who want that instead of bash, they’ll get it. And there’s a lot of bash people might want to replace.

Second, I’m targeting build systems. My language is so easy to grow, I’ve implemented a build system DSL, and then I put a build system on top.

Shell and build systems are both things people hate but use a lot. These are good targets.

Anyway, if I were to critique the original (and response), it’s that they were both right that growing a userbase is hard with no shortcuts, but it is possible to make growing a language easy.

The Best Test Suite Is a Real Application

I agree with the response here: the best test suite is a real test suite and a bunch of applications.

My language’s own build scripts are the first real program written in it. I’m also going to replace every shell script on my machine with my language, and most of them will make it into the formal test suite.

And this brings up another point: a “real” application doesn’t have to be big; it just has to do something useful.

The smaller the applications, the better, if they are useful.

Don’t Prioritize Performance over Functionality

Both the original and the response are correct.

The original is correct in that you shouldn’t prioritize performance of programs written in your language.

But the response is correct that making a slow compiler fast is difficult.

My personal advice: implement an interpreter first; you won’t depend on LLVM (shudder), and you can easily add more functionality. And do think about the performance of your compiler upfront, but not too hard.

Building a Language Takes Time

I’ve taken 11 years, and there’s no release yet. Yes, this is true.

cries in the corner

Items from the Response

The response also has extra items.

And actually…I have no critiques; they are all correct in my opinion!

Of course, that doesn’t mean I will have the same audience and goals as the author, so I may not care about the same details, but the items are correct.

And My Own Advice

Yes, I also have my own advice.

There’s just one item: get your programming language in front of users as fast as possible. You need feedback from users.

That’s right; my advice is to not do what I have done.

Conclusion

Even though I’m making a competitor, I wish both of these authors good luck!

And if you want to make a language, but would also like feedback, feel free to contact me; I’d love to have programming language pen pals.