7 ms·
Simplicity Matters By Rich Hickey (Keynote at RailsConf 2012)
- richhickey 14y agoSlides are here: https://raw.github.com/richhickey/slides/master/simplicitymatters.pdf https://raw.github.com/richhickey/slides/master/simplicityma...
- mattdeboard 14y agoThanks, great to see more material along the same lines as your Simple Made Easy talk. The concepts you outlined in that talk (and in this one) have made a tremendous impact on how I think about creating software. Can't thank you enough.
- VeejayRampay 14y agoGood stuff. Really enjoyed the video.
- t_hozumi 14y agoThank you. Are there slides of "Hammock Driven Development"?
- cageface 14y agoHis emphasis on simplicity is welcome, but I'm not so sure I agree that simple hashes are the best choice for internal data representations. Exposing all the fields of any particular datatype to all clients seems to invite exactly the kind incidental "complecting" he decries. Every non-trivial program is going to have to define abstract datatypes and I'm not sure how embedding and dispatching on a type tag in a hash is any better than using the more explicit support for dynamic dispatch you find in typical OO languages. The real problem with most OO is that it mashes a lot of interdependent, mutable state together.
- snprbob86 14y ago> I'm not so sure I agree that simple hashes are the best choice for internal data representations I've been contributing to the Clojure community lately. My experience working with hash-maps as the primary data structure has been entirely liberating. At my startup, we've got an app with Sinatra services, a Rails API, a Node.js web frontend, and Backbone client code. JSON gets passed between them. Being forced to encode keys as strings is a mild annoyance that Clojure's reader syntax avoids, but the real issue is that I've got raw JSON, Javascript domain objects (Backbone.Model), Ruby models (ActiveRecord), and Ruby hashes (hashie/mash/similar). Each has their own idiosyncrasies and interfaces. Of all of them, the raw JSON is most pleasurable to work with. CoffeeScript & Underscore.js roughly approximate 10% of the awesomeness that is Clojure's core data structures, including maps, sets, vectors, and lazy-seqs. ActiveRecord, for example, makes it super easy to tangle a bunch of objects up. If we had a big bag of functions, they could operate on in-memory hashes, or they could operate on database rows, or they could operate on the result of an API call. It would be so much simpler to reuse code between our main Rails API and our Sinatra service. And we could one-for-one translate functions for non-Ruby services. Instead of requiring a crazy tangled ness of polymorphism and mutable state. > Every non-trivial program is going to have to define abstract datatypes Absolutely true. However, Clojure has taught me that you really aught to only define a very small number of those. It's been said that it's much better to have 100 functions which operate on 1 data structures, than to have 10 functions that operate on 10. Clojure's get-in function for example: (get-in some-hash [:some :key :path]) is glorious compared to Ruby's some_hash[:some][:key][:path] because you don't need to go monkey patch in a get_path method. And even if you did monkey patch that in, it won't work for the some_object.some.key.path case, unless you got fancy with object.send and yet another monkey patch. Look at some of the substantial pieces of Clojure code out there. They may only define a small handful of data structures, but most of those are even defined with defrecord, which produces a hash-like object, which all those 100s of functions work on. The rest are tiny primitives that compose in powerful an interesting ways. > I'm not sure how embedding and dispatching on a type tag in a hash is any better than using the more explicit support for dynamic dispatch you find in typical OO languages Because you may want differing dispatch & single-dispatch inheritance doesn't let you change your mind as easily. Those dynamic dispatches in Ruby/Python whatever are simply hash lookups anyway. You'll get the same performance either way. Look at the output of the ClojureScript compiler for example. Most code paths dispatch on :op, but you could just as easily dispatch on some bit of metadata, maybe the [:meta :dynamic] key path to have a function that runs differently on static vars than dynamic ones. People are also working on advanced predicate dispatch systems. > The real problem with most OO is that it mashes a lot of interdependent, mutable state together. That's a real problem. But it's not the real one :-)
- espeed 14y agoRich better illuminates these concepts in his "Simple Made Easy" talk (http://www.infoq.com/presentations/Simple-Made-Easy http://www.infoq.com/presentations/Simple-Made-Easy) at the Strange Loop conference, where he doesn't pull any OO punches.
- bitops 14y agoI know that not everyone agrees with Rich, but I do think everyone who writes software professionally could benefit from watching this talk.
- frou_dh 14y agoAnd this one (2009): http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...
- SkyMarshal 14y agoThanks, was going to ask if this is worth watching if I've already watched his Strange Loop talk.
- Jasber 14y agoHas anyone watched both? Are they significantly different?
- bitops 14y agoThey are very different - one is geared towards more of an FP audience, the other targets the crowd at RailsConf.
- cconroy 14y agoIt seems strange (to me)--maybe in a good way, but would it be preferable to use the JSON literal over the if statement (for the sake of the argument assume in javascript if returns a value)? val = if (person === "Homer") { return expr } else if (person === "Bart") { return expr } ... ---- val = { "Homer": expr , "Bart": expr , ... }[person]; Would the literal be simpler because it uses data over syntax, or rules instead of conditionals?
- lucian1900 14y agoI frequently use the latter in Python. I like that it's easy to construct programatically (because it's data) and it more explicitly handles the various cases (especially the default case).
- dpritchett 14y agoAgree, I do it a lot as a way of selecting functions in a switch statement: handlers = { 'dave' : call_dave(), 'ted' : call_ted(), 'julie' : contact('julie') } handlers['dave']() # Call dave handlers['julie']() # Contact julie [handlers[person]() for person in ['dave', 'julie', 'ted']] # Contact all three
- deleted 14y ago[deleted]
- tferris 14y ago"If you want everything to be familiar you'll never learn anything new—you have to break out of that."
- tferris 14y ago"We can make the same exact software we are making today with dramatically simpler stuff—dramatically simpler languages, tools, techniques, approaches. Like really radically simpler—radically simpler than Ruby which seems simple. Why aren't we?"
- espeed 14y agoInertia. That uncomfortable feeling you get when you venture into a new paradigm that you don't understand acts as a barrier and an excuse for people to stay where they are.
- erichocean 14y agoI'm not sure that's it. I do 100% consulting, and so end up working with lots of programmers. In my experience, younger programmers who are otherwise competent tend to create the most complicated, generalized systems imaginable. It's only when you get older, and have done enough systems, that you start to favor the "simple" approach Rich is talking about. If I had to guess, I'd say that younger, more inexperienced programmers know there is a problem with complexity, and believe that "general", non-simple solutions are the way to tackle that complexity. A similar thing happens with college students introduced to a new topic. They'll write these elaborate, complicated papers about the simplest of topics -- because they don't understand it well, and don't want to miss anything. It looks and feels very similar to what inexperienced developers do.
- joske2 14y agoI don't understand his point on encapsulation of information versus implementation. If anyone can help me here, I would be grateful. * Should the user of your object/data have to make this distinction? Does he care if age is a piece of data or the result of a calculation? * Should the user of your object/data know where a piece of information is? Suppose I start of with having a birthdate attribute in my person hash. I later read something about CQRS and decide to build my person as an event store. My birthdate is now in some event hash inside an events list in person. If I encapsulate this birthdate information, the users of my object/data don't have to change. Encapsulating information/implementation might "complect" person, but doesn't it make it a lot more simple for the users/callers?
- wandybrad 14y agoThis is an interesting site and informative. I really impressed from this site. http://www.professional-term-paper-writers.com http://www.professional-term-paper-writers.com