Quest For The Perfect Language

Most hackers and programmers-at-the-heart spend some time of their larval stage, and even further, looking for the HolyGrail of computer languages, the Perfect Language.


Incidentally, this is not unique to programming. When I was on the verge of learning to drive, I asked my dad, "what's the best car?" I was on a QuestForThePerfectCar?.

Not surprisingly, his answer was, "for what?"

Recently, my teenaged son, on the verge of learning to drive, asked me, "Dad, which car is the best?"

And, not surprisingly, my answer to him was, "for what?"

Hell, over the years, I've asked variations on this question in every kind of situation I can think of, only to have the PersonOfExperience? say to me (in response to "which hammer/drill/saw/knife do you recommend?" or "can you recommend a good camera?" or "is there a gun you personally prefer?" or "what kind of hat should I get?") ... "what do you want from it?" I have (foolishly) found myself many times in some kind of QuestForThePerfectTool?.

If the problem domain is PD, then the perfect tool will be (gasp) PD.tool -- and of course PD might have many facets -- so that PD.apply and PD.remove and PD.adjust and PD.copy may all require slightly different tools.

For example, nail.apply and nail.remove can both be done with nail.hammer, but there will be times when the right tool for nail.apply is nail.gun and nail.remove needs nail.prybar -- and yes, I can make this same case for programming.

Keep a tool box. Learn to recognize the domain. Reach for the right tool.

PickTheRightToolForTheJob.

But languages aren't tools! IDEs are tools. Languages are material. See FallacyOfTheRightTool.


Master, what is the perfect programming language?

Why should one solve a perfect problem?


 To dream the impossible dream,
 To fight the unbeatable foe,
 To bear with unbearable sorrow,
 To run where the brave dare not go.
 To right the unrightable wrong,
 To love pure and chaste from afar,
 To try when your arms are too weary
 To reach the unreachable star.

This is my quest, to follow that star, No matter how hopeless, no matter how far, To Fight for the right, without question or pause, To be willing to march into APL for a heavenly cause; And I know, if I'll only be true to this glorious quest, That my heart will lie peaceful and calm When I'm laid to my rest.

And the world will be better for this, That one man, scorned and covered with scars, Still strove with his last ounce of courage To reach the un-reach-a-ble star.

(ThreeStarProgrammer?)


The pain of imperfect languages should diminish logarithmically over time. Your suboptimal language doesn't have some super-duper built-in function that the perfect language does? Then ThreeStrikesAndYouRefactor it.

It's much harder if your suboptimal language lacks some super-duper built-in capability for abstraction. It's awful tough to emulate functions in a language with only GoTo. Try doing PolyMorphism or MultipleDispatch in CeeLanguage (it can be done, but it makes you appreciate how much the compiler handles for you). And most mainstream languages are still lacking advanced features like LispMacros, MetaClasses, and AspectOrientedProgramming. Of course, you can implement them in any TuringComplete language, but then you start running into GreenspunsTenthRuleOfProgramming.


The PerfectLanguage should be both object and aspect oriented (and evolve to include new "orientations" - Perfection in the sense that it embodies latest research in computer language theory as well as simple syntax). It should nonetheless be capable of expressing simple operations simply out of the box without a string of dots (or download as the case may be) i.e. print("hello world") instead of system.println("hello world") or wshscript.echo("hello world"). For more complex expressions dots are ok. It should be easy to represent mathematical objects (StephenWolfram once said in the 21st century there would probably be a language called "M" that would embody symbolic computation like his Mathematica see MathematicaLanguage) i.e. Vector Int v = (1,2,3) or <1,2,3> or [1,2,3] it would have to be decided which is more accepted in mathematics, Matrix Int m = ((1,2,3),(4,5,6)) etc. Probably should be C++ like since that is now standard although what do curly brackets mean? In C/C++/Java etc it is ClassDefn? {attributes method1(params){...} method2(params){...}} since they contain an ordered sequence of statements isn't that a vector? We want to keep "{}" for sets to retain their mathematical meaning. So perhaps the syntax would be ClassDefn?(attributes method1(params)=(...) etc). Also separated with comma instead of SemiColon? Should be capable of doing symbolic procession like Prolog but instead of sort([a,b,c],X) it would be Vector Symbolic x = sort((a,b,c)).

It should be scriptable but also compilable to executable and run on any operating system.

It should be possible to type in variables without types (like vb) but with a utility to generate program2 from program1 with the types for checking ie x = (1,2,3) would become Vector Int x = (1,2,3). Should have an eval() function like JavaScript to interpret strings as a program. It should be modular and add functionality using packages similar to Java class files or windows dlls so simple programs don't have to be bloated but complex programs can add capability as needed from existing components. It should be easy to code with a text editor and compile from command line but there should also be fast small ide to draw gui screens and drag and create class diagrams to generate code. Ideally should be able to provide the ide as an example M (if that is what we call it) program including source. Drag and drop should be more like TheIncredibleMachine than RationalRose.

Of course it should be completely OpenSource.



DaveVoorhis's PerfectLanguage:

Well, if you're willing to accept FakeCussWords, consider using frel (finite relation).


This language pretty much exists. It is called Scheme. See http://www.drscheme.org

Scheme (a derivative of Lisp) has awkward syntax. In the PerfectLanguage a=1+2 should be written as that not (let a (+ 1 2)). Syntax in a more perfect language is as important as semantics. I agree Scheme has it's own aesthetic but as a daily working language for fun, study and profit it isn't the perfect language or more people would be using it than C++ ,Perl, VB or Java.

And how is a=1+2 natural? To be fair, it's really (a = (1 + 2)). At which point one notices that defining new operators such as = and + is going to get tricky, unless we limit ourselves to functions with two and only two parameters. And if we do, we still have to maintain a complete ordering of all functions, to handle order of operations.

Scheme has a consistent syntax. It is awkward in the same way a proper relational query language is awkward: if the concept being described is awkward, the description will be awkward. However, if there is a abstraction which contain that awkwardness, then the description can take advantage of it.

(1+2) is natural because that's the notation we use in mathematics. There must be several billion people alive today who are familiar with that notation. It has become cross-cultural, cross-language, and has thus far withstood the test of history (the use of Arabic numerals, too, has become near-universal, more and more displacing numerals of native scripts like Chinese etc). There's nothing wrong with Lisp syntax, but you have to understand that it is the one that is doing something nonstandard, not the Algol family languages.

[Horse breeder claims automobiles "awkward"; asks "where's the reigns? The whole world knows that you steer things with reigns, it's withstood the test of history and is cross-cultural etc.". Satire aside, the use of a=b+x isn't even all that old as notations go and there's nothing natural about order of precedence rules which PN and RPN eliminate completely.]

It's true that the assignment doesn't even occur in most parts of mathematics, so if you want to claim that '(setq a 1+2+3)' or '(let* ((a 1+2+3)))' is better than 'a = 1+2+3", then you're perhaps on stronger ground, but that's not usually what Lispers have in mind.

The common argument that there's a problem assigning precedence to new numerical operators doesn't hold a lot of water; you could forbid new operators, as does e.g. Java, you could easily assign arbitrary precedences to operators...I forget which modern language does that, but look at yacc, it's no big deal. Or you could make new operators non-associative. It doesn't matter much, because the argument is about the intuitiveness of the old arithmetic operator conventions.

Lastly, I personally have no problem using Lisp syntax for arithmetic; one can get used to anything pretty quickly - although it's a nuisance when translating from a math paper (which of course is always infix). But the only big argument in favor of Lisp syntax, for arithmetic or anything else, is its simplicity and uniformity and ease of writing new parsers so that it's trivially machine readable for things other than the interpreter/compiler. So Lispers tend to get used to prefix notation. That's not the same as saying that it is inherently superior or more intuitive.

Infix, prefix, postfix...from 20,000 feet it doesn't matter. Or it shouldn't; yet notation is the number one reason people avoid Lisp (I don't regard Dylan nor cgol as proving any points one way or another) -- DougMerritt

I only program at 1 foot. The difference is more visible down here.

- I think you may need a bigger monitor. It's generally considered better for the eyes to be at least two feet from the screen :-) -- BillWeston


The perfect language (for me) is one that maps to how *I* think, not how you think.

So let's hear how you think and what your vision of the PerfectLanguage would be. The opinions on the page are not necessarily right or wrong, just opinions.

That was my point. People just think vastly different from each other. Debates over language features will never end because of this.

However if we express them there might become evident some commonality of thought to make better languages and map more of how people think to a formalism. C++ does represent how a lot of people think (or they have learned the think that way) as does Java, VB, Scheme etc. - they all have their advocates. But are there improvements that would allow people to find programming easier/more fun/congruent with established formalisms. The purpose of a computer language is to communicate to humans as well as machines. If everyone had their own language it would be a tower of Babel.

So now the goal is finding the Perfect Compromise? I almost suspect that is an oxymoron, but the philosophizing to figure it out makes me grab the Tylonal.

To a large extent it is Babel - see http://99-bottles-of-beer.ls-la.net/. Current languages are great the question is are they as close to Perfect as they could be? By being able to construct classes, inheritance, types, events etc in a language you can define models in the language that reflect the way you think, your world view, your ontology. They question is how easy is it to build those models using current languages as a tool? How easy also is it for people to learn and teach those languages? To scale up, down (ie to HandHeld s), and port between OSs? Java is a good evolution but isn't it a bit verbose? There are packages to allow aspect-driven (ie JAspect) programming to it also embed scheme, prolog etc in Java but the fact that people still need/want to augment it with these things means it as a language should continue to evolve to allow that functionality to be carried out with less of a kludge. Another example the "=" sign has been around for hundreds of years (see http://www.pballew.net/arithme9.html and do a find for "aequus"). But now Perl has "eq" Scheme has (equalp?) for some constructs (they do use "=" in other contexts) would not keeping "=" in all cases be logical as a representation in a more PerfectLanguage? The question isn't whether new languages will be developed -- that is inevitable: existing ones will mutate, evolve, converge and completely new ones will emerge while others become extinct (very similar to an ecology). But since many of the people who will develop them read these pages shouldn't this forum try to offer some ideas and guide the evolution?


A list of some various possible language features for dynamic languages: http://www.geocities.com/tablizer/langopts.htm


What might be helpful would be for someone to create a simple GrammarInterpreter? say GI.exe or GI.class (written in some base language such as C++ or java) that would take as input a grammar file, say lang.g and a source file, say file.lng and interpret the latter using the former. Lang.g would use some variant of BakusNaurForm? (BNF) for syntax definition and a simple meta-language for semantics similar to the DenotationalSemantics style or Yacc. But instead of generating code that then needs to be compiled it would interpret the source immediately. That way people could make their own experimental languages easily. Prolog has a feature like this using "-->" but is basically just a pre-processor and you have to know prolog itself to create new languages. There exist perl parser modules but these are cumbersome too. The system above would only require a basic grasp of bnf and if the metalanguage was javascript-like that would be more accessible. It could come with samples of the core of common languages as a starting point. For example a command line invocation of the program would look like:

  gi cpp.g hello.cpp
or
  java gi cpp.g hello.cpp
even better
  java gi java.g hello.java
A way to bootstrap language development to the masses.


ObjectMath? (http://www.ida.liu.se/~pelab/omath/) is an ObjectOriented extension to Mathematica

Analytica (http://library.wolfram.com/infocenter/Articles/1682/) is an attempt at adding TheoremProving to Mathematica


A perfect language should have NO syntax and be defined entirely in terms of parse trees. See SyntaxFollowsSemantics.

Parse trees require too many levels of indirection. A perfect language would be represented as relational tables that specify the relationships between the elements in my program. Text (and the parse tree of that text) is just one representation generated from those relationships.

A perfect language should be secure. All its references are the capabilities of the Generalized Capability Model.


A perfect language should be well-suited to writing all of TheManyTypesOfPrograms. Examination of that list reveals an unfortunate truth, however - the languages that are best suited for writing data entry forms are poorly suited to mission-critical software, and vice versa.

So what to do?

Python also has a low-level cousin language in Pyrex. Lisp, of course, is infinitely malleable. Parts of the Scheme48 runtime are written in a language called PreScheme?, which compiles to C, and game developers Naughty Dog wrote a low-level, sexp-based language in Common Lisp for the "Crash Bandicoot" game.

One could argue such a situation exists within the C family tree... with C/C++, ObjectiveCee, JavaLanguage, CsharpLanguage, etc. all having similar syntax at a high level. Of course, the intersection of these is pretty close to the empty set.

So now we're on a quest for the perfect pair of SymbioticLanguages, or the perfect set of n ___ languages.


I would imagine that the PerfectLanguage would support all KeyLanguageFeatures, especially the mutually exclusive ones. (Especially the mutually exclusive ones?!? Hey, let's leave C++ out of this discussion! ;-)


Every worthwhile computer language introduces new abstractions and syntax that make programmers more productive. Improvements will continue for a long time, making it unlikely that the state-of-the-art will stabilize as a perfect language. Other technologies, such as building construction, have evolved for millennia and are changing faster than ever.

So what did Java introduce?

[Nothing, he said worthwhile languages, Java's not in that category.]

[[Sarcasm aside, I believe it's true that Java didn't introduce any new language features. It was supposed to be a cleaned-up version of C++ (although features were borrowed from a handful of languages altogether), so much of the emphasis was on what not to include, e.g. no pointers.]]

Besides, building construction isn't changing much at all. The three fundamental inventions in building construction are the brick, concrete, and iron girders. Each of these enabled fundamentally new types of buildings to be constructed. Everything else is just hacks that make construction cheaper by letting you get away with shoddier worksmanship. So for example, foamed concrete, pre-stressed concrete, reinforced concrete, nails, and even cement are all just hacks.

I'd have to disagree with you about reinforced concrete. Combining the compressive strength of concrete with the tensile strength of steel in the direction you need it is more than just a hack.


And without it you wouldn't have skyscrapers. *I* have to disagree with pretty much the entire paragraph about building construction not changing much at all. It has changed tremendously in the last few decades in regard to materials, building techniques, and even the skillsets used. To say that construction innovations have only made construction cheaper (which is in itself a GOOD thing) and encouraged shoddier workmanship is simply not true. Yes, some changes have had this effect -- and those that do generally get faster acceptance for economic reasons -- but there have been tremendous strides made in making stronger, lighter, more durable, and more comfortable buildings (often more cheaply).

Concrete, especially, has become a very high-tech material in many applications. There is even talk of using it to build spacecraft! Monolithic concrete domes are certainly a different kind of building, with many advantages, and a highly unusual way of constructing a building: blow up a big balloon and spray the inside with concrete until it forms a strong, attractive, highly insulating shell. Or ferrocement: weave a web of rebar and wire mesh in practically any shape you want, and plaster it with cement. Then there's SIPs - Structural Insulated Panels, and ICFs - Insulating Concrete Forms which are filled with concrete and rebar for strength, and the form itself becomes a part of the building, insulating and waterproofing it. Foamed concrete can be "skinned" with a stronger, denser formulation much like our bones have a hard, dense shell and a spongy interior which work together to create an incredible strong, light, and effective structure. Interlocking block foundations, new super-high strength concretes, entirely new roof systems...the list goes on and on. And that's just concrete!

I think this is an important point: new paradigms and ideas keep arriving to allow us better abstractions. That's why the perfect language should allow us to extend it infinitely and naturally, add to existing functionality that works in a particular context, give us access to the whole language environment for manipulation, if wanted. The perfect language gives us ultimate power, with ultimate simplicity. It's funny how most languages don't tend to be like this. The ones I've seen with the broadest capabilities in this sense would probably be ToolCommandLanguage (Tcl) and Lisp (although I'm not sure if even it allows us to replace core functionality?). -- Setok


PerfectLanguage Criteria

Before saying that a feature X would make a language perfect, let us talk how could you decide if you were looking at a perfect language if you were looking straight at it.

  1. You can't have typing mistakes. Declaring variables is a way to achieve this, but notice that it is the compiler that enforces this, not the language.
  2. After many years, you look at the code you wrote and you still understand it.
  3. You look at the code written by someone else and you always understand what the code is intended to do.
  4. You can be sure your code doesn't have most types of bugs, because the language IDE forces you to write code TestFirst. (*)
  5. "Simple" algorithms are easy to write.
  6. "difficult" algorithms are possible to write.
  7. Any other?

The perfect language has the highest KolmogorovQuotient.

So it's AplLanguage?

(*) Testing of any sort can reduce bugs, but cannot eliminate them altogether.


The language defines static type safety (which, btw, is orthogonal to declaring variables, e.g. TypeInference) and the compiler enforces it. How can the language enforce something that the compiler doesn't need to check?

Or how about the option of not using types if a given project can make better without them? There are places for type-heavy programming and places where types get in the way.

It all depends on your memory not the language characteristics. YouCanWriteFortranInAnyLanguage?.

Again it depends on the quality of the programmers. How can a language mandate MeaningfulNames?

Unfortunately, it's all too easy for a language to mandate UnMeaningfulNames. I've seen languages where only the first 8 characters of variables are significant, and even one where only the first 2 characters of variables were significant. ThingsWeHateAboutVbClassic claims that only the first 16 characters of method names are significant in VB.

Some remarks:
  1. A language that enforces an IDE to use can't be perfect by itself.
  2. A test doesn't prove absence of bugs.
  3. We can always write the wrong test or an insufficient one and the language won't be able to stop us.

I would add a fourth remark:
  1. If you tend to do "exploratory" programming, you aren't going to know what to test for, until you start writing some code. (Having said that, I've found that tests are useful when what you are writing doesn't even have an interface yet: you'd be doing these tests by hand anyway, so it's very useful to give them a more permanent form and keep them around!)

No language can enforce bug-free code.


Should have something like VisualBasic "with" construct ie

  with(object)
  {
.method1();
.method2();
  }

Because it gives a context while allowing OO to be used. I don't like using VB and prefer C/Java style syntax, but hate typing:

  somelongobjectname.somelongmethodname1(somelongsequenceofparameters1);
  somelongobjectname.somelongmethodname2(somelongsequenceofparameters2);
  somelongobjectname.somelongmethodname3(somelongsequenceofparameters3);
  ...
[Um... yuk... you can already do this in any OO language....]

 object
  .setThing()
  .setThing2()
  .setThing3();
[don't need a special with keyword, just do command query separation and have all commands return self, like smalltalk does automatically, and it's far prettier than "with", and doesn't complicate the language.]

*what if you are doing

object1.method();
object2.method();
object3.method();
object1.method();
object3.method();
...
i.e. calls randomly interspersed but repetitive, as occurs in most real programs

[Then a with statement wouldn't help you anyway... they're all different objects. And if it were a single object, I'd say your design is bad, change the object interface to something simpler and move all that code into the object. A long chain of calls to the same object isn't a pattern, it's a CodeSmell.]

[Or if you're using a language with any functional bent to it you would use map. In Ruby:]

  [object1, object2, object3].map { |o| o.method() }

class object method dolotsofstuff() method(); method(); method(); method(); method(); end method end class
then you just have to

 object.dolotsofstuff()
See below - nested with()s would deal with the case of multiple objects. If different objects have the same method name the most recent with() would be assumed or you could force which object by typing out explicitly in that case to override that rule. They are supposed to be different objects

[I understand your intention, I just see that as a CodeSmell, you shouldn't want a with statement, you should structure the code so it isn't necessary. If setting up your objects or running your objects requires that kind of structure, then I believe they are poorly designed and the interface needs some work. You're doing too much work outside the object rather than telling the object to do the work for you. No language needs a with statement, it is a flawed construct.]

[You assume that everyone wants C++/Java style object orientation. Most more-powerful variants (MultiMethods, PredicateDispatching, PatternMatching) do not give you automatic access to the receiver(s) scopes, though PatternMatching lets you bind variables to substructures. For these languages, a with- statement can be quite useful, as (for example) you might use a with-slots construct within a CLOS multimethod. -- JonathanTang]

[I wasn't assuming that, his samples were, I was just staying in context of object.method(), standard OO, not the advanced stuff offered in CLOS etc...]

[Smalltalk is not "any OO language". Most of them allow you to return something other than self from a method.]

[So does smalltalk, that wasn't the point, the point is all OO languages will let you return self, eliminating the need for a with statement.]

[Smalltalk has cascaded messages for this exact purpose, and there are reasons for not blindly relying on a method to return self. I admit I never used it, but I remember reading the Byte 1981 special issue, and checking Google confirms my memory.]

[The Pascal "with" construct wouldn't help with that either, of course, so what then is the point? Wait, I know, there should be a VIA construct that implies the method to call:]

VIA method() do something on:
object1;
object2;
object3;
... :-)

Interesting but method() above was not meant to be the same I should have put method_i(), method_j() etc. So wouldn't work. Don't know about Pascal but in VB or the with the with() construct above (pardon the pun) you could do:

  with(object1)
  {
.method_11();
with(object2)
{
.method_21();
with(object3)
{
.method_31();
.method_12();
.method_32();
//...
}
}
  }
which is overkill for this example but if you had many repetitive objects it might be helpful

It would be applying OnceAndOnlyOnce

Hitting "<ctrl>p" in vi gives you word completion based on the previous match of what you've typed so far. Using long names is better for reading and easy to type. Doesn't your editor have an equivalent feature?

That is not the point. When we use natural language, we say "That was nice tea. Could I please have some more? And a spoon for it, oh and more sugar" not "Nice tea, more tea please, a spoon for the tea and sugar for the tea" it is redundant. It would be inefficient and hence evolution has equipped us to understand pronouns and context. The perfect language should be intrinsically elegant, not rely on the features of arbitrary text editors

I understand your point and largely agree with it. My point of view, however, is that languages do not stand in isolation, and many features that people want to put into languages more rightly belong elsewhere. I agree that this is not necessarily one of them. I further add that pronouns in natural languages are difficult to parse and interpret unambiguously, so perhaps your analogy is not helping.

In *this* context (see discussion immediately above), the with() construct I proposed is completely unambiguous, so the analogy does not depend literally on pronoun parsing algorithms Agreed - I was taking the discussion wider because I believe that this is a case for syntactic sugar, not for genuine programming language features.

There are obviously cases for syntactic sugar, cases for language features, and cases for supporting tool features. I'm not sure which this is, if any.

What about simplifying the reference temporarily?

 bo = big.Long.Verbose.Ojbect;// copy of object reference
 bo.method1(...);
 bo.method2(...);
 bo.method3(...);
 bo.method4(...);
 ...


The perfect language is only suitable for the perfect computer.

And will lead to the perfect HolyWar.


A quote from ArthurWhitney, the inventor of a couple of AplLanguage derivatives:

I like to simplify things: shorter programs, fewer primitives, smaller systems to run on, all of which makes for more productive, more cost-efficient programming.

This is also the same sort of aesthetic that ChuckMoore is pursuing with ColorForth: the smallest possible combination of language and program. Of course, to really get the absolute smallest combination, you'd need to invent a new language for every program, so really you have to compromise and try to invent the smallest possible language resulting in the smallest possible programs for some particular problem space; embedded systems, scripting, etc.

Also, Chuck is only interested in finding his own perfect programming tool: ColorForth only runs on his PC, graphics cards, peripherals; is tailored for displaying chip layout and performing chip simulation; has large color fonts to help with his failing eyesight. Chuck never claimed to have the perfect language for everybody, only for himself and his needs.


See also LanguageFamilies, LearningProgrammingLanguages, MyFavouriteProgrammingLanguage, TheSearchForThePerfectPatternLanguage, LetsDesignProgrammingLanguage, InstantLanguageForm


CategoryProgrammingLanguage, CategoryIdealism


EditText of this page (last edited November 26, 2013) or FindPage with title or text search