The Problem With Today's Programming Languages

The problem with today's programming languages is that they are too general.

For example, Guido van Rossum's[1] language was designed to solve Guido van Rossum's problems, not yours.

Rhetorical question: if I were to write software to control a robot, would I use a language built for designing banking apps?  Only if I didn't have the freedom to choose.

SCLs not DSLs not PLs

Given that we can now create SCLs — PLs and DSLs — in one day, we can rearrange our workflow.

  1. Analyze the problem-at-hand.
  2. Create a notation to describe the problem-at-hand
  3. Create a solution to the problem-at-hand using the same notation
  4. Build an SCL for a single use — only for this single problem, without needing to generalize
  5. Build, test, release the solution.

The tools we need are:

The base language should:[2]

Lisp — Common Lisp — has many of the above features.  In particular, code and data are stored as lists.  Lists can be treated as relations[7].  Many of the high-falutin' languages were originally built in Lisp.  Lisp is a good toolbox[8] for automators[9].

Layered Software Design

Eliding Error Handling

People often omit error handling because it clogs up the readability of the original Architecture.

Error handling is a bag on the side of most programs.  

That is because most languages don't allow one to design software in a layered manner.  

[If you think that libraries and github give you layered software, think again.  Ask yourself, for example, how to extract and examine the error layers — only — in this kind of software.  Ask yourself how to extract and examine the Happy Path (Architecture w/o error handling nasties) — only — in this kind of software.  If you think that theorem provers help you build better software, try building a robot controller or a music sequencer (see if knowing the nitty-gritties of Natural Numbers is useful in such domains —programming language design is about how to hide and elide the details when solving a particular problem[10]).  Etc.]

Error-handling — non-linear control flow — is difficult to express in a text-only language.  It has been done, but the results  aren't natural.  Other forms of non-linear control flow have pushed the text-only paradigm beyond its natural limitations (e.g. Javascript callbacks, multitasking, etc.).  One of the oldest notations for non-linear and parallel control flow is music notation.  Humans understand and express parallelism (e.g. music chords, cooking recipes) — only programmers find this concept hard to express.

Theory Is Not PL Design

Programming language theory defines the Universe of programming languages.

This is not the same as designing a useful programming language.

A useful programming language:

Architect's Responsilibity

It is the Architect's responsibility to make a design clear and understandable to other readers.

RY vs. DRY

The goals of Architecture are not the same as the goals of Maintenance Engineering, Test Engineering, etc.

In particular, the Architect must be able to Copy/Paste designs — this is call RY (Repeat Yourself).

RY, though, is anathema to Maintenance Engineering.  From a maintenance perspective, DRY (Don't Repeat Yourself) is desirable.

With current techniques, DRY is generally not automated and programmers are expected to expend brain-power to achieve DRY, instead of using RY.

[1] I'm not picking on Guido, just using his name as a concrete example of a more general problem.

[2] I can't think of any language, except assembler, that has all of these features, yet, one can write SCLs that emit other languages (For example, I've successfully emitted Lisp and Javascript)

[3] If static typing is important to the solution, build static typing into the SCL

[4] 1st class functions are even possible in Assembler and C.  Some so-called HLLs snip this avenue off.  [Note that 1st class functions are GOTOs on steroids].

[5] Declaration-before-use is a  high-level-language feature that helps programmers spot typos.  This is an anti-feature for base languages used in automation.  Programmer-oriented features hinder automation.

[6] Note that I don't champion the idea of using C and Lisp macros.  PEGs provide a much richer environment for rewriting code.  Lisp macros were an attempt to build runtime syntax modification.  One could, simply build-in a PEG parser for this same purpose.  I have successfully used ESRAP (a PEG parser) in CL for a project (compiling diagrams to code).

[7] Lisp lists can represent a larger number of possibilities than just triples.  Avoid using this ability.


[9] I argue that Lisp should be used for the basis of projectional editors.

[10] Especially when you can't expunge time from the equation.