6 ms·
Warning! I made this comment because I thought this was an amazing and informative blog post, but nobody said anything in the last 7 hours it's been posted... :
by codewright 14y ago
Warning! I made this comment because I thought this was an amazing and informative blog post, but nobody said anything in the last 7 hours it's been posted... :\
As a result, I've decided to toss out some thoughts I've had about Ruby, programming languages, PL implementations, and Lisp lately.
This is a fairly interesting, dense, but accessible list of aspects of Ruby that make it hard to optimize.
An interesting counter-example in terms of relative expressive power vs. performance would be Common Lisp.
The main differentiator seems to be how accessible the expressive power is. Ruby just really doesn't demand much forethought or precision on the part of programmer in terms of what should be in scope, what data is getting passed around, how to even represent the data, let alone in memory.
That's saying a lot, given that the default data structure in 'classical' lisp is a linked-list, which is a pathologically poor choice for today's hardware for cache predictability. Thus why Clojure has emphasizes the generic sequencing protocols/API and tries to nudge people towards using vectors for everything.
This all adds up to a language that is "easy" and expressive, but not simple.
It leaves one to wonder why we haven't gotten much further in terms of raw expression and concision at a high and low level than Python, Ruby, and Common Lisp. There are others that deserve mention for being interesting and powerful (Haskell, Clojure, Io) but for various reasons/limitations/trade-offs aren't necessarily more concise/more powerful in the small (trivial example) or in the large (managing state, scope, composing code from afar).
Clojure and Haskell pick some smarter defaults for the scale-up to larger codebases, but don't do much to offset the loss in expressive power those trade-offs incur. I think the emphatic focus on immutability and keeping as much immutable as possible as is the case with Haskell and Clojure is the way forward, but only Haskell has really made any attempt to explore how to advance the power of expression in that mode.
Idiomatic Clojure code barely makes use of monads as it is.
To understand the scorn that Common Lispers have (I used to code primarily in CL) for Clojure, Haskell et al, it's important to remember that they principally care about what's possible, not about what's idiomatic, standard to the community/libraries, etc.
It has long been the case that you could write predominantly functional, immutable, expression-based code in Common Lisp. Many did. What Clojure did was formalize it, clean it up, etc.
Clojure didn't bring anything new to the table in terms of power. Not like Haskell's type system. I spoke to David Nolen recently about predicate dispatch and it seems as if progress on that front has even stalled.
The delay in progress on predicate dispatch is disappointing because I was going to use the predicate dispatch work as the "selling point" for Clojure for a few CL'ers I know. It would've been a genuinely distinguishing point as while there has been tons of work on predicate dispatch in Common Lisp, Clojure's core.logic foundation was shaping up to have a better API and be more composable.
Instead I'm left with nothing I'm able to recommend with a straight-face to an experienced Common Lisper who isn't interested in JVM integration.
So what's new? What do you really win with Clojure other than better libraries and community? Not much.
Oh and the uh...concurrency primitives? They're a canard. They're neat, they're designed excellently (being that it's Rich Hickey), but they're just not as impactful as other things are these days.
If single-node/instance performance was important, you wouldn't be able to do it on the JVM. If scalability is important, shared memory on a single node is irrelevant and it becomes a matter of implementing a partition tolerant database.
The concurrency primitives would've been more important in an alternate universe where we didn't use databases/data stores/filesystems for state management and synchronization and instead did Smalltalk stateful servers.
That didn't happen and it was an extremely bad idea and we live in a world where java.util.concurrent exists.
So the CL'er who codes like a bi-polar hermit doesn't care about Clojure.
You want to win the Lisp-community-at-large? Give them more power. It doesn't have to be the trivialized imprecision of expression that comes with something like Ruby. It doesn't have to be the minimalism of Io and Scheme. It doesn't have to be native continuations.
It doesn't even have to be Shen or Haskell-style static typing.
What it does have to be...is more powerful for the lone cowboy. It's going to be hard to convince a lot of them without really hitting a home-run on that one metric. Especially in a post-CLOS/Art of the Metaobject Protocol world.
I think Rich Hickey knew from the beginning he wasn't going to win a huge chunk of the CL'ers over. I don't think it mattered. I think what mattered is that people stuck in the Java enterprise universe could have their sanity-preserving escape hatch.
It's a mistake to believe Clojure was designed for CLers. It was designed to save Python, Ruby, and Java people.
A similar case of mis-targeting is Go. Go itself was ostensibly a "systems" language when it launched. They got called out on the absurdly inaccurate labelling so they've since repositioned it as a general purpose language. Which is accurate.
They thought they were going to compete with C++. That's nearly impossible until someone comes up with a true successor to C and C++. Anything that doesn't enable absolute control over memory and semantics will never succeed them. There always has to be the "bottom" where you can exert near-dictatorial control over the behavior of the computer. Many industries need this.
Go was never designed to enable that, it was designed to make writing simple code simpler. That's all. And it's good at that. I was surprised when people with the cultural wisdom and background such as Rob Pike were surprised that they were getting Python and Ruby people instead of C++ people.
The raw contempt Go programmers have for debugging and interactive programming is appalling. That alone turned me off completely to the community. Partly because the only reason for that attitude is some off-hand statements Ken Thompson made in Coders At Work and elsewhere. Cargo-cult at its most definitive.
Why would a C++ programmer move to Go? They lose control of the memory, for which they have many layers of abstraction they can resort to (malloc/free, new/delete RAII, unique/shared pointers, Boehm's GC which is basically equivalent to pre-Go-1.1 GC, etc.)
They also lose the benefit of their years of investment and learning in C++ which offers them a dizzying depth of choices in abstraction layers. This has obvious disadvantages. C++ is a terror to attempt to write safe and stable code in.
It is however, extremely powerful and the "pay only for what you use" is essential for systems programming. My personal preference is C since I feel like I'm not aiming a bazooka at my face, but as a Common Lisper I understand the appeal of the power they feel they get from C++.
Even if the 'power' in C++ is of a different sort than that which you get from Common Lisp.
People unwilling to recognize and understand the power, advantages, disadvantages, and design trade-offs made by "scary" languages like C++ and Common Lisp will never be able to fully learn the lessons borne.
So no, I'm not surprised Go didn't attract primarily C++ programmers. Not in the slightest.
It's mostly been Java, Python, and Ruby programmers...for various different reasons. Like Clojure.
Most of the programming languages of the last 5-10 years have been "sidegrades". Enhancements of accessibility, of cultural idioms, of extracting a different emphasis on a subset of semantics that previous languages supported.
Have we really advanced beyond Common Lisp, Prolog, Smalltalk, and C++?
What does it mean to make a language more powerful than those? Is there a limit to expressive power? What do languages like REBOL say about "normal" languages? What about APL?
On a parting note, the only language that I've felt has truly expanded my horizons and impressed me in the last ~5 years has been Haskell (although it's much older than that). That said, I feel Haskell is a spiky, uncomfortable urchin of a language that is highly optimized to a local maxima of expressing problems in code. I learned a lot from Haskell, but I'll never be more productive in it than Python or Clojure or Go or anything else.
Too awkward, if enlightening.
- willvarfar 14y agoI, too, came here to comment just because I thought an excellent article wasn't getting much discussion :( I think the concurrency - both Clojure and Go trying to fix it - is a big deal. I live in the world of the partition-tolerant databases and multiple nodes and all and its a super-crap horrid world where everything seems permanently fundamentally broken. You can go a long way on a single node if you just have good clean design. I pay a lot of attention to new stuff like Spanner but right now all our choices are flaky. Related blog posts of mine http://williamedwardscoder.tumblr.com/post/18065079081/cogs-bad http://williamedwardscoder.tumblr.com/post/18065079081/cogs-... http://williamedwardscoder.tumblr.com/post/16399069781/google-moresql-is-real http://williamedwardscoder.tumblr.com/post/16399069781/googl... etc Regards your point that Rob & co couldn't correctly define "system language"; well, surely their definition ought to trump the interweb? If they consider writing servers 'systems programming', then I'd say it was ;) I mean, they didn't make the claim in a vacuum; its presumably what Google internally calls a 'systems language'? That C/C++ people don't flock to Go is a shame, because C/C++ is so unnecessary for so many projects. Its really rare to need C, and never necessary to need C++ (and I've worked on C++ kernels back in the day). There, hopefully my comment is hyperbolic enough for someone to take issue with a point and discuss ;) I do stand by my general thrust though
- codewright 14y agoC/C++ are necessary for a lot of things, things that Go isn't capable of doing or wouldn't be very good at doing. Go isn't a systems programming language. They called it that because compared to a language like Python it's closer to the hardware. A systems language has various properties, like strict memory layout and management control, varying degrees control over code output, being able to bootstrap an OS without depending on a wrapper OS / bootstrap VM / extensive stdlib, etc. Go fails to meet any realistic definition of a systems language. Go is instead a compiled alterative to VM languages like Java and Python. Black is not white just because Rob Pike said so. He's a brilliant man but he's always been a bit off to the side in terms of not really being in 'sync' with everybody else. This is just an uncommonly concrete and inarguable example of that. He himself backed off the 'systems' descriptor when he realized his error. You're fighting a bogeyman that doesn't exist. >because C/C++ is so unnecessary for so many projects People don't really default to C/C++ for anything they shouldn't anymore. They live way higher up the stack by default by FAR. C is generally only used where appropriate (kernel, embedded, drivers, services like Redis, etc.) C++ is the province of Microsofties, game developers, database coders, browser implementors, and OKCupid employees. (Mild exaggeration) I mean seriously. When was the last time you heard of somebody doing a GUI desktop app or web app in C or C++? Dropbox is Python, most Ubuntu/Gnome/GTK apps are Mono/C#, most web apps are Java/PHP/Python/Ruby, frontend web code is inescapably JavaScript with their ongoing attempts to shoehorn Node.js onto the server-side. Some weirdos and Perl6 hopefuls even use Perl for their primary language these days. Node.js is as good an example of the "sidegrades" I mentioned in my original comment, except it's spectacularly awful in so many ways that I have to wonder if it's trying to draw even more uninformed and informed detractors than C++. So who exactly is using C for everything on the planet? It's a strawman. Nobody does that anymore. People have become comfortable with resorting to higher levels of abstraction as appropriate. Mostly because of Perl, PHP, Java, Python, and Ruby. In the end, performance and control either matter or they don't. If they do matter, you need that last-mile escape hatch that will never-fail. If they don't, pick something "fast enough" that makes sense for your personal tastes that suits the problem and have a ball. There will always and forever be a place for languages like Fortran, Ada, C, and C++ even if they themselves might not survive the next century.