
Programming Languages Are Simply Not Powerful Enough - dylangs1030
http://ivanjovanovic.com/2012/04/26/programming-languages-are-simply-not-powerful-enough/
======
coffeemug
_One simple example from everyday life: Imagine that you don’t have in your
vocabulary notion of a sum. Therefore, if you would like to tell someone to do
a sum of some things you would always have to express the process of summation
in details instead of just telling and then you sum these numbers._

I hear this a lot to explain the idea of abstraction to people, but the
trouble with applying it to software is that picking really good abstractions
is very, very _very_ hard. Abstractions evolve over a long time under pressure
of peer review and evolution of software systems. It took us ~2000 years to
get a solid foundation for mathematical concepts and notation (we understood
_sum_ way before that, but you get the idea). We don't have 2000 years to pick
really good abstractions for software systems.

I'm convinced that a programming language must be really good at allowing you
to change and evolve your programs as quickly as possible as your
understanding of abstractions improves. This is far more important than more
powerful ways to describe abstractions IMO. Functions are fine. Just let me
change things drastically without breaking too much or having to rewrite half
the darned thing, and I'll be happy.

------
cageface
The claim is often made that languages like Forth and Scheme are better for
building applications than less elegant and orthogonal languages. But the
evidence on the ground is overwhelmingly to the contrary. The vast majority of
commercially significant apps are built in relatively baroque and ugly
languages like Java and C++.

Personally I think that the ability to define your own language constructs is
ultimately a lot less useful than things like rich libraries and robust
tooling and I'm still waiting to see real-world proof of the advantages of
programmable programming languages.

~~~
rayiner
The popularity of programming languages is entirely a matter of historical
accident. C flourished while Pascal languished because UNIX was written in C.
Was there really a deep technical reason for preferring C to Pascal? No, not
really. Indeed, for most of early history, Pascal had far superior tooling to
C.

How else do you explain the popularity of languages like Javascript and
Objective-C? Javascript is an objectively terrible language, hacked together
by Brendan Eich in an afternoon. Yet, it's a tremendously popular language,
and tremendous amounts of money and time have gone into building good tooling
for it. Same thing with Objective-C. It's a shitty, ad-hoc, cobbled-together
patchwork of C and Smalltalk, yet it's tremendously popular now because that's
what the iPad is programmed in.

~~~
bad_user
Pascal (or more precisely Borland's version of it) was my first programming
language that I learned in school. I also used it when I was participating in
the CS Olympiads.

Going from Pascal to C was like a breath of fresh air. Pascal is like a
combination of everything I hate in all programming languages that I know and
I'm glad that the world moved on. C is small, elegant and portable. It's a
systems programming language that does what it's supposed to do.

> _Javascript is an objectively terrible language_

Our tastes are different and all proof to the contrary, as Javascript proved
that it's an _objectively_ good programming language, that has been burdened
with legacy, incompatibilities due to the browser wars and more recently slow
evolution due to its huge popularity and the stagnation of IExplorer. It has
quirks and it isn't what it should have been, but considering the context it's
the best outcome we could have had.

Name one other programming language that's (1) a true standard governed by a
standards body with multiple platform-independent implementations and (2) has
less problems than Javascript.

With Javascript your argument falls flat on its head too, because all of the
competing technologies failed because of really good technical and political
reasons ... lets not forget VBScript, Java Applets, Flash and Silverlight.
Yes, technologically speaking Javascript was and is better than all of them.

~~~
PommeDeTerre
There are a lot of problems (not merely "quirks", but outright problems) with
JavaScript that have absolutely nothing to do with past or present browser-
based implementations. They're problems that are inherent to the language
itself.

I'm talking about things like its extremely broken equality operators, its
extremely broken array handling (especially the behavior of the length
property), semicolon insertion, its broken scoping, its lack of support for
proper class-based OO, its lack of support for proper namespacing and
modularity, its lack of proper typing, and so forth.

These are far worse, and in many cases much stupider, than any problems we see
with C, C++, Java, C#, Python, Ruby, Erlang, Perl, Haskell, Scheme and
whatever other mainstream or semi-mainstream language you want to choose.

PHP is perhaps the only widely-used language that exhibits the same kind of
idiocy when it comes to many core features. But at least it has been moving in
the right direction, with its much more sensible support for OO and
namespaces, for instance. We keep hearing about how ECMAScript 6 will finally
bring at least some sensibility, but this is still very much up in the air.

It's incorrect to say that JavaScript is an "objectively good programming
language". It's objectively terrible, and all of the evidence proves this very
conclusively.

~~~
AnIrishDuck
Most of your peeves are addressed by correctness checkers like JSLint, or have
been alleviated by community projects. There's a lot of hate here, so I'm
going to address your points one by one:

> I'm talking about things like its extremely broken equality operators,

Don't use language features that are broken. Use === and !== instead. JSLint
complains about this.

> its extremely broken array handling (especially the behavior of the length
> property),

You're going to have to elaborate here, I have no idea what you're talking
about.

> semicolon insertion,

Put semicolons at the end of each line manually. Or don't use crazy multiline
expressions. JSLint will flag this down for you. Other languages like C force
you to do this, why the JavaScript hate?

> its broken scoping,

Never put things in the global scope. Always use var. Global-by-default is
annoying, but very easy for static tools like JSLint to flag and nag about.

> its lack of support for proper class-based OO,

Javascript's objects are very minimal; they can easily emulate semantics of
other OO languages. In my code I usually emulate the Python copy-superclass-
on-class-creation semantics of subclassing.

> its lack of support for proper namespacing and modularity,

RequireJS has effectively solved this problem for me. As per above, you should
never put things in global scope anyway.

> its lack of proper typing,

If you're looking for built-in static typing, you came to the wrong place. I
think it's important to remember that JavaScript the language was designed to
be very minimal (IIRC the entire initial language was created in a week); in
that regard, it at the very least is not a good fit for static typing. I
personally wish that it had stronger types, and can agree with you here that
ideally this would be different.

> and so forth.

I guess I don't see your concerns here. I prefer writing JavaScript over C and
Java; it allows me far more leeway for creating abstractions through closures
and anonymous functions. Think of JavaScript's problem statement: create a
simple minimal universal browser-based language. It's hard to imagine a better
language in JavaScript's place (Scheme is the only realistic alternative I can
think of). Here's a nightmare scenario for you: we could have ended up with
Visual Basic instead.

JavaScript isn't perfect, but what language is?

~~~
KingMob
While I don't quite agree with the parent poster, half of your points involve
a) best practices, which require programmer discipline, not parser smarts, b)
a lint-checker, which again, is not as good as the parser itself forbidding
something, or c) using certain libraries, which is not as portable and easy as
direct language support.

While I agree that these issues are surmountable, I don't think you've
rebutted the point that they are issues with the language itself.

That being said, no language is perfect and for being whipped up in a day,
Javascript's pretty nice.

------
andolanra
As a counterpoint to this article, I'd point to Yossi Kreinin's excellent "My
History with Forth & Stack Machines" [1] which has been posted on HN before
[2] and which discusses more extensively the particulars of Forth as a
powerful toolbox of primitive operations, as well as the use of Forth in
actual applications.

[1]: [http://www.yosefk.com/blog/my-history-with-forth-stack-
machi...](http://www.yosefk.com/blog/my-history-with-forth-stack-
machines.html)

[2]: <http://news.ycombinator.com/item?id=1680149>

------
DeepDuh
Am I the only one being put off by the CSS? I had to crank the display
brightness to the max in order to read it without strain.

Edit: I agree a lot with the content though - For many complex problems,
especially the kind where you can't just throw some standard software solution
at it, it would be helpful to first develop a suitable DSL. From personal
experience I'd say spend one third of your time budget into developing your
domain specific toolset - even if your managers get nervous. If it works you
will finish sooner than you expected _and_ you have developed reusable tools
and skills, if it doesn't you can still throw in a crunch and get it done. For
me it has always worked though.

~~~
aroman
Perhaps it is because I am in a dark room reading in bed with a MacBook Air
set at 50% brightness, but I actually really liked the experience of reading
that. Though I can absolutely understand where someone might not.

~~~
cpeterso
You might like Flux. It adjusts your display's color temperature depending on
the time of day. No more blinding screens when you open your MacBook at night.
:)

<http://stereopsis.com/flux/>

~~~
errnoh
Using flux as well but that site was one of the most enjoyable sites to read
that I've seen in couple years.

The colors aren't that beautiful but it's much less stressful for my eyes, and
the highlight colors were spot on as well.

Thanks to emidln for informing that it's Solarized Dark, I've used the default
Solarized but I've skipped the Dark one because of somewhat ugly colors.

------
Guthur
For me a language is getting close to "powerful enough" when it does not get
in the way of you as the programmer when you are developing abstractions of
the form that seems most natural to you.

This can cause problems in some cases; when the language is stepping that far
back to allow you the freedom then it is up to your to enforce your own
constraints to avoid your abstractions becoming...too abstract (maybe).

Also in my opinion there is not one abstraction form that will appeal to every
type of programmer. For me I like the freedom to manipulate and define
symbolic forms with Common Lisp for others it might be the expressive type
system of the Haskell. I don't think you can truly say one way is better than
the other.

I think those languages and a few others are giving the tools of abstraction
that will not get in the way of you as the programmer.

~~~
SomeCallMeTim
>enforce your own constraints to avoid your abstractions becoming...too
abstract (maybe).

Too abstract isn't necessarily the problem. When I've stepped too far away
from standard OO structure, the problem typically becomes organization. In OO
you know where just about everything SHOULD be, at least. If you're writing
your own rules, it's harder to be certain where new variables get set, or what
members you should find in what structures.

It takes a certain level of discipline to not shoot yourself in the foot. Or
at least to clean things up before they get too messy.

~~~
Guthur
Depending on the implementation of the OO system in question it could provide
you with relatively limited options for abstraction.

I can only really speak from a Common Lisp point of view and the problem there
that I was alluding to is the fact that you are so free to produce your own
forms of abstractions whether it be mini DSL macros, dynamic dispatch method
combinations, data driven programming using first class functions etc. that if
you are not careful you can easily obfuscate the real intention rather than
making it clearer.

~~~
SomeCallMeTim
I use Lua, with ALLOWS you to use OO, but doesn't enforce it. To say the
least. Lua does have first-class functions, including full closures, and the
one Lua data structure is a "table", which can act like a full OO class with
the right patterns applied, but which generally can be extended anywhere, each
"object instance" getting its own unique extra fields attached.

Lua doesn't have macros (well, you can use a library to get an extremely
powerful macro language if you want [1]), but the problem with going too far
down the macro/DSL route (IMHO) is that the code becomes harder for people who
didn't write it to understand. Or even if the code itself is easy to
understand (by virtue of being a good DSL), it becomes harder to extend or
modify, especially if the modification involves something not explicitly
designed for by the original developer.

If you stick with the syntax of a known and well documented language, then the
learning curve for new developers is easier. Though even then, the other
issues you point out can obscure the code flow, so probably the only thing you
can say is that complex code is complex. ;)

[1] <http://metalua.luaforge.net/>

------
Joeri
This is true from an academic perspective, but not from a practical
perspective. Typical crud apps don't have complex problem domains. They're
just electronic filers with a search field. You do need some dsl's, for
formulating views, tying those views to models, and tying those models to
persistent storage. That's why most popular frameworks implement pseudo-dsl's
for MVC and ORM. MVC and ORM can be solved in a generic way at the framework
or even language level, and it could be argued that you shouldn't try to solve
them in a project-specific way to ease maintenance. There is little value for
many (or even most) projects in having a more powerfully abstractable
language.

~~~
mattgreenrocks
> Typical crud apps don't have complex problem domains

I beg your pardon, but I think you're forgetting that there are plenty of
business apps that have _very_ complex requirements due to legislation, a
myriad of cross-cutting concerns, and audit requirements. Domain complexity is
a very real thing, and it often necessitates architecture beyond cramming
everything into this week's CRUD framework.

~~~
mamcx
Lets ride with that idea. The problem is that the info about functional
programming show how maginificient it is for _math-alike problems_ but barely
never for _crud-alike problems_. I can understand some of the genius of
haskell, but can't see how it make a better django or ruby on rails.

CRUD's apps have the stigma of be "patetic simple projects". Are not! Building
erp-like software is dam damm hard. Making a search engine? Where clever math
solve it? Where well understood ideas of scalability are clear? NOTHING
against the complexity of fly at the speed of a business, deadlines measured
not in months, but HOURS. Underfunded, not enough staff, working on legacy
code, and that is only the surface.

Building a language to truly be a MASTER of CRUDs apps is something I truly
wish for (the most close thing was Foxpro, IMHO).

Despite my love for python, and what I know for my use of .net, ruby, obj-c, I
don't think is something well solve yet

~~~
pessimizer
CRUD apps are lowest common denominators. They store data and then retrieve it
again. Functional languages are no worse at that than imperative languages,
and they're better at "math-alike" problems.

I'm not sure that you can come up with a language that is targeted towards
CRUD apps, because the entire concept of programming is CRD. The problem is
building domain specific abstractions on top of a system that just flips bits
and tells you what they say; and by "the problem" I mean "our job."

~~~
mamcx
Do you know foxpro? The zero-friction to manipulate tables (and back them,
nobody worry about the OOP impedance mismatch) the 0-necessity of use a ORM,
the complete tooling to make a full app (with report engine included), the
possibility to code store procedures in full foxpro (before become cool the
idea of embed full languages inside db engines) and a lot of other things.

The weak link was the fragile database engine, but more important, the kill of
the tool by MS.

The mix of a language, db engine, gui toolkit, and other things (similar, but
far better than Acces) make it a tool truly made for this area of CRUD.

Plus, you could work in their REPL, and do commands as BROWSE and see the full
data in a editable grid to use as you wish. I can't describe in words how
functional the whole thing is. Is similar in the power of smalltalk, but
instead of have a full reloadable code you have the full data at your hands.

Check
[http://books.google.com.co/books?id=k8fN2KMF1j4C&pg=PA54...](http://books.google.com.co/books?id=k8fN2KMF1j4C&pg=PA54&lpg=PA54&dq=foxpro+table+commands&source=bl&ots=VwKWK7MDCX&sig=UnHrnear1xAYU75QAhIW-5rnXP8&hl=es-419&sa=X&ei=qfUzUZHEO4KQ9QTi6YGYAw&ved=0CEcQ6AEwAw#v=onepage&q=foxpro%20table%20commands&f=false)
for a idea of the tool.

A modern version of foxpro is something I wish for, but without the coupled
GUI toolkit and a better syntax

------
Confusion
Obligatory reference to Ometa [1], a simple almost-PEG parser embedded in a
Scheme that allows the VPRI [2] (headed by Alan Kay of Smalltalk fame) to
quickly build layers upon layers of DSL's. Their goal:

    
    
      to create a model of an entire personal computer system
      that is extremely compact (under 20,000 lines of code) [3]
    

[1] <http://tinlizzie.org/ometa/>

[2] <http://www.vpri.org/index.html>

[3] <http://www.vpri.org/html/work/ifnct.htm>

------
kamaal
>>One exceptionally good resource is the Guy Steel’s keynote from OOPSLA’98
conference about Growing a Language.

If you want to know one practical language today that embodies this philosophy
and is yet main stream today, its Perl.

Perl 6 takes it further. Infact Perl 6 by design is supposed to be such. Here
is comment Larry Wall himself(<http://www.perlmonks.org/?node_id=836573>).
Thought the whole thread was a troll thread. The first time I encountered this
was like 6 months back while searching something related to Perl 6 on the
internet. And it stuck me that how amazing this concept was.

I then went back and watched some of his keynotes. I will recommend everybody
to have a look at it.

Perl 6 is definitely going to be a big game changer in this place. And unlike
Lisp its a very practical language for your everyday programmer.

~~~
cmwelsh
Perl 7 is going to be another Perl 5 stable release, just wait and see. No one
is going to use Perl 6.

See <http://news.ycombinator.com/item?id=5179513>

~~~
groovy2shoes
Then Perl and Scheme are more similar than I thought!

See <http://scheme-reports.org/2009/working-group-1-charter.html>

------
tikhonj
I think this roughly reflects my philosophy in languages as well. You
basically have two options: you can bend your problem to your language or your
language to your problem. The former is epitomized by Java and Python--all
Java and Python code looks the same, regardless of what it's actually doing.
The latter is the domain of Lisp and Haskell and Forth and so on.

I'm unabashedly in favor of the latter.

Ultimately, it's easier to reason about some domain _in_ that domain. I would
love my code for any particular project to look very similar to what I would
write on a whiteboard when solving the problem. If I'm solving something
inherently mathematical, I want the code to resemble math notation. If I'm
writing some parsing code, I want it to resemble a grammar. If I'm writing an
interpreter, I want it to resemble the operational semantics of the language.
This fits into more "practical" domains as well: if I'm writing a web app, I
want the routing to look like, well, routing and the database code to look as
close to the database structure as possible.

Any details in the implementation rather than the domain should be separated
from the domain logic. If you're trying to make the domain logic mirror the
domain itself, this is essentially inevitable. This makes your code more
general and easier to debug. You can redirect your domain logic to a different
backend, and it's much easier to figure out whether you have a problem in the
implementation or the logic.

More generally, such a strict separation of concerns is extremely important.
The difficulty of a problem increases exponentially with its complexity: all
the parts affect each other. If you manage to neatly split a problem like this
in two, each sub-problem will be less than half as difficult as the main
problem. So splitting away the high-level logic from the IO and the memory
management and the other implementation details is inherently valuable. In
fact, this is valuable even if the sum of both sub-problems is a bit greater
than the original problem.

The malleable language approach gives you a very natural way to split your
problems up: one part is implementing the DSL, modifying the host language or
writing a library--creating abstractions. The other part is actually using
these abstractions. I find this sort of split to not only be very useful but
also very natural; it mirrors how I usually think about things.

One very interesting recent development taking this idea to the extreme is
OMeta. There your program is essentially a tower of DSLs, with the base
language just being a simple way to specify the DSLs. This idea really is
extreme: for example, the code for implementing TCP is actually the ASCII art
diagrams describing it! [1]

Of course, all the usual suspects like Lisp and Haskell are also worth looking
at. Embedded DSLs in these langauges can go quite far, and they have some of
their own advantages to consider.

[1]: [http://www.moserware.com/2008/04/towards-moores-law-
software...](http://www.moserware.com/2008/04/towards-moores-law-software-
part-3-of-3.html)

~~~
wvenable
The problem with writing a DSL for every problem (and every programmer writing
different DSLs) is that you end up with all these different languages with
different vocabularies and different semantics. It's like a million different
variations of Esperanto.

Using a programming language is like speaking in common tongue to every other
programmer who knows that language. And most languages are so similar that
most programmers can communicate even between languages.

Having code that looks the same, regardless of what it's actually doing,
allows everybody to be able to read it.

~~~
klochner
"Welcome to our team, here's the spec for our project, and here's the spec for
our DSL. See you in a month."

~~~
limmeau
"and here is the spec for our in-house framework".

"and here is the 1M LOC codebase, which was carefully crafted to avoid using
any of the complicated frameworks; all you gotta know is the C standard
library".

~~~
anthonyb
Spec? For an in-house framework? Luxury!

~~~
limmeau
Did I say Spec? I meant the doxygen output of hundreds of classes with sparse
one-line doccumments.

Plus one outdated sequence diagram.

~~~
masklinn
One-line comment? What are you, a writer-librarian?

~~~
limmeau
It can be learned. Observe:

    
    
           //! \brief Transport diagnostic wrapper
           class TransportDiagnosticWrapper {
    

(Actually, meaningful one-line comments are a lyric discipline of their own,
related to haikus.)

~~~
npsimons
You joke, but a tool I have seen lauded for being really "smart" at
automatically generating doxygen comments does _exactly_ that. I guess it at
least saves the time of a human doing it by hand . . .

------
pjbrow
It's hard to argue with this article - it's self evident that languages lock
us into abstractions that aren't powerful enough to comfortably support the
increasingly ambitious applications of code.

Object oriented programming was a big step because it's so heavily modelled on
hierarchies - since found to be one of the most important principles in human
reasoning.

I'm no expert in the area, but I'd love to hear ideas on other human reasoning
principles or models that a language could be influenced by (particularly if
you know about neuroscience or AI).

------
BruceIV
Agreed, to a point. What kind of abstractions are sufficient, or useful? What
happens when they leak? What happens when you build the wrong abstraction, and
have to go back and build something slightly different from the ground up?
What about when your abstraction works, but is so far removed from the actual
execution environment that it's so slow as to be unusable?

Yes, abstraction is a wonderful, useful thing that lets us think and do all
sorts of wonderful, useful things - our high level programming languages and
networking protocols are abstractions over lower level programming languages
and networking protocols (repeat a few times) which are abstractions over the
physical hardware they run on, and that's great. _But_ abstractions are never
perfect, and what you don't know about the lower levels of the stack _will_
bite you, which is a good argument for using as few and as thin abstractions
as you can to get your thing done (reasonably ... I'm not about to write this
comment in binary ASCII, say).

~~~
nsmartt
He mentions the point when the abstractions in the language are no longer
sufficient. It seemed to me that this was more an argument in favor of using
languages that are easily extended rather than languages full of abstraction
with few options for extension. If you use a language like the latter, you'll
still eventually reach a point where the abstractions aren't sufficient, but
if you use a language like the former, though you'll reach that point sooner,
you'll be better equipped to handle it.

edit: word use

------
hdra
Maybe its just that I don't have enough experience, but I've never met and
can't think of any problem that may made think that I need to write a
programming language.

Most languages I know allows me to form some type of class/data structures for
my need. What kind of problems are OP referring to? some kind of extensive
math/scientific problem?

------
treerex
This is where Common Lisp comes in: through macros you can expand the language
to include the abstractions your application needs. PG talks about this
extensively. The issue is that doing this requires a deep understanding of the
language, and many programmers are not able to grasp what the CL toolbox gives
them.

------
keefe
overall great article, particularly this exceptionally elegant turn of phrase
-

'It is known since the early ages of programming, most elegant programs are
built as layers of "languages" or "dictionaries". These are represented by
abstractions in a program in order to facilitate expressing the ideas in a way
that is more related to the domain.'

Overall, I like to draw a line between canonical/ontological representations
of models and representations of models designed for calculation. The
ontological representation often times exists in a relational database or in
an explicit OWL/RDF ontology, but may also exist only ideally, where the
storage and calculation representations of the model are each customized for
their particular use, especially at large scale.

the following concept, I almost agree with...

'it is our job to express the abstractions of the domain for the best economy
of the expression'

As programmers (vs ontologists) I would say that our job is first to express
the abstractions such that they enable efficient, maintainable computation
that hopefully is expressing those abstractions economically. I feel like
programming languages don't lack power, they just make it quite complicated to
express complex abstractions.

------
michaelwww
Isn't this really describing what it means to write a program? Assembler is
really just mov, add, branch, etc.. but some really complex and useful
programs have been written in assembler. Or am I missing something? I had to
squint to read the text.

------
capkutay
"One simple example from everyday life: Imagine that you don’t have in your
vocabulary notion of a sum. Therefore, if you would like to tell someone to do
a sum of some things you would always have to express the process of summation
in details instead of just telling and then you sum these numbers."

If you can encapsulate an undefined idea into one stream of commands, can't
you just create a function to do it? What does that say about programming
languages? Maybe I missed the point.

------
protomyth
I have worked at places that used the same language but had totally different
custom business logic class libraries and practices. Learning a new DSL
probably would have been easier since the <Biz Speak> => <Code> step would
have been easier.

------
adamsaleh
Could we say, DSLs are the new frameworks?

For example for a web-dev in Java you'd use a MVC framework.

In Clojure you get a query DSL to do your model, templating DSL to create your
view and routing DSL to specify your controler.

------
nollidge
Low-contrast typography is not powerful enough.

------
berlinbrown
And yea Java is popular and doesn't really abstract much. I guess with
interfaces, it is kind of a rough abstraction.

------
army
I agree with the general approach, but isn't this just bottom-up design?

------
moron4hire
So this essentially sounds like "You gotta work at it to get it done."

------
edem
Have you tried Lisp?

------
marpalmin
Check Jetbrains MPS

