HN Theater @HNTheaterMonth

The best talks and videos of Hacker News.

Hacker News Comments on
Are We There Yet?

Rich Hickey · InfoQ · 139 HN points · 49 HN comments
HN Theater has aggregated all Hacker News stories and comments that mention Rich Hickey's video "Are We There Yet?".
Watch on InfoQ [↗]
InfoQ Summary
Rich Hickey advocates the reexamination of basic principles used today like state, identity, value, time, to create new constructs to deal with the massive parallelism and concurrency of the future.
HN Theater Rankings

Hacker News Stories and Comments

All the comments and stories posted to Hacker News that reference this video.
Jun 14, 2021 · sova on Tetris in ClojureScript
ClojureScript is awesome.

There are several tools available for live-coding (REPL-driven development) such as more recent shadowcljs or the older Figwheel.

Rum is a powerful wrapper over React.js and you can live code and see instantaneous results in the browser (using shadowcljs or figwheel).

ClojureScript's strengths largely stem from Clojure -- collections as fundamental types, REPL, macros, immutable datastructures* and lovely syntax.

As far as cons go, it takes some time to start up a REPL and making release builds is an extra step, but should work just fine unless you're a newbie like me and you leave strange unnecessary lines in your code. Javascript and js/CSS interop is there, but it's not super obvious and takes some getting used to what it looks like -- luckily there are enough online writeups to make that process easier.

The addage "why clojurescript? Because clojure rocks and javascript reaches" sums up nicely the motivation.

You can have largely isomorphic code on the front-end and back-end, which lends nicely to creating server-side rendered versions of SPAs for search engine indexing and fast load times. However, the server-side copy and the client rendered copy must match exactly for this to work, which can be a bit of a "thread the needle" kind of problem.

* immutable datastructures are awesome, contrast with mutable datastructures and "location oriented programming" -- any time you "edit" a value you're actually creating a new datum. This is done with atoms (immutable data stores that need to be dereferenced to retrieve their value) and operations such as swap! and reset! that either apply a function to the current value of an atom, resulting in a fresh new atom with the new value, or overwrite the atom completely with some value, respectively.

So yeah, if you like live-coding and appreciate the power of lisp, it's a really nice fit. Yes, the way to do stuff is "opinionated" but it's opinionated in what many years of trudging through the tar pit* would suggest is the right (only?) way to do things.

* Out of the Tar Pit [http://curtclifton.net/papers/MoseleyMarks06a.pdf]

I highly recommend Rich Hickey's talk "Are we there yet?" to give you an overview of the motivations behind Clojure and subsequently ClojureScript. [https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...]

My objection to this view is that, a "thing" is not the same thing as the data that represents it, and what data you use to represent the thing is dependent on what you intend to do with it. I think object-oriented programmers are more prone than others to wrongly equate their model with the thing they are modelling; the paradigm almost encourages that.

I found this talk by Rich Hickey very persuasive: https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi....

Jan 24, 2020 · 20 points, 4 comments · submitted by jtth
dang
Discussed at the time: https://news.ycombinator.com/item?id=938564

A bit from 2010: https://news.ycombinator.com/item?id=1315959

adamnemecek
I think that entity-component-system will replace oop in the near future.

https://en.wikipedia.org/wiki/Entity_component_system

zamalek
Entities are, very broadly speaking, only useful for games. ECS is a type of composition programming and, I agree, it certainly seems to be a better approach.

Rust traits are essentially static composition, and Rust seems to be eating the programming world.

I cannot fathom what a language with dynamic/late-bound/ECS composition would even look like. Hopefully we get to see some interesting stuff in that space.

jamespollack
react.js is an ECS system
refset
The transcript & slides on a single page: https://github.com/matthiasn/talk-transcripts/blob/master/Hi...

Regardless of Clojure's ultimate fate as a language implementation, I suspect that the magical combination of `Epochal Time Model + Persistent Data Structures + Pure Functions` is fairly future-proof.

> The world is not functional, as it turns out.

Have you watched the talk "Are we there yet?" by Rich Hickey? He makes a convincing case, referencing the philosophy of Alfred North Whitehead, that "the world is functional".

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

ukj
In a functional world persistence (e.g memory) cannot be a thing.

The case is convincing, but it requires you to reject your own, human, faculties.

Makes the use/expression of language rather awkward when you can't remember any words.

tome
Thanks for your input, Euthyphro!
ukj
My knack for spotting performative contradictions didn't sway you towards Deskartes?
kchamplewski
> In a functional world persistence (e.g memory) cannot be a thing.

Why not?

To give a functional Haskell flavoured example, I can use the Reader and Writer monads (which are functional) to create a whole bunch of operations which write to and read from a shared collection of data. That feels a lot like memory to me.

Indeed, the Reader monad is defined as:

> Computations which read values from a shared environment.

I just don't understand the whole "you can't have memory / order of operations / persistence / whatever else" as an argument against functional concepts when they have been implemented in functional ways decades ago. The modern Haskell implementation of the writer monad is an implementation of 1995 paper.

Edit: it looks like who I responded to doesn't actually want to have a reasonable discussion, but for anyone else reading along, it's entirely possible to have functional "state" or "memory" - what makes it functional is that the state / memory must be explicitly acknowledged.

Trying do dismiss functional computation in this way is essentially a no true Scotsman; functional computation is useless because it can't do X (X being memory or persistence or whatever), but when someone presents a functional computation that does do X, it's somehow not a "real" functional computation precisely because it does X. Redefining functional computation as "something that can't do X" doesn't help anyone, and doesn't actually help with discussing the pros and cons of functional programming since you're not actually discussing functional computation but some inaccurate designed-to-be-useless definition mislabeled as functional computation.

ukj
What are you reading from and writing to?
tome
Just FYI, you're debating with a troll.
ukj
If I am Euthyphro, then you are Socrates - no?

I thought Socrates was the troll.

ukj
What is this thing that you reading from and writing to?

It sounds mutable.

yakshaving_jgt
I’m sorry if immutability is a new concept to you, but you can read from one state, and write to a new state.

There you go. No mutation!

ukj
Writing state is the definition of mutation.

It's what all data storage systems do.

An immutable data store sounds pretty useless.

https://en.wikipedia.org/wiki/Persistence_%28computer_scienc...

yakshaving_jgt
It’s fine for you to think that. That’s not going to stop other people from finding these concepts useful though.

Once again, you are free to ignore the things you don’t understand. Your trolling is mostly harmless.

ukj
>you are free to ignore the things you don’t understand

Is that why you are ignoring the complexity behind persistence/mutability/state?

Even the Abstract Turing machine has ticker tape you know...

wlib
Interesting point. Lambda calc is equivalent, where the expression can be seen as equivalent to the ticker tape. So when a reduction occurs in lambda calculus, it's just like a group of symbols being interpreted and overwritten. But the thing is, no one has to overwrite the symbols to "reduce" them. It's just a space (memory) optimization. Usually to calculate something (you're fully correct by the way) we do overwrite symbols. The point of using immutable style is simply to make sure that references don't become overwritten. It sucks to have x+2=8 and x+2=-35.4 within the same scope, right? Especially when the code that overwrote x was in a separate file in an edge case condition you didn't consider.
ukj
>what makes it functional is that the state / memory must be explicitly acknowledged

Isn't state/memory assumed by default when talking about computation?

What kind of computations you can perform on a Turing machine without a ticker tape?

kchamplewski
Lambda calculus, for example, has no ticker tape.
ukj
What kind of computations can you perform with Lambda calculus without any input variables?

What are you applying your α-conversion and β-reduction operations to?

Barrin92
I like hickey but a lot of his examples are data driven domains where we can indeed model the world in functional or accounting-like terms.

Where this falls short is domains that are extremely ill-suited to keeping track of past states over time (his identity idea) simply because it would break performance or be hard to model in those terms, say simulations, game development, directly working with hardware and so on.

Much of his argument relies on the GC and internal implementation being able to optimise away the inefficiences of the functional model that needs to recreate new entities over and over, but this simply is not always enough.

This also is very obvious if you look into the domains where Clojure or other declarative functional languages have success, it's almost always business logic / data pipeline work.

edit: And in fact a lot of his most salient points aren't really as much about functional programming as they are about lose coupling and dynamic typing. A lot of his criticism of state and identity in languages like Java isn't related to Java not being functional, it's related to Java breaking with the idea of late binding and treating objects as receivers of messages rather than "do-ers".

karmakaze
A lot of what's done in software eventually ends up getting hardware support. Our current von-Neumann/modified-Harvard hardware architectures are old and it's precisely thinking outside these lines that will lead to non-local maxima.
filoeleven
> it would break performance or be hard to model in those terms, say simulations, game development, directly working with hardware and so on

Performance seems to be the problem there more than the model not fitting. And Rich’s answer would probably be that Clojure isn’t the right tool for those tasks in the same way that any general-purpose GC’d language isn’t.

Modeling a game or sim as a successive series of immutable states sounds great to me, so I’m curious where you see a mismatch with them. Abstracting hardware properties this way sounds useful too, but I’ve not worked with it enough to comment.

Barrin92
>Modeling a game or sim as a successive series of immutable states sounds great to me, so I’m curious where you see a mismatch with them.

because I don't really think the functional model describes it in an intuitive way. You can model a sim or game at a high level like worldstate1 -> worldstate2 etc.. but it doesn't really tell you much, because often you don't really care what the state was a second ago anyway in particular not in its entirety, and because at that high level of abstraction you don't really get any useful information out of it, so there's no point in tracking it in the same way it makes sense to track a medical history or a bunch of business transactions.

Rather instead of thinking of games or sims as high level abstract transitioning states we tend to reason about them as a sort of network of persistent agents or submodules and that lends itself much closer to a OO or message based view of the world.

I think in many systems that are highly complex and change very incrementally reasoning about things in terms of functions doesn't really tell you much. You can for example reason about a person as like say a billion states through time but there's not much benefit to it at least to me.

filoeleven
That makes sense, and the actor model (well, entity-behavior, which is fairly close) has been what I reached for in the past when doing game dev.

I agree that looking at a whole worldstate at once is unlikely to be useful. But I do see great value in keeping state changes isolated to the edges of a system, and acting upon it with pure functions. If you have the means to easily get at the piece of state tree that you’re interested in, you can reason more clearly about how each piece of a simulation reacts to changes by just feeding the relevant state chunk to it and seeing what comes back. That takes more work to set up or repeat if each agent tracks its own internal state.

I haven’t used Clojure to make a game before, so I’m speculating here. I find myself avoiding internal state by habit lately, though of course “collections of relevant functions” are valuable tools. I just lean towards using namespaced functions instead of objects with methods.

I was passively introduced to Clojure when I joined my current team at my current company a few years ago. After spending 5 years in a humongous, horribly-maintained Java code base, and a short period of time with a new-ish Scala code base that was littered with code written in almost all kinds of programming paradigms (procedural, object-oriented, and functional) and then being intimidated by the incidental complexity of the language itself prior to this transition, I was frustrated to realize the cruel fact that I had to learn another JVM language that feels even “weirder” and more “complicated” than Scala. At first, I had similar questions as you have now: “What makes this ‘ugly’ language so special that one of our smartest team leads preferred it to, say, Scala, Go, or Rust?” It was not until I watched one [1] of “Rich Hickey’s Greatest Hits” [2] did Clojure finally “click” with me. It’s all of those principles that were applied and the values that were upheld when Rich Hickey designed this elegant language. I cannot reiterate all of them here. Go watch those talks and give this language a serious try. You might end up falling in deep love with it just as I did. :-)

[1] https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...

[2] https://changelog.com/posts/rich-hickeys-greatest-hits

Nov 30, 2018 · ISO-morphism on Maybe Not [video]
Here's Rich Hickey giving a talk in 2009 guided by Whitehead quotes [1]

[1] https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...

Nov 30, 2018 · zonotope on Clojure REBL [video]
This concept is pretty subtle. Rich Hickey does a great job at explaining it (as always) in "Are We There Yet?"[1]. He deconstructs objects into state (attributes) and behavior (methods), and then uses values (or data) to represent state, and functions to represent behavior. Give that a watch a couple of times to get a better handle on what all this means from the Clojure perspective.

[edit] To answer your other question, a value that isn't a collection in Clojure is called a scalar.

1: https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...

aidenn0
Oh, so in TFA, Stuart is using the term "data" to mean "Value" in the sense that Rich talks about (Are We There Yet is only one of of many of his talks about values (I think he had one called something like The Value of Values).
Mar 26, 2018 · 2 points, 0 comments · submitted by swyx
One of the big benefits of clojure being dynamic is that everything is data (e.g. a map, set, vector or list).

This is what allows reuse.

- The vast core library of functions that manipulate those data structures can be used for everything in your program, cos it's all data.

- Most clojure libraries take and/or return data, reducing the need for clumsy adaptors, or even worse not being able to get at the data you need cos the library writer was really enthusiastic about encapsulation of everything they thought was of no use to consumers.

- You don't have a person class, you have a map with a first name and last name. Now the function that turns first + last name into full name can be reused for any other map with the same keys. (A rather spurious example, but a real one would take a large codebase and an essay to describe)

I can only recommend watching some of Rich Hickey's talks, particularly these ones, they're not entirely about types, but they express the above ideas much better than I can:

- Simple made easy https://www.infoq.com/presentations/Simple-Made-Easy

- Effective programs https://www.youtube.com/watch?v=2V1FtfBDsLU

- Are we there yet? (this one is more about OOP, but unless you're using something like haskell, idris etc its relevant for your type system of choice) https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...

mbrodersen
The data types in Clojure can be very easily (and better) expressed in (say) Haskell. For example: http://tech.frontrowed.com/2017/11/01/rhetoric-of-clojure-an...
joncampbelldev
The main issue is that Haskell is not a data-oriented language by default, this means its no fun to push it to be that. For example, I also have to use java in my job, I use persistent (functional) data structures all the time, but Java is not built for it, its not fun. (Although definitely more fun that using Java's mutable structures, ewww)

Also I personally find that to be too much overhead and ceremony in return for some type checking at compile type, as opposed to spec checking at runtime.

tome
> The main issue is that Haskell is not a data-oriented language by default

What do you mean by "data-oriented language"?

joncampbelldev
In the grandparent comment's link (showing clojure data in haskell): I'm pretty sure that is not how people code in Haskell, its not how the libraries are usually designed etc etc. Using only data is definitely possible in Haskell, but it's not encouraged by default, the core abstractions are used for concretions of information.

In the same way you can do immutable and functional stuff in java, it's not going to mesh with the rest of the ecosystem or language around you.

wtetzner
> One of the big benefits of clojure being dynamic is that everything is data (e.g. a map, set, vector or list).

What about this can't be done with types? Simple parametric-polymorphism gets you pretty far. Row types allow you to handle "maps as records" in a type-safe way. The rest is just having support for some kind of ad-hoc polymorphism so that you can re-use your functions on that small set of types (type classes, ML-style functors, interfaces, protocols, etc.).

joncampbelldev
Again, I would refer you to the Rich Hickey talks, I'm not very eloquent on this. I think its about the manual overhead that constructing your hierarchy of types, plus the cognitive overhead of doing all the fancy things in your brackets.

I'm familiar with the advantages of type systems (my progression was Java -> Haskell -> Idris) but I found my personal productivity (even in larger systems built in a team) was best in clojure. I didn't feel that the guarantees given to me by the type system were worth the mental overhead, a lot of people feel differently (you amongst them I'm guessing :p)

As a closing point, if I were to ever build something that truly had to be Robust in a "someone will die if this goes even slightly wrong" way, I would reach straight for Idris and probably something like TLA+. However most of my development revolves around larger distributed systems communicating over wires, still resilient but in a different way. Mainly I use clojure.spec in core business logic and at the edges of my programs, for generative testing and ensuring that the data flowing through the system is sensible.

Sep 20, 2017 · souenzzo on Kotlin vs. Scala
What is the difference between these (and all other languages)? All they are the same. Just syntax

https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...

Feb 16, 2017 · pmarreck on Simple Made Easy (2011)
You forgot "Are We There Yet?", which blew my mind at the time ("with respect to other code, mutability is an immutable function with a hidden time argument") and which was MY introduction to this fanclub.

https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...

Are we there yet? - Rich Hickey

https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...

wedesoft
Of all talks by rich Hickey, this is my favourite.
Sep 27, 2016 · 23 points, 2 comments · submitted by leandot
hga
This is the famous 2009 JVM Languages Summit keynote.
cpr
Fantastic talk. (Should say 2007 in the title.)

This was in August, with the first announcement of Clojure in October of the same year, so Rich was just preparing the world for Clojure concepts?

I think I take a lot of the above for granted. It all sounds like a solid CS education to me, something which many students already have.

So I think your point about being open minded is the strongest. Additionally, you bring up some excellent summaries of what each discipline is about. A lot of the time the failure here is lack of comprehensiveness, or coverage; coverage in space (what's out there) and coverage in time (what's been done historically). Current favorite example is APL: http://isomorphism.es/post/146379365169/unlike-many-language...

But as far as material goes, I suspect pure, bare metaphysics is underrated. Bearing with me, this talk by Hickey quotes a lot of Whitehead: https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...

Whitehead spearheaded Process philosophy: https://en.wikipedia.org/wiki/Process_philosophy

Most metaphysics is crap, but there are a few gems. Whitehead, Russell, Quentin Meillassoux, Wittgenstein, Northrop, Peirce, Kripke. Dealing with fundamental conceptions of space, material, time, cause, and uncertainty can go a long way when it comes to modeling code and understanding when it will correspond to reality. Programming languages give you enough flexibility to reach your ass and fuck yourself over. That needs to be constrained.

tl;dr

We're in agreement, I just like hearing myself talk.

I was hoping this would be about PLace Oriented Programming (PLOP) which confuses identity with state. It's a problem for OOP in general, where the identity of objects is predicated on their particular state. The talk http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... goes over the idea in more detail.
seanmcdirmid
Huh? The identity of an object allows for mutable state, it doesn't change with its state. I am the same person I was yesterday even if I'm in a different place or I cut my hair. State is predicated on identity, not the other way around (and given identity, you can have any kind of mutable state even in a language that doesn't support mutation, since an identity can be used as a key in an immutable map, changing the map changes the state where identity provides for a constant frame of reference).
aarpmcgee
"I am the same person I was yesterday even if I'm in a different place or I cut my hair."

Think so?

fleitz
lol, can't stop laughing, it's too bad the comments that reveal truths about the world are so often the ones that get down voted.

I'm sure eventually they will run through enough yesterdays to realize the error of their assertion.

amelius
The only constant is that we are slaves of our future selves.
seanmcdirmid
My identity is constant even if my state isn't.
straws
That's why the distinction is so lovely. Same identity, different value. State is a snapshot of an identity at some point in time.
seanmcdirmid
That still isn't right. Identity is immutable, state is something that is...identified by identity. The key of a map entry is different from the value of the entry, and in general the key can access the value, but not vice versa.
talles
The problem is when we have only the last version (state) of an identity, when we can't remember "how your haircut was yesterday".

In today RDBMS world this is on your shoulder (anyone creating columns with timestamps and PK hell?) or is left out entirely.

seanmcdirmid
True, but that doesn't change what identity is. It is only a key into a table, it is up to the table to contain values indexed by time if that is what is required.
talles
I agree with you there. Nowadays the identity points to a single thing without any notion of time, in the perfect world it would point to a set of things with their respective dates (and the database would have operations to deal with that).

If you want to get philosophical you can argue that in the real world everything mutates, even the identities. Heck, you can even say that the identity comes out of the value (the river is just on your mind, there's only water flowing). But in our digital/fuzzyless/mechanic computing models those abstractions are just unrealistic.

seanmcdirmid
Identity, or objectness, is a distinct concept from being a value that is defined purely by its form. So in that sense, identity is immutable because it is defined that way, it isn't a property that falls out of the universe. At least, its been that way since the Greek philosophy days.

A ball is an object, it has state, if its state changes, we can recognize it as being the same ball. A point/position is a value. It doesn't make sense for it to have state, a position with a different value is simply a different position. Getting around the arrow of time is something else entirely.

I looked it up, it's this talk, which indeed is the first one about Clojure, and it's philosophical foundations:

https://github.com/matthiasn/talk-transcripts/blob/master/Hi... (slides)

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... (recording)

The opening lines are:

> So I’m going to talk about time today. In particular, how we treat time in object-oriented languages generally and maybe how we fail to. So I’m trying to provoke you today to just reconsider some fundamental things that I just think we get so entrenched with what we do every day, we fail to step back and look at what exactly are we doing.

Whoever downvoted my previous comment does not know their Clojure, that's for sure.

Mar 31, 2016 · louthy on Immutability is not enough
Totally agree. Mutability adds significant cognitive difficulty that just goes away with immutable structures. Here's a great talk by Rich Hickey on the subject.

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

kkoomi
I'm watching this now and just wanted to say thanks for the great link!
louthy
My pleasure :) Even though I'm fully bought into the functional and immutable idea (I have a couple of fairly popular libraries bringing the functional world to C# [1][2]), I still like to watch this video from time to time.

The clarity of thought and the way he communicates the ideas is really impressive. Especially the notion of immutable structures being about managing time, and that's why the original blog is wrong. What he seems to totally miss is the fact that with immutable structures you can keep the old world and the new world: not collided and collided. And then step back in time to the not collided state. It gets far too bogged down on implementation attempts and doesn't think about the problem conceptually.

[1] https://github.com/louthy/language-ext

[2] https://github.com/louthy/csharp-monad

Mar 24, 2016 · 1 points, 0 comments · submitted by louthy
You don't understand comments like this because you probably don't speak from years (20+) of programming experience in OO languages, like I do, and because it is hard to show people certain better ways of doing things that unfortunately requires years of experience beating your head against the wall in other ways to really see it. But don't take my word for it, here is John Carmack (hardcore C++ developer) on the topic, from this link: http://gamasutra.com/view/news/169296/Indepth_Functional_pro...

"My pragmatic summary: A large fraction of the flaws in software development are due to programmers not fully understanding all the possible states their code may execute in. (Emphasis mine. That alone explains most of the bugs I've seen.) In a multithreaded environment, the lack of understanding and the resulting problems are greatly amplified, almost to the point of panic if you are paying attention. Programming in a functional style makes the state presented to your code explicit, which makes it much easier to reason about, and, in a completely pure system, makes thread race conditions impossible...

"No matter what language you work in, programming in a functional style provides benefits. You should do it whenever it is convenient, and you should think hard about the decision when it isn't convenient."

This is a man who has coded slightly longer than I have, and IMHO he is correct on all these points.

I merely believe he didn't go far enough (for example, immutable "variables", which are not available in OO languages without hairy workarounds, ENSURE that the state your code "sees" is not tampered with "from the outside," further reducing bugs), but statements like this are why I take the viewpoint I do.

Take the amount of time you debug as a percentage of your total programming time (and hell, we all enjoy debugging to a degree, don't we? But what's debugging, really? All it is, is trying to discover a state that wasn't conceived of when the code was designed, no? That's the whole point of your stack trace, right?). Now, chop that time in half. Would you want this? Who wouldn't?

Yes, FP is not appropriate for all realms where code lives. But it should most certainly fill all the spaces it currently does not, where its appropriateness is not out of the question.

I would also strongly recommend the "Are We There Yet?" talk by Rich Hickey http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... which pretty much destroys mutability as a language-level trait, pretty much rendering it the mother of all bugs (literally).

Again, don't take my word for it- here is MIT's core CS curriculum on mutability's dangers: http://web.mit.edu/6.005/www/fa15/classes/09-immutability/

Have I made a strong argument yet, now?

This is why I get upset whenever a new language comes out that does not feature FP/immutable paradigms. If you're new, you SHOULD be using these, otherwise you're just perpetuating more man-years of debugging hell for people. I am tired of watching new programmers make the same mistakes over and over and over again.

The very length of this comment alone indicates how hard it is to communicate this AND why it sounds like preaching/proselytizing/trolling.

This was the first presentation by Rich Hickey I watched about two years ago and since then I've been using almost exclusively Clojure. http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

I'd say start here, it will get you in the mindset of Clojure.

Aug 17, 2015 · jamii on Eve Version 0
It makes sense, I think :)

Hickey's ideas about time and state are also pretty relevant - http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

One of the things we are still working on is expressing non-monotonic logic nicely (things like "birds can fly, but penguins can't, but Harry the Rocket Penguin can"). It's unpleasant in standard datalog but I think we can provide a nicer interface.

hendzen
Is the endgame here making eve applications automatically distributed or parallelized?

I ask because the monotonic logic that Daedalus excels at expressing is quite limiting. Unless you are in an execution environment where operation ordering/synchronization is expensive (i.e. among a set of distributed processes) - the nice order-independent properties that CALM analysis gives you don't really buy you much.

jamii
I can't see us using CALM for anything in the near future. The focus right now is just on making the basic programming experience smooth. We chose Dedalus because the discrete, synchronous model of time makes it easy to separate things which are truly stateful from things which are not and to handle both in a live, interactive environment. CALM is just a bonus.
igravious
10 minutes into the Rich Hickey video and I can see why you responded to me with a link to it. This is indeed what I'm getting at; so many languages use fundamentally the same underlying logical and state model. Rich mentions single-dispatch, stateful OO. To that I would add boolean logic. Our systems or so riven by it we don't even see it. And I reckon it doesn't have to be that way! I can totally see why Eve is written in Rust from the 10 minutes of this talk that I've seen, and I can see that it is the incidental complexity of managing the lifetime of objects in your head in C++ that have forced this shift. Or, as per Hickey, Clojure-wards.

Still though, both Rust and Clojure, both presume an omnipresent bivalent atemporal logical discourse. If you're working on a different logic (or sets of logic?) in Eve then why not make them dynamically user-selectable at run-time in an intuitive manner :) Granted, I have _no earthly idea_ in practise what this means but when you reflect on how humans manipulate concepts internally you see that we have the machinery for this built into us -- or learnt somehow at a very early age. Tapping into this fluid logical apparatus would be ever so neat.

> but unfortunately because it uses a functional language, it drastically cuts down the mindshare of developers. I don't even know any developers in real life that use functional languages.

1) Once upon a time, almost no one used object oriented languages except for Smalltalk weirdos.

2) Ruby, javascript and a host of other languages have "functional" features. Does your language have a "lambda" feature, where you can define nameless functions and pass them around as arguments to other functions? Then you are already working with functional language paradigms. There's nothing really "magically hard" about it, you're overselling how hard it is. This is not rocket science. Most existing programmers can handle it.

The hardest thing I had to wrap my mind around when switching my work to Elixir was letting go of mutable state. And attributes and methods on objects. And guess what... It seems that it's a good idea, generally!

If you see enough bugs that are only there because something modified an attribute in some unpredictable way which impacted upstream code... You will realize mutable state is bad.

If you still aren't convinced that mutable state is evil, watch this Rich Hickey presentation http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... which basically proves that mutable state actually makes state a function of a hidden/conflated "time" variable, proving it's not just wrong from a practical standpoint (in the form of extra bugs that are hard to reason about, and all this brittle mutex code) but from a theoretical one, too. Mutable state comes from a time when memory was expensive, and it's time to ditch the training wheels so we can get the real work done.

Both Javascript and Ruby use mutable state extensively, and it's unfortunately not something you can just slap onto the language after the fact (although ClojureScript must make a valiant effort!) And if the high-level language wasn't built with it from the get-go, then you're stuck dealing with legacy libraries using the poorer-written code (see: Ruby gems).

ab5tract
Right...

Another fad brought up for the sheer fashionability of it.

Saying "mutable state is bad" is just as inane as saying "immutability is bad". There are tradeoffs for either. There is absolutely no reason to pretend that one trumps the other in all cases.

Other than looking cool to your peers, I guess.

lectrick
I spent over 10 years writing and working on (and debugging... many hours of debugging) Ruby code.

Towards the end I started to write all my Ruby code, as much as possible, as so-called PORO objects (Plain Ol' Ruby Objects). These feature zero inheritance, and are initialized with all the state they need to do their work. I started doing this because I found that writing code that way produced more easily testable, more maintainable, more stable code.

Then I realized that functional languages basically all already forced you to do those things, by not holding state anywhere, forcing you to pass it around.

These were all logical steps (with the end goal optimization of "useless work elimination"). There was no faddiness involved, other than having "a good feeling" about working with Elixir (over, say, Clojure, Haskell or the other options out there).

yellowapple
Nobody's "pretending" that immutability trumps mutability. Rather, we're observing it firsthand. By making immutability the rule rather than the exception thereof, one eliminates a huge swath of bugs and makes an even bigger swatch much more difficult to achieve.

That said, you're right that there are tradeoffs, which is why languages like Rust - while defaulting to immutability - allow a programmer to define variables as mutable, and why Elixir (unlike Erlang) allows variables to be reassigned (though the data stored in those variables is still immutable; this is something that's enforced by BEAM).

And of course, you can still get many of the benefits of immutability with mutable variables by being careful about how you're using those variables; the difference, however, is that a language which assumes immutability will be able to catch those bugs more easily, forcing the programmer to fix them (either by making the variable mutable (in applicable languages) or refactoring until mutability isn't necessary).

Reminds me of this (absolutely spectacular) talk from 2009 by Rich Hickey: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...
I love when computing mixes with philosophy, despite being unable to grasp most of it.

Take for instance Rich Hickey's Are We There Yet?[1], the Alfred North Whitehead quotes are great food for thought: you dive into it just as much you are able to swim.

[1]: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

The idea behind OOP makes sense. But the carry-out of OOP in pragmatic programming languages is the problem.

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

vinceguidry
You seriously expect me to watch an hour-long presentation just to get your point?
thomasloh
if you seriously want to understand it :)
vinceguidry
Please don't treat me like an idiot. I've been studying OOP concepts for quite some time now. I'm quite capable of figuring out any deep concepts you care to throw at me. If you can't explain them in your own words, fine, but don't expect me to believe you have any real insight on this question because of that. I could watch that whole video and still not know what you were trying to argue.
thomasloh
Doing OOP in languages like Java and Ruby tend to involve classes, objects, encapsulation and state coordinating. Now, the truth is, state is really hard to maintain. You have this piece of information where everyone is trying to change or grab at, it's gonna end up leading to race conditions and locking. It may work for a small app, but as your application scale up, it's a maintainability disaster. So you said OOP done right helps. But, OOP was the wrong paradigm to begin with, it's like saying "Horse-riding done right gets you anywhere faster". I'm not saying everyone who has been programming in OOP is wrong, it totally makes sense to use OOP because it's easier to model real world things with. But no one has ever question, "This paradigm may be facilitating my understanding of the problem, BUT is it the right paradigm?"

As Dijkstra said,

"Dont't trade simplicity for familiarity."

vinceguidry
> You have this piece of information where everyone is trying to change or grab at, it's gonna end up leading to race conditions and locking.

Why is everything trying to grab at state? I call information that everything wants access to 'data', and I manage that accordingly. Each application interested in it grabs the data, preferably stored in a database selected specifically for the needs of the data and how it's accessed, parses it into objects, does the operation it needs to on it, and then perhaps writes a new record of data. The objects can go away as soon as they go out of scope, leaving the data available to construct a new object when it's needed.

People say to store state in a RDBMS, I think that's ridiculous and a perversion of OOP. Program state belongs in memory, not on the network. It's not intended to be tabular, an object's state often consists of references to other objects. I sure hope you're not storing these in a database.

An object's state is only supposed to be accessible through it's interface. It's bad OOP to have other parts of the program interrogating its state directly. It's bad OOP to have an object interact with more than a few other objects. If you find yourself violating that, then you're treating data as state and you need to start managing that data separately, through a persistence layer.

Maintainability means being able to alter a program's behavior without having to understand the whole thing or make drastic edits. If you follow the rules of OOP and don't just say you're doing OOP because you're using classes and stuff, then you'll have earned maintainability because you'll be able to change a class's internal behavior without affecting the rest of the program because it's using an interface rather than needing deep knowledge of the altered class. And you can change the interfaces too, only changing the two or so other classes that use them.

I would suggest to you that Clojure has a very clear "the Clojure Way" I would say, more so then almost any other language. It goes beyond syntax to a pretty deep design level. Its not even all that unique to clojure, you could do 'the clojure way' in other languages, but they usally dont.

Some of the importent keynotes from some of the early conjs are really importent, and they really went deep in the community, you can see it in almost every major library.

Another commenter has mentioned the notion of 'simple' but thats not really all that clear. I not enougth of a writer to tell you about it, but I can give you the resources:

- This classic got Clojure on the map for many people: Are We There Yet? - Rich Hickey www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

- Simple Made Easy - Rich Hickey - http://www.infoq.com/presentations/Simple-Made-Easy-QCon-Lon...

- Simplicity Ain't Easy - Stuart Halloway - https://www.youtube.com/watch?v=cidchWg74Y4

- Ousterhout's Dichotomy Isn't (Part 2 of the Simplicity/Power/Focus Series) - Stuart Halloway - https://www.youtube.com/watch?v=cidchWg74Y4

- The Language of the System - Rich Hickey https://www.youtube.com/watch?v=ROor6_NGIWU

- Hammock Driven Development - Rich Hickey https://www.youtube.com/watch?v=f84n5oFoZBc

In addition to these, there are many talk that are about people trying to run with these ideas. Datomic is a example of taking these ideas to the max, it really standas as a nice example. You can find others in talks by David Nolan for example, but there are tons of applied talks.

- The Design of Datomic - Rich Hickey http://www.infoq.com/presentations/The-Design-of-Datomic

A talk by Rich Hickey (creator of Clojure) about what sets Clojure apart from the usual object oriented languages, concurrency-wise: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...
Apr 05, 2014 · louthy on C# 6: First reactions
> Yes it's enough if the property setting logic is only executed once during the lifetime of the object. So, it only works if they're supposed to be immutable.

They are. Dig out some of the talks by Rich Hickey on immutability, he tends to put it pretty concisely, better than I ever could. But primarily it's about capturing snapshots of your world at a particular point in time so that you have a consistent view of the world. So all objects should be immutable.

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

> Plus, public fields cannot be used for data binding.

JsonConvert.SerializeObject()

JsonConvert.DeserializeObject()

That's all I need, or a .Select(). I don't use WinForms or any of the standard ASP.NET databinding stuff, it's ugly as sin. Even if I did, isn't there a LinqDataSource or something these days? Not sure if that would do the job, but I'd assume it would work with the results of a LINQ expression? Anyway, I don't really need that, and being able to reason about my code is more important.

> Plus, you can't debug nor log whenever a field value is read.

Never caused a problem, there's always the code that reads from it. Stick your breakpoint there. Also when you use immutable structures throughout, your bugs tend to not be in the 'values' (i.e. an immutable structure).

I tend to be breakpointing in the ctor if anything to check the setter logic or input values. Once the object is set, that's it. No need to keep checking.

> Also, you can end up having to convert it into a property, and this involves various compatibility risks.

Fields an properties are incompatible? How?

> What do you gain instead, with your design choice?

* I can pass an object to another method and know it's not going to change it without my permission.

* I don't have to analyse the inner workings of a class to find out how the state is going to be changed when I call a method on it.

* I can pass the same object to two threads running in parallel knowing that there won't be problems with the two threads writing to the same object..

* I can easily write transactional code and 'rollback' when it fails.

* I can write pure functions which makes it easier to test my code.

It's much easier to reason about a data structure if you know they won't change basically. There's huge advantages to that. Personally I find it makes my code more reliable and easier to compose and manage long term.

I agree it's not all sweetness and light using immutability with C#. There's more boilerplate than necessary and there's very little in the language to help the process.

Personally I think it's worth it, YMMV.

V-2
> So all objects should be immutable.

YMMV as you say, but I think that your needs are very specific if that's your base principle. Objects in C# are mutable by design, so you're kind of working against the language here. It sounds like your approach is closer to functional programming (but again, I don't know the context)

> I don't use WinForms or any of the standard ASP.NET databinding stuff

Neither WPF, Siverlight... long story short, hardly any popular .NET framework (nothing wrong about that, it just goes to show that your case is not mainstream)

> Fields an properties are incompatible? How?

See http://csharpindepth.com/articles/chapter8/propertiesmatter.... - "Compatibility issues".

> Never caused a problem, there's always the code that reads from it. Stick your breakpoint there

As long as it's only one or two places and as many breakpoints, sure :) life's beatiful then

> I can pass an object to another method and know it's not going to change it without my permission.

Achievable with properties (with private setter), so I wouldn't count it as a benefit.

I see where you're coming from, but to me you are pointing out the advantages of immutability, not choosing fields over properties. I think you are not wrong in preferring immutability, of course - I know it has its perks - but in assuming that one is synonymous with the other. Whereas you can implement immutability with properties just as well (and you can still use a readonly field as the backing field).

louthy
> YMMV as you say, but I think that your needs are very specific if that's your base principle.

Not really. This is for a very large web-based medical practice-management system and tertiary services. It mostly sits on top of stripped-back ASP.NET, but yes it's a framework I developed myself because 9 years ago when this project started ASP.NET was awful.

So yeah, whilst it's non-standard, it's not rocket science, or some bizarre parallel C# universe. I still need to get data from the server to the client in an efficient way, I still have controllers, server pages, database CRUD, etc.

> Objects in C# are mutable by design

Objects are mutable by default, but there also exists a keyword called readonly which has been there since v1.0 of C#, so I would argue that it's just as much of a language feature. It not being the default doesn't make it any less of a valid approach. One of the most used library types is immutable: String.

> It sounds like your approach is closer to functional programming (but again, I don't know the context)

I try to follow that route, yes. Clearly it's not always possible because of the limitations of the language or the .NET framework, and that's fine, I'm not going to be dogmatic over it. I think however that immutability where possible helps code quality overall.

> Fields an properties are incompatible? How? > See http://csharpindepth.com/articles/chapter8/propertiesmatter..... - "Compatibility issues".

That's very interesting, but none of those are really issues for me, and I'd argue they'd be minor issues for most people too:

> You lose binary compatibility

We always compile from source

> You can use a field for ref parameters, whereas you can't (in C# at least) use a property in the same way.

Ref fields are nasty, I wouldn't want to see anyone on my team using them. obviously passing a readonly field to a ref is pretty pointless. So non-issue for me.

> Involving a mutable structs

Don't use mutable structs.

> You lose reflection compatibility

Call GetFields instead of GetProperties. Non-issue internally. I guess if a 3rd party lib didn't support fields then it might be a problem, so far it hasn't been.

> Achievable with properties (with private setter), so I wouldn't count it as a benefit.

No it isn't, because the method you called could call a method on the object you passed, affecting the underlying state of the object. If you work on small code-bases and you understand the implications of every function you call then great, but the added peace of mind knowing that this structure you passed to a method isn't going to be changed (now or by a programmer in the future) is very powerful.

It's also makes method signatures tell you explicitly the behaviour of the code within, which makes it easier to look at the surface of a library to know what it does, i.e.:

    MutableState state = new MutableState(...);
    MutableLib.DoSomething(state);
    // ... any code run after DoSomething is now flying-blind, has state changed?

    public class MutableLib
    {
        public static void DoSomething(MutableState state)
        {
            // What happens here?  Does MutableState get changed?  How can you know when the 
            // method returns 'void' and takes a mutable object?  You have to look at the code
            // to know for sure.
        }
    }
Then the immutable version. Notice how the signature to DoSomething is explicit in its purpose.

    ImmutableState state = new ImmutableState(...);
    var newState = ImmutableLib.DoSomething(state);
    // ... any code run after DoSomething is entirely aware that state has changed

    public static class ImmutableLib
    {
        public static ImmutableState DoSomething(ImmutableState state)
        {
            // What happens here?  Well it doesn't matter to the caller, they know
            // they get a new ImmutableState back, and if they chose to ignore it
            // then the original state object they passed in will be unaltered.
        }
    }
It also allows for free transactional behaviour with rollbacks, which can be super useful:

    ImmutableState state = new ImmutableState(...);
    try
    {  	
    	var newState = ImmutableLib.DoSomething(state);
    	newState = ImmutableLib.DoSomethingElse(newState);
    	newState = ImmutableLib.DoAnotherThing(newState);

    	// Commit
    	state = newState;
    }
    catch
    {
        // If an exception fires then state won't have changed. 
    }

> I see where you're coming from, but to me you are pointing out the advantages of immutability, not choosing fields over properties.

You're right that I'm primarily arguing for immutability, but I would also argue that properties can't achieve immutability because the object can always change itself. A private property can always be changed by a member function. Clearly you can make classes that are immutable for all intents and purposes by using properties; I just prefer the explicit nature of 'readonly' - it's a language feature to be used in my humble opinion.

There's also the argument that properties are an extra unnecessary abstraction for this case. With a readonly field/property it is only set once, so having a layer of getter/setter logic is unnecessary. You only need that logic once at construction.

None
None
V-2
> What happens here? Well it doesn't matter to the caller, they know they get a new ImmutableState back, and if they chose to ignore it then the original state object they passed in will be unaltered.

Yes if they choose, but how are they supposed to make this choice? :)

You can't make an informed decision about it UNLESS you know what is the difference between ImmutableState instance returned by DoSomething and the original one.

We're back to the same problem, then. We can't be sure what DoSomething does without peeking into its implementation.

That it produces another instance in process may be nice, but the core problem is the same.

Can I know for sure how the state of my MutableState object changed?

Can I know for sure what is the difference between the ImmutableState I passed to you and the other ImmutableState you made me pull out of your blackbox? I'm flying blind just the same

> It also allows for free transactional behaviour with rollbacks, which can be super useful:

Agreed, but there is more than one right way to achieve it. This could be also done with mutable objects and deep copies. Just make yourself a backup clone before you go wild.

The cost of your approach is that all behaviour and logic is moved into some ImmutableLib class, so you're creating various "Libs", "Managers", "Services" and the like, which means that you're essentially writing procedural code.

This OOP anti-pattern is known as anemic domain model.

http://www.martinfowler.com/bliki/AnemicDomainModel.html

Thanks for the link to Rich Kickey's presentation, it seems to be some food for thought. I'll watch it when I have some free time on my hands and maybe it will affect the way I see it.

In order to understand the frame of reference for Om, you really need to watch some Rich Hickey presentations [1][2] (or have a good understanding of functional programming). The first one is more relevant to your questions here, the second is just because Clojure programmers have very specific definitions of "simple" and "easy" and because it's a good talk.

[1] http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... [2] http://www.infoq.com/presentations/Simple-Made-Easy

That said, on to answering your questions:

> If data changes, it needs to mutate, right? ...

Data doesn't change in this model (see [1]). Incoming events (keyup, network request, page load) occur and your program responds to those events by producing a new, immutable set of data that you're going to use going forward. Om apps keep one reference to the root of the data tree–Om examples use app-state as the name–which represents the official current state of the data. You can reasonably argue that swapping out app-state is changing data except that anything that had a reference to the previous root(s) still has that reference and you have to go dereference app-state to get the current value instead of having it changed out from under you.

> If that's the way, how can you efficiently do updates on relatively large chunks of data? ... Or am I missing something and is it really not that bad?

[3] http://eclipsesource.com/blogs/wp-content/uploads/2009/12/cl...

Clojure(script)'s data structures use structural sharing. The above picture shows inserting a single node into the middle of the structure. The red outlined nodes are the parents which need to be copy+updated, as shown on the right with all the dotted lines being shared references. The most misleading thing about the picture is that the actual cljs trees have 32 branches at each node instead of 2 or 3 so the lookup time is log32 N (basically constant [4], impl in a systems language vs classic datastructures for comparison). In your Gmail example you'd have to make ~3 new nodes.

[4] https://github.com/michaelwoerister/rs-persistent-datastruct...

> In general, doesn't this make model code much much more complicated?

It requires a different mindset and generally some helper code. In Clojure using Om it's pretty straightforward once you're over the initial hurdle. In javascript using Mori [5] it looks a lot like awkward Backbone with very heavy Underscore use. I've poked around at it and if I were going to try to adopt Mori+React for a real project I'd want to do some quality of life tweaks on Mori. Mostly setting a prototype on the Mori objects to get the feel closer to Backbone+Underscore and trying to get the data structure console output to be more useful.

[5] https://github.com/swannodette/mori

skrebbel
Thanks a lot for the detailed explanation. I'll watch the videos (saw the Simple/Easy one already, they're good definitions of the words and it would be great if they'd be adopted more broadly outside the Clojure community too).

I think I'm catching the drift here. This app-state variable was the concept I was missing. That, and how smart the Clojure(Script) data structures really are.

Mori looks pretty damn nice, actually. Would consider using it in practice.

Dec 03, 2013 · sesm on The Language-Language Matrix
Clojure is designed as a hosted languages from the start and intentionally exposes platform semantics for many operations, such as math, strings, etc. This makes porting easier, since one doesn't have to implement "compatibility layer" for all those operations.

On a side note, Clojure concurrency primitives implement different ideas compared to FRP. A good source to learn about ideas behind Clojure concurrency is this talk by Rich Hickey: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... . At 1:08:25 Rich tells his opinion about FRP.

mtrimpe
I haven't watched that part of the video yet, but I've always believed that Rich's biggest blind-spot seems to be about not realizing how Clojure's macro system can be used to rewrite regular code into FRP.

Just have a look at what a macro like Javelin [1] already enables [2] and imagine how powerful that would be when combined with 'live' Datolog queries where the query results in the browser will stay up to date with the results from the logic datalog query on Datomic.

I've tried explaining it to Rich at EuroClojure 2012 but I'm pretty sure he was still thinking in terms of 'classic FRP' back then.

[1] https://github.com/tailrecursion/javelin [2] http://www.infoq.com/presentations/ClojureScript-Javelin

lukev
It's not classic FRP, but you're basically describing core.async. Have you looked at that at all?
mtrimpe
Core async is also an example of a very powerful macro that rewrites execution flow; but they do decidedly different things.

While Core Async is about powerful non-threaded coordination of processes, Javelin is about creating self-updating non-cyclical function graphs.

Basically it's about automatically keeping a derived a view from a small set of data up to date when the source data changes.

It's the exact same thing a spreadsheet does for numbers, but becomes much more interesting when the derived view is a DOM tree derived from database+view state.

FWIW; I was inspired by the the work of Kenny Tilton (a.k.a. Smuglispweeny) and his Cells library and manifesto [1]. His work seems to be falling in disarray, but there's still some stuff up on the wayback machine [2][3]

[1] http://smuglispweeny.blogspot.nl/2008/02/cells-manifesto.htm...

[2] https://web.archive.org/web/20080925125040/http://www.tilton...

[3] https://web.archive.org/web/20080925113544/http://bc.tech.co...

mtrimpe
Just watched it and his response is definitely not about the kind of FRP I'm talking about here, but seems to be criticising a specific interpretation of continuous FRP.

When asked what is the right direction he explicitly mentions that it's when all your data is immutable, which definitely applies to Javelin.

Oct 30, 2013 · 1 points, 0 comments · submitted by aespinoza
Yes, "Simple Made Easy" is a must watch imo. http://www.infoq.com/presentations/Simple-Made-Easy

"Are we there yet" is also great: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

I also love "Hammock Driven Development": http://www.youtube.com/watch?v=f84n5oFoZBc

Jun 21, 2013 · cgag on Ask HN: Clojure vs Go
In my mind Clojure is an easy win unless you're writing short running things that need to boot fast (though you could consider clojurescript + node for that).

Both languages have good support for concurrency, but for me Clojure has much more going for it:

- It's fast, and has all the tooling and libraries from the JVM - it has immutable datastructures with literals for all of them) by default, this is huge, they're probably the thing I miss most when I have to use other languages. - It encourages functional programming very strongly, but has excellent support for managing mutable state when you need it. - It's very simple (it's a lisp) and has a very small number of primitives, with much of the standard library coming from macros rather than actually being baked into the language. - The community is amazing, #clojure on freenode is incredibly helpful and friendly towards noobs.

I probably don't sell it well, but I'd highly recommend watching some of Rich Hickey's talks to sort of understand the philosphy that goes into Clojure:

http://www.infoq.com/presentations/Simple-Made-Easy http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

Don't go for Go just because it's familiar ;)

The quotation is nearly twenty years old. For context that's before Java [practically speaking] and before C++ was standardized - and when programmers of Graham's age had a background using PEEK and POKE and GOTO in BASIC or exposure to assembly and the older programmers had often seen plugboards in use.

I won't guess at Graham's definition today. He can speak for himself, anyway. But it resonated with me in the context of Rich Hickey's ideas - particularly "Are We There Yet?" http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

As I understand it, an issue with [some] object systems is that when objects are made by aggregation, rather than inheritance, they are of a different type than each of their components. And this requires the programmer to write some code [however minimal] for the new type in order to reimplement any desirable feature of the objects from which it is composed.

In other words, the behavior of an aggregate of objects is undefined. Hickey's comparison is to data. Which he claims aggregates into more data. When, I ask myself "what is data?" lisp-a-cadabra - it's code. Which is the [structuralist] way in which I read Graham's note.

Summary of the links shared here:

http://blip.tv/clojure/michael-fogus-the-macronomicon-597023...

http://blog.fogus.me/2011/11/15/the-macronomicon-slides/

http://boingboing.net/2011/12/28/linguistics-turing-complete...

http://businessofsoftware.org/2010/06/don-norman-at-business...

http://channel9.msdn.com/Events/GoingNative/GoingNative-2012...

http://channel9.msdn.com/Shows/Going+Deep/Expert-to-Expert-R...

http://en.wikipedia.org/wiki/Leonard_Susskind

http://en.wikipedia.org/wiki/Sketchpad

http://en.wikipedia.org/wiki/The_Mother_of_All_Demos

http://io9.com/watch-a-series-of-seven-brilliant-lectures-by...

http://libarynth.org/selfgol

http://mollyrocket.com/9438

https://github.com/PharkMillups/killer-talks

http://skillsmatter.com/podcast/java-jee/radical-simplicity/...

http://stufftohelpyouout.blogspot.com/2009/07/great-talk-on-...

https://www.destroyallsoftware.com/talks/wat

https://www.youtube.com/watch?v=0JXhJyTo5V8

https://www.youtube.com/watch?v=0SARbwvhupQ

https://www.youtube.com/watch?v=3kEfedtQVOY

https://www.youtube.com/watch?v=bx3KuE7UjGA

https://www.youtube.com/watch?v=EGeN2IC7N0Q

https://www.youtube.com/watch?v=o9pEzgHorH0

https://www.youtube.com/watch?v=oKg1hTOQXoY

https://www.youtube.com/watch?v=RlkCdM_f3p4

https://www.youtube.com/watch?v=TgmA48fILq8

https://www.youtube.com/watch?v=yL_-1d9OSdk

https://www.youtube.com/watch?v=ZTC_RxWN_xo

http://vimeo.com/10260548

http://vimeo.com/36579366

http://vimeo.com/5047563

http://vimeo.com/7088524

http://vimeo.com/9270320

http://vpri.org/html/writings.php

http://www.confreaks.com/videos/1071-cascadiaruby2012-therap...

http://www.confreaks.com/videos/759-rubymidwest2011-keynote-...

http://www.dailymotion.com/video/xf88b5_jean-pierre-serre-wr...

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

http://www.infoq.com/presentations/click-crash-course-modern...

http://www.infoq.com/presentations/miniKanren

http://www.infoq.com/presentations/Simple-Made-Easy

http://www.infoq.com/presentations/Thinking-Parallel-Program...

http://www.infoq.com/presentations/Value-Identity-State-Rich...

http://www.infoq.com/presentations/We-Really-Dont-Know-How-T...

http://www.mvcconf.com/videos

http://www.slideshare.net/fogus/the-macronomicon-10171952

http://www.slideshare.net/sriprasanna/introduction-to-cluste...

http://www.tele-task.de/archive/lecture/overview/5819/

http://www.tele-task.de/archive/video/flash/14029/

http://www.w3.org/DesignIssues/Principles.html

http://www.youtube.com/watch?v=4LG-RtcSYUQ

http://www.youtube.com/watch?v=4XpnKHJAok8

http://www.youtube.com/watch?v=5WXYw4J4QOU

http://www.youtube.com/watch?v=a1zDuOPkMSw

http://www.youtube.com/watch?v=aAb7hSCtvGw

http://www.youtube.com/watch?v=agw-wlHGi0E

http://www.youtube.com/watch?v=_ahvzDzKdB0

http://www.youtube.com/watch?v=at7viw2KXak

http://www.youtube.com/watch?v=bx3KuE7UjGA

http://www.youtube.com/watch?v=cidchWg74Y4

http://www.youtube.com/watch?v=EjaGktVQdNg

http://www.youtube.com/watch?v=et8xNAc2ic8

http://www.youtube.com/watch?v=hQVTIJBZook

http://www.youtube.com/watch?v=HxaD_trXwRE

http://www.youtube.com/watch?v=j3mhkYbznBk

http://www.youtube.com/watch?v=KTJs-0EInW8

http://www.youtube.com/watch?v=kXEgk1Hdze0

http://www.youtube.com/watch?v=M7kEpw1tn50

http://www.youtube.com/watch?v=mOZqRJzE8xg

http://www.youtube.com/watch?v=neI_Pj558CY

http://www.youtube.com/watch?v=nG66hIhUdEU

http://www.youtube.com/watch?v=NGFhc8R_uO4

http://www.youtube.com/watch?v=Nii1n8PYLrc

http://www.youtube.com/watch?v=NP9AIUT9nos

http://www.youtube.com/watch?v=OB-bdWKwXsU&playnext=...

http://www.youtube.com/watch?v=oCZMoY3q2uM

http://www.youtube.com/watch?v=oKg1hTOQXoY

http://www.youtube.com/watch?v=Own-89vxYF8

http://www.youtube.com/watch?v=PUv66718DII

http://www.youtube.com/watch?v=qlzM3zcd-lk

http://www.youtube.com/watch?v=tx082gDwGcM

http://www.youtube.com/watch?v=v7nfN4bOOQI

http://www.youtube.com/watch?v=Vt8jyPqsmxE

http://www.youtube.com/watch?v=vUf75_MlOnw

http://www.youtube.com/watch?v=yJDv-zdhzMY

http://www.youtube.com/watch?v=yjPBkvYh-ss

http://www.youtube.com/watch?v=YX3iRjKj7C0

http://www.youtube.com/watch?v=ZAf9HK16F-A

http://www.youtube.com/watch?v=ZDR433b0HJY

http://youtu.be/lQAV3bPOYHo

http://yuiblog.com/crockford/

ricardobeat
And here are them with titles + thumbnails:

http://bl.ocks.org/ricardobeat/raw/5343140/

waqas-
how awesome are you? thanks
Expez
Thank you so much for this!
X4
This is cool :) Btw. the first link was somehow (re)moved. The blip.tv link is now: http://www.youtube.com/watch?v=0JXhJyTo5V8
Two great ones by Rich Hickey, the creator of Clojure -

Are We There Yet? - http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

Simple Made Easy - http://www.infoq.com/presentations/Simple-Made-Easy

stretchwithme
Yes, I was quite impressed with the second one. Haven't seen the first one.
ravimbalgi
http://channel9.msdn.com/Shows/Going+Deep/Expert-to-Expert-R...

this one is so far the best by the Guru himself

I agree – anything from Rich Hickey. Especially "Persistent Data Structures"[1] and "Are We There Yet?"[2].

Though related to Clojure, they make you think about development in different ways.

[1]: http://www.infoq.com/presentations/Value-Identity-State-Rich...

[2]: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

adams601
'Simple Made Easy'[1] is one of my favorite Hickey talks.

[1]: http://www.infoq.com/presentations/Simple-Made-Easy

Nov 26, 2012 · 2 points, 0 comments · submitted by olenhad
Sep 24, 2012 · spacemanaki on Learning to Learn
All of Rich Hickey's talks great, but they're not really about learning how to learn. "Hammock Driven Development" is probably the closest, and is about approaching problem solving generally.

Both "Simple made easy" and "Are we there yet" are pretty general, not necessarily Clojure-specific talks, although they do point to Clojure and more broadly FP as a possible solution to the problems presented.

http://blip.tv/clojure/hammock-driven-development-4475586

http://www.infoq.com/presentations/Simple-Made-Easy

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

For Rich, two of my favorites are:

Are We There Yet http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

Clojure Concurrency http://blip.tv/clojure/clojure-concurrency-819147 These early videos of Rich demoing his little project have such a cool feel. There are several more on the blip.tv account.

And in addition to the two you mention and these are good:

Hammock Driven Development http://blip.tv/clojure/hammock-driven-development-4475586

Clojurescript http://blip.tv/clojure/rich-hickey-unveils-clojurescript-539...

> a time dimension (or, if you prefer, place-oriented programming)

Place oriented is the opposite of having a time dimension. It means that at any time, the thing at that place might be different. This was done for your second argument, efficiency. The talk argues that if functional programming with values is efficient enough for you, than you shouldn't be writing object oriented software.

Values on the other hand absolutely have a time dimension. His "Facts" slide says it as does datomic and his revision control example.

He has another great talk that touches a bit more on time:

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

Chris_Newton
For the avoidance of doubt, when I’m talking about (not) doing away with a time dimension here, I mean from the perspective of the world changing over time as our program runs, not of associating values that effectively last forever with a certain point in time (as in purely functional data structures, version control systems, etc.).

That is, even if we follow the current trend of adopting more ideas from functional programming in mainstream programming languages, I’m saying that I doubt we will ever completely remove variable state, which is what I understand Rich to mean by “place-oriented programming”, or events that must happen in a certain order.

Instead, I think we will learn to control these aspects of our programs better. When we model time-dependent things, we want to have well-specified behaviour based on a clean underlying model, so we can easily understand what our code will do. Today, we have functions and variables, and we have type systems that can stop us passing the colour orange into a function eat(food). Tomorrow, I think we’ll promote some of these time-related ideas to first-class entities in our programming languages too, and we’ll have rules to stop you doing time-dependent things without specifying valid relationships to other time-dependent things. Some of the ideas in that second talk you linked to, like recognising that we’re often modelling a process, are very much what I’m talking about here.

As an aside, it’s possible that instead of adding first-class entities for things like effects, we will instead develop some really flexible first-class concepts that let us implement effects as just another type of second-class citizen. However, given the experience to date with monads in Haskell and with Lisps in general, I’m doubtful that anything short of first-class language support is going to cut it for a mainstream audience. It seems that for new programming styles to achieve mainstream acceptance, some concepts have to be special.

In any case, my hope is that if we make time-related ideas explicit when we care about them, it will mean that when we don’t need to keep track of time, we needn’t clutter our designs/code with unnecessary details. That contrasts with typical imperative programming today, where you’re always effectively specifying things about timing and order of execution whether you actually care about them or not, but when it comes to things like concurrency and resource management the underlying models of how things interact usually aren’t very powerful and allow many classes of timing/synchronisation bug to get into production.

danenania
I'm far from an expert on this topic, but it seems that you're still missing the main point--this talk is exactly about how to model time dependent data (immutable data), and how not to (mutable state, oo). Hickey definitely isn't advocating a system that can't change with time. Such a system would be pointless. He wants changes in state (which, naturally, occur on a time axis) to be represented by new values, not as in place, destructive updates of old values, as it's done in oo and currently popular databases.

If you look at the results of this approach in Datomic, I think you actually do see a design that treats time as much like a first-class citizen as it's ever been treated, in the sense that time essentially acts as a primary key, and developers are provided with a time machine that allows them easy and efficient access to any state that has existed in their data in the history of the application. (In theory, at least--I haven't personally tried Datomic).

Chris_Newton
I’m pretty sure I understand where Rich is coming from. I’m just arguing that while moving to persistent, immutable values is a big step in what could be a good direction, it’s not sufficient by itself to justify or cause a shift in mainstream programming styles on the scale of abandoning OOP (as suggested in the original post I replied to).

You lose things in that transition, very useful things that are widely applicable. We’re not going to just give those up without having something good enough to replace them, and I thought that in this specific talk those two areas I mentioned were glossed over far too readily.

For example, although Rich said very clearly that he thought it was OK to manipulate data in-place as an implementation detail of how a new value is built, he then argued that once the finished result was ready it should become an immutable value, and that we no longer need to use abstractions that are based on or tied to that kind of underlying behaviour. I contend that there are many cases where it is not so simple even with today’s technology, and that the idea of constraining in-place mutation to the initial creation of a value is a leaky abstraction that will not survive a lot of practical applications.

Later on, processes are briefly mentioned, but that part of the talk is about information systems, which are mostly concerned with pure data analysis. That makes it is rather easy to dismiss the idea of modelling interactive processes in context, but unfortunately, very many real world programs do need to be concerned with the wider time-related concepts like effects.

I’m sure Rich himself is well aware of all of these issues. He’s discussed related ideas in far more detail on other occasions, including in the talk that lrenn cited above. But I find his challenge near the end of this talk, “If you can afford to do this, why would you do anything else? What’s a really good reason for doing something else?” to be rather unconvincing. For one thing, that’s a mighty big “if”, whether you interpret “afford” in terms of performance or dollars. For another thing, the answer to those questions could simply be “Because ‘this’ isn’t capable of modelling my real world, interactive system effectively.”

Thanks a lot for the detailed reply. I think the best strategy for me is option (c).

I agree that slide decks suck as a sharing medium (unless you go to the trouble of adding "notes" under each slide, and share that, but then you're better off sharing a different document). Martin Fowler puts it very well in this post: http://martinfowler.com/bliki/Slideument.html

I can see how sharing a slide deck would dilute the value of a talk. At the same time, sharing my slides lets me reach more people. They might learn more by watching the talk, but it's a trade-off.

There's also the question of the legality of sharing these slides on websites such as InfoQ or Parleys, where the slides are synchronized with the video. But I guess option (c) could work for these.

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... http://www.parleys.com/#st=5&id=2103&sl=2

nchlswu
One thing to note is that converting to outlines will essentially change the text to an 'image'. So it's like looking at a jpeg of text - it won't be able to be highlighted, copied etc. (I'm sure there was a better way to word that, but the terminology escapes me)

Given how it's a slide deck, this probably isn't a big deal for distribution. But if it's important to you, I'm sure you can OCR the final product, and that wouldn't end up embedding the fonts. Unfortunately that's sort of a roundabout process.

eneveu
Good point about not being able to copy/paste the final text.

I don't understand why I should OCR the final output, though, since I already have access to the "raw" text. If I were to OCR it and generate a new PDF, I'm back to square one, since I'd need to specify a font. Unless you meant that some people might want to OCR my public PDF to access the underlying text, since it only contains images?

In the end, I guess I'll simply use a font with a more permissive licence (free or commercial).

tptacek
It's true that you can't treat the type as text anymore (if you can select it, it's probably not OK to share the file), but, importantly, you can scale it to any size with perfect fidelity. That's what you don't get in any process involving round-tripping through a JPG.

This is surely an annoying process bound to put anyone off of commercial typography... unless you're already typesetting your presentations in Illustrator. Which, admittedly, I haven't been doing. But now that I think about it: I do a lot of stuff in Illustrator, and Illustrator is so. much. better. than Keynote.

The big differences between Clojure and Python are probably twofold: it's a Lisp, and it focuses on getting concurrency right. We've had Lisps for a while, and Python only really lacks Lisp macros, so let's think about the concurrency stuff...

Clojure's design goals combine some deep ideas about identity, state and time together and includes data structures and a concurrency API that supports these goals. It's going to be hard for anyone to just convince you in a comment like this, and even if they could, I'm not the one to do it as I'm a Clojure noob.

You should read this essay http://clojure.org/state and watch this talk http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic....

I think you will find that Clojure is pretty interesting, even if you don't start using it right away. I apologize for just throwing you links, but I can't do it justice, and Rich Hickey is a great lecturer, so you'll get more from his stuff.

I'd like to point out in particular "Are We There Yet?" (http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...)

If you liked this talk, then you will definitely like "Are We There Yet?" In it, Hickey argues that most popular object-oriented languages make similar mistakes by bundling identity, time and state into objects. He discusses how we might simplify programming by separating these components and rethinking each.

It has a similar theme but focuses on one concrete issue in depth. It has a similar philosophical style while remaining clear-headed and practical. And, in my opinion, it is similarly enlightening. If you couldn't tell by now, I recommend it :)

Rich's talk at the JVM language summit, "Are We There Yet?", gives a really good look into some of the ideas that underlie clojure. It's worth viewing even if one never uses clojure.

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

If you build a house you dont need worry about the inside of bricks. Objects dont have that property, Pure Functions do.

The Objects loss this proberty because they have inheritance. The other problem is that every in OO the data is mixed with the functions.

Rich Hicky on how it can be done right: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

trezor
If you build a house you dont need worry about the inside of bricks. Objects dont have that property, Pure Functions do.

I see this exactly the other way around. Objects makes sure you don't have to worry about what's on the inside, but if you use pure functions you need to know how the function is implemented, how it processes data, how it expects input to be and how the output will be.

Using pure functions requires you to seek out lots of information and verify implementation. Not that you shouldn't investigate this when using OOP, but in OOP a lot more of this is formalized in class-definitions IMO making the interaction easier to understand.

The way I see your analogy, is that if you use pure functions, the electricity in your house needs to know what material the bricks are made of so that current doesn't accidentally leak and cause a fire. With OOP this is a detail you don't have to worry about as long as the pieces fit.

If that sounds somewhat flawed or too simplistic, I will take the liberty of blaming the poor metaphor. I'm just pointing out that I see the exact same metaphor in the exact polar opposite way ;)

merijnv
Why would I need to know the implementation and how it processes data?

The entire point of pure functions is that you don't need to know. Referential transparency guarantees that a pure function given inputs X and Y always returns the same output Z. So if I just follow the interface specification about accepted inputs and accepted outputs I can switch in any arbitrary implementation of that function and have my code keep working.

trezor
So if I just follow the interface specification about accepted inputs and accepted outputs I can switch in any arbitrary implementation of that function and have my code keep working.

The funny thing is that this is what I would say about OOP, while for functional solutions I often find the specifications much looser, so that I cannot trust this to always be true.

I'm not saying you are right and I am wrong. But I am saying that the arguments about what holds true for what, and especially the arguments for "OOP is bad" or "FP is bad" etc, they just seem to be highly subjective.

And unless someone can come up with empirical evidence to show that one side is actually better/right, I find this debate both pointless and rather amusing. Pointless in that it doesn't give more insights. Amusing in the sense that it makes people reveal lots of the preconceptions and prejudice against things they seemingly don't fully grasp.

nickik
What how do you have to know about the implementation of the function? Think of something like quicksort or a partiton function (partition 2 [1 2 3 4]) => ([1 2][3 4]). How do you have to know anything about that functions implemantation. Sure if the function has a name like myfunction and no docs then you have to look at the code but thats the same with OO.

In clojure you can say (doc anyfunction) and you will get a description of what the function does and it does only that.

You describe the perfect case in OO where you have only objects that only have immutable members and pure methodes. :)

I n the realworld I you often see that something does not work anymore because im some other object some variable changed or that it worked first but after a variable somewhere changed it breaks. With inheritance adds to that a hole set of new problems.

I'm not saying you cant make a good design with object im saying with a FP stile its easy to do the right thing while with objects its harder to do the right thing.

Thats as good as I can argue in a comment.

trezor
Think of something like quicksort or a partiton function (partition 2 [1 2 3 4]) => ([1 2][3 4]). How do you have to know anything about that functions implemantation.

Well. I need to know that it accepts two parameters, first being an integer, the second being an array of integers.

In an OOP solution this would at least be exposed by type signatures, something you don't always see in FP solutions (often due to type-inference). Hence you need to check the implementation.

And this is for a simple example. What about more complex example? Where the input-data has a more complex nature? Take the following example:

    var data = [ { id: 1, value: 2 }, { id: 2, value: 3} ];
    var ordered = orderByValue(data);
Ignoring the "var data ="-line: Without checking the implementation, how would you know how the input-data should be formatted? What types and properties are needed, and in what format the function accepts the data? A seq? A list? An object with properties? You don't.

In C# the same function would probably be contained in a relevant class and have a signature akin to the following:

    IEnumerable<ValueHolder> OrderByValue(IEnumerable<ValueHolder> data)
Now I know what it returns, what it expects and don't have to worry about that. The type-signature tells me everything. The types it expects tells me everything. Moreover, this is probably already implemented on a specialized collection class, so all I need to do is:

    var data = new ValueHolderList();
    // populate
    var ordered = data.OrderByValue(); // notice -pure- implementation in OOP ;)
Again. The implementation tells me what I need to know. Details are blackboxed, abstracted and objects easy to work with. I don't have to worry about functions, context, what they expect and in which order the glue is expected. In FP you are more commonly exposed to the internals of things and need to figure these things out yourself.

I'm not saying I am 100% right and you are 100% wrong. I'm saying there is lots of grey here which this thread doesn't really seem to cover or acknowledge.

FP is not a silver-bullet and nor is OOP. FP has strengths. So does OOP. Lots of the "weaknesses" I see people complain about with regard to OOP here are what I consider weaknesses in FP and strengths of OOP.

I sometimes wonder if we are living on the same planet.

weavejester
> Without checking the implementation, how would you know how the input-data should be formatted?

How does OOP solve this problem? Either way, you need to check the type signature of the function. If your IDE does that for you, that's great, but it's not an inherent difference between OOP and FP.

fogus

    In an OOP solution this would at least 
    be exposed by type signatures
I think you're mixing OOP and FP with language implementations.
swift
In both OOP and FP, to know what a function (or a method) does, you need (at a minimum) to check its type signature. There are _many_ OOP languages which do not use explicit type signatures, and many FP languages which do; it seems to me that you have confused the OOP vs. FP issue with the issue of explicit vs. implicit typing, or perhaps with static typing vs. dynamic typing. There are languages available to suit pretty much every combination of those properties, so you can easily avoid whatever you don't like.

Further, when you check a type signature, what you read is much more valuable in a pure FP context than in a typical OO context, because OO languages generally (1) allow and encourage the use of state, and (2) do not distinguish in the type system between functions/methods that use state and those that don't. The type signature of a pure function strongly constrains what that function can actually do - so much so that it's possible, and effective, to look up the function you need just by specifying the type that you expect it to have. In a typical OO language, the type signature indicates much less about a method's behavior, because its inputs include not only the parameters you provide, but also the entire "world" at the time it is invoked; similarly, its outputs include the entire "world" in addition to its return value. As an example, a pure function that takes no parameters can only be a constant, but an impure method that takes no parameters could play a song on the speakers, display a window on the screen, or launch a missile.

FP and OOP certainly have both strengths and weaknesses. I suspect one reason that OOP catches so much flak around here is that people are more familiar with it, and the flaws in tools you're familiar with are easier to see. Unfortunately, when you're not familiar with a tool, it can also be easy to see flaws - flaws that aren't really flaws at all, but simply aspects of the tool you don't yet understand. The result of this, I think, is that one should ignore criticisms of OOP from people who aren't deeply familiar with it, and similar for shallow criticisms of FP. Unfortunately, there are a lot of both on Hacker News.

> What does too much global state mean? Is having singletons in your application inherently wrong, because they introduce global state? I don't think so.

I do. If you have an hour, the following talk by Rich Hickey (clojure) covers philosophy behind global state being the problem. This is not a code talk and he takes his time getting into it so it's not the easiest talk to get into but it does explain the mindset.

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

To answer your question more directly:

I believe Java's lack of functions/closures lead to excessive factory use, which tend to be singletonish and so you get the set of dependency injection/IoC frameworks that simply don't exist in other languages but exist in Java due to too much global state. There are other symptoms, but this is the first one that came to mind.

Nov 18, 2010 · zach on Clojure game development wiki
I'd actually never read that series, although I had seen links to it a couple time. Just read through it and a few things should be pointed out:

1. The author has had second thoughts about his original conclusions: http://prog21.dadgum.com/37.html

2. The author is constrained by the Erlang feature set. The author rejects out of hand the idea of using "structs", but Clojure's maps and records are easy to use, share data and would perform admirably.

3. The author is constrained by his retrogame and microsystem domain. No modern gaming platform has issues with game state using too much memory or generating too much garbage (exception: complex physics). In fact, data duplication is now a common game performance technique. But if your tastes run toward ultralean programming, this is a distasteful state of affairs.

4. Much of modern game development has moved to an increasingly functional dataflow model already because of the necessities of multiprocessing and network gaming. It's rarely elegant and never done in a functional language, but it's the current reality.

5. Games are one of the places where a sophisticated view of time, as Rich Hickey advocates in his fantastic JVM Languages Summit keynote, offers a lot of value. It's a problem that thoughtful programmers and designers in the game industry have often considered, but have been unable to innovate much in the current technological regime. I just rewatched the talk last week, in fact, and highly recommend it for game programmers who read Hacker News:

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

frou_dh
I like that talk. I saved the video a while ago and have watched it several times. His disambiguation of identity, state and value makes a lot of sense.
zach
As a game developer, the treatment of perception vs. presumed authority about the state of a system resonated with me. Trying to infer a state of a system, given observations that are already in the past, is something networked game developers are especially familiar with.

Actually, Clojure would be a great host for a library that makes deriving a valid and consistent state from multiple observations in the past, something every networked game needs to do, more regular and predictable. That's often one of those "scary" parts of a game's code base. Things get pretty hairy, there is a lot of ad-hoc code, bugs are hard to track down and nobody wants to mess with it so it tends to get even cruftier and scarier.

frou_dh
But the use of an existing game engine or other substantial middleware might impose certain idioms on you. I worked on an MMO myself, though not on game logic. Anyway, I agree that Clojure's strengths being used in gamedev is an exciting prospect!
zach
Very true, and ultimately why I think Clojure is a lot more ripe for nontraditional markets than expecting it to break into mainstream game development. There may be quirky and clever developers who put Clojure into mainstream game technology, but I think new platforms are where it can achieve the greatest leverage.
frou_dh
Speaking of that, my interest in big movie-wannabe games is dwindling rapidly, both as a player and career. Simple focused games and playthings are what I find myself admiring.
Aug 18, 2010 · nkh on Why Clojure?
I agree with the article, and I have to admit I think Rich Hickey (creator of Clojure) is a brilliant man. If you check into his thoughts on programming you will find some very interesting arguments. His talk on state and identity: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... is awesome, and I can not recommend highly enough.

If you want motivation for learning a lisp (Clojure is one) check out http://www.paulgraham.com/avg.html if you have not already done so. An awesome essay to re-read if you have not done so in a while.

Edit: Fixed Link (thanks atuladhar)

None
None
jules
Can you explain the point he is making in "Are we there yet"? I have watched it but I didn't really get a different viewpoint on state and identity. That could be because I already had the same viewpoint, but I doubt that.
nkh
The text below is directly lifted from the Clojure site at: http://clojure.org/state The article describes it more clearly and succinctly then I could.

There is another way, and that is to separate identity and state (once again, indirection saves the day in programming). We need to move away from a notion of state as "the content of this memory block" to one of "the value currently associated with this identity". Thus an identity can be in different states at different times, but the state itself doesn't change. That is, an identity is not a state, an identity has a state. Exactly one state at any point in time. And that state is a true value, i.e. it never changes. If an identity appears to change, it is because it becomes associated with different state values over time. This is the Clojure model.

jules
So is he saying that you should not nest refs? i.e. you should not create a vector of refs and assign the vector to a ref. Because now the state itself can change.
May 03, 2010 · 22 points, 3 comments · submitted by SlyShy
runT1ME
I really love his ideas, and think he's right on so much, but as for the question of STM, i'm gonna have to go with Cliff Click on this one:

http://www.azulsystems.com/blog/cliff-click/2008-05-27-cloju...

shoesfullofdust
Great talk! Thanks for pointing this out.

"You superimpose the notion of cloud on a series of related cloud values." Whoa!

SlyShy
If people are interested, here's some extra reading matter courtesy of reddit: http://www.bestinclass.dk/index.php/2009/09/dining-philosoph... http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
Here's a very quick dump of some things waiting to be read/digested/whatever in my Firefox tabs and other notes:

Learning Clojure:

The best concise intro I've come across: http://en.wikibooks.org/wiki/Learning_Clojure

You can't go wrong starting with the introductory stuff on the site: http://clojure.org/rationale

This looks like a good longer intro, but I haven't more than glanced at it: http://java.ociweb.com/mark/clojure/article.html

A longer Wikibook: http://en.wikibooks.org/wiki/Clojure_Programming

Monad tutorial (site currently broken): http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure...

And there's one Clojure v 1.0 book out, only $20 for the ebook version: http://www.pragprog.com/titles/shcloj/programming-clojure

(Note that a whole lot of learning material assumes you're coming from a Java background ... which I'm not (in fact, I learned MACLISP before C and never had a chance to go beyond C++ to C# or Java).)

Setting up your EMACS Clojure development environment (VIM and various IDEs are also supported): http://incanter-blog.org/2009/12/20/getting-started/ and http://lisp-book.org/contents/ch18.html

And there are a bunch of videos, Rich Hickey does them well; note that most of the quotes below are from someone else that I then cut and pasted into my TODO file for future reference:

Clojure for Lisp Programmers Part 1 of 2: http://blip.tv/file/1313398

Part 1 of a presentation by Rich Hickey at the Boston Lisp meeting. A fairly extensive introduction to Clojure, with a presumption of prior knowledge of Lisp. Transcript available at: http://clojure.googlegroups.com/web/clojure-for-lispers-tran...

Clojure for Java Programmers - 1 of 2: http://blip.tv/file/982823

Part 1 of a presentation by Rich Hickey to the NYC Java Study Group. A gentle introduction to Clojure, part 1 focuses on reader syntax, core data structures, code-as-data, evaluation, special operators, functions, macros and sequences. No prior exposure to Lisp is presumed.

Persistent Data Structures and Managed References: http://www.infoq.com/presentations/Value-Identity-State-Rich... (very good).

Clojure Concurrency: http://blip.tv/file/812787

A presentation by Rich Hickey to the Western Mass. Developers Group on Clojure and concurrency. Brief overview of Clojure, discussion of concurrency issues, locking, and immutabiity. In-depth look at Clojure's refs, transactions and agents. Demonstration and review of code for a multithreaded ant colony simulation.

Clojure Sequences: http://blip.tv/file/734409

An informal introductory talk/screencast covering Clojure's sequences by Rich Hickey, the author of Clojure. Covers the motivation behind sequences, their relationship to cons, iterators/enumerators and collections, the sequence library, and laziness.

Clojure Data Structures - Part 1: http://blip.tv/file/707974

Part 1 of an informal introductory talk/screencast covering Clojure's data structures by Rich Hickey, the author of Clojure. Covers numbers, symbols, keywords, lists, vectors and maps.

At the 2008 JVM Language Summit he gave a talk, at the 2009 a keynote, "Are We There Yet?": http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...

Check Infoq for other items as well.

The Full Disclojure videos have helped [ the author if this note ] understand some of the features new to clojure in 1.1: http://www.vimeo.com/channels/fulldisclojure

alttab
Holy crap thank you.
evangineer
Thanks, this should help in figuring out if Clojure is the way forward for me!
jacquesm
I've bookmarked your comment, thanks a ton.
Nov 30, 2009 · bwanab on Clojure Experiences
I don't know if it's identical, but many if not all of the slides are from here: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...
hsuresh
I love this talk. Rich talks about the concept of time and identity and its importance in programming in general, and especially in concurrency. Good stuff. I was able to better appreciate clojure after watching this talk.
Nov 12, 2009 · 68 points, 21 comments · submitted by sharksandwich
tsuraan
A bit off-topic, but I've been seeing more infoq lately, and I'm wondering if there's a pwnyoutube/deturl type thing for infoq. I found the conclusion to Rich's talk on youtube, but it looked like it was filmed with a cell phone and it was only the last few minutes of the talk. Any pointers to a download link would be much appreciated.
va_coder
I admire Rich Hickey and Stuart Halloway and I've been reading the prag programmer book on Clojure, but I still haven't been able to wrap my head around why I should replace my preferred language - Ruby - with Clojure.

I understand that if I was building a database, or a traffic control system or something with lots of concurrency, it's useful.

But if I'm building a web app, the appserver and database handle the concurrency issues for me.

So I haven't quite understood why Clojure is so important.

runevault
That's really going to depend on what your web app does. Simple CRUD work? Clojure may not give you much benefit over RoR (at least not until compojure or one of the other frameworks gets a lot more time put into it).

If part of what your web app does involves heavy duty data processing then it could be much more interesting. Flightcaster (Ruby or JRuby, I forget which) on Rails front end, Clojure doing all the hardcore machine learning data crunching on the back end.

Of course being a compiled language, odds are you can write faster code in clojure in at least comparable number of lines of code to ruby, with the speed of the jvm. So if you think your site will see much traffic that might be valuable to you as well.

nearestneighbor

    JRuby
    
    faster code in clojure ... with the speed of the jvm.
Something irks me about this argument :-)
runevault
Touche, though way more people use things other then the JVM for ruby from the sounds of what I see standing on the outside looking in.
ramchip
JRuby seems quite slow though. Definitely not 'close to the JVM' like Clojure. Perhaps we could say it's the speed of the JVM versus the speed of the JVM with an elephant sitting on it ;)
sreque
I haven't seen a compelling reason to switch to clojure either. Despite some people trying to argue to the contrary, fair benchmarks that I've seen put clojure on average at least 10 times slower than Java in CPU performance, and Java itself is often 50% slower than C or more. Why bother parallelizing when you're already 10-15 times slower? CPU's aren't free to run! They have to be purchased, consume power, require maintenance, and are prone to failure.

Also, as far as productivity goes, I don't see clojure providing any significant short-term productivity gains over existing scripting languages like Python and Ruby. The use cases for macros beyond lazy evaluation appear few and far between in practice, and most of us get along fine in practice without persistent heterogeneous immutable data structures and lazy order evaluation.

So, unless you enjoy learning languages for fun or find yourself thinking more clearly using a functional approach, and there appear to be many people on this site who fit into one or both of the above categories, you are just fine sticking with Ruby.

anonjon
I think that it is difficult to know what constitutes a 'fair benchmark' for Clojure. Are we talking unadorned Clojure, Clojure with type annotations, Clojure using Java structures, or Clojure calling Java code? Clojure calling Java is as fast as Java (obviously). And what if I had 60 cores as opposed to just 4 or 8? Parallel naive Clojure would then be 4 times faster than the Java version. The parallel clever version in Clojure would most likely be much faster. And barring a breakthrough in quantum computing, you will some day have 60+ CPUs in your desktop.

Most of the benchmarks that I have seen that were legitimately 10x the time of Java were using unadorned Clojure on Clojure data structures... of course it is slower, the machine is doing a lot more for you.

And it is well and good that this is the case, because the purpose of Clojure is not to make that tight loop really fast; it is to get the logic of your program correct and avoid a lot of the subtle bugs that can happen. Concurrency has many advantages above and beyond parallelism.

As far as getting along without macros and lazy evaluation and heterogeneous immutable data structures, I will say that for a long time we got along 'just fine' without garbage collection; but now it is a feature of a large subset of languages (to the extent that Google has now added it to C).

sreque
This link is fairly illuminating of clojure's performance: http://gnuvince.wordpress.com/2009/05/11/clojure-performance.... A guy writes some Java code, writes some clojure code, and notices that the clojure code is ridiculously slower, about 100 times or more, even slower than his Python implementation! After some serious profiling and help from the clojure mailing list he gets it down to 6 times as slow. What if he decided to try to optimize the Java code even further? He might be even be able to push the gap to 10x.

As far as all computers having 60 cores some day, if your clojure code is 10 times slower than my Java code, I only have to use 6 of my 60 cores to be as fast as your clojure program, which would be bringing my 60 core system to it's knees. It's not like you can't parallelize in Java! It's going to be decades indeed before a 5-10x reduction in performance doesn't matter because of ubiquitous core availability.

anonjon
I think you are missing my main point. If the java code is faster, and you really need speed, just call the optimized java code.

If you take seriously the rule that most programs spend 90% of their cycles in a limited number of subroutines (and you rewrite those few locations in Java), you should get speed pretty much equivalent to the Java code.

(Of course, in benchmarks this fails, because benchmarks generally measure the places that i might rewrite).

And then you use Clojure for the tricky and error-prone flow control types of jobs. I hate it when people turn this into a 'Clojure vs. Java' debate. It isn't like that.

It is about Clojure and Java. And I think Clojure and Java wins hands down over the Java only approach (at least for a lot of applications).

sreque
Sorry if I started sounding like I was making this a Java vs. Clojure approach. I wasn't. My original point is that there are no compelling reasons for me to use a language like Clojure over a language like Ruby. Clojure's biggest selling point, having high-level primitives to parallelize with, is meaningless to me because it is so slow, and it's other selling point, increased productivity, doesn't doesn't mean much to me either because I feel like I can be just as productive in Ruby or Python. I can make those my glue languages. I was originally responding to a post by someone asking "Why Clojure over Ruby?"

By the way, I think combining multiple languages on the JVM is a great idea and it was what prompted me to investigate Clojure in the first place.

sunkencity
One of the amazing things in rails compared to many other frameworks is that the methods are all so forgiving, very neatly written multimethods: it doesn't matter if you enter a number,a string, an array or a hash, rails will be able to use the arguments properly.

With lisp/macros you can have similar power but with structure and logic.

Look at the difference between ERB templates and the beautiful templating language in compojure for example. It really kicks the llamas ass.

vdm
One of Clojure's nicest features is the seq abstraction, which lets you use almost all the data structures, from a String to a JDBC ResultSet, with a first/rest (aka car/cdr) interface.
anonjon
It is hard to describe in a HN post why Clojure is a good idea.

Easy concurrency is a reason, certainly. You can build applications without having to worry too much about locks and such. You can utilize in language data structures for concurrency rather than worrying about a database handle (if you have, for example, data you don't need in a database, there is no reason to use one...)

Functional programming is another reason, programs are easier to reason about if you limit state to a few key places in the program.

Macros are a good reason too, instead of working around deficiencies in a language, just implement a macro. I used erlang Jinterface to implement an erlang-style message passing library last weekend. (With process spawning semantics and blocking receive, I haven't done pattern matching.. yet).

Java libraries are another reason to use it. You have full access to Java libraries like Jetty and Jinterface and others, and they pretty much blend into the language.

I have no idea about the relative merits of Ruby and do not wish to offer my reply as a challenge; 'i bet it can't do this or that'.

But Clojure certainly offers some interesting solutions to common problems in code (verbosity, clarity, libraries, concurrency, reliability).

Slashed
I'm not very familiar with Clojure. On the first glance it looks like Clojure has a good concurrency system. I know many people are talking about Actors(like in Erlang) these days, but from my experience with Scala Actors, they're not very suitable to solve some problems(like when you need a very good performance). Even though Scala makes your life easier to work with native Java concurrency, it's definitely a good reason to have a deeper look at Clojure. Thanks for the info!

Edit: Is there an 'easy' way to create OSGi bundles with Clojure, maybe some sort of Maven plugin?

mike_organon
Actors for Clojure has been mentioned as a future feature, but this would be for remote procs. Clojure has Agents for local async state changes, but these are only used when you need that feature, not ubiquitously. You should ask on on the mailing list - people have worked with osgi and maven.
tmountain
Clojure has a few different concurrency mechanisms. Agents are useful for asynchronous manipulation of mutable state while refs allow for coordinated synchronous changes. Atoms allow uncoordinated synchronous access to state while vars act as mutable storage locations on a per thread basis.

Between these, you get four different strategies for dealing with concurrency. Depending on your problem, you can choose the most efficient mechanism. Rather than shoehorning you into a particular strategy, Clojure gives a you a toolbox for dealing with concurrency and lets you chose what makes the most sense.

dkersten
You forgot one: if, for some reason, none of the four mentioned concurrency strategies suit your needs, you can fall back to Javas monitor-based threading model. I don't see why one would want to, but I'm sure there are situations when this actually is the most appropriate mechanism.
tayssir
And a possible future feature is something like statically-checked locking, where order-of-acquisition issues are dealt with.
rads
Clojure is important because it's a Lisp that runs on the JVM and uses existing Java libraries. It has taken big steps to improve Lisp's accessibility.

Do you like Lisp? If you like Lisp, Clojure is its most pragmatic dialect. I personally enjoy the simple, consistent syntax and functional programming style that Ruby lacks.

Note that while Clojure was designed with concurrency in mind, it's also good at other things — like Ruby, it's a general purpose language. However, you're going to be more productive writing a web app with Ruby right now because there are no libraries for Clojure that are as robust as Rails. That may change as Clojure's ecosystem grows.

dkersten
Its more a case of do you understand lisp, because it seems to me that few people who really understand it actually dislike it, while most people who don't understand it seem to dislike it (parentheses and prefix notation being the two things people seem to hate most). Its difficult to explain the benefits of Lisp to someone who doesn't already understand Lisp...
HN Theater is an independent project and is not operated by Y Combinator or any of the video hosting platforms linked to on this site.
~ yaj@
;laksdfhjdhksalkfj more things
yahnd.com ~ Privacy Policy ~
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.