19 May 2006

Small, complete environments

If I were to design a programming language today, I wouldn't.

Instead, I would design a programming environment. The basic requirements would be something like this:

  • It's generally pleasant and productive. To me, this means the environment itself is small, simple, and fast.

  • It produces the kind of programs people like (featureful, unburdensome, fast enough, small enough, easy to use, and on time :)).

  • It interoperates. You can drop in external stuff (source code, binary libraries, editors, tools) and it'll work smoothly. And vice versa: you can drop your project into an existing environment that has lots of other stuff going on, and it'll work.

What would this environment look like? I'll know it when I see it. In the meantime, here are some thoughts. It would have:

  1. A language with these properties:

    1. I can compile it to a raw executable that doesn't require the end user to install a VM. The simplest deployment model is, end user drops a single executable file into a directory of his or her choosing. End of story. (Almost nobody attempts this these days, since it's hard to reconcile this with rich libraries, portability across hardware, and good high-level language features. But it can be done.)

    2. I can add a third-party library to my project just by dropping it into the appropriate place in the source tree. (The Java WAR deployment model gets this right.)

    3. It's easy to integrate with pieces written in other languages. (This is really hard to get right. Microsoft .NET interop comes closest, as far as I know.)

    4. Build dependencies are present in the source code. (I haven't thought much about this, but the build system needs it.)

    5. The ability to express basic metadata about a project in source code. If it's a program, as opposed to a shared library, the source code reflects that.

    6. ...And of course the various properties any good language should have, things like well-designed libraries, readable syntax, decent support for refactoring, stupid mistake checking, portability, similar behavior across operating systems and hardware architectures, debugability, and as few irritating features as possible. (Nobody has it all, but there are plenty of nice languages out there.)

  2. A build system with these properties:

    1. It ordinarily works without any makefiles. Dependencies are determined by looking at the source code. Things like linker options are determined by looking at the metadata, which is also in the source code.

    2. You can type something ridiculously simple, like "build foo", and it builds foo, including dependencies, relatively quickly.

    3. It can handle generated code.

  3. An installer system with these properties:

    1. Extremely basic, intentionally anemic compared to, say, MSI. Can't install e.g. registry keys. It only installs files; it's parameterizable. But it groks versions.

    2. You can type something ridiculously simple, like "build foo.msi", and it builds foo.msi. Creates an MSI file on Windows, an RPM on Linux, whatever.

    3. It's optional. You can always use the "simple deployment model" (see 1a.)

  4. A decent IDE and debugger that work well without project files. (Microsoft Visual C++ 2003 and later score high marks here.)

The language requirements alone are nowhere near being met, but of course you pick the language of your choice and work toward implementing the features that are missing.

Small, complete programming languages hold appeal for lots of people. It seems weird that I haven't seen a small, complete programming environment since vi+cc+make.

No comments: