<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Sharding /dev/null - Latest Comments</title><link xmlns="http://www.w3.org/2005/Atom" rel="http://api.friendfeed.com/2008/03#sup" href="http://disqus.com/sup/all.sup#forumcomments-04a5e64a" type="application/json"/><link>http://shardingdevnull.disqus.com/</link><description></description><atom:link href="http://shardingdevnull.disqus.com/comments.rss" rel="self"></atom:link><language>en</language><lastBuildDate>Wed, 29 May 2013 06:53:00 -0000</lastBuildDate><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2013/03/21/erlang-the-movie-ii-the-sequel#comment-912333200</link><description>&lt;p&gt;Now I want to learn Outlaw Techno Psychobitch!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">ZoIomon</dc:creator><pubDate>Wed, 29 May 2013 06:53:00 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2013/03/27/writing-beautiful-code-erlang-factory-2013#comment-865238975</link><description>&lt;p&gt;These are from Landslide. Alas I have the same problem viewing them on my Android phone :( I'd love some recommendations on a slideshow generator that creates universally readable HTML! The idea of using Landslide in the first place was that it made accessing these slides easy for people.&lt;/p&gt;

&lt;p&gt;#fail&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">gar1t</dc:creator><pubDate>Tue, 16 Apr 2013 11:52:54 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2013/03/27/writing-beautiful-code-erlang-factory-2013#comment-865062168</link><description>&lt;p&gt;Which library did you used to create these slides? Btw, please consider adding on screen buttons if possible. The slides can't be read from a tablet&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Le Viet Bach</dc:creator><pubDate>Tue, 16 Apr 2013 07:52:21 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2013/03/21/erlang-the-movie-ii-the-sequel#comment-852846700</link><description>&lt;p&gt;Having watched the "new" video, I think I'm going to need some serious therapy... or a stiff drink.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Barry</dc:creator><pubDate>Fri, 05 Apr 2013 04:23:16 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2013/03/21/erlang-the-movie-ii-the-sequel#comment-843989065</link><description>&lt;p&gt;:)&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">gar1t</dc:creator><pubDate>Wed, 27 Mar 2013 11:27:06 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2013/03/21/erlang-the-movie-ii-the-sequel#comment-843959428</link><description>&lt;p&gt;"Jolly Good" indeed.&lt;/p&gt;

&lt;p&gt;Forced Pair Programming will never be the same.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Joe</dc:creator><pubDate>Wed, 27 Mar 2013 10:52:40 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2013/03/21/erlang-the-movie-ii-the-sequel#comment-841354694</link><description>&lt;p&gt;Great - Hollywood next stop - we thought "OTP" was a "Jolly Good" name with wide appeal at the time&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Joe Armstrong</dc:creator><pubDate>Mon, 25 Mar 2013 01:27:26 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/otp#comment-838473589</link><description>&lt;p&gt;No worries Garret. We truly loved it!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Robert Virding</dc:creator><pubDate>Fri, 22 Mar 2013 10:04:20 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2013/03/21/erlang-the-movie-ii-the-sequel#comment-838136967</link><description>&lt;p&gt;Well done!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Kotedo</dc:creator><pubDate>Fri, 22 Mar 2013 03:00:01 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-787601225</link><description>&lt;p&gt;It's impossible to argue that tests are *bad* and should be avoided. The One True Religion doesn't say that. It says that it's acceptable to trade time writing tests for time making your code *obvious*.&lt;/p&gt;

&lt;p&gt;If your code is obvious and you have nothing better to do, write tests.&lt;/p&gt;

&lt;p&gt;All of the advantages of tests that you list are True and Good. But they cost time and effort. If that time and effort is well spent, write tests.&lt;/p&gt;

&lt;p&gt;If your code is sensitive to regressions, write tests.&lt;/p&gt;

&lt;p&gt;But what's the point of writing tests for incomprehensible code? I've frequently seen code put into production that *sucks ass* only because it appeared thoroughly tested. The tests indeed passed -- but the whole ball of twine was so impenetrable no one could reason about errors when they occurred.&lt;/p&gt;

&lt;p&gt;Incidentally, the bug in the original code example would have been caught the first time the code was *run*. That's one of the virtues of Erlang in particular -- you get a high degree of runtime testing from pattern matching.&lt;br&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">gar1t</dc:creator><pubDate>Sun, 03 Feb 2013 17:15:28 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2012/12/12/techmesh-2012-application-platform#comment-773365877</link><description>&lt;p&gt;I am assuming there are no videos of this event that I can peruse.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">indrayam</dc:creator><pubDate>Sun, 20 Jan 2013 15:59:14 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2012/11/11/more-embarrassingly-obvious-problems#comment-713534360</link><description>&lt;p&gt;This is a fantastic post. This code is beautiful...almost perfect. There is one small flaw, my son. You have too many functions at the same level of abstraction.&lt;/p&gt;

&lt;p&gt;"Wat? That's the whole fucking point!" You may say.&lt;/p&gt;

&lt;p&gt;Not so fast.&lt;/p&gt;

&lt;p&gt;def print_db_table_row_counts(db_name):    cur = db_cursor(connect_db(db_name))    print_row_counts(row_counts(all_tables(cur), cur))&lt;/p&gt;

&lt;p&gt;Is at a higher level of abstraction. It asks for two different pieces:&lt;/p&gt;

&lt;p&gt;a database manipulator that works with the db&lt;br&gt;a presenter that emits output.&lt;/p&gt;

&lt;p&gt;You are missing classes. If you hate the class keyword, fine, call it a module. In the end, the point of encapsulation and separation of concerns is not only to open the way for modification/extensibility, it is also to manage cognitive load.&lt;/p&gt;

&lt;p&gt;The classes, even if they end up being static classes that store no state, serve as a logical boundary of related functionality. They keep like concerns together and make it easy to see the actors in the play of your application.&lt;/p&gt;

&lt;p&gt;Clearly you see how&lt;/p&gt;

&lt;p&gt;def connect_db(db_name):&lt;br&gt;def db_cursor(db):&lt;br&gt;def all_tables(cur):&lt;br&gt;def row_counts(tables, cur):&lt;br&gt;def row_count(table, cur):&lt;br&gt;def db_name():&lt;/p&gt;

&lt;p&gt;Belong together. It is not that much more work. It does not hide our meaning, but rather enhances it, when we place these in DatabaseManager.&lt;/p&gt;

&lt;p&gt;We could self-flagellate, of course, and make a DatabaseConnector, TableQuerier, and RowCounter...but clearly this seems too fine a granularity, adding almost no additional value.&lt;br&gt;  &lt;br&gt;In the same way that you have correctly derived that functions should follow Miller's Magic Number to reduce complexity (&lt;a href="http://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two)" rel="nofollow"&gt;http://en.wikipedia.org/wiki/T...&lt;/a&gt; , so too should your classes. This metric scales. &lt;/p&gt;

&lt;p&gt;7+-2 lines in a function, functions in a class, classes in a package, packages in a library, libraries in a framework, frameworks in a component, components in an application, applications (like ls | grep) in a higher order application (e.g. enterprise application).&lt;/p&gt;

&lt;p&gt;"In the garden man and woman were tricked by the ORM, which was disguised as a serpent. The ORM promises ease of use and productivity, but poisons applications with deformed, grotesque, incomprehensible SQL."&lt;br&gt;Yea, My Son. But Ye Must Experience The Glory of Proper ORM in GORM and dynamic finders, the way we were all searching for. &lt;a href="http://grails.org/doc/latest/guide/GORM.html" rel="nofollow"&gt;http://grails.org/doc/latest/g...&lt;/a&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nick Vaidyanathan</dc:creator><pubDate>Sun, 18 Nov 2012 20:45:29 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-713524824</link><description>&lt;p&gt;I was with you until the part about tests, where you betrayed our One True Religion:&lt;/p&gt;

&lt;p&gt;"In our One True Religion, it’s no sin to trade key strokes, which are cheap, for clarity, which is precious."&lt;br&gt;"Our religion emphasizes clarity over economy."&lt;/p&gt;

&lt;p&gt;It's just as trivial and simple to write tests that sanity check that functions that do one thing as doing the right thing. That they properly sanitize user input and set good boundaries, that they correctly call the next function with the proper set of arguments, and that if any logic, transformation/modification, is done by that function, it is done correctly.&lt;/p&gt;

&lt;p&gt;If you would've had a unit test that compared expected versus actual outputs for your stacktrace bug, you would've caught the bug in 2 minutes instead of relying on readers to find it.&lt;/p&gt;

&lt;p&gt;You are on the right track with this code. Engineers interested and professional enough to read and contemplate this MUST READ Robert Martin's Clean Code. But it is simply ridiculous and unrelated to argue that doing this obviates the need for tests.&lt;/p&gt;

&lt;p&gt;Tests&lt;br&gt;- Make sure Ass O'Cluckolus, who looks at the system and modifies a feature after you, doesn't fuck up the existing logic and blindly copypasta into error.&lt;/p&gt;

&lt;p&gt;- explicitly create a usage API. Wonder how it works in practice? Look at the integration tests.&lt;/p&gt;

&lt;p&gt;- document requirements by creating an executable verification and validation mechanism. On every check-in, a continuous integration server can verify that no regressions have been introduced by running the tests.&lt;/p&gt;

&lt;p&gt;- help drive design by forcing you to think about the problem, potential inputs/outputs and expected state, at every level of granularity.&lt;/p&gt;

&lt;p&gt;- are cheaper. 10 minutes of debugging a unit test by looking at the 8 effected lines of code &amp;gt;&amp;gt;&amp;gt; 2 hours trying to trace execution flow through a chained A-&amp;gt;B-&amp;gt;C-&amp;gt;D-&amp;gt;E mess only to discover that C was making the input 3 instead of 4.&lt;/p&gt;

&lt;p&gt;- Help drive conversations with your product manager. If they want some "soft, cuddly" requirement that says "should be fun to use", you can make that actionable by saying "let's define a scenario where fun to use = true, and one where fun=false." &lt;br&gt;Instead of storing that in Tribal Knowledge or static documentation, we store that AS CODE that has to change when our understanding of the system's performance envelope changes.&lt;/p&gt;

&lt;p&gt;- Help solve arguments about design and implementation quickly. Instead of arguing with your peers for hours/weeks in meetings/discussions about whether something "may work",or whether something would be "dog slow", you write tests that mock simple scaffolding and quickly verify whether an approach is valid. Test written against interfaces form the Tracer Bullets (The Pragmatic Programmer)/architectural prototype that drives system.&lt;/p&gt;

&lt;p&gt;If you're not doing Behavior Driven Development, putting the user desires as a result of Acceptance Test Driven Development in comprehensible and verifiable assertions of the behavior your software is expected to exhibit in various contextual conditions...YOAR DOING IT WRONG. These tests are small, they're easy, and they need to exist as run-time documentation/specification, design guide, and guard against unintended regression.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nick Vaidyanathan</dc:creator><pubDate>Sun, 18 Nov 2012 20:21:02 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2012/09/30/so-long-microsoft#comment-710737185</link><description>&lt;p&gt;Right on !  I feel the same way about Microsoft -- except for one little thing --&lt;br&gt;It isn't that they don't innovate anymore -- I can't think of a time that they EVER innovated anything significant.  They started by buying DOS from a small developer in ~1981.  Windows 1.0 was an obvious rip-off of the Mac, and they were forced to change it.  They took the spreadsheet from Lotus123.  The original MS Word (which was very good for it's time) -- was also bought from a small developer.  &lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Rob</dc:creator><pubDate>Thu, 15 Nov 2012 00:42:42 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2012/07/16/oscon-2012-erlang-kung-fu#comment-702642101</link><description>&lt;p&gt;Any ideas when the video will end up being uploaded.  Keen to see it happening.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Wmealing</dc:creator><pubDate>Wed, 07 Nov 2012 07:58:34 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://www.gar1t.com/blog/2012/09/30/so-long-microsoft#comment-690778182</link><description>&lt;p&gt;Hey, your RSS/Atom is 404ing. Please fix so I don't miss your awesome videos!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Anonymous Coward</dc:creator><pubDate>Wed, 24 Oct 2012 03:41:17 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-681817966</link><description>&lt;p&gt;I'm not an Erlanger but I love the focus on simplicity. It reminded me of my pet favorite language, Factor, so I wrote a little post about it:  &lt;a href="https://gist.github.com/3888404" rel="nofollow"&gt;https://gist.github.com/388840...&lt;/a&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Fred Alger</dc:creator><pubDate>Sun, 14 Oct 2012 08:36:38 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-610530837</link><description>&lt;p&gt;Really well written with a focus on the essence of Erlang which really invites a programmer to write beautiful code and split it up into small pieces that are obviously correct. It takes some time to get used to single assignment variables and pattern matching. But those are simple to grasp. And once understood the rewards are immense. &lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jan Willem</dc:creator><pubDate>Sun, 05 Aug 2012 16:07:29 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/04/26/erlang-web-development-with-modlib#comment-609603027</link><description>&lt;p&gt;Great work.  Just spent weeks with yaws, chicago boss, mochiweb and webmachine.  I love webmachine, but I have a need to provide quick interfaces to Erlang code via http.  This is nice.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Deanwagner13</dc:creator><pubDate>Sat, 04 Aug 2012 10:42:59 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-575162148</link><description>&lt;p&gt;Yes - I meant Prolog -- and Lisp, not LISP :) Corrected. Thanks!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">gar1t</dc:creator><pubDate>Tue, 03 Jul 2012 07:45:10 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-575149816</link><description>&lt;p&gt;Awesome article; I am heading to refactor some of my Erlang code at the moment. &lt;br&gt;When I came to Erlang from Prolog I felt I lost a bit of declarativeness; but I think that this will change. Something I noticed: when you mention Prologue, did you mean Prolog perhaps?&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">thanosqr</dc:creator><pubDate>Tue, 03 Jul 2012 07:13:47 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-572879165</link><description>&lt;p&gt;Great article, really. I think you're ready for lisp/clojure now ;)&lt;/p&gt;

&lt;p&gt;While coding Erlang I don't like function imbrication, I prefer some more "monadic" style. &lt;br&gt;I call a function, with the result of that function I call another one, etc etc...&lt;br&gt;It's less clear because you have a foldl but you win another point for clarity : you see functions in order (not the other way around à la Lisp)&lt;br&gt;Funs_to_apply = &lt;br&gt; [fun create_db_args/1,&lt;br&gt;  fun (Db_args) -&amp;gt; create_db(DB_args, Msg, State),&lt;br&gt;  fun handle_create_db_result/1)],&lt;br&gt;lists:foldl(fun(Fun, Acc) -&amp;gt; Fun(Acc) end, Msg, Funs_to_apply).&lt;br&gt; &lt;br&gt;It works like this : You have some data, call this function, then this other function, then is other one..&lt;/p&gt;

&lt;p&gt;Of course I can be clearer with a function wrapping that foldl .&lt;/p&gt;

&lt;p&gt;What bothers me is the lack of tests. I understand that some functions don't need to be tested because in a way :- they are simple translations&lt;br&gt;- Or they simply some clarification, you symbolize what is happening (and thus don't really need to test tit)&lt;/p&gt;

&lt;p&gt;But to me, in Erlang more than in other languages, you do need tests because of the lack of typing. I mean, I need to write somewhere that the result of my function is Either {ok, this} or {error, that}.&lt;br&gt;Or that my result is a list of four values. etc.&lt;br&gt;Smaller functions make the test code simpler too. In fact you copy/past what you do in the REPL in a test and that's it, end of the story. That way, you have a test that explain what your function do. And the test is so short you have no issue in throwing it&lt;/p&gt;

&lt;p&gt;But there is another problem that I can't (for the moment) really easily put words on it. When you have many functions, many functions calling one the other, at a point it's harder to test because functions are  doing a huge tree of function calls. If you test one entry point you don't know at what level of function calls it breaks. The more I write tests, the more I try to have simple functions and you call one, then another, then anotheretc etc..  Chaining function call, not nesting one in the other&lt;br&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">lambdadev</dc:creator><pubDate>Sat, 30 Jun 2012 05:53:27 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-568892771</link><description>&lt;p&gt;Thanks Ulf! I'm always fascinated to hear Erlang war stories.&lt;/p&gt;

&lt;p&gt;While I've only started to adopt this style consistently, it's becoming clear that embarrassing obviousness is not just useful for correctness -- it brings sanity to change management.&lt;/p&gt;

&lt;p&gt;When each piece of the puzzle is small (as you say, solve only one type of problem), with well reasoned inputs and outputs, changes tend to have limited impact. I can say, "here's where this fits -- it goes right into this slot" and modify the code with minimal ripple effect. It's the same refactoring process, but applied to new requirements!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">gar1t</dc:creator><pubDate>Wed, 27 Jun 2012 09:19:11 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-568846033</link><description>&lt;p&gt;Great post! And the presence of the bug in the first refactoring even made it better. ;-)&lt;/p&gt;

&lt;p&gt;The thing illustrated by the bug is of course that functions, in addition to being short and clear, should solve only one type of problem (just as your create_db() function should only worry about creating the db, not dealing with messaging issues). Another important aspect is that if you can break the code down into short functions &lt;em&gt;free of side-effects&lt;/em&gt;, these functions are very easy to test.&lt;/p&gt;

&lt;p&gt;Either they are so embarrassingly obvious, as you say, that you don't really need to test them, or they are so easy to test that you can do so anyway. And once you have tested the function for all legal inputs (which you can, if the function is sufficiently limited in its scope), &lt;em&gt;it will stay correct&lt;/em&gt;, forever, until requirements change.&lt;/p&gt;

&lt;p&gt;This is something that we observed even in very complex erlang-based products: a large part of the code, once battle-tested and corrected, would tend to stay correct, even across major feature releases. Indeed, for each major release, we would tend to have lower bug density, even if we added lots of features. In some code, we never saw a single bug from the field! (for years, at least - I don't know what happened after I left) In many cases, that was code tested with QuickCheck.&lt;/p&gt;

&lt;p&gt;That is where this type of refactoring work really pays off.&lt;br&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ulf Wiger</dc:creator><pubDate>Wed, 27 Jun 2012 08:15:05 -0000</pubDate></item><item><title>Re: Sharding /dev/null</title><link>http://gar1t.com/blog/2012/06/10/solving-embarrassingly-obvious-problems-in-erlang#comment-561002944</link><description>&lt;p&gt;The Code is much happier now :-)&lt;br&gt;Na zdraví!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bossek</dc:creator><pubDate>Mon, 18 Jun 2012 09:42:10 -0000</pubDate></item></channel></rss>