Six Programming Languages I'd Like to See
A few weird ideas for programming languages I came up with that it'd be "really" "cool" if someone made (wink)
I got 1,000 words into "what, exactly, is software complexity" before remembering that this is supposed to be less effort than the blog. So instead I'm going to list some ideas I had for programming languages. I think all of these are technically doable, so it's more a "nobody else wants this badly enough" thing. Also caveat these might all already exist; I just know the languages I know!
A serious take on a contract-based language
Contracts are predicates on the code, usually attached to functions and treated like assertion statements. The canonical example is withdrawing from a bank account:
method withdraw(amnt: int)
requires amnt <= self.balance
ensures self.balance >= 0
{
self.balance -= amnt;
}
The standard bearer for contracts used to be Eiffel, which people stopped caring about in the mid-90's. Nowadays the only mainstream language to get serious about contracts is Clojure. Most languages have a contracts library, which mean the language doesn't have affordances to use contracts well. Take the predicate is_sorted(l)
:
forall i, j in 0..len(l):
i < j => l[i] <= l[j]
Most languages have all
and any
functions but they don't allow quantifying over multiple elements, and basically no languages have an implication operator (because it's near-useless for programming). I want to see a language integrate contracts into the syntax well. At the very least, dedicated syntax for preconditions, postconditions, and inline assertions. Also the ability to label and reuse predicates, and "orthogonal" contracts (postcondition A is only checked if precondition A' was true). Stuff like that.
And tool integration! One of the coolest things Eiffel sorta did was use contracts to infer tests. If you have contracts, you can use a fuzzer to get integration tests for free. Clojure's Spec does something kinda similar, I think.
A language with semantic relations
Inheritance and interfaces are relationships between classes. But what about relationships between functions? Take the following two functions:
def window1(l, n):
if len(l) < n:
return []
out = []
for intervals in range(len(l) - (n - 1)):
window = l[intervals:(intervals+n)]
out.append(prod(window))
return out
def window2(l, n):
if len(l) < n:
return []
out = []
val = prod(l[0:n])
for i in range(n, len(l)):
out.append(val)
val *= (l[i] / l[i-n])
out.append(val)
return out
These take the rolling products of a list l
, so window1([1, 2, 3, 4, 5], 2) == [2, 6, 12, 20]
. window2
is an optimized version of window1
and should have the same outputs for every input. I should be able to encode that in the language, and have the tooling generate checks showing the two are the same, and also run benchmarks testing if the optimized version actually is faster.
I can think of other relationships between stuff. A'
is an instrumented version of class A. g
is an inverse of f such that f(g(x)) == x
. P'
is an ontological subtype of P
but not a Liskov subtype. UML had things like "traces" and "refines" and "generalizes", there could be things there too. The point is I want to be able to express semantic relationships at the language level in a way that the program can leverage.
Would go nicely with contracts, too, as you could have relationships that preserve/transform/expand contracts. The usual one is that "inherited methods have less restrictive preconditions and more restrictive postconditions." What else could we do?
Everything is a Graph
- Lisp: everything's a list
- Bash: everything's a string
- Smalltalk: everything's an object
- APL: everything's an array
Graphs are really common data structures but there hasn't yet been an "everything's a graph" language. In fact, almost no languages even have graphs in their standard library! I think that's because graphs are an extremely complicated data structure. You know how annoying linked lists are? Graphs are 1000x worse.
Nonetheless, I wanna see someone try! Give me a language where key-value maps are emulated with directed bipartite graphs.
A better calculator language
I have a love/hate relationship with J. There's so much about the language that drives me batty, but I stick with it because it's the only language that gets remotely close to being a good desktop calculator. When doing quick computations for work projects, I care about two things. The first is the number of keystrokes. Here's how to get the product of factorials of a list in python:1
import math
prod([math.factorial(x) for x in l])
No! Bad python! In J it's just */ ! l
, quite literally an order of magnitude fewer keystrokes. When I'm trying out lots of different equations, keystokes matter a lot. J is very much "everything is an array", though, which limits its potential as a calculator. You can't work with strings, json, sets, or hash maps very well, date manipulation is terrible, you can barely do combinatorics problems, etc etc etc. I want a language that's terse for everything. Maybe you could namespace operators.
The other feature I want for a calculator is built-in reactive programming, like an unholy combination of a textual programming language and Excel. I want to be able to do something sorta like this:
input = 1
out1: input + 1
#out1 is now 2
input = 4
#out1 is now 5
out2: out1.replace(+, -)
#out2 is now 3
# let's pull an APL
input = 4 2
#out1 is 5 3
#out2 is 3 1
This would be absolutely hell to learn at first, but I've learned plenty of weird languages that promised a lot of power. Interactive computation is a common enough activity for me that I'd put a lot of time into learning something like this.
...Maybe I should just get real good with Excel.
A really dynamically-typed language
(Someone's gonna tell me this is 100% smalltalk for sure)
Static types are great! There's lots of cool stuff being done with static typed languages right now. Not so much with dynamic types, though. Most of the research and interest is in adding gradual typing to dynamic languages. I think there's a lot of interesting experiments we can do with dynamic types. I mean, you can generate new types at runtime! Combine that with contracts and we can attach constraints to variables, like this:
type Interval(x, y) <: Int {
x <= self <= y;
}
var i: Interval(1, 10) = 3
i += 7 #ok
i += 1 #error!
How cool is that?! Now I don't know how useful this would be (maybe it's just syntactic sugar over classes), but it's still interesting to me. I want to see what people do with it.
I also like the idea of modifying function definitions at runtime. I have these visions/nightmares of programs that take other programs as input and then let me run experiments on how the program behaves under certain changes to the source code. I want to write metaprograms dammit
A language designed around having first-class GUI support
I miss VB6.
Update for the Internets
This was sent as part of an email newsletter; you can subscribe here. Common topics are software history, formal methods, the theory of software engineering, and silly research dives. Updates are usually 1x a week. I also have a website where I put my polished writing (the newsletter is more for off-the-cuff stuff).
-
Given a set of independently acting processes, each with a certain number of steps to complete, the total number of interleavings is the factorial of their sum divided by the product of their factorials. ↩
If you're reading this on the web, you can subscribe here. Updates are once a week. My main website is here.
My new book, Logic for Programmers, is now in early access! Get it here.