The learning curve for imperative programming structure just seems easier for people to understand and work with.
The learning curve for imperative programming structure just seems easier for people to understand and work with.
I would disagree, though, that there's anything inherently easier about imperative languages. Could it not be that it's simply more familiar to people today? People don't (IME) learn to program in school. They learn by futzing around with whatever free thing is on their computer. In the 1980's we had BASIC, and today we have JavaScript, and Python/Ruby/Java/C# also seem to be popular. At this point, imperative programming is winning because of path dependence. Nobody ends up using Erlang by accident.
Once you get to concurrency, functional languages are clearly punching above their weight. I find it impressive that Go makes imperative programming work well here, but it still looks a bit old-fashioned to me.
Is Go leading the pack by having a great concurrency model, yet with an imperative language that runs on bare metal? Or is it trying to hold back the tide, when almost the entire rest of the industry is solving concurrency by moving to functional languages running on a portable VM? I don't know.
I'd suspect if you gave someone who didn't know lisp or java a simple program and had them try and explain what it was doing they'd have more luck with understanding the java syntax.
I see three major programming styles: imperative, declarative, and functional.
Declarative seems extremely popular these days (see Rails, CSS, Webpack, etc). My guess is it’s because it’s fairly obvious how to design a declarative API. You just think about what you’d want as an application programmer, write that down in English, and then target that with your implementation.
These interfaces are totally unstable, and so they just degrade with time but they’re so easy to stand up they dominate the field.
Imperative interfaces are a bit harder because you need to explicitly pass all of your data through every call. This is laborious at first and you have to do lots of refactoring of the interface as you implement it. API developers generally don’t like this feeling, and would rather have a stable interface to target and only futz with the internals. And it takes longer and requires more pondering when you can’t just reach directly into arbitrary parts of your code base and do whatever TF you want. And since APIs are usually released before they stabilize, application developers also don’t like seeing their interfaces move.
Functional APIs are like the imperative ones but even moreso. Not only do you have to pass around data explicitly all the time, you have to model every intermediate state in your data explicitly too.
This is even more constrictive, which just makes all of the above even worse.
Personally, I think this pain pays off in the end, and I code in a purely imperative style deep in a haunted wood. The suffering over moving interfaces eventually leads to a stable interface that’s actually well thought out and composeable. Code can become “finished” whereas declarative code almost always just rots til it’s replaced.
But in terms of “Don’t make me think” which is most pro developers dominant mode of working, there is a clear declarative > imperative > functional hierarchy.
In theory a purely imperative or purely functional ecosystem could gain a kind of network effect of good code that would eventually outweigh the work slowdown.... your application code would be harder to write, but you’d be writing on top of a richer, more composeable library base.
However we don’t seem to observe this in practice.
My theory is that imperative and especially functional languages tend to attract masochists, who get yakshorn into radical experiments into purism, trying to bend every aspect of an ecosystem into a perfect Q-dimensional prism. This leads to just less effort in churning out pragmatic tools. And it also leads to a kind of dazzling conversation around the languages that turns away people who are just trying to get something done.
With sustained effort these effects could be overcome. Over time I am building a library of pure imperative JavaScript modules. They seem to be reaching “finished” one by one. We’ll see.
This is easier when similar languages look and -- through the power of abstraction, appear to -- work in similar ways. Go benefits from looking similar to the wider C family, while Erlang suffers from a syntactic heritage that never achieved as much prominence. The prevalence of languages in the syntactic style of C allows people unfamiliar with Go to be able to glean a lot of what's going on, and develop their understanding of Go-specific features gradually.
if
something()
or other()
then
do_whatever()
end
It's very easy to read; your eye doesn't "stumble" anywhere it doesn't have a reason to. In C (and Java, C# etc), on the other hand: if (something()
|| other()) {
do_whatever()
}
This makes for some confusing indentation, and now it's hard to distinguish what's condition and what's body! Sometimes people indent the entire condition to make it clearer: if ( something()
|| other()) {
do_whatever()
}
but now you have holes in the middle which draw attention to that spot for no good reason. Or you can put ){ on a separate line: if (
something()
|| other()
) {
do_whatever()
}
but so much punctuation hanging by itself is still an eyesore. And Python is hardly better: if (
something()
or other()
):
do_whatever()
Go doesn't need the () in condition, so it's slightly more tolerable if you do that (but go fmt will object): if
something()
|| other()
{
do_whatever()
}
But I'll take the Lua/Ruby syntax any day of the week.That's just one example. In retrospect, I think that C-style syntax was a bad idea in general, and adopting it as the "default syntax" across a large part of the industry was a monumental mistake. It favored compactness and speed of writing over readability and clarity. I really wish something like Modula or Ada would become the syntactic basis of modern languages today. I'd rather spend a few more keystrokes typing out things like "var" and "end", but end up with code that reads smoothly in a code review, or when debugging some ancient codebase.
http://james-iry.blogspot.com/2009/05/brief-incomplete-and-m...
> His lambda calculus is ignored because it is insufficiently C-like. This criticism occurs in spite of the fact that C has not yet been invented.
Anyway, it's not because C-like languages are any easier. It's just that nearly all programmers learn to code in a C-like language. Most of them won't ever learn a second language, the number that will do the work of learning something actually different is minuscule.
I suspect (but cannot prove) that certain languages and/or programming styles make more sense for certain people, and others do so for other people. (There also is almost certainly some bias toward familiarity.)