Most of my concerns last time were about syntax, which might strike you
as superficial. So before I get any further into syntax, let me recognize
the importance of a clean underlying language model.
There’s a lot of value to a pure language model. A clear low-level imperative
model enables languages like C and FORTRAN to be translated into efficient
machine code, making them good system and scientific computation languages,
respectively. A clear object model enables packaging vast quantities of code
into rich libraries for reuse, making Smalltalk and Java good languages for
experimentation and rapid development, respectively. Pure functional
orientation makes correctness proofs and parallel transforms easy,making
Haskell and Objective Caml darlings of the language design movement.
And pure logical design makes it easy to specify what you want to do,
rather than how, and that makes languages like Prolog and Mercury
popular in certain artificial intelligence circles.
But, in my mind, pragmatics ultimately trumps all. There’s a reason
C++ was built on top of C, a reason Java has bare-metal types,
a reason Lisp has (progn) and (loop), a reason Prolog has cut.
Programmers have to be able to use the language to solve useful
problems, or the language is a toy.
Now, this isn’t intended to denigrate language designers who have
taken one element of the paradigm to the max while at the same
time focusing on pragmatic concerns like execution efficiency,
expressiveness, and ease of use. But, to be frank, most language
designers who do leap onto the fundamentalist imperative / functional
/ logic / object-oriented bandwagon don’t even bother to address
such concerns — because they are fundamentally incompatible
with the programmatic consequences of the delusions and lies that
their religious views force them to adopt.
Which brings us back to syntax. Time and time again, I’ve heard
language designers say “I don’t like such-and-so features, so I’m not
going to put them into my language.” Balderdash. That’s not a valid
reason to do something in a programming language that
other programmers are supposed to use; it’s just childish
foolishness. Oh, you don’t wan’t multi-line comments, nested comments,
or function types in your language? Too bad. Grow the fuck up.
What’s a good reason to do something in a language? It’s about the
consequences. Multiple inheritance was omitted from Java because
it caused problems in the semantics and construction of C++ which
made it difficult for programmers to construct correct programs. Similarly,
at the syntactic level Java uses a separate assignment and equality
symbol and removes the equivalence of integers and booleans
to prevent a class of common programmer errors.
On the flip side, having expressive syntactic notations like the slice syntax,
list comprehensions and hash table constructors makes it possible for
programmers to write programs that accomplish a great deal concisely.
Lisp, my favorite language, makes it hard to write concise programs
because of its over-reliance on parentheses as its single list / grouping
/ code block / function definition / macro / what have you construct.
I understand completely why ultimately a real Lisp dialect has to be
reducible to something like an s-expression comprising functions and
data. But programmers should not have to write
all of those s-expressions if there’s a more concise way to represent
it, nor should they have to rely on squinting at flashing parens and
reformatting indentation in their syntax-aware graphical editor just
to know whether or not they’ve written the right number of enclosing
parens on whatever godawful cond-lambda-reduce-map construct
they had to construct to get their job done.
So my plan moving forward: collect examples of syntax I like, and
show how they might reduce to s-expressions in a variant of Lisp.
Ultimately I want to push this back to collecting examples of semantic
features I like, and derive a clean model that would be both expressive,
interpretable, compilable and efficient.