Not all programmers are alike (a rant on Clojure).
scottlocklin.wordpress.com
scottlocklin.wordpress.com
What's so great about LabVIEW for spetroscopy? I ask because, as part of my MS thesis, I built a fourier transform spectrometer. After messing around for a few days with some LabVIEW code someone else had written for a similar task, I wrote the control code in C in a couple of hours, including the time it took to learn the (deprecated) LabWindows C API. I have no doubt that LabVIEW has improved since I did my thesis (almost ten years ago), but it's not obvious, a priori, that graphical programming should be better for controls.
I've done a reasonable amount of programming in Max/MSP and while, again, most code I've seen online was a horrible mess, I attribute that to the fact that these languages usually target non-programmer audiences who, sadly, don't get taught about proper encapsulation, abstraction, naming conventions (ie use actually descriptive names!) and software patterns.
My own code read (to me - though others have commented on it too) almost like something you'd write on a whiteboard to show how the software works to non programmers. I encapsulated each chunk of code that does a single task into its own component, so an individual component (ie diagram) never had more than a few high level "things" connected together, so you can tell - at a glance - what does what. Of course, this means that there are many layers of components, from very high level all the way down to low level, but the point is that with proper encapsulation, visual languages are no harder to understand, read or manage than textual ones and I personally feel that, in many ways, they're actually easier.
I also found debugging Max/MSP code to be the best debugging experience that I've ever had, due to the fact that you can visually see where data comes from and flows and you can intercept it at any point to see whats happening.
I also found Max/MSP a dream to do experiment-driven-development and code design and far superior to using the Python and Clojure (the two languages I use most at the moment) REPL's. I think one of the reasons is that while I'm still experimenting with concepts and design/algorithm ideas, I do not need to name things, I can just lay down a few components, connect them and see what happens. In textual languages, everything needs a name, so often you end up with a, b, x etc. I should point out, though, that when I design software (architecture or algorithms), I do it with boxes and lines, so graphical languages may just be a good fit for how I think and I guess not everybody is like that.
Don't even think of keeping things tidy, wires will be everywhere, and the auto-arranger doesn't work well.
With proper software engineering practices, this is not an issue. Without proper software engineering practices, we have the same issues in textual languages.
Modern Tools
This is a very good and important point, but its not inherently a graphical language problem. Things like version control and diffs - sure. They just work in textual languages, but in general, all languages start off with tooling problems. I do believe that good diff tools could be developed for graphical languages and that they would be at least as good as for textual languages and writing a git-compatible file format is obviously possible too (in fact, Max/MSP files look a tiny bit like JSON IIRC). This of course doesn't change the reality that currently there definitely is a tooling problem, so you are very right! But it need not always be that way.
My only complaint about Max/MSP is that I'm one of those people who hates the mouse... I spend most of my days in a keyboard-centric window manager using vim and a keyboard centric web browser, so graphical languages aren't exactly ideal from that point of view.
The 'wires going everywhere' thing is potentially a problem, but I usually took it to mean that it was time for more encapsulation or better code organization, which is I think more or less what you were suggesting. On the other hand, lots of artists create amazing work that's so will make you think you're going to have a heart attack just looking at the rats nest. But hey--these are programming amateurs and they're doing amazing things, really fast! I know some musicians who could cook up amazing stuff in Max so fast I would still be thinking about how I would structure the code and they'd be demoing it. It's also important to remember that much of what we focus on as professional programmers is less important to artists for whom cost of implementation is far more important than reuse.
Regarding version control, yes, modern max patches are in fact serialized to disk as JSON. There's an option you can set that causes the program to perform a sort on the structure on save, hopefully minimizing the diff. I worked w/ max patches in git for years, and it was fine though I never really tried to do anything even remotely interesting like merge from another branch; I treated my max patches more like binaries in version control that happened to be stored really efficiently.
In the end, much of the work I would do in Max involved writing a lot of things in C/Java/Javascript and wiring it up, and the reason is, as you alluded to, the mouse. It's just not as productive to move boxes around for me as it is to write text, but boxes and lines make really great glue code for putting together inputs, outputs, and a set of algorithms into a single work, especially if that work is time-related in some way.
It's also important to remember that much of what we focus on as professional programmers is less important to artists for whom cost of implementation is far more important than reuse.
These are two things I did not touch on in my comment at all, but you are of course correct and I feel its important enough to mention again. The fact is that people without programming backgrounds are doing amazing things and that they seem to be finding it much easier than with textual languages. The fact is that graphical languages are very successful both in audio (Max/MSP, Reaktor, Synthmaker etc) and graphics (voreen and blender embed a visual language) where they are used successfully by a lot of non-technical people. I've also seen them used in game engines, both for shading/effects/materials and for scripting of game logic[1]. As you mentioned, however, the goals and priorities of these people are generally not the same as those of professional programmers, so often writing once - but quick - is much more important to them than re-usability and modularity and that's perfectly ok if that's what makes sense for them.
boxes and lines make really great glue code for putting together inputs, outputs, and a set of algorithms into a single work
Graphical languages make for fantastic glue code/dependency injection. XML has been traditionally used to externally glue components together and IMHO is often more complex than doing it in the code itself and not really all that much more flexible at the end of the day. Graphical languages are IMHO ideal for this as they show at-a-glance, at a high level, how components in the system are connected, yet still allowing the lower level nitty-gritty algorithms to be managed in a textual language, which may be more optimized for those tasks.
LabVIEW probably has a library to talk to the spectrometer.
Apart from that, LabVIEW has very little advantage.
Anyway his overall point seems to be that Clojure isn't the only programming language, or the best one for every case. Well, ok. No one worth taking the time to talk to would ever make that assertion, so it seems like wasted bluster.
Pg -> promoting Lisps. Clojure -> a Lisp. Pg -> influential. Clojure -> got traction on HN and startup crowd.
Not true. Some of us have fallen under the sway of the Rich Hickey hypnotoad. :) Anyway, point being that Clojure is gaining traction because it has some objective strengths that converge in a way that isn't common in the realm of programming languages.
There was a tweet from Nathan Marz that I felt summed it up nicely a while back "Paul Graham set the bait, Rich Hickey reeled me in". Maybe you're right that I think it's more common than it is because it's true for me, but maybe you think it's less common than it is because it's false for you?
But yeah I'm definitely prepared to entertain the possibility that I undervalue pg's essays in the world of general purpose computing. It may be that indeed Rich Hickey should be paying Paul Graham royalties but I truly doubt it.
This. The attitude the OP describes is very common on HN as well, and can't be attributed to Uncle Bob only: the idea that programming means web, cloud, and databases. Other influential writers, like Jeff Atwood, make exactly the same mistake[1]. He can't imagine anyone doing any other martial art than Tai Chi.
A bit sad, really.
[1] http://www.codinghorror.com/blog/2009/08/all-programming-is-...
Jeff Atwood has a point that desktop apps are dead. I would not build another business app on the desktop. Users are now used to being able to access their data and applications from anywhere, and without having to install any software.
There must be other forums dedicated to scientific computing and similar topics. These topics do find a place in HN from time to time. However, they are not the norm.
Do you mean this literally? Or just business apps? I mean it doesn't seem likely that web or mobile apps are going to replace Photoshop, or Illustrator or Maya in the next decade.
But my point was that the typical readers on HN are interested in the kinds of posts here (it is a self-serving argument) - which is mostly about building web apps that help people communicate better, share content, connect people, remove middlemen, manage businesses, buy and sell stuff, increase productivity and consume content.
Scientific computing, low level programming, language research, theoretical computer science and the vast array of other computing related stuff that we don't talk about here - they are extremely important. But it doesn't find a place here for a reason and that is just fine.
I was slightly offended when I read this - I'm 'only' a web developer, but I don't believe I'm any more or less useful or talented than anyone who say, programs kernel drivers.
I'm sure the people who program kernel drivers would disagree with me, on the other hand.
It's a topic which has bugged me for an age now, am I a real programmer? Am I actually making any difference to the world? And the answer to both of those, perhaps, is no, but on the other hand, with the exception of Tim berners-lee, Linus Torvalds and Dennis Ritchie, all of us are pretty much interchangeable. I.E. You could remove us from the team and replace us pretty easily with someone else.
All those "superstar" programmers started somewhere.
Whether they were a teenage-hacker prodigy or not is irrelevant, they were young, inexperienced, and foolish programmers at one point.
Yet once they age (and gain knowledge, or perhaps more importantly, _practical_ experience) they suddenly forget that their journey had a beginning.
When you're on the road, everything feels like the middle. So I think it's important to keep perspective, and realize that (irrespective of age) their journey has just been longer than yours.
---
The other thing is: I think a programmer's fundamental job is to make computers useful for people.
At the end of the day: we provide meaningful abstractions that allow others to get computable tasks done.
I don't think it really matters how you define "get stuff done."
To the end user: the computer is a blackbox.
The fact that they can buy underwear online is just as amazing as the fact that they can turn around and plug in their digital camera. Thanks to the magic of device drivers; they can then download pictures of themselves in their fancy new underwear.
So, no, I don't think a web developer is any less of a programmer. For the same reason I don't look at a heart doctor and think: "he is clearly less of a doctor than the neurosurgeon down the hall."
Just my $.02
What about programmers writing programs for other programmers; e.g., IDEs and compilers?
Clojure actually gets quite a decent nod here, which, given Locklin's overall snarky tone, is saying something.
- Programming language innovation is rather cyclical.
- Frameworks can be re-implemented, languages ecosystems and frameworks are very important but one should not exclude a language because of it's lack of a framework feature (I think he was picking out .NET and Java here, suggesting that enterprises who select C# or Java because of the frameworks are missing the point)
- Polymorphism is achievable in Clojure, so many popular programming techniques are achievable.
I thought the talk was thought provoking and interesting. Whilst it certainly advocated Clojure, I certainly took the conclusion with a pinch of salt. The entire talk is twinged with humour. It's supposed to spark debate and help push people from their comfort zones IMHO.
Similarly, many posts around here are targeted at people in (at least) the US, often California, and usually SF or the Valley. I don't post "Noooo! It doesn't apply to me because I live in South Africa!" every time, because I understand what the context is. Something doesn't have to be universally true for it to be true in its context, and often useful for us outside of it.
In any case, thanks for the alternate opinion - it's good to be reminded that there are universes outside of ours.
The weird thing about this is that it probably wouldn't happen if he were listening to Uncle Bob (or whomever) in person. He'd raise a point, and probably get some reasonable qualification, and move on. But when the talk has already happened, and all you can do is read/listen and stew, people have an amazing ability to parse and reparse the phrasing, treating it like someone's last word and final position forever.
Maybe that makes sense for PG's essays; he seems pretty careful with words. But I don't think most people are that careful.
Read in context, I took that "shell script" statement as trying to describe Lein from the user's perspective-- which would make sense, given that his point there is its utility.
For what it's worth, I've never used Lein, and had no presuppositions about it. When I read the paragraph, I carried away the idea that Lein was written in Clojure and acts like a well-done command-line tool.
Furthermore, he did clearly state that lein's design is "Oogly" and seemed to be using his shell script statement as an example.
EDIT: Re-reading your post, I'd like to point out that my response here is solely about his remarks about leiningen and not the post in general. I'm passing no judgement on what he knows and doesn't know in general and merely pointing out that Leiningen is absolutely not just a big ol' shell script like he implies. Whether he meant it that way or not, I felt someone needed to point out that it isn't true.
scott@thinkpad ~/j64-701/bin $ file /usr/bin/lein
/usr/bin/lein: Bourne-Again shell script text executable
I picked the word "lein" instead of "leiningen" for a reason. That's the part that people use.
Of course CLOS is far more powerful than what Clojure has, but I wouldn't be so quick to discard OO in Clojure.
OO doesn't imply mutability: even in Java it's encouraged (per Bloch) to create "functional objects" -- objects that create other objects instead of mutating internal state.
Sending a message to one particular object isn't just a method dispatch mechanism. It also defines "self" and hence what data can be accessed without breaking encapsulation - another principle of OO.
Now, I'm not saying Clojure doesn't support OO. It does. What I'm saying is that whenever you go beyond thinking in terms of passing a message to one individual object you are using features that are not object oriented on a conceptual level. You could even do that in Smalltalk and it still wouldn't be OO.
What about a language like Perl, where any reference (not just a reference to a hash) can be blessed and be used to dispatch methods? Would you say OO Perl is not OO?
(I think you could argue either way).
Personally I think CLOS is a very interesting mode of doing OO. You could always define define multimethods based only on the first argument. Some parts of CLOS (method interceptors) have also made it to Java in forms of AOP (and in fact the author of AspectJ is one of the authors of CLOS) -- which provides "magic" for Java frameworks such as Guice.
While I also hate to Biblethump, but Alan Kay has also spoken very favourably of CLOS despite CLOS not being message passing. If you prefer, you can think of CLOS as a "meta OO" which lets you implement different OO behaviour including message passing.
Back to Clojure deftype and defrecord do provide encapsulation, by the way: in types with :mutable-unsyncyronized fields can only be accessed via self/this pointer.
I do agree that Clojure's protocols/multimethods aren't a full blown CLOS, but they could (sensibly) be called a form of OO (even if it's a form OO that differs greatly from Java and C++)
I agree with the article and the author seems like a reasonable and experienced programmer, but the Common Lisp comparisons just felt like hipsterism to me.
This sounds like the best you can say is "it's probably very well designed for the wrong purpose"; and I'm not sure that can be usefully distinguished from "poorly designed".
(I have dabbled with both CL and Clojure, but never used either ASDF or Lein.)
(If you don't know what "apt-get" is you can ignore this thread.)
Is somebody here knowledgeable enough to comment further on this? May this be due to excessive allocations and indirections? (It was also one of Bjarne's objections against Java.. composition of classes is always by reference.)
If you write Java as if the garbage collector and malloc actually worked as advertised, you deserve to have your software run dog slow. Nobody has ever invented a garbage collector or memory defragmentor that works for the usual CRUD Java workloads and for data-heavy or scientific computing tasks.
APL was actually the first real programming language I learned, 35 year ago! It was very cool and mind-bending, and has hugely influenced the way I think today. APL has also been hugely influential on the world, but after I learned Lisp, I'd never go back to APL. Though I do wish there were an APL embedded DSL for Lisp.
I wasn't aware that anyone still uses APL for anything real. Back when I used it, it didn't even have arrays of strings. Though you could make a twelve dimensional array of characters instead, for whatever that might be worth.
There's also J http://jsoftware.com which is the APL's designer "fix all the deficiencies" iteration. It only uses ASCII characters, and takes APL to the extreme -- e.g., +/ % # (that is: plus-slash-percent-hash) is a complete unary function that computes averages. J is open source.
And there's also K, http://kx.com which is popular in the financial world. The relation is K:J like C:Ada, I think. Whereas J strives to be pure, and mathematically complete and extremely well defined and rounded, K throws away almost every language redundancy (e.g. it only has nested vectors, which are also used to represent matrices), and does everything to be superfast. In the latest revision of the language, K4, they incorporate a database into the language. There's an open source implementation of K3 called Kona which you can find on github.
I've been working on something like this in Racket, but I'm still exploring the design space (though I worry that I'll spend too much time doing this and never actually be satisfied with anything).
By the way, was it Bob Martin who did the TDD sudoku solver? I'm always mixing up my XP evangelists.
And regarding last languages, I'm always reminded of the transputer/4GL/Prolog hype of ages past. Although one might argue that Lisp itself is probably a good candidate - but given the wide variety of existing and possible languages that could theoretically be called by that name, this isn't saying a lot.
Attempt to make so-called lisp by breaking code-is-data concept, or trying to use some yaml-like notation instead of s-expression with annotations (to describe a representation where we need only a structure), without proper recursion is something as far from Lisp as, say, Python.
there is more - http://karma-engineering.com/lab/blog
this is idiomatic Lisp:
(define (keep pred l)
(cond ((null? l) '())
((pred (car l))
(cons (car l) (keep pred (cdr l))))
(else (keep pred (cdr l)))))
this is nonsense: (defn keep
"Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects."
{:added "1.2"
:static true}
([f coll]
(lazy-seq
(when-let [s (seq coll)]
(if (chunked-seq? s)
(let [c (chunk-first s)
size (count c)
b (chunk-buffer size)]
(dotimes [i size]
(let [x (f (.nth c i))]
(when-not (nil? x)
(chunk-append b x))))
(chunk-cons (chunk b) (keep f (chunk-rest s))))
(let [x (f (first s))]
(if (nil? x)
(keep f (rest s))
(cons x (keep f (rest s))))))))))
When one breaks the underlying ideas he ruins the spell..