<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Manuel Paccagnella</title>
 <link href="http://manuelp.github.com/atom.xml" rel="self"/>
 <link href="http://manuelp.github.com/"/>
 <updated>2016-10-04T19:33:53+00:00</updated>
 <id>http://manuelp.github.com/</id>
 <author>
   <name>Manuel Paccagnella</name>
   <email>manuel.paccagnella@gmail.com</email>
 </author>

 
 <entry>
   <title>Validations with TotallyLazy</title>
   <link href="http://manuelp.github.com/blog/2015/07/22/validations-totallylazy.html"/>
   <updated>2015-07-22T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2015/07/22/validations-totallylazy</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://totallylazy.com/&quot;&gt;TotallyLazy&lt;/a&gt; is a library that gives you some tools to do functional programming on the JVM and particularly in Java, like: &lt;code&gt;Option/Maybe&lt;/code&gt;, &lt;code&gt;Either&lt;/code&gt;, persistent data structures, &lt;code&gt;Sequence&lt;/code&gt; operations, etc. Unfortunately, even if quite useful and nice to use this library is also practically &lt;em&gt;undocumented&lt;/em&gt; (and no, I don&amp;#39;t consider raw code as &lt;em&gt;sufficient&lt;/em&gt; documentation).&lt;/p&gt;

&lt;p&gt;Since I&amp;#39;ve been using this library for some time now, in my pet projects and also using it in production, I&amp;#39;d like to share a thing or two that I&amp;#39;ve learned along the way. In particular, I&amp;#39;d like to show you how to do &lt;em&gt;validations&lt;/em&gt; using the primitives offered by TotallyLazy.&lt;/p&gt;

&lt;h2&gt;What does it means to validate?&lt;/h2&gt;

&lt;p&gt;TotallyLazy model a validation like a &lt;em&gt;function&lt;/em&gt; on some data type that can either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be successful.&lt;/li&gt;
&lt;li&gt;Be a failure with a list of error messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More precisely, &lt;a href=&quot;https://github.com/bodar/totallylazy/blob/1.69/src/com/googlecode/totallylazy/validations/Validator.java&quot;&gt;Validator&lt;T&gt;&lt;/a&gt; is a &lt;code&gt;Predicate&amp;lt;T&amp;gt;&lt;/code&gt; with an additional method &lt;code&gt;ValidationResult validate(T instance)&lt;/code&gt;. A &lt;a href=&quot;https://github.com/bodar/totallylazy/blob/1.69/src/com/googlecode/totallylazy/validations/ValidationResult.java&quot;&gt;ValidationResult&lt;/a&gt; is a type which can be successful or failed, and in the latter case can contain a list of error messages (as &lt;code&gt;String&lt;/code&gt;s).&lt;/p&gt;

&lt;p&gt;In Haskell we&amp;#39;d have something like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ValidationResult&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Successful&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Failed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;validate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ValidationResult&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Ok, how do I do that?&lt;/h2&gt;

&lt;p&gt;In this case, an example can be much more informative that a lot of words. Let&amp;#39;s take for example the validation of an email.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;Email&lt;/code&gt; in this example is a classic POJO, that I express here as an Haskell record because it&amp;#39;s much more concise and the point is not the structure of this class. The only peculiarity of this class is that &lt;em&gt;every field is optional&lt;/em&gt;. &lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Email&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromAddress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;toAddress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First of all, we want to write a &lt;code&gt;Validator&lt;/code&gt; for checking to validate that an optional &lt;code&gt;String&lt;/code&gt; field must contain a value:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/**
 * Builds a {@link Validator} that checks that a given {@link Option} contains
 * a value.
 *
 * @param name Name of the datum
 * @return {@link Validator}
 */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Validator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notEmpty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Validator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&amp;gt;&amp;gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ValidationResult&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ValidationResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;constructors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;pass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ValidationResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;constructors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Parameter &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; missing&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isDefined&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We&amp;#39;ve defined a creation method that builds and returns a &lt;code&gt;Validator&amp;lt;Option&amp;lt;?&amp;gt;&amp;gt;&lt;/code&gt; that validates an &lt;a href=&quot;https://github.com/bodar/totallylazy/blob/1.69/src/com/googlecode/totallylazy/Option.java&quot;&gt;optional&lt;/a&gt; value by checking if it actually contains a value. Note that since &lt;code&gt;Validator&lt;/code&gt; is also a &lt;code&gt;Predicate&lt;/code&gt;, we define the corresponding &lt;code&gt;#matches()&lt;/code&gt; method and use that in our &lt;code&gt;#validate()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, we need to define an ad-hoc validation for the host: it&amp;#39;s optional (in fact ignored) if the system is configured to use a mock mailer. Let&amp;#39;s assume that we a method that says if it&amp;#39;s configured the mock mailer or not, and write this validation:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/**
 * Builds a validator that checks that the host is present (unless the SMTP
 * server is a mock).
 *
 * @return {@link Validator}
 */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Validator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;validHost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Validator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ValidationResult&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ValidationResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;constructors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;pass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ValidationResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;constructors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Host is missing&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isDefined&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mailServerIsAMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, we can use this &lt;code&gt;Validator&lt;/code&gt;s to &amp;quot;declaratively&amp;quot; validate an entire &lt;code&gt;Email&lt;/code&gt; value as follows:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ValidationResult&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;validateEmailParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Email&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;notEmpty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;from&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getFromAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()),&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;notEmpty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;to&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getToAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()),&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;notEmpty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;subject&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()),&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;notEmpty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;body&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBody&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()),&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;validHost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getHost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()))&lt;/span&gt;
         &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ValidationResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;functions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that &lt;code&gt;#notEmpty()&lt;/code&gt; is defined in very general terms and can be reused in many more circumstances.&lt;/p&gt;

&lt;h2&gt;And now?&lt;/h2&gt;

&lt;p&gt;This is just a quick overview on the validation primitives offered by TotallyLazy. A good next step would be looking at all the fine &lt;a href=&quot;https://github.com/bodar/totallylazy/blob/1.69/src/com/googlecode/totallylazy/validations/Validators.java&quot;&gt;combinators&lt;/a&gt; for &lt;code&gt;Validator&lt;/code&gt;s.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Roy Fielding on Versioning, Hypermedia, and REST</title>
   <link href="http://manuelp.github.com/blog/2014/12/19/versioning-rest.html"/>
   <updated>2014-12-19T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/12/19/versioning-rest</id>
   <content type="html">&lt;p&gt;Some highlights from &lt;a href=&quot;http://www.infoq.com/articles/roy-fielding-on-versioning&quot;&gt;this&lt;/a&gt; interview to &lt;a href=&quot;http://en.wikipedia.org/wiki/Roy_Fielding&quot;&gt;Roy Fielding&lt;/a&gt; on InfoQ:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;hypermedia as the engine of application state&amp;quot; is a REST constraint. Not an option. Not an ideal. Hypermedia is a constraint. As in, you either do it or you aren’t doing REST. You can’t have evolvability if clients have their controls baked into their design at deployment. Controls have to be learned on the fly. That’s what hypermedia enables.&lt;/p&gt;

&lt;p&gt;The techniques that developers learn from managing in-house software, where they might reasonably believe they have control over deployment of both clients and servers, simply don’t apply to network-based software intended to cross organizational boundaries. This is precisely the problem that REST is trying to solve: how to evolve a system gracefully without the need to break or replace already deployed components.&lt;/p&gt;

&lt;p&gt;don’t build an API to be RESTful — build it to have the properties you want. REST is useful because it induces certain properties that are known to benefit multi-org systems, like evolvability. Evolvability means that the system doesn’t have to be restarted or redeployed in order to adapt to change.&lt;/p&gt;

&lt;p&gt;there is no need to anticipate such world-breaking changes with a version ID. We have the hostname for that. What you are creating is not a new version of the API, but a new system with a new brand. &lt;/p&gt;

&lt;p&gt;Websites don’t come with version numbers attached because they never need to. Neither should a RESTful API. A RESTful API (done right) is just a website for clients with a limited vocabulary.&lt;/p&gt;

&lt;p&gt;I had to define a system that could withstand decades of change produced by people spread all over the world. How many software systems built in 1994 still work today? I meant it literally: decades of use while the system continued to evolve, in independent and orthogonal directions, without ever needing to be shut down or redeployed. Two decades, so far.&lt;/p&gt;

&lt;p&gt;the initial reaction to using REST for machine-to-machine interaction is almost always of the form &amp;quot;we don’t see a reason to bother with hypermedia — it just slows down the interactions, as opposed to the client knowing directly what to send.&amp;quot; The rationale behind decoupling for evolvability is simply not apparent to developers who think they are working towards a modest goal, like &amp;quot;works next week&amp;quot; or &amp;quot;we’ll fix it in the next release&amp;quot;.&lt;/p&gt;

&lt;p&gt;What we learned from HTTP and HTML was the need to define how the protocol/language can be expected to change over time, and what recipients ought to do when they receive a change they do not yet understand. HTTP was able to improve over time because we required new syntax to be ignorable and semantics to be changed only when accompanied by a version that indicates such understanding.&lt;/p&gt;

&lt;p&gt;Software developers have always struggled with temporal thinking.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Imparare la programmazione funzionale</title>
   <link href="http://manuelp.github.com/blog/2014/11/17/imparare-fp.html"/>
   <updated>2014-11-17T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/11/17/imparare-fp</id>
   <content type="html">&lt;p&gt;(Un amico mi ha chiesto un consiglio su dove iniziare per imparare la programmazione funzionale, ri-pubblico qua la mia risposta leggermente adattata.)&lt;/p&gt;

&lt;h2&gt;FP in breve&lt;/h2&gt;

&lt;p&gt;Prima di tutto una breve parentesi riguardo la programmazione funzionale (FP) in generale. Non c&amp;#39;è una definizione universalmente accettata di FP, ma i tratti generali sono abbastanza comuni:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Le &lt;em&gt;funzioni&lt;/em&gt; sono cittadini di prima classe, manipolabili come valori. E&amp;#39; possibile ovvero passarle come parametri e ritornarle tramite altre funzioni (per esempio, vedi Javascript).&lt;/li&gt;
&lt;li&gt;Tipicamente le funzioni sono &lt;em&gt;pure&lt;/em&gt;, ovvero non ci sono effetti collaterali. In altre parole, il valore ritornato da una funzione dipende &lt;em&gt;solo ed esclusivamente dal valore dei suoi parametri&lt;/em&gt;, in modo tale che per uno stesso insieme di valori in ingresso alla funzione, questa ritornerà sempre lo stesso risultato.&lt;/li&gt;
&lt;li&gt;In molti casi, si lavora principalmente con strutture dati &lt;em&gt;immutabili&lt;/em&gt;. Questo significa che, per esempio, modificare una lista significa crearne una nuova (in modo effiente in termini di spazio e tempo ovviamente, utilizzando delle &lt;a href=&quot;http://en.wikipedia.org/wiki/Persistent_data_structure&quot;&gt;persistent data structures&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Queste caratteristiche hanno tutta una serie di grandi vantaggi in termini di (per esempio):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modularizzazione&lt;/li&gt;
&lt;li&gt;Composizione&lt;/li&gt;
&lt;li&gt;Riuso&lt;/li&gt;
&lt;li&gt;Flessibilità&lt;/li&gt;
&lt;li&gt;Potenza espressiva&lt;/li&gt;
&lt;li&gt;Capacità di astrazione&lt;/li&gt;
&lt;li&gt;Manutenibilità&lt;/li&gt;
&lt;li&gt;Possibilità di sfruttare facilmente concorrenza e parallelismo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il tutto ha una solida base teorica nel &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt;, un modello computazionale equivalente in termini di possibilità ma &lt;em&gt;diverso da quello di &lt;a href=&quot;http://en.wikipedia.org/wiki/Von_Neumann_architecture&quot;&gt;Von Neumann&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Il modello di Von Neumann prevede una memoria condivisa e delle procedure che la alterano. Questo crea essenzialmente un accoppiamento temporale e spaziale tra diverse unità funzionali che, anche se gestito tramite oggetti, rimane una caratteristica intrinseca di questa architettura. Il che rende praticamente impossibile sfruttare facilmente il parallelismo offerto dalle odierne CPU multi-core.&lt;/p&gt;

&lt;p&gt;In contrasto, il modello computazionale basato sul lambda calcolo si basa su &lt;em&gt;trasformazioni di strutture dati immutabili da parte di funzioni pure&lt;/em&gt;. Il che come dicevo ha tutta una serie di vantaggi, non ultima la possibilità da parte del compilatore/interprete di sfruttare in molti casi automaticamente ed in modo trasparente il parallelismo.&lt;/p&gt;

&lt;h2&gt;Approccio didattico&lt;/h2&gt;

&lt;p&gt;Alcuni sostengono che il FP sia qualcosa di &amp;quot;alieno&amp;quot;, &amp;quot;difficile&amp;quot;, &amp;quot;impratico&amp;quot;, &amp;quot;inutile&amp;quot;. Cavolate! In realtà è piuttosto semplice ed &lt;em&gt;estremamente&lt;/em&gt; utile e potente.&lt;/p&gt;

&lt;p&gt;Il problema, piuttosto, è che semplicemente è qualcosa di un po&amp;#39; diverso da ciò che fin&amp;#39;ora è stato l&amp;#39;approccio mainstream. Ma anche il mainstream si sta rendendo conto che il FP è un requisito essenziale per poter lavorare in modo sano con concorrenza, parallelismo e sistemi distribuiti. Basti vedere la sempre maggiore popolarità di Clojure e Scala per esempio, ma soprattutto che anche Java si sta evolvendo in questa direzione. Già nella versione 8 sono state aggiunte &lt;a href=&quot;http://www.infoq.com/presentations/java-8-lambda-streams&quot;&gt;le lambda expressions e gli stream&lt;/a&gt;. In ambito .NET poi, F# esiste già da tempo come cittadino di prima classe in Visual Studio. Senza contare Facebook che si sta orientando su soluzioni di stampo FP come &lt;a href=&quot;http://facebook.github.io/react/docs/flux-overview.html&quot;&gt;Flux&lt;/a&gt;, basato su &lt;a href=&quot;http://facebook.github.io/react/&quot;&gt;React.js&lt;/a&gt; e &lt;a href=&quot;https://github.com/facebook/immutable-js&quot;&gt;immutable-js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;L&amp;#39;ostacolo principale che ti troverai davanti all&amp;#39;inizio è che si tratta il tutto con una angolazione un pò diversa da quella a cui normalmente si è abituati proveniendo da un percorso &amp;quot;standard&amp;quot; di formazione. In realtà è semplice: &lt;em&gt;c&amp;#39;è molta carne al fuoco certo, ma si costruisce tutto su solide e semplici basi&lt;/em&gt;. Perciò uno dei primi consigli che posso dare al riguardo è: &lt;strong&gt;sospendi il giudizio, e affronta l&amp;#39;argomento con mente aperta&lt;/strong&gt; (con &lt;a href=&quot;http://en.wikipedia.org/wiki/Shoshin&quot;&gt;Shoshin&lt;/a&gt;, per evitare l&amp;#39;&lt;a href=&quot;http://en.wikipedia.org/wiki/Einstellung_effect&quot;&gt;effetto Einstellung&lt;/a&gt;). Se ti applichi, ti posso assicurare che avrai una lunga serie di momenti &amp;quot;a-ha!!&amp;quot;, che ti arricchiranno e miglioreranno professionalmente per il resto della tua vita (oltre a essere tremendamente eccitanti e soddisfacenti ;)&lt;/p&gt;

&lt;p&gt;Ok, ma all&amp;#39;atto pratico da dove cominciare? Qualcuno direbbe: &lt;a href=&quot;http://scala-lang.org/&quot;&gt;Scala&lt;/a&gt;! Ma essendo un misto-mare pieno di &lt;a href=&quot;http://scalapuzzlers.com/&quot;&gt;casi particolari&lt;/a&gt; e che tenta di &amp;quot;fondere&amp;quot; il paradigma OO con quello FP, rischia veramente di confonderti le idee. Oltre a &lt;a href=&quot;http://queue.acm.org/detail.cfm?id=2611829&quot;&gt;non funzionare&lt;/a&gt;. Ha un type system più avanzato di quello di Java, ma la sua type inference è abbastanza limitata rispetto quella di &lt;a href=&quot;http://new-www.haskell.org/&quot;&gt;Haskell&lt;/a&gt; per esempio. Ergo, secondo me &lt;em&gt;più è diverso da ciò che già conosci, più facile è evitare che gli schemi di pensiero abituali ti rendano più difficili le cose&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Percorso&lt;/h2&gt;

&lt;h3&gt;Haskell for all!&lt;/h3&gt;

&lt;p&gt;Per queste ragioni, tenderei a consigliarti di iniziare con Haskell. E&amp;#39; un linguaggio funzionale &lt;em&gt;puro&lt;/em&gt; e staticamente tipato, che compila in codice nativo (quindi niente JVM nè .NET). Tieni conto che imparare questo stile migliorerà il tuo codice in qualsiasi linguaggio, anche se non utilizzerai Haskell o simili sul lavoro di tutti i giorni.&lt;/p&gt;

&lt;p&gt;Il percorso che consiglio è quello delineato da &lt;a href=&quot;https://github.com/bitemyapp/learnhaskell&quot;&gt;Chris Allen&lt;/a&gt;. Per cominciare, ti consiglio caldamente il corso &lt;a href=&quot;http://www.seas.upenn.edu/%7Ecis194/spring13/index.html&quot;&gt;CIS 194&lt;/a&gt; di Brent Yorgey dell&amp;#39;università della Pennsylvania. E&amp;#39; un corso molto completo e ben fatto. Puoi trovare qualche appunto (per ora sulle prime due settimane) sul &lt;a href=&quot;http://manuelp.herokuapp.com/category/cis-194&quot;&gt;blog&lt;/a&gt; del sottoscritto, ma a cui consiglio di dare uno sguardo solo dopo che hai affrontato il materiale di Brent Yorgey. Non è eccessivamente impegnativo, ma molto utile.&lt;/p&gt;

&lt;p&gt;Altro consiglio: &lt;strong&gt;fai gli esercizi&lt;/strong&gt;. Leggere e capire non significa assimilare, per imparare veramente occorre applicare le cose, solo allora ti rendi conto di ciò che sai e cosa no. L&amp;#39;unico apprendimento è quello &lt;em&gt;attivo&lt;/em&gt;. Inoltre tieni presente che si parte dalle basi quindi &lt;em&gt;non avere fretta&lt;/em&gt; di scrivere web application in quattro e quattr&amp;#39;otto. Tuttavia dalle basi si progredisce abbastanza velocemente, quindi persevera e &lt;a href=&quot;http://manuelp.herokuapp.com/posts/16&quot;&gt;vedrai&lt;/a&gt; ;)&lt;/p&gt;

&lt;p&gt;Come ambienti di sviluppo io uso Emacs (vedi istruzioni di &lt;a href=&quot;https://github.com/bitemyapp/learnhaskell&quot;&gt;Chris Allen&lt;/a&gt; anche per questi aspetti), ma potresti anche usare &lt;a href=&quot;https://www.fpcomplete.com/business/haskell-industry/&quot;&gt;FPComplete&lt;/a&gt;: un IDE web-based gratuito (nel cui sito tra l&amp;#39;altro ci sono molte risorse didattiche).&lt;/p&gt;

&lt;p&gt;Padroneggiato un pò Haskell, le possibilità sono diverse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Esiste una versione di Haskell sulla JVM: &lt;a href=&quot;https://github.com/Frege/frege&quot;&gt;Frege&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Web frameworks per Haskell (in ordine di &amp;quot;indagine&amp;quot;):

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/scotty-web/scotty&quot;&gt;Scotty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://snapframework.com/&quot;&gt;Snap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://happstack.com/page/view-page-slug/1/happstack&quot;&gt;Happstack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.yesodweb.com/&quot;&gt;Yesod&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://elm-lang.org/&quot;&gt;Elm&lt;/a&gt;, un linguaggio ispirato ad Haskell per realizzare applicazioni web client-side basate sul paradigma &lt;a href=&quot;http://elm-lang.org/learn/What-is-FRP.elm&quot;&gt;FRP&lt;/a&gt;. Vedi la &lt;a href=&quot;http://elm-lang.org/learn/Roadmap.elm&quot;&gt;learning roadmap&lt;/a&gt; per maggiori dettagli.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.purescript.org/&quot;&gt;PureScript&lt;/a&gt; è un linguaggio Haskell-like che &amp;quot;transpila&amp;quot; in Javascript. Vedi anche il libro &lt;a href=&quot;https://leanpub.com/purescript/&quot;&gt;PureScript By Example&lt;/a&gt; che mi dicono sia anche una buona introduzione alla FP.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Alternative track: Clojure&lt;/h3&gt;

&lt;p&gt;Anche Clojure è una buona scelta per imparare l&amp;#39;approccio FP. Ha bene o male tutti gli attributi necessari e fino a poco tempo fa era il mio linguaggio preferito. Di diverso rispetto ad Haskell:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ha il &lt;em&gt;dynamic typing&lt;/em&gt;, ovvero ti aiuta meno nella comprensione/manutenzione di una base di codice ma è più flessibile. Puoi darti la zappa sui piedi con più flessibilità insomma :P&lt;/li&gt;
&lt;li&gt;E&amp;#39; &lt;a href=&quot;http://en.wikipedia.org/wiki/Homoiconicity&quot;&gt;omoiconico&lt;/a&gt;, ovvero la sintassi con sui si scrive il &lt;em&gt;codice&lt;/em&gt; è identica a quella delle &lt;em&gt;strutture dati&lt;/em&gt;. Il famoso detto:&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Code is data, data is code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pur essendo un linguaggio marcatamente funzionale, un po&amp;#39; per scelta un po&amp;#39; per limitazioni della piattaforma sottostante, è da una parte più semplice di Haskell dall&amp;#39;altra ti assiste meno a tempo di compilazione tramite il type system. C&amp;#39;è &lt;a href=&quot;http://typedclojure.org/&quot;&gt;core.typed&lt;/a&gt; certo, ma non è la stessa cosa. Questa differenza si nota molto a livello di impostazione e workflow: si usa molto la &lt;a href=&quot;http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop&quot;&gt;REPL&lt;/a&gt; e l&amp;#39;enfasi è sul modificare ed evoltere i sistemi manipolandoli direttamente a runtime (cfr. &lt;a href=&quot;http://en.wikipedia.org/wiki/Smalltalk&quot;&gt;Smalltalk&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Di interesse la sua &lt;a href=&quot;http://www.infoq.com/presentations/An-Introduction-to-Clojure-Time-Model&quot;&gt;concezione&lt;/a&gt; del tempo, valori e identità (dello &lt;a href=&quot;http://clojure.org/state&quot;&gt;stato&lt;/a&gt; insomma) che facilita di molto la concorrenza. Da notare che la STM è &lt;a href=&quot;http://www.haskell.org/haskellwiki/Software_transactional_memory&quot;&gt;presente anche in Haskell&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Clojure gira sulla JVM, ma anche &lt;a href=&quot;https://github.com/clojure/clojure-clr&quot;&gt;su .NET&lt;/a&gt; e transpila &lt;a href=&quot;https://github.com/clojure/clojurescript&quot;&gt;su JS&lt;/a&gt;, interoperando con naturalezza con la piattaforma ospite.&lt;/p&gt;

&lt;p&gt;Come risorse, se vuoi approfondirlo, ti consiglio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(libro) &lt;a href=&quot;https://pragprog.com/book/shcloj2/programming-clojure&quot;&gt;Programming Clojure, seconda edizione&lt;/a&gt;. E&amp;#39; un libro introduttivo e conciso che ho trovato molto chiaro e utile. Probabilmente è la risorsa migliore per cominciare con Clojure.&lt;/li&gt;
&lt;li&gt;(libro) &lt;a href=&quot;http://www.clojurebook.com/&quot;&gt;Clojure Programming&lt;/a&gt; (si lo so...) E&amp;#39; considerato più o meno universalmente come il miglior libro per &amp;quot;beginner&amp;quot; (è uscito dopo quello del punto precedente). Copre tutto il liguaggio e molti aspetti pratici come programmazione web, uso di DB di vario tipo, testing, ecc. Ma è un mattone di quasi 600 pagine, quindi l&amp;#39;ho messo per secondo.&lt;/li&gt;
&lt;li&gt;(video) &lt;a href=&quot;http://shop.oreilly.com/product/0636920030409.do&quot;&gt;Clojure: Inside Out&lt;/a&gt;: corso tenuto da giganti, interessante e utile.&lt;/li&gt;
&lt;li&gt;(video) &lt;a href=&quot;http://www.purelyfunctional.tv/intro-to-clojure&quot;&gt;LispCast&amp;#39;s Introduction To Clojure&lt;/a&gt; altra serie di video.&lt;/li&gt;
&lt;li&gt;(online) &lt;a href=&quot;http://www.4clojure.com/&quot;&gt;4clojure&lt;/a&gt;: valangate di &lt;em&gt;esercizi&lt;/em&gt; (anche con Clojure è importate farli!).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Che ho esaminato meno da vicino, ma che ti segnalo comunque:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(libro/online) &lt;a href=&quot;www.braveclojure.com&quot;&gt;Clojure For The Brave And True&lt;/a&gt;: una idiosincratica introduzione gratuita :)&lt;/li&gt;
&lt;li&gt;(online/libro?) &lt;a href=&quot;http://aphyr.com/tags/Clojure-from-the-ground-up&quot;&gt;Clojure From The Ground Up&lt;/a&gt;. Aphyr in questi mesi si sta dedicando a completare questa introduzione.&lt;/li&gt;
&lt;li&gt;(online) &lt;a href=&quot;http://hitchhikersclojure.com/&quot;&gt;Hitchhicker&amp;#39;s Guide To Clojure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dal punto di vista dello sviluppo, io uso &lt;a href=&quot;https://github.com/clojure-emacs/cider&quot;&gt;Emacs&lt;/a&gt; ma ti segnalo anche:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://lighttable.com/&quot;&gt;LightTable&lt;/a&gt; un avvenieristico IDE (scritto in ClojureScript) facile da usare, che ha spopolato su Kickstarter un paio di anni fa. &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cursiveclojure.com/&quot;&gt;Cursive Clojure&lt;/a&gt;: IDE basato su IntelliJ IDEA che sta rapidamente guadagnando adepti e che mi pare abbastanza completo (sta evolvendo velocemente).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ci sarebbe molto altro da dire, ma per il momento basti questo. Ulteriori aree di indagine se sei interessato:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Puoi dare un&amp;#39;occhiata a del &lt;a href=&quot;https://github.com/manuelp&quot;&gt;mio codice&lt;/a&gt;. Probabilmente di relativamente presentabile/semplice ci sono:

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/manuelp/assert-json&quot;&gt;assert-json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/manuelp/obj-hierarchy&quot;&gt;obj-hierarchy&lt;/a&gt; (e &lt;a href=&quot;http://manuelp.herokuapp.com/posts/6&quot;&gt;post&lt;/a&gt; di accompagnamento)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/manuelp/elekti&quot;&gt;elekti&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/manuelp/actions&quot;&gt;actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/manuelp/dicepass&quot;&gt;dicepass&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/manuelp/virtual-adventure&quot;&gt;virtual-adventure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/manuelp/confunion&quot;&gt;confunion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Programmazione lato frontend con &lt;a href=&quot;https://github.com/swannodette/om&quot;&gt;Om&lt;/a&gt; o, forse meglio, &lt;a href=&quot;http://holmsand.github.io/reagent/&quot;&gt;Reagent&lt;/a&gt; (basati su &lt;a href=&quot;http://facebook.github.io/react/&quot;&gt;react.js&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Programmazione web con &lt;a href=&quot;http://hoplon.io/&quot;&gt;hoplon&lt;/a&gt;, &lt;a href=&quot;http://luminusweb.net/&quot;&gt;Luminus&lt;/a&gt; o &lt;a href=&quot;http://pedestal.io&quot;&gt;Pedestal&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Molto interessante, come database, &lt;a href=&quot;http://www.datomic.com/&quot;&gt;Datomic&lt;/a&gt;. Un vero e proprio database funzionale.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Altro?&lt;/h3&gt;

&lt;p&gt;Personalmente ti posso dire che parecchie delle cose imparate le sto applicando anche sul lavoro. In ambito Java per esempio sto usando molto &lt;a href=&quot;http://totallylazy.com/&quot;&gt;TotallyLazy&lt;/a&gt;: sfortunatamente di documentazione c&amp;#39;è poco, ma ha una tonnellata di roba funzionale molto interessante. Comunque già solo col concetto di &lt;code&gt;Callable&lt;/code&gt; e &lt;code&gt;Sequence&lt;/code&gt; puoi fare molto e ti abilita un bel po&amp;#39; di idiomi funzionali (anche se non sempre convengono data la verbosità del linguaggio). &lt;/p&gt;

&lt;p&gt;Interessante anche da esplorare &lt;a href=&quot;https://code.google.com/p/lazyrecords/&quot;&gt;lazyrecords&lt;/a&gt; (degli stessi autori), che fornisce un accesso ai dati funzionale a-la &lt;a href=&quot;http://queue.acm.org/detail.cfm?id=2024658&quot;&gt;LINQ&lt;/a&gt; in ambito .NET.&lt;/p&gt;

&lt;p&gt;Lato Javascript ci sono di interessanti da esplorare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flux con React e immutable-js (precedentemente linkati)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://eliperelman.com/fn.js/&quot;&gt;fn.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://lodash.com/&quot;&gt;lodash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/puffnfresh/bilby.js&quot;&gt;bilby.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dailyjs.com/2010/06/08/wujs/&quot;&gt;wu.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ci sarebbe tantissimo altro da dire/esplorare/discutere, ma credo di aver già dato abbastanza materiale per ora.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CIS 194, week 2, Algebraic Data Types</title>
   <link href="http://manuelp.github.com/blog/2014/08/14/cis194-week2.html"/>
   <updated>2014-08-14T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/08/14/cis194-week2</id>
   <content type="html">&lt;p&gt;This is a post about &lt;a href=&quot;http://www.seas.upenn.edu/%7Ecis194/lectures/02-ADTs.html&quot;&gt;week 2&lt;/a&gt; of the &lt;a href=&quot;http://www.seas.upenn.edu/%7Ecis194/&quot;&gt;CIS 194: Introduction to Haskell&lt;/a&gt; course by &lt;a href=&quot;http://www.cis.upenn.edu/%7Ebyorgey/&quot;&gt;Brent Yorgey&lt;/a&gt;, from the &lt;a href=&quot;http://www.upenn.edu/&quot;&gt;Penn University of Pennsilvania&lt;/a&gt;.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;This week is all about &lt;strong&gt;Algebraic Data Types&lt;/strong&gt; (ADT), not to be confused with &lt;em&gt;Abstract&lt;/em&gt; Data Types (also ADT) which are another topic.&lt;/p&gt;

&lt;p&gt;Haskell has &lt;em&gt;enumeration types&lt;/em&gt; (like Java, but still less verbose and more intuitive). An example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Food&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Pizza&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bacon&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Salad&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Show&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We have just declared a new (algebraic data) type called &lt;code&gt;Food&lt;/code&gt;, with three &lt;em&gt;data constructors&lt;/em&gt; which are the &lt;em&gt;only&lt;/em&gt; values of the type &lt;code&gt;Food&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can now define new functions on the new data type using &lt;em&gt;pattern matching&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;n&quot;&gt;isTempting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Food&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Boolean&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;isTempting&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Salad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;isTempting&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But in Haskell enumeration types are only a special case of Algebraic Data Types. One common class of ADT is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Sum_type&quot;&gt;sum type&lt;/a&gt; (a.k.a. tagged union). A simple example of ADT which is not an enumeration is this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OperationResult&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OK&lt;/span&gt;
                     &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Integer&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Show&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here we see that &lt;code&gt;Error&lt;/code&gt; is a data constructor that &lt;em&gt;takes an argument&lt;/em&gt; of type &lt;code&gt;Integer&lt;/code&gt;. We can &lt;em&gt;construct&lt;/em&gt; new &lt;code&gt;OperationResult&lt;/code&gt; values using the &lt;code&gt;Error&lt;/code&gt; data constructor:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OperationResult&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;success&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OK&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OperationResult&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;404&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;OK&lt;/code&gt; is a value of type &lt;code&gt;OperationResult&lt;/code&gt; (since it&amp;#39;s a data constructor with zero arguments), but &lt;code&gt;Error&lt;/code&gt; by itself it&amp;#39;s not. We have to pass an &lt;code&gt;Integer&lt;/code&gt; value to it to build an &lt;code&gt;OperationResult&lt;/code&gt; with it. &lt;/p&gt;

&lt;p&gt;We&amp;#39;ve just introduced &lt;em&gt;polymorphic data types&lt;/em&gt;. Specifically, we can have &lt;em&gt;type signatures with variables&lt;/em&gt; just as we can have function implementations with variables. The difference here is that while in actual code variables are symbols bound to &lt;em&gt;values&lt;/em&gt;, in &lt;em&gt;type variables are bound to types of values&lt;/em&gt;. In other words, types are actually values in type signatures. We&amp;#39;re reasoning on a higher and more abstract level. Take a moment to contemplate this fact.&lt;/p&gt;

&lt;p&gt;Formally, in Haskell an ADT is &lt;em&gt;a type with one or more data constructors, each one of them can have zero or more arguments&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A general example that shows how to build values is:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;n&quot;&gt;isSafeDiv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OperationResult&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;isSafeDiv&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;isSafeDiv&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can also use pattern matching to make decisions based on the &lt;em&gt;structure&lt;/em&gt; of the &lt;code&gt;OperationResult&lt;/code&gt; value and bind variables to the arguments:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;n&quot;&gt;isSuccessful&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OperationResult&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Boolean&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;isSuccessful&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OK&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;isSuccessful&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#39;s idiomatic in Haskell when you have an algebraic data type with a single data constructor, to name it like the data type itself. Example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Show&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This can be done since &lt;em&gt;types and data constructors live in separate namespaces&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Pattern Matching&lt;/h2&gt;

&lt;p&gt;In general, pattern matching is a way to &lt;em&gt;know what data constructor has been used to create a value of a certain ADT, and to take apart its arguments&lt;/em&gt;. Effectively, in Haskell this is &lt;em&gt;the only way to make decisions&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;pat ::= _
    | var
    | var @ (pat)
    | (Constructor pat1 pat2 ... patn)  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_&lt;/code&gt; is a wildcard.&lt;/li&gt;
&lt;li&gt;We can pattern match against literal values (for example: &lt;code&gt;OK&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;We can pattern match against a pattern, and still bind the entire value to a variable.&lt;/li&gt;
&lt;li&gt;We can pattern match against a data constructor (even recursively).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It&amp;#39;s worth noting that types like &lt;code&gt;Int&lt;/code&gt; can be viewed like an ADT:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Indeed, we can pattern match on its values. But, perhaps obviously, they are not implemented like that in the compiler.&lt;/p&gt;

&lt;h3&gt;Case expressions&lt;/h3&gt;

&lt;p&gt;A way (the only one actually) to do pattern matching is by using &lt;em&gt;case expressions&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;kr&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;of&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pat1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exp1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pat2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exp2&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For example, we could reimplement the &lt;code&gt;isSuccessful&lt;/code&gt; function from earlier using a case expression:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;n&quot;&gt;isSuccessful&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;OperationResult&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Boolean&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;isSuccessful&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;of&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;OK&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However it&amp;#39;s more elegant to use the first version. Indeed, the syntax for doing pattern matching in a function definition is just &lt;em&gt;syntactic sugar&lt;/em&gt; on case expressions.&lt;/p&gt;

&lt;h2&gt;Recursive algebraic data types&lt;/h2&gt;

&lt;p&gt;It&amp;#39;s interesting to note that ADTs can be &lt;em&gt;recursive&lt;/em&gt;. For example, let&amp;#39;s define a list of integers:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;IntList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Empty&lt;/span&gt;
             &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Cons&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;IntList&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This definition can be read as: &amp;quot;an &lt;code&gt;IntList&lt;/code&gt; is either an &lt;code&gt;Empty&lt;/code&gt; one or an &lt;code&gt;Int&lt;/code&gt; value followed by an &lt;code&gt;IntList&lt;/code&gt;&amp;quot;. This kind of definition is quite clear and elegant (see &lt;a href=&quot;http://en.wikipedia.org/wiki/Church_encoding&quot;&gt;Church encoding&lt;/a&gt;). For example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;c1&quot;&gt;-- [1,2,3] can be represented as an IntList:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;IntList&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Cons&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Cons&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Cons&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A recursive data ADT naturally leads to recursive functions. For example, to calculate the sum of all the values in an &lt;code&gt;IntList&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;n&quot;&gt;calcSum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;IntList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;calcSum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Empty&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;calcSum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Cons&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calcSum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ns&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, we&amp;#39;ve seen so far that type signatures can have variables, and can be recursive. Sounds like we could have a Turing-complete type system... indeed, we have one. Someone even implemented &lt;a href=&quot;https://github.com/seliopou/typo&quot;&gt;a LISP interpreter that completely runs on the Haskell type system&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;That&amp;#39;s all for this week. Remember: &lt;em&gt;do the exercises&lt;/em&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Introduction to Haskell, week 1</title>
   <link href="http://manuelp.github.com/blog/2014/08/10/cis194-week1.html"/>
   <updated>2014-08-10T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/08/10/cis194-week1</id>
   <content type="html">&lt;p&gt;A while ago I&amp;#39;ve finally started to study &lt;a href=&quot;http://www.haskell.org/&quot;&gt;Haskell&lt;/a&gt;, in particular following the &lt;a href=&quot;http://www.seas.upenn.edu/%7Ecis194/&quot;&gt;CIS 194: Introduction to Haskell&lt;/a&gt; course by &lt;a href=&quot;http://www.cis.upenn.edu/%7Ebyorgey/&quot;&gt;Brent Yorgey&lt;/a&gt; from the &lt;a href=&quot;http://www.upenn.edu/&quot;&gt;Penn University of Pennsilvania&lt;/a&gt;. This is the first resource of the curriculum I plan to follow to &lt;a href=&quot;https://github.com/bitemyapp/learnhaskell&quot;&gt;learn Haskell&lt;/a&gt; (thanks a lot to &lt;a href=&quot;https://github.com/bitemyapp&quot;&gt;Chris Allen&lt;/a&gt; for laying out a path to FP enlightenment :)&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve worked through the first 4 weeks now, but I decided at this point to switch gears and go back to recap what I&amp;#39;ve learned so far.&lt;/p&gt;

&lt;p&gt;Without further ado, let&amp;#39;s recap CIS 192: week 1.&lt;/p&gt;

&lt;h2&gt;What is Haskell?&lt;/h2&gt;

&lt;p&gt;Haskell (named after &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;Haskell Curry&lt;/a&gt;, for his work on combinatory logic and for the &lt;a href=&quot;http://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence&quot;&gt;Curry-Howard Correspondence&lt;/a&gt;), is a &lt;em&gt;lazy, statically typed, pure functional programming language&lt;/em&gt; created in the 1980&amp;#39;s by a committee of academics. It&amp;#39;s very well &lt;a href=&quot;http://www.huffingtonpost.com/aaroncontorer/haskell-the-language-most_b_4242119.html&quot;&gt;alive&lt;/a&gt; today, as it&amp;#39;s one of the most advanced (statically typed) languages out there.&lt;/p&gt;

&lt;p&gt;Haskell is:&lt;/p&gt;

&lt;h2&gt;Functional&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Functions are &lt;em&gt;first-class values&lt;/em&gt;. That is, they can be passed to other functions or returned by them like any other values.&lt;/li&gt;
&lt;li&gt;The computation model is based around &lt;em&gt;evaluating expressions&lt;/em&gt;, not &lt;em&gt;executing instructions&lt;/em&gt;. In other words, it&amp;#39;s not based on the &lt;a href=&quot;http://en.wikipedia.org/wiki/Von_Neumann_architecture&quot;&gt;Von Neumann architecture&lt;/a&gt; (instructions that operate on a shared memory), but on the &lt;a href=&quot;http://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt; (you can think about it in terms of &lt;em&gt;composing functions to transform streams of immutable data&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Pure&lt;/h2&gt;

&lt;p&gt;Every expression is &lt;em&gt;referentially transparent&lt;/em&gt;. This means that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Everything is immutable&lt;/em&gt;. Every &amp;quot;mutation&amp;quot; is modeled as a transformation, a &lt;em&gt;function&lt;/em&gt; that doesn&amp;#39;t change the original value but creates a new one.&lt;/li&gt;
&lt;li&gt;There are &lt;em&gt;no side effects&lt;/em&gt; (well, there are: modeled with monads to retain purity, but you don&amp;#39;t need to know what a monad is to use them!).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a consequence of the previous points, calling the same function with the same arguments results in the same output, always.&lt;/p&gt;

&lt;p&gt;This approach has a number of very nice benefits, that once you wrap your head around this paradigm you won&amp;#39;t give away too easily:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Equational reasoning&lt;/em&gt;: thinking about the code becomes much more easier. Refactoring becomes a breeze.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Parallelism&lt;/em&gt;: using multiple cores is much easier when you know that functions are guaranteed not to interfere with each another. There is no shared state!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, with &lt;em&gt;static types&lt;/em&gt; and &lt;em&gt;pure functions&lt;/em&gt; programs become much more easy to maintain, refactor, debug and &lt;em&gt;reasoning about&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;Lazy&lt;/h3&gt;

&lt;p&gt;In Haskell values are computed only when needed (&lt;a href=&quot;http://en.wikipedia.org/wiki/Lazy_evaluation&quot;&gt;call-by-need&lt;/a&gt; evaluation strategy).&lt;/p&gt;

&lt;p&gt;Advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It&amp;#39;s easy to &lt;em&gt;define new control structures&lt;/em&gt; just by defining a new function. Contrast this with languages like Clojure where you need &lt;a href=&quot;http://clojure.org/macros&quot;&gt;macros&lt;/a&gt; to achieve that, or languages like Java where it&amp;#39;s basically impossible.&lt;/li&gt;
&lt;li&gt;It&amp;#39;s easy to work with &lt;em&gt;infinite data structures&lt;/em&gt;, since values are only computed when needed. You can achieve the same in idiomatic Clojure by using the &lt;a href=&quot;http://clojure.org/sequences&quot;&gt;seq&lt;/a&gt; abstraction and &lt;a href=&quot;http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/lazy-seq&quot;&gt;lazy-seq&lt;/a&gt;, in Java 8 using &lt;a href=&quot;http://www.drdobbs.com/jvm/lambdas-and-streams-in-java-8-libraries/240166818&quot;&gt;Streams&lt;/a&gt;, etc.&lt;/li&gt;
&lt;li&gt;It enables a &lt;em&gt;compositional style&lt;/em&gt; (we will see it down the road with &lt;em&gt;wholemeal programming&lt;/em&gt;, currying and point-free style).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Downside: it becomes harder to reason about the time and space characteristics of programs. &lt;/p&gt;

&lt;h2&gt;Themes&lt;/h2&gt;

&lt;p&gt;The course revolves around thee key areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Types&lt;/li&gt;
&lt;li&gt;Abstractions&lt;/li&gt;
&lt;li&gt;Wholemeal programing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Types&lt;/h3&gt;

&lt;p&gt;Static type systems can be annoying, and some of them really are. But this isn&amp;#39;t because type systems are inherently annoying, that&amp;#39;s because &lt;em&gt;some of them are insufficiently expressive&lt;/em&gt; (for example, Java and C++ ones).&lt;/p&gt;

&lt;p&gt;A type system (especially the Haskell one):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gives you clarity of thinking and helps you to &lt;em&gt;design&lt;/em&gt; and &lt;em&gt;reason&lt;/em&gt; about programs. Types become an organizing principle, a precise and powerful tool to think about and express abstractions. Using them, you are able to &lt;em&gt;reason at a higher level, in a systematic way&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Is a form of documentation, always in sync with the actual code.&lt;/li&gt;
&lt;li&gt;Turns a lot of runtime errors to compile time ones. Computers can do complex, repetitive and clearly specified things efficiently: why not delegate to them some of the burden that a human has to carry on while writing software?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you start to get the hang of it, a (good) type system becomes an invaluable ally. It feels liberating, since it can help you long before you write the first line of code: it helps you in the &lt;em&gt;design&lt;/em&gt; of the system.&lt;/p&gt;

&lt;h3&gt;Abstraction&lt;/h3&gt;

&lt;p&gt;In some way, designing and maintaining software is a battle against repetition: you frequently need to take similar things and factor out their commonality (a process known as &lt;a href=&quot;http://manuelp.herokuapp.com/posts/5&quot;&gt;abstraction&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Haskell gives you a lot of abstraction power: parametric polymorphism, higher-order functions, type classes, etc. Its type systems is also a powerful, methodic and sound tool to think mathematically about them.&lt;/p&gt;

&lt;h3&gt;Wholemeal programming&lt;/h3&gt;

&lt;p&gt;Quoting Ralf Hinze:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Functional languages excel at wholemeal programming, a term coined by Geraint Jones. Wholemeal programming means to think big: work with an entire list, rather than a sequence of elements; develop a solution space, rather than an individual solution; imagine a graph, rather than a single path. The wholemeal approach often offers new insights or provides new perspectives on a given problem. It is nicely complemented by the idea of projective programming: first solve a more general problem, then extract the interesting bits and pieces by transforming the general program into more specialised ones.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short, it&amp;#39;s about working with &lt;em&gt;abstractions&lt;/em&gt; rather than concrete instances of the problem/solution space, with &lt;em&gt;group/types of things&lt;/em&gt; instead of with single instances.&lt;/p&gt;

&lt;p&gt;Next, Brent Yorgey goes on showing the basic types (scalars and lists), how to define and combine functions, etc. Lots of good stuff.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Data types as graphical shapes</title>
   <link href="http://manuelp.github.com/blog/2014/07/04/types-graphical-shapes.html"/>
   <updated>2014-07-04T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/07/04/types-graphical-shapes</id>
   <content type="html">&lt;p&gt;A very interesting idea that I&amp;#39;ve just found in a &lt;a href=&quot;http://spiegela.com/2014/06/21/programming-on-4-strings-part-0/&quot;&gt;post&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/spiegela&quot;&gt;Aaron Spiegel&lt;/a&gt;: to explain basic FP constructs like map, filter and fold/reduce graphically (nothing new, I&amp;#39;ve already done that several times), but with an interesting twist: &lt;em&gt;by representing types as shapes&lt;/em&gt;. That&amp;#39;s a clever trick to better explain that HOFs (Higher-Order Functions).&lt;/p&gt;

&lt;p&gt;However, &lt;a href=&quot;http://www.nickerson.to/visprog/visprog.htm&quot;&gt;visual languages&lt;/a&gt; rapidly become &lt;a href=&quot;http://www.nickerson.to/visprog/ch8.htm&quot;&gt;inadequate&lt;/a&gt; to express more high level concepts. For example you can sort-of encode algebraic data types using different colors for example. Then maybe you can express &lt;a href=&quot;http://en.wikipedia.org/wiki/Monad_%28functional_programming%29#The_Maybe_monad&quot;&gt;options&lt;/a&gt; using full or empty shapes. But, as you probably can see, there are limits in this medium and we can reach them pretty fast.&lt;/p&gt;

&lt;p&gt;In some sense it&amp;#39;s like understanding certain mathematical concepts using geometry (as a visual learner, that&amp;#39;s how I really understood integrals), but one of the reasons mathematicians use textual notation is that it&amp;#39;s much more concise and expressive.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Summary: x-Driven x do not change anything</title>
   <link href="http://manuelp.github.com/blog/2014/05/03/summary-star-driven.html"/>
   <updated>2014-05-03T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/05/03/summary-star-driven</id>
   <content type="html">&lt;p&gt;This is a short summary of my takeaways of the article &lt;a href=&quot;http://www.infoq.com/articles/star-driven-approaches&quot;&gt;&lt;em&gt;-Driven&lt;/em&gt; do not change anything&lt;/a&gt; by &lt;a href=&quot;http://www.infoq.com/author/Micha%C5%82-Bartyzel&quot;&gt;Michał Bartyzel&lt;/a&gt;.&lt;/p&gt;

&lt;hr&gt;

&lt;ul&gt;
&lt;li&gt;Mental frameworks (like *-Driven*) need to be &lt;em&gt;intepreted&lt;/em&gt; in the light of the appropriate &lt;em&gt;context&lt;/em&gt;, and require &lt;em&gt;experience&lt;/em&gt; to be applied to unknown ones.&lt;/li&gt;
&lt;li&gt;These frameworks are usually formed over many years of experience by &lt;em&gt;induction&lt;/em&gt;, and adapted to other contexts by &lt;em&gt;deduction&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Instead of focusing on context/experience-dependent mental frameworks, invest in &lt;strong&gt;developing the foundamentals&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Responsibility&lt;/li&gt;
&lt;li&gt;Encapsulation&lt;/li&gt;
&lt;li&gt;Composition&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Interesting links</title>
   <link href="http://manuelp.github.com/blog/2014/03/29/interesting-links.html"/>
   <updated>2014-03-29T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/03/29/interesting-links</id>
   <content type="html">&lt;h2&gt;&lt;a href=&quot;http://xprogramming.com/articles/deliver-working-software-frequently/&quot;&gt;Deliver Working Software Frequently&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Before you can run, you need to learn how to walk. This is a good primer on &lt;a href=&quot;http://pragdave.me/blog/2014/03/04/time-to-kill-agile/&quot;&gt;agility&lt;/a&gt;. Focus first on &lt;em&gt;delivery&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Until you can deliver, work on delivery. Work on nothing else until then. The rest will come in due time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;&lt;a href=&quot;http://programmingisterrible.com/post/81015328859/i-reckon-your-message-broker-might-be-a-bad-idea&quot;&gt;I reckon your message broker might be a bad idea.&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Message brokers can be a bad idea if treated like &amp;quot;infallible gods&amp;quot;, because they aren&amp;#39;t. Think about three good design principles for realiable systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fail fast&lt;/li&gt;
&lt;li&gt;Process supervision&lt;/li&gt;
&lt;li&gt;End-to-End principle&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;In the end, it isn’t so much about message brokers, but treating them as infallible gods. By using acknowledgements, back-pressure and other techniques you can move responsibility out of the brokers and into the edges. What was once a central point of failure becomes an effectively stateless server, no-longer hiding failures from your components. Your system works because it knows that it can fail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;&lt;a href=&quot;http://www.craigkerstiens.com/2014/03/24/Postgres-9.4-Looking-up&quot;&gt;PostgreSQL 9.4 - Looking Up (With JSONB and Logical Decoding)&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;PostgreSQL 9.4 is going to be exciting with JSONB support. As &lt;a href=&quot;https://twitter.com/davidlesches/status/449675286947573760&quot;&gt;David Lesches&lt;/a&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JSONB has been committed to Postgres 9.4, making Postgres the first RDBMS with rock-solid support for schemaless data&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>On "Enlightenment"</title>
   <link href="http://manuelp.github.com/blog/2014/03/24/on-enlightenment.html"/>
   <updated>2014-03-24T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/03/24/on-enlightenment</id>
   <content type="html">&lt;p&gt;The more I think about it, the more I see it. They say that you should expose yourself to different kind of programming languages, and more specifically to different kind of &lt;em&gt;paradigms&lt;/em&gt;. The key of that advice is to get exposure (and hopefully proficiency) with different &lt;em&gt;ways of thinking&lt;/em&gt;. The more high-level thinking tools you have at your disposal, the more &lt;em&gt;effective&lt;/em&gt; and &lt;em&gt;efficient&lt;/em&gt; you are at identifying and solving problems. &lt;/p&gt;

&lt;p&gt;You become able to really &lt;em&gt;see&lt;/em&gt; the problem and build a general solution. You start to deconstruct what you know, the constraints and the problem at hand, and you become able to build general solutions by &lt;em&gt;composing simple things&lt;/em&gt;. Systematically. When you start to think in terms of data transformations via &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, &lt;code&gt;juxt&lt;/code&gt;,  etc. you realize that you are operating on a higher level. You start to really see what the &lt;a href=&quot;http://en.wikipedia.org/wiki/Single_responsibility_principle&quot;&gt;single resposibility principle&lt;/a&gt; is all about. And then, you start to see all the &lt;a href=&quot;http://en.wikipedia.org/wiki/Accidental_complexity&quot;&gt;accidental complexity&lt;/a&gt; that used to slow you down and hide the &lt;em&gt;essence&lt;/em&gt; of the solution behind reams of low level details (syntactical or otherwise). When your mind is not distracted by accidental complexity, you can step back and think clearly about what you have and what is really needed.&lt;/p&gt;

&lt;p&gt;Unfortunately, this kind of &amp;quot;enlightenment&amp;quot; has some downsides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You become painfully aware that you could do much better and much faster than when you develop with less advanced languages (for example: Java). Here starts the frustration.&lt;/li&gt;
&lt;li&gt;Your &amp;quot;yet-to-reach-enlightenment&amp;quot; colleagues don&amp;#39;t &lt;em&gt;see&lt;/em&gt; the way you do. They don&amp;#39;t understand (yet). This is the &lt;a href=&quot;http://paulgraham.com/avg.html&quot;&gt;blub paradox&lt;/a&gt; at work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combine both factors, and you have a recipe for &lt;a href=&quot;http://joelmccracken.github.io/entries/the-misery-of-lisp/&quot;&gt;misery&lt;/a&gt;. It&amp;#39;s depressing seeing friends (and yourself) wasting time with unnecessary complexity.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.performancemanagementcompany.com&quot;&gt;&lt;img src=&quot;/images/SWs%20One%20Main%20FINAL%20%C2%A9%C2%AE%20tiny%20133.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, even if it requires work, practice and dedication to reach a master level, I think that &lt;em&gt;it&amp;#39;s worth it&lt;/em&gt;. I&amp;#39;m certainly not a master, and yet I&amp;#39;m seeing benefits of this learning journey even when I&amp;#39;m not writing &lt;a href=&quot;http://clojure.org/&quot;&gt;LISP&lt;/a&gt; code. &lt;a href=&quot;http://www.catb.org/esr/faqs/hacker-howto.html&quot;&gt;Eric Raymond&lt;/a&gt; was right:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;LISP is worth learning for a different reason — the profound enlightenment experience you will have when you finally get it. That experience will make you a better programmer for the rest of your days, even if you never actually use LISP itself a lot.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So go ahead and learn some &lt;a href=&quot;http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome&quot;&gt;Clojure&lt;/a&gt;, &lt;a href=&quot;http://learnyouahaskell.com/&quot;&gt;Haskell&lt;/a&gt; and &lt;a href=&quot;http://factorcode.org/&quot;&gt;Factor&lt;/a&gt; (for example). You don&amp;#39;t need to spend &lt;a href=&quot;http://pragprog.com/book/btlang/seven-languages-in-seven-weeks&quot;&gt;a lot of time&lt;/a&gt; to get a feel of what&amp;#39;s out there. You will be a better programmer anyway, and I think this is a worthwhile goal.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>On frameworks</title>
   <link href="http://manuelp.github.com/blog/2014/02/18/on-frameworks.html"/>
   <updated>2014-02-18T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/02/18/on-frameworks</id>
   <content type="html">&lt;blockquote&gt;
&lt;p&gt;Frameworks remove your ability to solve your specific problems from first principles. They opt you out of innovation, simplicity &amp;amp; elegance
&amp;mdash; &lt;a href=&quot;https://twitter.com/sanityinc/status/435725406055186432&quot;&gt;Steve Purcell&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>How to programmatically manage a Light Table-aware nREPL server</title>
   <link href="http://manuelp.github.com/blog/2014/01/26/light-table-nrepl.html"/>
   <updated>2014-01-26T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2014/01/26/light-table-nrepl</id>
   <content type="html">&lt;p&gt;Starting an &lt;a href=&quot;https://github.com/clojure/tools.nrepl&quot;&gt;nREPL&lt;/a&gt; server for a Clojure application is trivial if you use &lt;a href=&quot;http://leiningen.org/&quot;&gt;Leiningen&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lein repl

&lt;span class=&quot;c&quot;&gt;# or:&lt;/span&gt;

lein repl :headless
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But what if you have an application deployed as a JAR (or WAR in an application server) and you want to have remote access to an nREPL server? Fortunately, it&amp;#39;s easy to start one programmatically:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clojure.tools.nrepl.server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:refer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;start-server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stop-server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; Starting an nREPL server is trivial:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defonce&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nrepl-server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;start-server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:port&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12345&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; So is stopping it:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stop-server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nrepl-server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It works out of the box if you use Emacs with &lt;a href=&quot;https://github.com/clojure-emacs/cider&quot;&gt;Cider&lt;/a&gt; to connect to it, but if you use &lt;a href=&quot;http://www.lighttable.com/&quot;&gt;Light Table&lt;/a&gt;, you need to add an additional nREPL middleware to support some functionality that LT needs to work properly. Again, this is &lt;a href=&quot;http://docs.lighttable.com/#how&quot;&gt;easy&lt;/a&gt; if you use Leiningen: you just need to declare the dependency to the middleware and add some &lt;code&gt;:repl-options&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defproject&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;some-awesome-thing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0.1.0-SNAPSHOT&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:description&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;FIXME: write description&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:dependencies&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org.clojure/clojure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.5.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lein-light-nrepl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0.0.13&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
  &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:repl-options&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:nrepl-middleware&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lighttable.nrepl.handler/lighttable-ops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using the &lt;code&gt;lighttable-ops&lt;/code&gt; nREPL middleware programmatically is also quite easy, but you have to &lt;a href=&quot;https://github.com/clojure/tools.nrepl#middleware&quot;&gt;know&lt;/a&gt; how to compose nREPL middlewares. First, you need to add the dependency to the LT middleware in your &lt;em&gt;project.clj&lt;/em&gt; as before:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defproject&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;some-awesome-thing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0.1.0-SNAPSHOT&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:description&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;FIXME: write description&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:dependencies&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org.clojure/clojure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.5.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lein-light-nrepl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0.0.13&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then you can add it to the middlewares chain in your code:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clojure.tools.nrepl.server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:refer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;start-server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stop-server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lighttable.nrepl.handler&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:refer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lighttable-ops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; Starting a server with custom middlewares is trivial:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defonce&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nrepl-server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
         &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;start-server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:port&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12345&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                       &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:handler&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;default-handler&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;'lighttable-ops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; So is stopping it:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stop-server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nrepl-server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that we passed &lt;code&gt;lighttable-ops&lt;/code&gt; to the &lt;code&gt;default-handler&lt;/code&gt; as a &lt;em&gt;var&lt;/em&gt; (in fact, &lt;code&gt;#&amp;#39;lighttable-ops&lt;/code&gt; is a &lt;a href=&quot;http://clojure.org/reader&quot;&gt;reader macro&lt;/a&gt; that expands to &lt;code&gt;(var lighttable-ops)&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Now you can connect to your project remotely using Light Table and inspect, modify and control it &lt;em&gt;live&lt;/em&gt;. Enjoy :)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Terrifying</title>
   <link href="http://manuelp.github.com/blog/2013/12/12/terrifying.html"/>
   <updated>2013-12-12T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2013/12/12/terrifying</id>
   <content type="html">&lt;p&gt;This is one of the most terrifying technical books I&amp;#39;ve ever read (not an affiliated link):&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://pragprog.com/book/mnee/release-it&quot;&gt;&lt;img src=&quot;http://imagery.pragprog.com/products/93/mnee_xlargecover.jpg?1298589747&quot; alt=&quot;Release It!&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I haven&amp;#39;t finished it yet, and I already think it&amp;#39;s a foundamental read for every professional software developer. Along with, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://pragprog.com/the-pragmatic-programmer&quot;&gt;The Pragmatic Programmer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pragprog.com/book/pad/practices-of-an-agile-developer&quot;&gt;Practices Of An Agile Developer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>JDBC Lint</title>
   <link href="http://manuelp.github.com/blog/2013/12/11/jdbclint-primer.html"/>
   <updated>2013-12-11T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2013/12/11/jdbclint-primer</id>
   <content type="html">&lt;p&gt;Recently I&amp;#39;m working quite heavily with straight JDBC and I&amp;#39;m learning some things from best practices and some others the hard way. One tool that I&amp;#39;ve found useful is &lt;a href=&quot;https://github.com/maginatics/jdbclint&quot;&gt;JDBC Lint&lt;/a&gt;: it&amp;#39;s a tool that acts as a dynamic proxy for &lt;code&gt;Connection&lt;/code&gt; objects (so that it can be used transparently) and reports errors at runtime on the standard error channel.&lt;/p&gt;

&lt;p&gt;For a primer on some JDBC best practices, see &lt;a href=&quot;http://javarevisited.blogspot.it/2012/08/top-10-jdbc-best-practices-for-java.html&quot;&gt;this&lt;/a&gt; post.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Fainting Goat Systems</title>
   <link href="http://manuelp.github.com/blog/2013/12/09/fainting-goat-systems.html"/>
   <updated>2013-12-09T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2013/12/09/fainting-goat-systems</id>
   <content type="html">&lt;p&gt;Paraphrasing &lt;a href=&quot;https://en.wikipedia.org/wiki/The_Moon_Is_a_Harsh_Mistress&quot;&gt;Robert Heinlein&lt;/a&gt;, reality is a harsh mistress. Have you ever designed or worked on a system which was finally declared &amp;quot;done&amp;quot; (the mythical 1.0 release): it passed all &lt;a href=&quot;http://en.wikipedia.org/wiki/Quality_control&quot;&gt;QC&lt;/a&gt; tests, all was green, all the checks in place... but that failed miserably when deployed in production? Unfortunately, a real system &lt;em&gt;lives&lt;/em&gt; in a harsh reality made of unreliable networks, crashing subsystems, crazy users and &lt;a href=&quot;https://en.wikipedia.org/wiki/Elbonia#Elbonia&quot;&gt;Elbonian&lt;/a&gt; hackers.&lt;/p&gt;

&lt;p&gt;Architecture is extremely important: flexibility, rapid development, modularity. All technically cool and necessary (I&amp;#39;m all for it!), but you need to take into account and &lt;strong&gt;design for the real world&lt;/strong&gt;. You don&amp;#39;t want to design a cool system on paper only to be constantly in emergency mode, struggling and working frantically just to keep the system live (still, with 80% availability, or worse). When you are in &lt;a href=&quot;http://5whys.com/blog/definition-survival-mode.html&quot;&gt;survival-mode&lt;/a&gt; you can&amp;#39;t spend time learning, practicing and developing new systems (that generates revenue). I call those &amp;quot;&lt;a href=&quot;https://en.wikipedia.org/wiki/Fainting_goat&quot;&gt;Fainting Goat&lt;/a&gt; Systems&amp;quot;: they are beautiful, functional, but when they are under stress, they just &lt;a href=&quot;http://www.youtube.com/watch?v=AnVv0RkiG4U&quot;&gt;crash&lt;/a&gt; and fall to the ground. Here is an informative slide of a Fainting Goat System just deployed to production for the first time:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://upload.wikimedia.org/wikipedia/commons/d/d6/Fainted.jpg&quot; alt=&quot;A fainting goat&quot;&gt;&lt;/p&gt;

&lt;p&gt;The first thing is &lt;em&gt;stability&lt;/em&gt;. The system should be stable, &lt;em&gt;built for cheap and easy operations&lt;/em&gt; and ready to make contact with the real world and real users. It&amp;#39;s important to release early and often, in production, and &lt;em&gt;adapt to reality&lt;/em&gt;. Certain lessons can only be learned in production, with real users and real deployments.&lt;/p&gt;

&lt;p&gt;A good book on the subject is &lt;a href=&quot;http://pragprog.com/book/mnee/release-it&quot;&gt;Release It!&lt;/a&gt; by the &lt;a href=&quot;http://cognitect.com/&quot;&gt;Cognitect&lt;/a&gt; Michael T. Nygard.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>(JAR) Hell is here</title>
   <link href="http://manuelp.github.com/blog/2013/12/05/jar-hell.html"/>
   <updated>2013-12-05T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2013/12/05/jar-hell</id>
   <content type="html">&lt;p&gt;From &lt;a href=&quot;http://blog.borud.no/2013/03/gorging-on-java-frameworks-and.html&quot;&gt;Gorging on Java frameworks and dependencies&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I can&amp;#39;t remember who said it, but I think one of my colleagues at Comoyo said something along the lines of: &lt;strong&gt;&amp;quot;we obsess over our own code with code reviews and such, but we happily depend on any piece of shit some crazy monkey on the net has cobbled together in his spare time&amp;quot;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think about that.  Because it is true.&lt;/p&gt;

&lt;p&gt;Right now your Java application probably contains a dozen version conflicts that you have not noticed.  The more common variety being the same library occurring in your transitive dependency graph more than once and in different versions.  It is sheer dumb luck that your application works at all.  If you don&amp;#39;t know what I am talking about I suggest you have a close look at your transitive dependency graph.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There has to be a better way to manage dependencies. One that is not necessarily a &lt;a href=&quot;https://groups.google.com/d/msg/clojure/WuS31RSiz_A/lmEFS71pEiYJ&quot;&gt;one-level&lt;/a&gt; dependency tree (which isn&amp;#39;t an unreasonable thing given a suitable language/ecosystem). Well, maybe &lt;a href=&quot;http://nixos.org/docs/papers.html&quot;&gt;there is&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Power comes from Emergence</title>
   <link href="http://manuelp.github.com/blog/2013/10/24/power-comes-from-emergence.html"/>
   <updated>2013-10-24T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2013/10/24/power-comes-from-emergence</id>
   <content type="html">&lt;p&gt;I&amp;#39;ve been thinking a lot about the intersection of OOP and FP, and I&amp;#39;ve come to realise one thing: &lt;em&gt;there is real power on the *&lt;/em&gt;composition** of &lt;a href=&quot;http://www.infoq.com/presentations/Simple-Made-Easy&quot;&gt;simple&lt;/a&gt; things*.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s more general than the objects VS functions debacle, and I won&amp;#39;t talk about immutability right now. The point I want to make is that when you have a small set of &lt;em&gt;simple&lt;/em&gt; concepts/abstractions that you can compose at will, you get a great deal of expressivity and power that you can build on. Just look at &lt;a href=&quot;http://www.michaelnielsen.org/ddi/lisp-as-the-maxwells-equations-of-software/&quot;&gt;LISP&lt;/a&gt; or &lt;a href=&quot;http://worrydream.com/EarlyHistoryOfSmalltalk/&quot;&gt;Smalltalk&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;git&lt;/h2&gt;

&lt;p&gt;Maybe you are among the ones that consider &lt;a href=&quot;http://git-scm.com/&quot;&gt;git&lt;/a&gt; difficult. Well, at its core git is quite &lt;a href=&quot;http://www.infoq.com/presentations/git-details&quot;&gt;simple&lt;/a&gt;: it&amp;#39;s a set of simple concepts at your disposal that give you a &lt;em&gt;lot&lt;/em&gt; of power and flexibility. &lt;/p&gt;

&lt;p&gt;Understanding them in isolation is easy, because they are simple. However, there are a lot of ways to compose simple things and it isn&amp;#39;t equally easy to grok all the ways you can combine them. The real power and expressiveness &lt;em&gt;emerge from the interactions between the foundational concepts&lt;/em&gt;. In other words: &lt;em&gt;it&amp;#39;s more than the sum of their parts&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Git it&amp;#39;s a perfect example of the concept of &lt;a href=&quot;http://en.wikipedia.org/wiki/Emergence&quot;&gt;emergence&lt;/a&gt; at work. Quoting Wikipedia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In philosophy, systems theory, science, and art, emergence is the way complex systems and patterns arise out of a multiplicity of relatively simple interactions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Pedestal&lt;/h2&gt;

&lt;p&gt;Another example is &lt;a href=&quot;http://pedestal.io/&quot;&gt;Pedestal&lt;/a&gt;. It&amp;#39;s difficult to get it: in part because it&amp;#39;s different from the &amp;quot;standard&amp;quot; Rails-esque web framework, and in part because it&amp;#39;s designed as a set of simple concepts. Taken one by one they are quite simple, but the real power and perceived complexity is on the number of ways you can compose them.&lt;/p&gt;

&lt;p&gt;Contrast this with the average framework: usually there is THE way to do things and you only have to plug your code here and there and BAM! It works. A blog engine in &lt;a href=&quot;http://vimeo.com/5362441&quot;&gt;15 minutes&lt;/a&gt;, cool uh? It&amp;#39;s certainly &lt;a href=&quot;http://www.infoq.com/presentations/Simple-Made-Easy&quot;&gt;easy&lt;/a&gt;, but not simple and by a large degree not nearly as powerful.&lt;/p&gt;

&lt;p&gt;BTW, yes I know that Pedestal has been designed with &lt;a href=&quot;http://pedestal.io/documentation/&quot;&gt;real-time collaboration&lt;/a&gt; in mind :)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A short tutorial on clojure.java.jdbc</title>
   <link href="http://manuelp.github.com/blog/2013/07/18/clojure-jdbc-tutorial.html"/>
   <updated>2013-07-18T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2013/07/18/clojure-jdbc-tutorial</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/clojure/java.jdbc&quot;&gt;clojure.java.jdbc&lt;/a&gt; is a useful library to have in your toolbelt when you need to work very close to JDBC and for various reasons you can&amp;#39;t or don&amp;#39;t want to use higher level tools like &lt;a href=&quot;http://sqlkorma.com/&quot;&gt;Korma&lt;/a&gt;. In fact it is a thin wrapper over JDBC that makes working with it from Clojure easier and safer.&lt;/p&gt;

&lt;p&gt;This library is undergoing a major API overhaul (starting with version 0.3.0-alpha1) to make it more idiomatic. I&amp;#39;ve used previous versions but the new API is significantly different and after toying around with it and reading bits of informations here and there, I wanted to jot down a short guide on how to use it.&lt;/p&gt;

&lt;h2&gt;Dependencies&lt;/h2&gt;

&lt;p&gt;Using Leiningen is easy to import this library and the hsqldb driver to fiddle with it:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:dependencies&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org.clojure/clojure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.5.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org.clojure/java.jdbc&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0.3.0-alpha4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hsqldb/hsqldb&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.8.0.10&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Than a &lt;code&gt;lein deps&lt;/code&gt; and you are good to go.&lt;/p&gt;

&lt;h2&gt;Idea&lt;/h2&gt;

&lt;p&gt;The main idea behind clojure.java.jdbc (as I understand it) is to provide functions to basically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Query&lt;/em&gt; a DB and &lt;em&gt;transform&lt;/em&gt; resulting data sets&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Mutate&lt;/em&gt; a DB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both managing connections and transactions in a transparent way, using plain old SQL strings.&lt;/p&gt;

&lt;p&gt;There is a basic DSL for composing SQL strings in the &lt;code&gt;clojure.java.jdbc.sql&lt;/code&gt; namespace, but as the &lt;a href=&quot;http://clojure.github.io/java.jdbc/#clojure.java.jdbc.sql&quot;&gt;documentation&lt;/a&gt; says it is deliberately not very sophisticated. To make this guide short we&amp;#39;ll only explore the JDBC managing stuff, using raw SQL strings. If you want you can use it in conjunction with &lt;a href=&quot;https://github.com/jkk/honeysql&quot;&gt;HoneySQL&lt;/a&gt; to generate SQL strings from Clojure data structures (a-la Hiccup).&lt;/p&gt;

&lt;h2&gt;A short example&lt;/h2&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clojure.java.jdbc&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:as&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db-spec&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:subprotocol&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hsqldb&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:subname&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mem:testdb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A JDBC connection can be configured using both a map or a string. Here the HSQLDB configuration is very simple since we want a simple in-memory database, but you can specify a full connection to PostgreSQL, MySQL, Oracle, etc:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:classname&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.mysql.jdbc.Driver&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:subprotocol&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mysql&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:subname&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//127.0.0.1:3306/mydb&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:user&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myaccount&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:password&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;secret&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now to &lt;em&gt;mutate&lt;/em&gt; a database you can use &lt;code&gt;db-do-commands&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;j/db-do-commands&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db-spec&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;CREATE TABLE movies (id INTEGER IDENTITY, name VARCHAR(256), year INTEGER)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;j/db-do-commands&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db-spec&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;INSERT INTO movies(name,year) VALUES('Iron Man', 2008)&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;INSERT INTO movies(name,year) VALUES('Gattaca', 1997)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The second parameter is for running all the following SQL statements inside that expression in a transaction.&lt;/p&gt;

&lt;p&gt;However, I should mention that for inserting new rows there is a more idiomatic way to do it:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;j/insert!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db-spec&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:movies&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Iron Man&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:year&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2008&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Gattaca&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:year&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1997&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Querying&lt;/em&gt; database is even simpler:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;j/query&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db-spec&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
         &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SELECT * FROM movies WHERE year&amp;gt;?&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The cool thing about &lt;code&gt;query&lt;/code&gt; is that you can add keyword parameters to pass transformer functions that can operate both on single rows or the entire result set.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;j/query&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db-spec&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SELECT * FROM movies&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
         &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:row-fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; was released in &quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:year&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;clojure.java.jdbc&lt;/em&gt; is a valuable tool to work with databases via JDBC when other approaches such as Korma are not applicable or desired. It is even more powerful when used in conjuction with a good DSL to &lt;em&gt;compose&lt;/em&gt; SQL strings.&lt;/p&gt;

&lt;p&gt;For a more in depth look at this library, go to the corresponding section at &lt;a href=&quot;http://clojure-doc.org/articles/ecosystem/java_jdbc/home.html&quot;&gt;clojure-doc.org&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Update: 2013-11-04&lt;/h2&gt;

&lt;p&gt;clojure.java.jdbc 0.3.0 has just reached beta status. Go read the &lt;a href=&quot;http://corfield.org/blog/post.cfm/clojure-java-jdbc-0-3-0-beta-1&quot;&gt;official announcement&lt;/a&gt; for all the details. In short, now it has been declared feature-complete.&lt;/p&gt;

&lt;h2&gt;Update: 2013-11-25 ##&lt;/h2&gt;

&lt;p&gt;clojure.java.jdbc 0.0.3-beta2 has been &lt;a href=&quot;https://groups.google.com/forum/#!msg/clojure/pSnXWxpwvT8/9yca3iAohgcJ&quot;&gt;relesed&lt;/a&gt; with &lt;em&gt;breaking changes&lt;/em&gt;. Based on the feedback from the community, now the &lt;em&gt;sql&lt;/em&gt; and &lt;em&gt;ddl&lt;/em&gt; namespaces have been removed (they have been extracted in a separate lib: &lt;em&gt;java-jdbc/dsl&lt;/em&gt;) and the official recomendation is to use more sophisticated DSLs like &lt;a href=&quot;https://github.com/jkk/honeysql&quot;&gt;HoneySQL&lt;/a&gt;, &lt;a href=&quot;https://github.com/r0man/sqlingvo&quot;&gt;SQLingvo&lt;/a&gt;, &lt;a href=&quot;https://bitbucket.org/czan/clojure-sql&quot;&gt;clojure-sql&lt;/a&gt; or &lt;a href=&quot;http://www.sqlkorma.com/&quot;&gt;Korma&lt;/a&gt;. The second breaking change is that the deprecated API has been moved in the &lt;em&gt;clojure.java.jdbc.deprecated&lt;/em&gt; namespace to eliminated confusion on what the new API is and to highlight this distinction even in the &lt;a href=&quot;http://clojure.github.io/java.jdbc/&quot;&gt;generated API documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Update: 2013-12-18&lt;/h2&gt;

&lt;p&gt;The stable 0.3.0 version has just been released. You can read the related &lt;a href=&quot;http://corfield.org/blog/post.cfm/clojure-java-jdbc-0-3-0-released&quot;&gt;post&lt;/a&gt; by Sean Cornfield on his blog.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Clojure and Java data structures interoperability</title>
   <link href="http://manuelp.github.com/blog/2013/04/21/clojure-ds-interoperability.html"/>
   <updated>2013-04-21T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2013/04/21/clojure-ds-interoperability</id>
   <content type="html">&lt;p&gt;Clojure is a language &lt;a href=&quot;http://clojure.org/jvm_hosted&quot;&gt;designed to be hosted&lt;/a&gt;, this means that it utilizes all the power of the hosting platform &lt;em&gt;without trying to hide or abstract it&lt;/em&gt;. This design choice has several consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have full access to the hosting platform.&lt;/li&gt;
&lt;li&gt;Usually Clojure code can interoperate nicely with other code that runs in the same platform, even if it&amp;#39;s written in another language (for example Clojure on the JVM can easily interoperate with code written in Java, Ruby, Python, Groovy, etc).&lt;/li&gt;
&lt;li&gt;It uses the basic types available on the hosting platform and builds on them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, Clojure emphasizes &lt;em&gt;functional programming&lt;/em&gt; and &lt;em&gt;immutability&lt;/em&gt;, and this has to be taken into account when interoperating with code written in another language that works on lossy &lt;em&gt;mutable state&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Using Clojure data from Java&lt;/h2&gt;

&lt;p&gt;Usually there is no problem in using Clojure data structures in Java code since all data types in Clojure implements the relevant Java interfaces like &lt;code&gt;java.util.List&lt;/code&gt;, &lt;code&gt;java.util.Map&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s see the classes and interfaces &lt;a href=&quot;https://github.com/manuelp/obj-hierarchy&quot;&gt;hierarchies&lt;/a&gt; for the main data structures of Clojure: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lists

&lt;ul&gt;
&lt;li&gt;Class: &lt;code&gt;clojure.lang.PersistentList&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.ISeq&lt;/code&gt;, &lt;code&gt;clojure.lang.Sequential&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;java.util.List&lt;/code&gt;&lt;/strong&gt;, &lt;code&gt;java.io.Serializable&lt;/code&gt;, &lt;code&gt;clojure.lang.IHashEq&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.ASeq&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IObj&lt;/code&gt;, &lt;code&gt;java.io.Serializable&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.Obj&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;java.lang.Object&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Vectors

&lt;ul&gt;
&lt;li&gt;Class: &lt;code&gt;clojure.lang.PersistentVector&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IPersistentVector&lt;/code&gt;, &lt;code&gt;java.lang.Iterable&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;java.util.List&lt;/code&gt;&lt;/strong&gt;, &lt;code&gt;java.util.RandomAccess&lt;/code&gt;, &lt;code&gt;java.lang.Comparable&lt;/code&gt;, &lt;code&gt;java.io.Serializable&lt;/code&gt;, &lt;code&gt;clojure.lang.IHashEq&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.APersistentVector&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IFn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.AFn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;java.lang.Object&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Maps

&lt;ul&gt;
&lt;li&gt;Class: &lt;code&gt;clojure.lang.PersistentArrayMap&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IPersistentMap&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;java.util.Map&lt;/code&gt;&lt;/strong&gt;, &lt;code&gt;java.lang.Iterable&lt;/code&gt;, &lt;code&gt;java.io.Serializable&lt;/code&gt;, &lt;code&gt;clojure.lang.MapEquivalence&lt;/code&gt;, &lt;code&gt;clojure.lang.IHashEq&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.APersistentMap&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IFn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.AFn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;java.lang.Object&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Sets

&lt;ul&gt;
&lt;li&gt;Class: &lt;code&gt;clojure.lang.PersistentHashSet&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IPersistentSet&lt;/code&gt;, &lt;code&gt;java.util.Collection&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;java.util.Set&lt;/code&gt;&lt;/strong&gt;, &lt;code&gt;java.io.Serializable&lt;/code&gt;, &lt;code&gt;clojure.lang.IHashEq&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.APersistentSet&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IFn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.AFn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;java.lang.Object&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So you can easily write libraries in Clojure that can be used from Java without problems. Clojure data structures outside the Clojure contex usually behave like regular Java collections, maps and sets.&lt;/p&gt;

&lt;h2&gt;Using Java data from Clojure&lt;/h2&gt;

&lt;p&gt;Usually, the other way around is &lt;a href=&quot;http://clojure.org/java_interop#Java%20Interop-Support%20for%20Java%20in%20Clojure%20Library%20Functions&quot;&gt;straightforward&lt;/a&gt; too. But there are some corner cases that you have to be aware of &lt;em&gt;when writing libraries that can be used from Java&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Idiomatic Clojure code often works on data structures through the &lt;a href=&quot;http://clojure.org/sequences&quot;&gt;seq&lt;/a&gt;(uence) abstraction. In fact a lot of higher-order functions in clojure.core just call &lt;code&gt;seq&lt;/code&gt; on their collections arguments. But there are corner cases, and we&amp;#39;ll look at one of them that I discovered recently when writing the &lt;a href=&quot;https://github.com/manuelp/assert-json&quot;&gt;assert-json&lt;/a&gt; library.&lt;/p&gt;

&lt;h3&gt;A corner case&lt;/h3&gt;

&lt;p&gt;Let&amp;#39;s build a regular map:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:a&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:b&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;= (clojure.lang.MapEntry clojure.lang.MapEntry)
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;= :a
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;= 1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok, so &lt;code&gt;map&lt;/code&gt; when iterating on a... map, works on a &lt;em&gt;sequence of &lt;code&gt;clojure.lang.MapEntry&lt;/code&gt;&lt;/em&gt;. And &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;second&lt;/code&gt; functions can be used on these &lt;code&gt;MapEntry&lt;/code&gt; to extract respectively the key and value of the map entry. Easy.&lt;/p&gt;

&lt;p&gt;Now let&amp;#39;s try it with a &lt;code&gt;java.util.HashMap&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hm&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;doto&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;java.util.HashMap.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.put&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.put&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;= (java.util.HashMap$Entry java.util.HashMap$Entry)
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.util.HashMap$Entry
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;   RT.java:494 clojure.lang.RT.seqFrom
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;   RT.java:475 clojure.lang.RT.seq
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;   RT.java:567 clojure.lang.RT.first
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                   &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;   core.clj:55 clojure.core/first
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What&amp;#39;s the problem here? In the stacktrace we see that &lt;code&gt;first&lt;/code&gt; calls &lt;code&gt;seq&lt;/code&gt; on its argument, and &lt;code&gt;seq&lt;/code&gt; on a &lt;code&gt;java.util.HashMap$Entry&lt;/code&gt; fails miserably. Why? Let&amp;#39;s read the documentation of this function:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;-------------------------
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;clojure.core/seq
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;([coll])
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;Returns a seq on the collection. If the collection is
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;    empty, returns nil.  (seq nil) returns nil. seq also works on
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;    Strings, native Java arrays (of reference types) and any objects
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;    that implement Iterable.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Well, since &lt;code&gt;seq&lt;/code&gt;uence is a sequential list abstraction, every &lt;code&gt;seq&lt;/code&gt;able data structure must be &lt;code&gt;Iterable&lt;/code&gt; (or either a String or an array of reference types). If you look again in the &lt;em&gt;Using Clojure data from Java&lt;/em&gt; section, you&amp;#39;ll see that Clojure maps implements the &lt;code&gt;java.lang.Iterable&lt;/code&gt; interface that in this case iterates on &lt;code&gt;clojure.lang.MapEntry&lt;/code&gt; instances. These &lt;code&gt;MapEntry&lt;/code&gt; objects live in this hierarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Class: &lt;code&gt;clojure.lang.MapEntry&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IMapEntry&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.AMapEntry&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IPersistentVector&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;java.lang.Iterable&lt;/code&gt;&lt;/strong&gt;, &lt;code&gt;java.util.List&lt;/code&gt;, &lt;code&gt;java.util.RandomAccess&lt;/code&gt;, &lt;code&gt;java.lang.Comparable&lt;/code&gt;, &lt;code&gt;java.io.Serializable&lt;/code&gt;, &lt;code&gt;clojure.lang.IHashEq&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.APersistentVector&lt;/code&gt;, interfaces: &lt;code&gt;clojure.lang.IFn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;clojure.lang.AFn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;java.lang.Object&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And so &lt;code&gt;MapEntry&lt;/code&gt; objects are &lt;code&gt;Iterable&lt;/code&gt; too. That&amp;#39;s why &lt;code&gt;first&lt;/code&gt; on map entries works.&lt;/p&gt;

&lt;p&gt;On the Java side? We already know that &lt;code&gt;HashMap&lt;/code&gt;s are &lt;code&gt;Iterable&lt;/code&gt; on &lt;code&gt;java.util.HashMap$Entry&lt;/code&gt; instances. But these &lt;code&gt;HashMap$Entry&lt;/code&gt; are &lt;code&gt;Iterable&lt;/code&gt; too? Probably not, let&amp;#39;s see the class and interfaces hirarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Class: &lt;code&gt;java.util.HashMap$Entry&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SuperClass: &lt;code&gt;java.lang.Object&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uhm, no they are not.&lt;/p&gt;

&lt;h3&gt;A better solution&lt;/h3&gt;

&lt;p&gt;The problem here is that &lt;em&gt;to extract key and value from a map entry&lt;/em&gt; I used the wrong functions. &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;second&lt;/code&gt; are more appropriate on generic sequences, instead for this specific task there are more suitable (and interoperable) functions: &lt;code&gt;key&lt;/code&gt; and &lt;code&gt;val&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:a&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:b&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;= :a
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;= 1
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hm&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;doto&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;java.util.HashMap.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.put&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.put&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;= &quot;a&quot;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;;= 1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Wrap up&lt;/h2&gt;

&lt;p&gt;Clojure and Java are usually nicely interoperable, but pay attention to use the appropriate functions in Clojure to manipulate data structures when it&amp;#39;s possible that your code will be used from Java.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Abstraction</title>
   <link href="http://manuelp.github.com/blog/2013/02/26/abstraction.html"/>
   <updated>2013-02-26T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2013/02/26/abstraction</id>
   <content type="html">&lt;p&gt;I&amp;#39;ve noticed that when two or more people discuss about some technical matter, some words are sometimes used inappropriately and mean different things for different people. You can easily imagine that in this context having meaningful and fruitful discussions is almost impossible.&lt;/p&gt;

&lt;p&gt;If you try to discuss about object-oriented programming for example, you&amp;#39;ll quickly find out that there are a lot of different ideas on what OO is all about, most of them somewhat &amp;quot;fuzzy&amp;quot;. Can you pinpoint exactly what OOP is? I mean, what Alan Kay had in mind when he coined that (unfortunate) term? I would have several things to say here but I digress, lets return on topic.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s why here I&amp;#39;ll try to define exactly what the meaning of the word &lt;em&gt;abstraction&lt;/em&gt; really is, and what I mean when I use it.&lt;/p&gt;

&lt;h2&gt;Definition&lt;/h2&gt;

&lt;p&gt;First, let&amp;#39;s see what &lt;a href=&quot;http://www.etymonline.com/index.php?term=abstract&quot;&gt;etymonline&lt;/a&gt; has to say about it (emphasis is mine):&lt;/p&gt;

&lt;blockquote&gt; 
*abstract (adj.)*, late 14c., originally in grammar (of nouns), from Latin abstractus &quot;drawn away,&quot; pp. of abstrahere &quot;to drag away; detach divert,&quot; from ab(s)- &quot;away&quot; (see ab-) + trahere &quot;draw&quot; (see tract (n.1)).   

Meaning *&quot;withdrawn or separated from material objects or practical matters&quot;* is from mid-15c [...]
&lt;/blockquote&gt;

&lt;p&gt;So, here we have something important that we can work with. Something is abstract when it&amp;#39;s &lt;em&gt;separated from material practical matters&lt;/em&gt;. Excellent! Now let&amp;#39;s see what the &lt;a href=&quot;http://dictionary.reference.com/browse/abstract&quot;&gt;dictionary&lt;/a&gt; says. As an adjective:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;thought of apart from concrete realities, specific objects, or actual instances: an abstract idea.&lt;/li&gt;
&lt;li&gt;expressing a quality or characteristic apart from any specific object or instance, as justice, poverty,  and speed.&lt;/li&gt;
&lt;li&gt;theoretical; not applied or practical: abstract science.&lt;/li&gt;
&lt;li&gt;difficult to understand; abstruse: abstract speculations. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So from these definitions we can say several things. First of all that &lt;em&gt;something can be abstract&lt;/em&gt;, in which case that thing is not concerned with practical considerations. &lt;/p&gt;

&lt;p&gt;Another interesting consideration is that when something is abstract it &lt;em&gt;can&lt;/em&gt; be difficult to understand. It can happen when the abstract thing has no or very little connections with practical matters, or when it&amp;#39;s so complex and with so many interconnected parts that mapping all of them to corresponding more &lt;em&gt;concrete&lt;/em&gt; things is very difficult.&lt;/p&gt;

&lt;p&gt;As a verb:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;to draw or take away; remove.&lt;/li&gt;
&lt;li&gt;to divert or draw away the attention of.&lt;/li&gt;
&lt;li&gt;to steal.&lt;/li&gt;
&lt;li&gt;to consider as a general quality or characteristic apart from specific objects or instances: to abstract the notions of time, space, and matter.&lt;/li&gt;
&lt;li&gt;to make an abstract of; summarize. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Furthermore, it&amp;#39;s also an &lt;em&gt;action&lt;/em&gt;. We can &lt;em&gt;abstract away practical details&lt;/em&gt; and have a conceptual model to work with more easily.&lt;/p&gt;

&lt;h2&gt;Abstraction in the software development domain&lt;/h2&gt;

&lt;p&gt;Now I think we can try to give a sort-of definition of abstraction in the software development context:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;abstraction (noun) is a conceptual model of the structure or function of a software construct that is not concerned with mechanics and other practical considerations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Probably it isn&amp;#39;t a good definition, but it&amp;#39;s a starting point (I&amp;#39;m open to discuss and refine or rewrite it). From this definition we can make some deductions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To abstract in the programming domain means separating a concept from it&amp;#39;s implementation details&lt;/strong&gt;. This way, when we have an abstraction we have a &lt;em&gt;concept&lt;/em&gt; that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It&amp;#39;s generally easier to understand, reason about, specify and test.&lt;/li&gt;
&lt;li&gt;We can implement it in completely different ways without changing its &lt;em&gt;essence&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If components &lt;em&gt;depends&lt;/em&gt; on an abstraction, we can change its implementation and refactor how we want without affecting its users. Nice!&lt;/p&gt;

&lt;p&gt;Notice that this concept is independent from scale: we can abstract functions, classes, components, systems or even entire networks of services. And this is exactly the premise and original meaning of OO: &lt;strong&gt;a way of thinking and designing systems to manage their complexity, by creating loosely coupled abstractions that communicates by messages at all scales&lt;/strong&gt;. So &amp;quot;real&amp;quot; object-oriented design is a &lt;em&gt;fractal design thinking&lt;/em&gt; that produces a network of abstractions (on both state and behavior) that can be easily rearranged and modified (even at runtime, see &lt;a href=&quot;http://en.wikipedia.org/wiki/Smalltalk&quot;&gt;Smalltalk&lt;/a&gt; for example). Actual mechanics (encapsulation, inheritance and polymorphism) are only consequences, not the definition itself.&lt;/p&gt;

&lt;p&gt;We can map the same concept in a different way to FP, but this is matter for another post.&lt;/p&gt;

&lt;h2&gt;Abstraction or indirection?&lt;/h2&gt;

&lt;p&gt;Sometime I see the word &amp;quot;abstraction&amp;quot; used when the real meaning is &amp;quot;indirection&amp;quot;. Abstraction implies removing implementation details, whether indirection only adds another step to reference the same thing with all the specific low level details in place that you have to take into account. They are both useful but different things.&lt;/p&gt;

&lt;p&gt;Suppose that you have to cook a pie, and you can ask a friend for help. But he doesn&amp;#39;t have the slightest idea on how to do it, so you sit on your couch and describe to your friend with excruciating details how to cook a pie. Congratulation, you just added a level of &lt;em&gt;indirection&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now suppose that your friend is an excellent chef. In this case you only need to ask him &amp;quot;just cook an apple pie&amp;quot;. And this, my friend, is &lt;em&gt;abstraction&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;They are quite different, isn&amp;#39;t it? Notice how in the first case you didn&amp;#39;t touch the pie with a finger, but you still need to know how to mix, how much to cook it, etc. etc. In the second case however, you didn&amp;#39;t have to think about all of that low level details. You just wanted an apple pie!&lt;/p&gt;

&lt;p&gt;If you want, let&amp;#39;s discuss on &lt;a href=&quot;http://www.reddit.com/r/programming/comments/19a8qq/what_is_abstraction/&quot;&gt;Reddit&lt;/a&gt;, or read Zed Shaw &lt;a href=&quot;http://zedshaw.com/essays/indirection_is_not_abstraction.html&quot;&gt;take&lt;/a&gt; on this topic.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Learning faster</title>
   <link href="http://manuelp.github.com/learning/2012/10/26/learning-faster.html"/>
   <updated>2012-10-26T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/learning/2012/10/26/learning-faster</id>
   <content type="html">&lt;p&gt;Learning fast, and being able to master concepts and techniques is more important that ever nowadays in the &amp;quot;information age&amp;quot;. Learning something &lt;em&gt;deeply&lt;/em&gt; and mastering it to the point of having an &lt;em&gt;intuition&lt;/em&gt; about it is very important in every field. The point is developing &lt;em&gt;knowledge and skills&lt;/em&gt;, not only being able to reharse dry informations.&lt;/p&gt;

&lt;p&gt;But what we could do about this? &lt;em&gt;Learning to learn&lt;/em&gt; is underrated, but very important. Here I summarize my understanding of a &lt;a href=&quot;http://calnewport.com/blog/2012/10/26/mastering-linear-algebra-in-10-days-astounding-experiments-in-ultra-learning/&quot;&gt;guest post&lt;/a&gt; by &lt;a href=&quot;http://www.scotthyoung.com/&quot;&gt;Scott Young&lt;/a&gt; on &lt;a href=&quot;http://calnewport.com/blog/&quot;&gt;Study Hacks&lt;/a&gt;, a very interesting blog written by Cal Newport. This guy (Scott), completed the 4-year MIT computer science curriculum in just 12 months... So I suppose he has some good tips to share on this.&lt;/p&gt;

&lt;h1&gt;The Drilldown Method&lt;/h1&gt;

&lt;p&gt;The so-called &amp;quot;drilldown method&amp;quot; has this basic structure:&lt;/p&gt;

&lt;h2&gt;1) Coverage&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The first step is gaining a general understanding of what you need to learn.&lt;/strong&gt; This could mean watching videos, presentations, reading books, papers, doing research, etc.&lt;/p&gt;

&lt;p&gt;Don&amp;#39;t make the mistake to consider this step the most important. Since this a necessary step but generally the ROI is not so high (the real learning is &lt;em&gt;active&lt;/em&gt;), &lt;em&gt;in many cases it&amp;#39;s better to speed-up this stage so that you can invest more time on the latter ones&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The interesting thing is that if you&amp;#39;re reading a book, &lt;em&gt;highlighting is a poor way of processing informations&lt;/em&gt;. It&amp;#39;s much better to use techniques like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Note-taking&lt;/strong&gt;: taking sparse notes while reading.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Summarizing&lt;/strong&gt;: writing a one paragraph summary of each major section.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Maybe both, but the point here is &lt;strong&gt;to be &lt;em&gt;actively&lt;/em&gt; engaged with the material and quickly processing it&lt;/strong&gt; to gain a general understanding. Probably you won&amp;#39;t understand or remember everything: this is perfectly normal. If the subject is not trivial there will be more &lt;em&gt;iterations&lt;/em&gt;, but for the first one remember that &lt;em&gt;it&amp;#39;s better to quickly review the material and gain a &amp;quot;mental framework&amp;quot; of the subject for further learning than grinding on every section only to give up in frustration&lt;/em&gt;. Indeed, often you&amp;#39;ll gain enough informations in the first iteration so that in the following ones you&amp;#39;ll understand a lot more.&lt;/p&gt;

&lt;h2&gt;2) Practice&lt;/h2&gt;

&lt;p&gt;Practice serves a dual purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To test what you learned and &amp;quot;persist&amp;quot; its &lt;em&gt;mechanics&lt;/em&gt; and &lt;em&gt;connections to other concepts&lt;/em&gt; into your brain.&lt;/li&gt;
&lt;li&gt;To Discover what you don&amp;#39;t understand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first point is self-evident, but the second one is equally important: often you&amp;#39;ll think that you understand a subject after reading some material about it... until you try to test it. Practice is both a way to achieve mastery and a way to test your understanding against reality.&lt;/p&gt;

&lt;p&gt;One very important thing about practice is that &lt;strong&gt;feedback should be immediate&lt;/strong&gt;. The sooner you know whether you have done is right or wrong, the better. The best way to go about it is to do some exercises with the solutions in hand. This way you do the exercises and immediately know if you really understand that particular subject/technique/process/whatever.&lt;/p&gt;

&lt;h2&gt;3) Insight&lt;/h2&gt;

&lt;p&gt;With the previous steps you&amp;#39;ll gain informations, some skills, but more importantly &lt;em&gt;an understanding of what areas you need to develop a better intuition for&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One great way to dig deeper and create a profound understanding and mastery of concepts is the &lt;strong&gt;Feynman Technique&lt;/strong&gt;: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get a piece of paper (actual paper, this way you&amp;#39;ll be able to easily draw diagrams, doodles, formulas, etc.) and &lt;em&gt;write at the top in a simple and unambiguous way the top idea or process you want to understand&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Explain the idea, as if you were teaching it to someone else&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This technique is fairly easy to describe, but it enables some important advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sometimes you&amp;#39;ll reach a point in which you can&amp;#39;t really explain something: that is a gap in your understanding. Now you can reach out to textbooks, mentors or online to fill that gap.&lt;/li&gt;
&lt;li&gt;During this process, you&amp;#39;ll come up with insights, novel connections with things you already know, metaphors and problems that will benefit from this new understanding.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;You do not really understand something unless you can explain it to your grandmother.&amp;quot;
-- &lt;a href=&quot;http://www.diracdelta.co.uk/science/source/q/u/quotes/source.html&quot;&gt;Albert Einstein&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This technique can be applied in several ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For ideas you don&amp;#39;t get at all: in this case it&amp;#39;s often useful to copy the author&amp;#39;s explanation, adding your own insights and ideas in the process. Maybe &lt;em&gt;trying to rewrite the concepts in your own words&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;To procedures: writing down the process step-by-step in your own words. What they do, how and why.&lt;/li&gt;
&lt;li&gt;To formulas: explaining them piece by piece and how they fits together. What they mean, what are their relationships.&lt;/li&gt;
&lt;li&gt;To check and exercise your memory: writing down a summary of a particular concept without using any material other than your memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Down the rabbit hole&lt;/h2&gt;

&lt;p&gt;With the Feynman Technique you can go deeper, but you could go further and develop not just an understanding, but even a &lt;em&gt;deep intuition&lt;/em&gt; about it. That&amp;#39;s the Ri stage in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Shuhari&quot;&gt;Shuhari&lt;/a&gt; model.&lt;/p&gt;

&lt;p&gt;Understanding intuitively and idea is not easy, but that&amp;#39;s when you&amp;#39;d have really internalized it. Most intuitions about an idea, according to Scott, can be classified in this &amp;quot;classes&amp;quot;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Analogies&lt;/strong&gt;: similarities with easier-to-understand ideas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visualizations&lt;/strong&gt;: visual metaphors that captures some essential aspects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simplifications&lt;/strong&gt;: taking out and being able to explain the &lt;em&gt;essence&lt;/em&gt; in simple words (to grandmothers).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Gaining deep understanding and mastery&lt;/h2&gt;

&lt;p&gt;Don&amp;#39;t fall trap of the illusion that these steps in reality are strictly executed in sequence. &lt;em&gt;They are more a cycle that you go through several times&lt;/em&gt;, section after section, chapter after chapter, book after book.&lt;/p&gt;

&lt;p&gt;Sure, it&amp;#39;s more work to do compared to one mindless reading. But it&amp;#39;s a faster way to develop a real and deep understanding and mastering the concepts. That is, if you aren&amp;#39;t serious and motivated about learning something, you&amp;#39;ll give up. And this is good! Not every subject is really useful or interesting to you and that&amp;#39;s fine. That&amp;#39;s the way you discover what you are really interested into.&lt;/p&gt;

&lt;h2&gt;What does it means for us developers?&lt;/h2&gt;

&lt;p&gt;We developers tend to go through only the first two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Coverage: reading a book (or pieces of it) that teaches the basics.&lt;/li&gt;
&lt;li&gt;Practice: applying that basics to a toy project (or a production system).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, some developers extend that practice with the third step: summarizing their insights and new understanding in blog posts, guides, tutorials, presentations and even entire books or courses. I think this is a very useful practice.&lt;/p&gt;

&lt;p&gt;On a related note, that&amp;#39;s why I claim that good programming books should have &lt;em&gt;exercises with solutions&lt;/em&gt; for at least every chapter (for a recent example, see &lt;a href=&quot;http://leanpub.com/fp-oo&quot;&gt;Functional Programming for the Object-Oriented Programmer&lt;/a&gt; by Brian Marick).&lt;/p&gt;

&lt;p&gt;They should also don&amp;#39;t stop after teaching syntax and mechanics, but also teach about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design patterns&lt;/li&gt;
&lt;li&gt;Best practices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And in general &lt;em&gt;not only the how, but also the why and when&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;That is, the best programming language books infuse a strong sense of design into the narrative. The strength of this approach is that not only are you learning a programming language, but you’re also learning how to think in that language, and the very why of the language itself.&amp;quot;
-- &lt;a href=&quot;http://blog.fogus.me/2011/08/14/perlis-languages/&quot;&gt;Michael Fogus&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It&amp;#39;s the same Michael Fogus that with Chris Houser wrote &lt;a href=&quot;http://joyofclojure.com/&quot;&gt;The Joy Of Clojure&lt;/a&gt;, a book that won a Jolt Award in 2011 as one of &lt;a href=&quot;http://www.drdobbs.com/joltawards/jolt-awards-the-best-books/231500080?pgno=4&quot;&gt;The six best books every developer should read&lt;/a&gt;. Another example to look closely to :)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Software Construction</title>
   <link href="http://manuelp.github.com/oop,fp,tdd,bugs/2012/09/05/software-construction.html"/>
   <updated>2012-09-05T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/oop,fp,tdd,bugs/2012/09/05/software-construction</id>
   <content type="html">&lt;p&gt;I&amp;#39;ve just read an interesting post from Daniel Sobral: &amp;quot;&lt;a href=&quot;http://dcsobral.blogspot.com.br/2012/09/bugs-tdd-and-functional-programming.html&quot;&gt;Bugs, TDD and Functional programming&lt;/a&gt;&amp;quot; in which he gives some ideas on how to bridge the gap between software and physical constructs.&lt;/p&gt;

&lt;p&gt;The point in that post is that while physical things obey to the &amp;quot;&lt;em&gt;law of proximity of cause and effect&lt;/em&gt;&amp;quot; (ie. when something goes wrong you often find the cause where the problem manifested itself) because of the physics constraints and forces, in software you don&amp;#39;t naturally have this kind of direct cause-effect relationships. &lt;/p&gt;

&lt;p&gt;I&amp;#39;m not convinced that this is the case for physical things, but I think the point is valid: &lt;em&gt;for introducing direct cause-effect relations, you need to introduce constraints&lt;/em&gt; in order to &lt;strong&gt;manage complexity&lt;/strong&gt;. And &lt;a href=&quot;oop,fp,alan-kay/2012/08/16/true-oop.html&quot;&gt;OOP&lt;/a&gt; is one response to this need, &lt;em&gt;functional programming&lt;/em&gt; is another.&lt;/p&gt;

&lt;p&gt;On a related note, TDD is a very useful &lt;em&gt;practice&lt;/em&gt; that helps with realizing this proximity (useful both in OOP and FP contexts).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>True OOP</title>
   <link href="http://manuelp.github.com/oop,fp,alan-kay/2012/08/16/true-oop.html"/>
   <updated>2012-08-16T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/oop,fp,alan-kay/2012/08/16/true-oop</id>
   <content type="html">&lt;blockquote&gt;
&lt;p&gt;OO was not translated properly from the original Alan Key propositions of components sending messages between each other. [...] The Actors model of computation is typically an OO pattern that implements message passing. It’s strange nowadays to see actors being used as a strong argument to adopt FP instead :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From &lt;a href=&quot;http://reborg.tumblr.com/post/29473150827/clojure-weekly-aug-09-16-2012&quot;&gt;Reborg&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After studying and exploring papers, articles and talks by Alan Kay I couldn&amp;#39;t agree more to this. There was clearly a misunderstanding on the original object-orientation&amp;#39;s vision.&lt;/p&gt;

&lt;p&gt;Since the rationale for OOP was &lt;em&gt;managing complexity and creating massively scalable systems&lt;/em&gt;, I think we need to rediscover the original meaning of this design philosophy if we want to be better armed to solve real world modern problems. Maybe it&amp;#39;s not the best way to solve some problem, but it&amp;#39;s an additional tool at your disposal.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Come prolungare la vita delle batterie dei laptop</title>
   <link href="http://manuelp.github.com/hardware,/laptop/2011/03/28/cura-batterie-laptop.html"/>
   <updated>2011-03-28T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/hardware,/laptop/2011/03/28/cura-batterie-laptop</id>
   <content type="html">&lt;p&gt;Ho da poco acquistato un nuovo portatile e voglio trattarlo bene, facendo durare la batteria il più a lungo possibile. Informandomi in giro ho incontrato molti &amp;quot;boh&amp;quot; e diverse risposte poco convincenti, così mi sono deciso a fare qualche ricerca in proposito (vedi &lt;em&gt;Riferimenti&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Innanzitutto, il famoso &lt;a href=&quot;http://it.wikipedia.org/wiki/Accumulatore_di_carica_elettrica#Effetto_memoria&quot;&gt;effetto memoria&lt;/a&gt; (secondo il quale ricaricando ripetutamente la batteria senza arrivare alla capacità massima questa &amp;quot;ricorda&amp;quot; questo livello energetico abbassandone a tutti gli effetti la capacità) riguarda le batterie al nickel-metalidrato (NiMH) e nickel-cadmio (NiCd) &lt;em&gt;che non sono più utilizzate nei portatili moderni&lt;/em&gt;. Ad oggi, tutti i dispositivi elettronici dotati di batteria come portatili, videocamere, IPod, etc sono alimentati da batterie aglio ioni di litio (Li-ion) che &lt;em&gt;non soffre di questo problema&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Quando si parla di durata della batteria, due sono i fattori chiave che determinano la durata della vita di una batteria: la &lt;em&gt;temperatura&lt;/em&gt; e la &lt;em&gt;carica&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Temperatura&lt;/h2&gt;

&lt;p&gt;Nel caso delle batterie Li-ion una temperatura troppo altra, specialmente se prolungata nel tempo, accorcia la vita delle batterie. Perciò ecco alcuni suggerimenti da tener presenti:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Assicurati che il dispositivo sia ben areato e non ci sia nulla ad ostruire la ventilazione. In particolare evita di appoggiare il portatile su materiali isolanti come coperte, cuscini e simili che ostacolano la circolazione dell&amp;#39;aria e portano quindi al surriscaldamento.&lt;/li&gt;
&lt;li&gt;Evita di ricaricare la batteria mentre stai lavorando: la scheda video, il processore e l&amp;#39;hard disk scaldano e la temperatura diminuisce la vita della batteria.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Carica&lt;/h2&gt;

&lt;p&gt;Una batteria può essere ricaricata solo un numero limitato di volte, in genere tra le 300-1000 (il numero reale dipende da come la batteria è stata tenuta). Perciò è importante &lt;em&gt;trattarla bene&lt;/em&gt; e &lt;em&gt;non ricaricarla troppo spesso&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Qualche suggerimento:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Calibra la batteria ogni 30 cariche&lt;/strong&gt;. Calibrare significa scaricarla completamente e quindi ricaricarla.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non scaricarla completamente&lt;/strong&gt;. Come detto poco sopra le batterie agli ioni di litio non hanno effetto memoria, anzi &lt;em&gt;scaricare completamente una batteria ne accorcia la vita&lt;/em&gt; quindi è preferibile limitarsi a farlo solo per la calibrazione. &lt;em&gt;E&amp;#39; perfettamente sicuro ricaricare la batteria anche se non è completamente scarica, meglio se intorno al 20% della capacità totale.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evita di caricarla completamente&lt;/strong&gt;. Le batterie caricate completamente, specialmente se sottoposte ad alte temperature, si deteriorano più in fretta. &lt;em&gt;Di norma è bene non superare l&amp;#39;80% della capacità totale.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evita lavori intensivi durante la ricarica&lt;/strong&gt;. Anche scaricare la batteria troppo velocemente ne accorcia la vita.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evita di ricaricare.&lt;/strong&gt; Di norma i laptop cercano di ricaricare le batterie al 100% (il che non è un bene), e continuano a ricaricarle non appena scendono al di sotto di un certo livello per mantenerle completamente cariche. Per di più di solito un portatile connesso alla rete elettrica lavora in modalità performace la quale produce più calore. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Conservare la batteria ##&lt;/h2&gt;

&lt;p&gt;E&amp;#39; bene &lt;em&gt;rimuovere la batteria se si lavora prevalentemente connessi alla rete elettrica&lt;/em&gt;. Bisogna però considerare che una batteria anche se non connessa continua a perdere lentamente la carica, che invece viene persa più velocemente se viene riposta al 100%. Perciò:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Riporre la batteria ad un livello di carica compreso tra il 40-60%&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Riponila in un posto freddo e asciutto, meglio se intorno ai 0°C.&lt;/strong&gt; Per esempio in un frigorifero, avvolta in della plastica.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ricalibra la batteria ogni 30 giorni circa.&lt;/strong&gt; Ma &lt;em&gt;farla tornare a temperatura ambiente prima di montarla&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;In breve&lt;/h2&gt;

&lt;p&gt;In breve, ecco cosa tenere presente per allungare la vita della propria batteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Assicurarsi che il laptop sia ben areato.&lt;/li&gt;
&lt;li&gt;Mantenere il livello di carica della batteria tra &lt;strong&gt;20-80%&lt;/strong&gt; della sua capacità massima, assicurandosi di non effettuare lavori intensivi durante la ricarica.&lt;/li&gt;
&lt;li&gt;Calibrare la batteria (ciclo completo di scarica-carica) ogni &lt;strong&gt;30 cariche&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Se si utilizza il portatile prevalentemente connessi alla rete elettrica, rimuovere la batteria e riporla in un posto freddo e asciutto ad una temperatura di &lt;strong&gt;0°C&lt;/strong&gt; ed un livello di carica tra il &lt;strong&gt;40-60%&lt;/strong&gt;. Calibrare la batteria ogni &lt;strong&gt;30 giorni&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Riferimenti&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://4sysops.com/archives/how-to-take-care-of-your-laptop-battery-to-prolong-its-lifespan/&quot;&gt;How to take care of your laptop battery to prolong its lifespan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://4sysops.com/archives/how-to-charge-and-discharge-laptop-batteries-to-extend-their-lifetime/&quot;&gt;How to charge and discharge laptop batteries to extend their lifetime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://4sysops.com/archives/how-to-store-a-laptop-battery-properly-to-save-it-from-an-early-death/&quot;&gt;How to store a laptop battery properly to save it from an early death&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[&lt;a href=&quot;http://thisweekinbatteries.blogspot.com/2010/02/pull-plug-your-battery-will-thank-you.html&quot;&gt;TWiB: Pull the plug. Your battery will thank you.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://batteryuniversity.com/learn/article/how_to_prolong_lithium_based_batteries&quot;&gt;How to prolong lithium-based batteries&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Discussione - Adozione dell'Agile</title>
   <link href="http://manuelp.github.com/agile/2009/11/09/discussione-adozione-agile.html"/>
   <updated>2009-11-09T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/agile/2009/11/09/discussione-adozione-agile</id>
   <content type="html">&lt;p&gt;Di seguito riporto qualche appunto sull&amp;#39;&lt;a href=&quot;http://www.infoq.com/articles/failed-agile-adoption-reasons&quot;&gt;articolo&lt;/a&gt; &lt;em&gt;Why Agile Adoption Fails in Some Organizations&lt;/em&gt; apparso su InfoQ il 4 Novembre 2009.&lt;/p&gt;

&lt;p&gt;L&amp;#39;agile presuppone che l&amp;#39;organizzazione finanzi il &lt;em&gt;team&lt;/em&gt; e che lo sviluppo sia un&amp;#39;attività continuativa e considerata come un &lt;em&gt;investimento&lt;/em&gt;. In questo contesto si riconosce l&amp;#39;inevitabile inaccuratezza delle stime iniziali e si procede in modo iterativo e incrementale, accumulando esperienza e imparando a prevedere le tempistiche mano a mano che si avanza con lo sviluppo. In un team agile le stime sulle tempistiche hanno scarsa importanza e il team procede a produrre valore in modo continuativo, ma non si sa con precisione a priori quanto tempo ci vorrà per completarlo.&lt;/p&gt;

&lt;p&gt;In uno scenario diverso in cui l&amp;#39;organizzazione finanzia separatamente i singoli &lt;em&gt;progetti&lt;/em&gt;, che sono visti come un &lt;em&gt;costo&lt;/em&gt;, il management richiede delle stime sui tempi e non è disposto a finanziarlo oltre i tempi preventivati. In questo contesto, a differenza del caso precedente, si hanno dei problemi se la stima iniziale non si rivela corretta e il management è costretto a una scelta: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modificare i piani e riducendo lo &lt;em&gt;scope&lt;/em&gt; del progetto.&lt;/li&gt;
&lt;li&gt;Oppure ottenere un ROI negativo (il progetto va in perdita).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le principali cause del fallimento nell&amp;#39;adozione di uno stile agile di sviluppo possono essere riassunte nei seguenti punti:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L&amp;#39;Agile assume che l&amp;#39;organizzazione voglia uno sforzo di sviluppo continuativo, non un progetto a breve termine. &lt;strong&gt;L&amp;#39;agile presuppone un finanziamento a team, non a progetto.&lt;/strong&gt; In altre parole questo approccio presuppone che non ci siano vincoli di budget sul singolo progetto.&lt;/li&gt;
&lt;li&gt;L&amp;#39;Agile è una metodologia che influenza sia il management che il processo di sviluppo: ci sono ripercussioni sia nelle pratiche adottate dal team, sia nella gestione (pianificazione e costi) del progetto stesso. &lt;strong&gt;Il management e il processo di sviluppo sono interrelati e qualsiasi metodologia influenza entrambi.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Date queste considerazioni, i progetti a costo fisso sono chiaramente un contesto inadatto nel quale collocare l&amp;#39;Agile. Spesso le aziende che ci provano finiscono per sovrapporre un façade agile su un progetto che in realtà è condotto in stile &lt;em&gt;Waterfall&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In ultima analisi, &lt;strong&gt;se l&amp;#39;organizzazione è in grado di finanziare un team di sviluppo in modo continuativo, allora l&amp;#39;agile è un approccio vincente. Se invece i fondi sono allocati per progetto, un approccio più tradizionale è la scelta obbligata.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;Discussione&lt;/h2&gt;

&lt;p&gt;Di seguito riassumo i contributi espressi nei commenti all&amp;#39;articolo da alcuni lettori:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Si assume che un approccio waterfall abbia successo quasi automaticamente in un progetto a costo fisso, quando in realtà è vero l&amp;#39;opposto. Con un cliente che sappia prioritizzare i propri requisiti efficacemente l&amp;#39;agile è un approccio utilizzabile anche in quel caso.&lt;/li&gt;
&lt;li&gt;Occorre scegliere la metodologia di sviluppo in base ai requisiti e al contesto: &lt;em&gt;se i requisiti non sono chiari fin dall&amp;#39;inizio e c&amp;#39;è rischio importante che cambino, allora un approccio agile è quasi obbligatorio&lt;/em&gt;. Una volta scelto l&amp;#39;approccio più adatto si sceglie la forma contrattuale consona. Le decisioni sulla conduzione del progetto vanno prese in modo pragmatico che rifletta le reali esigenze.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Perhaps we need to start asking, &amp;quot;how much can we get for $X&amp;quot; rather than stating, &amp;quot;I want all this for $Y. Make that happen.&amp;quot; -- Robert Dempsey&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;I metodi agili hanno l&amp;#39;obiettivo di massimizzare l&amp;#39;efficienza, la produttività e il business value realizzato indipendentemente dal budget quindi sono ugualmente applicabili in un progetto a costo fisso. Inoltre, con l&amp;#39;avanzare del progetto e specialmente con l&amp;#39;acquisizione di competenze da parte del team diventa possibile stimare con sempre maggior precisione i tempi richiesti. Ovviamente, in un progetto a costo fisso è ancora più importante avere un team con esperienza e un cliente in grado di prioritizzare le features.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Commenti personali&lt;/h2&gt;

&lt;p&gt;Innanzitutto l&amp;#39;approccio agile (iterativo e incrementale) comporta importanti vantaggi per tutte le parti coinvolte (clienti, management, sviluppatori), ed è utile educarle &lt;em&gt;tutte&lt;/em&gt; sui suoi vantaggi.&lt;/p&gt;

&lt;p&gt;Inoltre, data la natura dell&amp;#39;agile (focus su &lt;em&gt;efficienza&lt;/em&gt; e &lt;em&gt;qualità&lt;/em&gt;) è applicabile anche in un contesto a costo fisso secondo me. Però qualsiasi progetto a costo fisso comporta un rischio sostenibile solo in questi casi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I requisiti sono chiari fin dall&amp;#39;inizio, sono immutabili e il team è composto da esperti che hanno già affrontato progetti nello stesso dominio applicativo. Solo in questo caso è possibile fare una stima ragionevolmente precisa e adottare un ciclo di vita di tipo sequenziale (&lt;em&gt;Waterfall&lt;/em&gt;) con un certo successo.&lt;/li&gt;
&lt;li&gt;Lo scope è variabile. In questo caso l&amp;#39;approccio agile continua a essere il più conveniente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Scelta pragmatica&lt;/h3&gt;

&lt;p&gt;La scelta della metodologia di sviluppo va fatta in modo pragmatico a seconda del contesto (progetto, dominio applicativo, cliente, team, ecc), non c&amp;#39;è un approccio universalmente migliore (&lt;em&gt;Silver Bullet&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;La scelta va fatta anche in base ai parametri che si vuole ottimizzare: &lt;em&gt;costi, tempi, scope e qualità&lt;/em&gt;. E&amp;#39; evidente che il fissare tutti questi parametri a priori è praticamente impossibile, allora occorre trovare la combinazione più conveniente per le parti in causa. Fissando la qualità come un parametro imprescindibile e considerando che costi e tempi sono strettamente connessi, individuo i seguenti casi interessanti:&lt;/p&gt;

&lt;table&gt;
    &lt;tr&gt;

        &lt;th&gt;Tempo&lt;/th&gt;
        &lt;th&gt;Costo&lt;/th&gt;
        &lt;th&gt;Scope&lt;/th&gt;
        &lt;th&gt;Commento&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;fisso&lt;/td&gt;

        &lt;td&gt;fisso&lt;/td&gt;
        &lt;td&gt;fisso&lt;/td&gt;
        &lt;td&gt;Praticamente impossibile.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;fisso&lt;/td&gt;
        &lt;td&gt;fisso&lt;/td&gt;

        &lt;td&gt;variabile&lt;/td&gt;
        &lt;td&gt;Sicurezza sui costi ma scope variabile.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;variabile&lt;/td&gt;
        &lt;td&gt;fisso&lt;/td&gt;
        &lt;td&gt;fisso&lt;/td&gt;

        &lt;td&gt;Alto rischio di ROI negativo.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;variabile&lt;/td&gt;
        &lt;td&gt;variabile&lt;/td&gt;
        &lt;td&gt;fisso&lt;/td&gt;
        &lt;td&gt;Scenario ideale per l'applicazione dell'Agile.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
        &lt;td&gt;variabile&lt;/td&gt;
        &lt;td&gt;variabile&lt;/td&gt;
        &lt;td&gt;variabile&lt;/td&gt;
        &lt;td&gt;Efficiente con l'Agile.&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;blockquote&gt;
&lt;p&gt;Forse dobbiamo cominciare a domandare &amp;quot;quanto posso avere per X$&amp;quot; invece che affermare &amp;quot;voglio tutto questo per X$. Fatelo.&amp;quot; --Robert Dempsey&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alla luce di queste considerazioni, a meno che non si tratti di un progetto a requisiti completamente specificati e immutabili, e condotto da un team esperto nel dominio applicativo, &lt;strong&gt;conviene adottare un approccio agile negoziando la forma contrattuale più adatta.&lt;/strong&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Agile Coach</title>
   <link href="http://manuelp.github.com/agile/2009/11/06/the-agile-coach.html"/>
   <updated>2009-11-06T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/agile/2009/11/06/the-agile-coach</id>
   <content type="html">&lt;p&gt;Attualmente sto lavorando come una sorta di &amp;quot;Agile Coach&amp;quot; all&amp;#39;interno di un&amp;#39;azienda nell&amp;#39;ambito di uno stage, e mi sono ritrovato a studiare molto materiale al riguardo. In questo post ho annotato i punti più importanti dal mio punto di vista leggendo l&amp;#39;articolo &lt;em&gt;The Agile Coach&lt;/em&gt; sul &lt;a href=&quot;http://pragprog.com/magazines/download/5.pdf&quot;&gt;numero di Novembre&lt;/a&gt; di &amp;quot;PragPub&amp;quot;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Il compito dell&amp;#39; &lt;strong&gt;agile coach&lt;/strong&gt; è quello di aiutare il team a incrementare le proprie performance e ottenere i benefici dei principi dell&amp;#39;agile. Il modo in cui questo viene fatto è &lt;em&gt;guidando il team ad essere più consapevole del proprio workflow e di modi più efficienti di collaborare&lt;/em&gt;. Un buon coach deve essere in grado di insegnare come applicare le tecniche agili e di aiutare il team ad acquisirne competenza.&lt;/li&gt;
&lt;li&gt;Il coach può essere anche un membro del team, ma le responsabilità nel progetto possono distrarlo dal suo compito (coaching del team). Perciò &lt;em&gt;un coach preferibilmente non ha un ruolo attivo nel progetto a cui lavora il suo team&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Le doti e i requisiti necessari per un &lt;em&gt;agile coach&lt;/em&gt; sono:
** Passione per l&amp;#39;Agile.
** Esperienza nell&amp;#39;applicarne le pratiche e i principi.
** Abilità interpersonali: comunicazione, lavoro di squadra, ecc.
** Abilità di problem-solving.
** Pragmaticità.
** Umiltà.&lt;/li&gt;
&lt;li&gt;L&amp;#39;approccio di &lt;em&gt;planning&lt;/em&gt; conviene rimanga semplice: preferibilmente una lavagna fisica sul posto di lavoro. Per team distribuiti in genere usare fogli di calcolo e wiki è sufficiente, il software di &lt;em&gt;ALM&lt;/em&gt; (Agile Lifecycle Management) porta facilmente a piani iper-complicati. Su questo punto non sono molto d&amp;#39;accordo: un buon software è essenzialmente una lavagna virtuale con molte funzionalità aggiuntive che permette di semplificare molto la gestione di un progetto al punto di potersi quasi &amp;quot;dimenticare&amp;quot; del planning. Comunque mi manca esperienza in questo, vedrò.&lt;/li&gt;
&lt;li&gt;Avere il cliente spesso a disposizione è di essenziale importanza per il successo del progetto e uno dei compiti del coach è quello di aiutare a costruire una relazione stretta tra il team di sviluppo e il committente &lt;em&gt;creando un senso di impegno condiviso&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Se l&amp;#39;organizzazione non è convinta e non è consapevole di cosa significhi veramente essere &lt;em&gt;agile&lt;/em&gt;, conviene cominciare con l&amp;#39;educarla da questo.&lt;/li&gt;
&lt;li&gt;E&amp;#39; importante, come coach, supportare la transizione all&amp;#39; &lt;strong&gt;agile&lt;/strong&gt; e &lt;em&gt;incoraggiare un atteggiamento di sperimentazione e apprendimento continuo&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Wiki Creole mode for Emacs</title>
   <link href="http://manuelp.github.com/emacs/2009/11/03/wikicreole-mode-emacs.html"/>
   <updated>2009-11-03T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/emacs/2009/11/03/wikicreole-mode-emacs</id>
   <content type="html">&lt;p&gt;I needed a syntax highlighting support for the wiki &lt;a href=&quot;http://www.wikicreole.org/wiki/Creole1.0&quot;&gt;Creole&lt;/a&gt; syntax in Emacs, but I couldn&amp;#39;t find it anywhere... until I found the &lt;a href=&quot;http://www.emacswiki.org/cgi-bin/wiki/menu-bar%2B.el/Search/AlexSchroeder/AlexSchroederConfigPyrobombus&quot;&gt;dot.emacs&lt;/a&gt; configuration file of Alex Schroeder of &lt;a href=&quot;http://www.emacswiki.org&quot;&gt;emacswiki&lt;/a&gt; fame, which contains a little wonderful elisp snippet that I show you (a little bit modified) here:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot; data-lang=&quot;scheme&quot;&gt;&lt;span class=&quot;c1&quot;&gt;;; WikiCreole mode (wiki-mode)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; Thanks to Alex Schroeder of www.emacswiki.org &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; And Jason Blevins for his inspiring Markdown Mode&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; http://jblevins.org/projects/markdown-mode/&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;define-generic-mode&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'wiki-mode&lt;/span&gt; 
  &lt;span class=&quot;nv&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; comments &lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; keywords &lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;^\\(= \\)\\(.*?\\)\\($\\| =$\\)&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'info-title-1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;^\\(== \\)\\(.*?\\)\\($\\| ==$\\)&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'info-title-2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;^\\(=== \\)\\(.*?\\)\\($\\| ===$\\)&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'info-title-3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;^\\(====+ \\)\\(.*?\\)\\($\\| ====+$\\)&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'info-title-4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\[\\[.*?\\]\\]&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\[.*\\]&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\[b\\].*?\\[/b\\]&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'bold&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\[i\\].*?\\[/i\\]&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'italic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\*\\*.*?\\*\\*&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'bold&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\*.*?\\*&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'bold&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\_&amp;lt;//.*?//&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'italic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\_&amp;lt;/.*?/&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'italic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;__.*?__&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'italic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;_.*?_&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'underline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;|+=?&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;font-lock-string-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\\\\\\\[ \t]+&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;font-lock-warning-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; font-lock list&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.wiki\\'&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; auto-mode-alist&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'goto-addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; function-list&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;Wiki stuff including Creole Markup and BBCode.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Just copy this snippet in your .emacs and any file &amp;quot;*.wiki&amp;quot; will be highlighted correctly. You can also enable this mode from within emacs by: &lt;em&gt;M-x wiki-mode&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve adapted it a little bit and stealed some regexps from Jason&amp;#39;s &lt;a href=&quot;http://jblevins.org/projects/markdown-mode/&quot;&gt;markdown-mode&lt;/a&gt; for highligthing titles. But there is still something missing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Highlighting of lists&lt;/li&gt;
&lt;li&gt;Support for images&lt;/li&gt;
&lt;li&gt;Better highlithing of external links&lt;/li&gt;
&lt;li&gt;Some functions for preview maybe?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Further versions of this mode will be updated here.&lt;/p&gt;

&lt;p&gt;Enjoy :)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Come fare una presentazione</title>
   <link href="http://manuelp.github.com/comunicazione/2009/11/03/come-fare-una-presentazione.html"/>
   <updated>2009-11-03T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/comunicazione/2009/11/03/come-fare-una-presentazione</id>
   <content type="html">&lt;p&gt;Con tutta probabilità sei già stato &lt;em&gt;vittima&lt;/em&gt; di presentazioni noiose e confusionarie, esposte da esperti in materia che nonostante tutti i tuoi eroici sforzi sono riusciti a farti addormentare.... E questo non è necessariamente dovuto all&amp;#39;oggetto dell&amp;#39;esposizione, infatti persino gli argomenti più noiosi possono essere resi avvincenti e interessanti da un buon speaker.&lt;/p&gt;

&lt;p&gt;Fare una presentazione o insegnare in generale è molto di più che essere degli esperti nella materia. Occorrono delle competenze differenti per &lt;em&gt;presentare&lt;/em&gt; informazioni in modo corretto: &lt;strong&gt;si devono sviluppare le capacità di comunicazione.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Presentation skills are worthy of extreme obsessive study.&amp;quot; --Tom Peters, Management guru&lt;/p&gt;

&lt;p&gt;&amp;quot;Presentation is the &amp;#39;Killer Skill&amp;#39; we take into the real world. It&amp;#39;s almost an unfair advantage.&amp;quot; --The McKinsey Mind&lt;/p&gt;

&lt;p&gt;Ottima presentazione = conoscenze + comunicazione&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Sommario&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Obiettivo delle presentazioni&lt;/li&gt;
&lt;li&gt;Sull&amp;#39;uso delle slide&lt;/li&gt;
&lt;li&gt;Preparazione: Audience, Tema, Struttura, Pratica, Slide&lt;/li&gt;
&lt;li&gt;Delivery: Apertura, Talk (show), Chiusura&lt;/li&gt;
&lt;li&gt;Infrangere le regole&lt;/li&gt;
&lt;li&gt;Conclusioni&lt;/li&gt;
&lt;li&gt;Fonti&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Obiettivo delle presentazioni&lt;/h2&gt;

&lt;p&gt;Prima di imbarcarsi in qualsiasi impresa, occorre conoscerne la &lt;em&gt;ragione&lt;/em&gt;. Lo stesso vale per una presentazione: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Qual&amp;#39;è l&amp;#39;obiettivo del talk?&lt;/li&gt;
&lt;li&gt;Che cosa voglio che il pubblico apprenda?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Troppo spesso invece si comincia subito a preparare l&amp;#39;esposizione senza alcuna idea di partenza di dove si andrà a parare. &lt;strong&gt;Conoscere l&amp;#39;obiettivo di una presentazione è indispensabile per esprimere con efficacia il messaggio principale e per preparare un discorso con un suo filo logico.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Ci sono ben poche cose più noiose di un elenco disordinato di fatti. Una vera presentazione non è un semplice elenco di dati, altrimenti sarebbe più conveniente scrivere un articolo. La ragion d&amp;#39;essere delle presentazioni è il dialogo e l&amp;#39;&lt;em&gt;interpretazione&lt;/em&gt; di tali dati. La gente è in grado di leggere, e il motivo per cui si scomoda ad assistere ad un talk è per conoscere il &lt;em&gt;significato&lt;/em&gt; e per vedere come questo possa &lt;em&gt;prendere vita&lt;/em&gt;. Se ci sono dei dati importanti (grafici, tabelle, fonti, ecc) può essere più conveniente scriverle in un documento apposito e renderlo disponibile agli interessati.&lt;/p&gt;

&lt;p&gt;Ma il primo e più importante valore che uno speaker &lt;em&gt;deve&lt;/em&gt; tenere sempre a mente è il &lt;strong&gt;rispetto&lt;/strong&gt;: rispetto per l&amp;#39;audiece e per sè stessi. Troppo spesso invece gli speaker dimostrano un&amp;#39;insensibilità totale verso il pubblico, esponendo gli argomenti in modo confuso, incomprensibile e noioso, e subissando gli ascoltatori con aridi e lunghi elenchi puntati nello sforzo di fare bella figura e dimostrare di &amp;quot;sapere&amp;quot;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The deepest human need is the need to be appreciated. (William James)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;E&amp;#39; essenziale riconoscere al pubblico il rispetto che merita il suo tempo e la sua attenzione, veicolando le informazioni in modo &lt;em&gt;conciso, chiaro e interessante&lt;/em&gt;.&lt;/strong&gt; Si deve essere disposti a sacrificare alcuni dettagli per presentare l&amp;#39;argomento in modo corretto all&amp;#39;audience. E&amp;#39; questo l&amp;#39;&lt;strong&gt;obiettivo&lt;/strong&gt; di ogni buona presentazione.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The presentation isn’t about you, it’s about your material.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Per avere un&amp;#39;idea di come sono delle presentazione fatte &lt;em&gt;veramente&lt;/em&gt; bene:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vedere su &lt;a href=&quot;http://www.youtube.com/&quot;&gt;YouTube&lt;/a&gt; le presentazioni di: Seth Godin, Tom Peters, Guy Kawasaki, Steve Jobs e Dick Hardt.&lt;/li&gt;
&lt;li&gt;Guardare le presentazioni di alcuni dei &amp;quot;maghi&amp;quot; su &lt;a href=&quot;http://www.ted.com&quot;&gt;TED.com&lt;/a&gt;, ad esempio: Rives, Hans Rosling, Barnett Thomas, Lawrence Lessig e Ken Robinson.&lt;/li&gt;
&lt;li&gt;Se si ha occasione, assistere a qualche talk di &lt;a href=&quot;http://damian.conway.org/&quot;&gt;Damian Conway&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Vai su &lt;a href=&quot;http://www.commoncraft.com/&quot;&gt;Common Craft&lt;/a&gt; a dare un&amp;#39;occhiata ai loro tutorial &amp;quot;plain English&amp;quot; sul Web 2.0&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Sull&amp;#39;uso delle slide&lt;/h2&gt;

&lt;p&gt;L&amp;#39;uso di slide (lucidi) è diventato ormai sinonimo di presentazione in molti campi, tanto che la stragrande maggioranza si cimenta nel realizzare questi &lt;em&gt;ausili&lt;/em&gt; senza pensarci un istante. Il problema, soprattutto con slide contenenti molto materiale, è che ad un certo punto o la gente legge le slide e non segue più lo speaker (a quel punto converrebbe scrivere un semplice articolo), oppure ascolta lo speaker e non guarda nemmeno le slide (in questo caso non servono neppure).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Replace Powerpoint with directness and enthusiasm.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ripensando all&amp;#39;obiettivo della presentazione e al contesto, occorre invece essere &lt;em&gt;pragmatici&lt;/em&gt; e riflettere sull&amp;#39;utilità delle slide: &lt;strong&gt;il principale asset e contenuto di un talk è... l&amp;#39;esposizione di un&amp;#39;argomento dal vivo e dalla voce dello speaker. Le slide sono sono un ausilio che può essere utile in alcuni casi.&lt;/strong&gt; L&amp;#39;esposizione è qualcosa di dinamico, di vivo. Se il pubblico volesse leggere una lista di punti proiettati su uno schermo andrebbe semplicemente a leggersi un libro o un articolo su internet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PRIMA viene il discorso, DOPO (eventualmente) gli ausili visivi.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alcuni realizzano delle slide per sentirsi più sicuri durante l&amp;#39;esposizione, ma &lt;strong&gt;i lucidi non possono essere un sostituto per la conoscenza dell&amp;#39;argomento che si presenta&lt;/strong&gt;. O lo si conosce o non lo si conosce. Usare le slide come &amp;quot;stampelle&amp;quot; è la ragione sbagliata per propinarle e una chiara indicazione del bisogno di fare più &lt;em&gt;pratica&lt;/em&gt;. &lt;strong&gt;Un argomento lo si conosce e lo si comprende veramente solo quando si è in grado di spiegarlo senza alcun ausilio&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Perciò se devi preparare una presentazione, poniti prima questa domanda: &lt;strong&gt;posso fare a meno delle slide?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Prima di tutto è necessario avere ben chiaro in mente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;L&amp;#39;obiettivo.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Il messaggio.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;L&amp;#39;audience.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L&amp;#39;uso degli strumenti adatti viene di conseguenza.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Focus on your purpose, your message and your audience and you won’t go far wrong. Once you are clear on those, the details of tools and delivery will become apparent.&amp;quot; --Rowan Manahan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Per un esempio di come è possibile fare una presentazione &lt;strong&gt;memorabile&lt;/strong&gt; senza usare &lt;em&gt;nessuna&lt;/em&gt; slide, vedere il talk di &lt;a href=&quot;http://www.ted.com/index.php/talks/ken_robinson_says_schools_kill_creativity.html&quot;&gt;Sir Ken Robinson&lt;/a&gt;. Inoltre, per un uso creativo e molto visuale delle slide per sottolineare l&amp;#39;esposizione vedere lo &lt;a href=&quot;http://presentationzen.blogs.com/presentationzen/2005/09/living_large_ta.html&quot;&gt;stile Takahashi&lt;/a&gt; orginale e le sue variazioni che usano anche immagini, come ad esempio la presentazione di Kent Beck sul &lt;a href=&quot;http://www.infoq.com/presentations/responsive-design&quot;&gt;Responsive Design&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Vediamo ora alcuni suggerimenti su come preparare e effettuare una buona presentazione.&lt;/p&gt;

&lt;h2&gt;Preparazione&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Il suggerimento più importante sulla preparazione di una presentazione è quello di &lt;em&gt;preparala lontano dal PC (e da PowerPoint).&lt;/em&gt; Una volta chiaro l&amp;#39;obiettivo, esporre a voce alta in modalità &amp;quot;freestyle&amp;quot; provando vari approcci e annotando idee, frasi e pensieri importanti. Dopo aver steso l&amp;#39;ossatura della presentazione, scriverla su carta (come minimo sotto forma di &lt;em&gt;outline&lt;/em&gt; o &lt;a href=&quot;http://en.wikipedia.org/wiki/Mind_map&quot;&gt;mappa mentale&lt;/a&gt;).&lt;/strong&gt; Solo &lt;em&gt;dopo&lt;/em&gt; si può considerare se servono slide o meno.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Presentazione = discorso &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un passo importante che molti non considerano è che un pezzo scritto prima di raggiungere la sua forma definitiva viene modificato molte volte. Lo stesso vale per i discorsi: &lt;strong&gt;per renderli concisi ma evocativi e memorabili è necessario scriverli e perfezionarli esercitandosi molto nell&amp;#39;esposizione&lt;/strong&gt;. E&amp;#39; così che i &lt;strong&gt;grandi&lt;/strong&gt; discorsi sono stati creati e hanno potuto esercitare un impatto enorme sulle generazioni a venire: vedi Martin Luther King, Lincoln, Ghandi...&lt;/p&gt;

&lt;p&gt;Uno dei più grandi &amp;quot;presentatori&amp;quot; contemporanei, &lt;a href=&quot;http://damian.conway.org/&quot;&gt;Damian Conway&lt;/a&gt;,  raccomanda un &lt;em&gt;minimo di 10 ore di preparazione per ogni ora di presentazione&lt;/em&gt; (20 se l&amp;#39;argomento è relativamente ostico). Questo ovviamente se si vuole fare un talk &lt;strong&gt;memorabile&lt;/strong&gt;...&lt;/p&gt;

&lt;p&gt;E&amp;#39; anche utile preparare almeno un piano di &lt;em&gt;backup&lt;/em&gt; per non essere colti impreparati dalle evenienze.&lt;/p&gt;

&lt;p&gt;Inoltre, tenere presente che il modo migliore di illustrare certi concetti è attraverso delle &lt;em&gt;dimostrazioni&lt;/em&gt;. Inserirne il più possibile.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Demonstrations beat descriptions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Audience&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Informarsi sull&amp;#39;audience.&lt;/strong&gt; Quali sono i suoi interessi, lo stato d&amp;#39;animo, &lt;em&gt;i bisogni e le aspettative&lt;/em&gt;?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quanto tempo si ha a disposizione?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E&amp;#39; importante capire con chi si ha a che fare per veicolare il messaggio nel modo più efficace ed efficiente possibile. Vedere anche un mio precendente &lt;a href=&quot;http://manuelp.github.com/metaprogramming/2009/05/30/importanza-di-comunicare.html&quot;&gt;post&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Tema&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Identificare la singola &lt;em&gt;idea chiave&lt;/em&gt; che si vuole comunicare con la presentazione e focalizzarsi su quella.&lt;/strong&gt; E&amp;#39; più facile lasciare il segno quando il punto importante è uno piuttosto che una collezione di fatti blandamente correlati.&lt;/p&gt;

&lt;p&gt;L&amp;#39;idea centrale costituisce il &lt;em&gt;tema&lt;/em&gt; della presentazione. Una volta identificato, raccogliere citazioni, aneddoti, fatti a supporto e organizzarli per costruire una storia attorno ad esso.&lt;/p&gt;

&lt;p&gt;Per talk più articolati, possono esserci più idee chiave che si vuole trasmettere, ma è bene non andare mai oltre le &lt;em&gt;3-5&lt;/em&gt;. Avere più di 5 messaggi principali rende difficile seguire il discorso e conservarne qualche memoria.&lt;/p&gt;

&lt;h3&gt;Struttura&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;La presentazione deve avere una struttura &lt;em&gt;lineare&lt;/em&gt;, semplice, chiara e facile da seguire.&lt;/strong&gt; Qualunque sia la tipologia dell&amp;#39;esposizione, la sequenza di elementi deve avere una struttura logica coerente.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Bad storytelling is beginning, muddle, end.&amp;quot; --Philip Larkin&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gli esseri umani amano e trovano più semplice seguire ragionamenti &lt;em&gt;lineari&lt;/em&gt;, e tale deve essere la presentazione: &lt;strong&gt;una sequenza lineare, logica e concisa di dati, informazioni e aneddoti correlati.&lt;/strong&gt; Bisogna resistere alla tentazione di farcire il talk di dati per dimostrare la propria conoscenza (ma non il proprio rispetto). Quasi invariabilmente si è spinti a inserire &lt;em&gt;troppo&lt;/em&gt; materiale, conviene quindi  distillare la presentazione in modo quasi &amp;quot;brutale&amp;quot; eliminando tutto quanto non è essenziale (il tempo è qualcosa di prezioso, non va sprecato).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;La semplicità è la sofisticazione ultima.&amp;quot; --Leonardo Da Vinci&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aiuta avere buone doti di &lt;em&gt;storytelling&lt;/em&gt;, ma in ogni caso il talk deve avere un inizio, uno svolgimento (possibilmente che porta ad un &lt;em&gt;climax&lt;/em&gt;) e una conclusione che lasci il segno.&lt;/p&gt;

&lt;p&gt;Il workflow potrebbe essere:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identificare i punti rilevanti per l&amp;#39;audience.&lt;/li&gt;
&lt;li&gt;Metterli nell&amp;#39;ordine più interessante per il pubblico.&lt;/li&gt;
&lt;li&gt;Fornire il contesto necessario.&lt;/li&gt;
&lt;li&gt;Arricchire con elementi di teatralità.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Distillare ulteriormente&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;La perfezione si raggiunge attraverso la quotidiana diminuzione, non aumento.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Per esempio, per una presentazione incentrata su una soluzione ad un problema:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Illustrare le cause del problema che affligge l&amp;#39;audience.&lt;/li&gt;
&lt;li&gt;Mostrare perchè è serio.&lt;/li&gt;
&lt;li&gt;Proporre una soluzione.&lt;/li&gt;
&lt;li&gt;Sommario e &amp;quot;chiamata alle armi&amp;quot;, riassumendo chiaramente cosa bisogna fare.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;E&amp;#39; molto utile illustrare questa struttura all&amp;#39;inizio della presentazione per dare un&amp;#39;idea di cosa tratterà il talk e come.&lt;/p&gt;

&lt;h3&gt;Pratica&lt;/h3&gt;

&lt;p&gt;Una volta costruita la presentazione: &lt;strong&gt;fare pratica, pratica e ancora pratica. Preferibilmente ad alta voce&lt;/strong&gt;. Sperimentare spostando concetti, eliminando quelli superflui e modificando la presentazione in modo che &lt;em&gt;sia ben coesa e comunichi efficacemente l&amp;#39;idea centrale&lt;/em&gt;. Possibilmente avendo qualcuno in carne ed ossa che ascolta e fornisce feedback. Inoltre &lt;em&gt;fare attenzione che si rientri nei tempi&lt;/em&gt;.  E&amp;#39; molto importante praticare la presentazione, per poi poterla esporre con sicurezza e padronanda davanti al pubblico. Non occorre memorizzare tutto il talk, basta ricordarsi i punti fondamentali, gli accessori verranno con naturalezza se si conosce bene la materia e si è fatta abbastanza pratica.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;The only way to speak better is to speak.&amp;quot; --Damian Conway&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La pratica è &lt;strong&gt;essenziale&lt;/strong&gt;, non basta preparare un discorso sulla carta. Come gli speaker esperti e gli attori ben sanno, lo scritto e il parlato sono due veicoli di espressione abbastanza diversi e ciò che è scritto spesso non ha lo stesso effetto quando viene letto ad alta voce. Lo stesso dicasi per l&amp;#39;inverso. Il lavorare al discorso sia in forma scritta che parlata (e praticandolo) permette di chiarire il messaggio essenziale ed &amp;quot;editarlo&amp;quot; in modo da renderlo ad alto impatto.&lt;/p&gt;

&lt;h3&gt;Slide&lt;/h3&gt;

&lt;p&gt;Come descritto le slide &lt;strong&gt;non&lt;/strong&gt; sono indispensabili per una presentazione, ma se &lt;em&gt;dopo&lt;/em&gt; ever preparato il materiale si decide di utilizzarle, tanto vale renderle memoriabili.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Great content is a necessary condition, but not a sufficient one.&amp;quot; --Garr Reynolds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Data la facilità disarmante nel realizzarne di irritanti e inutili, il modo migliore per rendere delle slide attraenti è essere consapevole che sono un &lt;em&gt;ausilio&lt;/em&gt;, uno &lt;em&gt;strumento&lt;/em&gt; il cui compito è quello di sottolineare ed enfatizzare i punti importanti, non di distrarre il pubblico costringendolo a leggere decine e decine di parole. Inquadrare le slide come uno strumento poi, permette di utilizzarle in modo &lt;em&gt;creativo&lt;/em&gt; per sorprendere, mantenere l&amp;#39;attenzione e fissare i concetti.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Nothing in your slide should be superfluous, ever.&amp;quot; --Garr Reynolds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Il criterio più importante da tenere a mente nella realizzazione di slide è: &lt;strong&gt;semplicità e stile&lt;/strong&gt;. Vedere come esempio le slide di: Apple, Bang &amp;amp; Olufsen, The Perl Journal, ecc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Your slides, if you choose to use them, should not be textual orgies. Use visual shorthand.&amp;quot; --Chris Brogan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un grande errore compiuto da molti è quello di pensare alle slide come ad un documento a sè stante: così facendo però realizzano un documento in un formato adatto ad essere presentato su uno schermo, non dei lucidi. Ma semplicemente questo non è l&amp;#39;uso per cui le slide sono state inventate e di certo non è quello migliore nel contesto di una presentazione. &lt;strong&gt;Le slide non sono la &lt;em&gt;presentazione&lt;/em&gt;, sono solo le &lt;em&gt;illustrazioni&lt;/em&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Le slide NON SONO la presentazione.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In quest&amp;#39;ottica, &lt;strong&gt;impiegare poche parole ed eventualmente delle immagini significative&lt;/strong&gt;. L&amp;#39;uso delle immagini delle slide ha un grande potere: rende possibile coinvolgere il pubblico anche emotivamente e ne stimola l&amp;#39;immaginazione aiutando a mantenere desta l&amp;#39;attenzione e migliorare la memoria di quello che viene detto. &lt;/p&gt;

&lt;p&gt;L&amp;#39;approccio risulta ancora più potente se si scelgono immagini significative che rappresentano una &lt;em&gt;metafora&lt;/em&gt; (meglio se divertente) dei concetti presentati.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Un&amp;#39;immagine vale più di mille parole.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inoltre, &lt;em&gt;sorprendere&lt;/em&gt; l&amp;#39;audience. E&amp;#39; un altro modo per creare un&amp;#39;esperienza emozionante che verrà ricordata.&lt;/p&gt;

&lt;h4&gt;Flusso di informazioni&lt;/h4&gt;

&lt;p&gt;Se si decide di utilizzare delle slide come ausilio, bisogna &lt;em&gt;controllare il flusso di informazioni&lt;/em&gt; in modo che il talk e i lucidi restino in sincrono.&lt;/p&gt;

&lt;p&gt;Quando ad esempio si vogliono elencare una serie di punti, il mostrarli tutti contemporaneamente in un&amp;#39;unica slide mentre si parla, significa fare in modo che l&amp;#39;audience li legga tutti e aspetti che vengano trattati cercando di collegare ciò che è scritto a ciò che viene detto. Questo a scapito dell&amp;#39;attenzione. E&amp;#39; più opportuno in questo caso mostrare un punto alla volta.&lt;/p&gt;

&lt;p&gt;Allo stesso modo, se si vuole presentare un grafico, per prima cosa occorre spiegare i dati e il significato prima di mostrarlo nella slide successiva, in modo che a quel punto gli ascoltatori siano in grado di interpretarlo subito. Tra l&amp;#39;altro, il mostrare il grafico dopo averlo spiegato può aiutare anche a creare anticipazione e innalzare l&amp;#39;interesse.&lt;/p&gt;

&lt;h4&gt;Design&lt;/h4&gt;

&lt;p&gt;E&amp;#39; importante che le slide siano leggibili e rispettino delle buone linee guida tipografiche. Se c&amp;#39;è qualcosa di peggio di slide mal realizzate, sono slide mal realizzate &lt;em&gt;e&lt;/em&gt; illeggibili. Ecco le linee guida più importanti:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Semplicità e stile!&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attenzione al contrasto&lt;/strong&gt;: colori complementari. Sfondo chiaro, testo scuro. Sfondo scuro, testo chiaro. Chiaro?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Allineare il testo a destra o a sinistra&lt;/strong&gt;: l&amp;#39;allineamento centrale è poco professionale, amatoriale e meno leggibile.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Andare all&amp;#39;essenziale&lt;/strong&gt;: Un titolo, qualche punto e al massimo un&amp;#39;immagine. Avere troppi elementi rende difficile &amp;quot;decodificare&amp;quot; la pagina ed è stressante. La cosa migliore è inserire poche parole con un font di dimensione molto grande.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usare font della famiglia Serif per il corpo&lt;/strong&gt;: sono i font che rendono meglio su schermo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limitare l&amp;#39;uso di font decorativi ai titoli e &lt;em&gt;solo&lt;/em&gt; se sono leggibili&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evitare di inserire il logo in ogni slide&lt;/strong&gt;. Non si vuole dare l&amp;#39;impressione di essere dei venditori.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limitare l&amp;#39;uso di effetti di transizione&lt;/strong&gt;, possibilmente non usarne nessuno: distraggono e basta. Non essere esibizionista.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Delivery&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Presentare qualcosa è più di una semplice recitazione di fatti. Si tratta di una vera e propria &lt;em&gt;esibizione&lt;/em&gt; comprendente elementi teatrali e di drammaticità&lt;/strong&gt;. Bisogna imparare a comunicare con efficacia usando non solo le parole ma anche il linguaggio del corpo, il giusto ritmo, le emozioni, la consapevolezza dell&amp;#39;audience e di come questi elementi li influenzino. &lt;strong&gt;Ogni presentazione è una performace finalizzata all&amp;#39;intrattenere il pubblico in modo che al termine ne esca arricchito&lt;/strong&gt; (possibilmente di quello che si aspettava, meglio se di più).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Entertaining always trumps informative.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se possibile, arrivare prima dell&amp;#39;inizio del talk e preparare tutto prima che il pubblico giunga in sala. Non è molto professionale armeggiare con il proiettore e il portatile mentre l&amp;#39;audience aspetta... &lt;strong&gt;Prepararsi per tempo in modo da essere pronti, sicuri che tutto funziona e (relativamente) rilassati quando arriva l&amp;#39;ora di iniziare.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Una piccola nota: vestirsi in modo consono all&amp;#39;occasione e all&amp;#39;audience. Ovvio, ma meglio precisarlo...&lt;/p&gt;

&lt;h3&gt;Apertura&lt;/h3&gt;

&lt;p&gt;E&amp;#39; normale essere un pò nervosi prima di cominciare un&amp;#39;esposizione. Le cose importanti sono fare molta pratica e &lt;strong&gt;iniziare la presentazione con entusiasmo e sicurezza&lt;/strong&gt;. Ad esempio, per rompere il ghiaccio si può:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Porre una domanda.&lt;/li&gt;
&lt;li&gt;Sfidare l&amp;#39;audience.&lt;/li&gt;
&lt;li&gt;Citare una persona famosa.&lt;/li&gt;
&lt;li&gt;Raccontare una storia divertente.&lt;/li&gt;
&lt;li&gt;Raccontare un fatto interessante.&lt;/li&gt;
&lt;li&gt;Proporre una visione grandiosa (e poi proporre come farla avverare)&lt;/li&gt;
&lt;li&gt;Proporre una visione spaventosa (e poi parlare di come &lt;em&gt;non&lt;/em&gt; farla realizzare)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In altre parole basta cominciare il talk con qualcosa di interessante che catturi l&amp;#39;attenzione.&lt;/p&gt;

&lt;h3&gt;Talk (show)&lt;/h3&gt;

&lt;p&gt;Di seguito qualche suggerimento su come condurre al meglio la &lt;em&gt;performace&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Muoversi e guardare le persone negli occhi.&lt;/strong&gt; Usare il linguaggio del corpo per sottolineare certi punti è utile, ma senza esagerare: non è una prestazione sportiva!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non recitare i punti a memoria o peggio leggere le slide.&lt;/strong&gt; Bisogna avere rispetto per il tempo degli altri e dato che catturare l&amp;#39;attenzione non è affatto semplice, una volta che la si ha va gestita correttamente. Si deve conoscere bene ciò che si presenta, e questo significa essere in grado di illustrarlo senza che siano &lt;em&gt;necessari&lt;/em&gt; ausili esterni.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usare un tono di voce chiaro, parlare lentamente e variare spesso il ritmo.&lt;/strong&gt; Bisogna parlare in modo da essere sentiti, chiaramente e ancora una volta portando rispetto verso il pubblico evitando di annoiarlo a morte con un tono di voce costante e noioso (soporiferio). Spesso i novizi durante i talk parlano troppo velocemente: rallentare deliberatamente.

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Evitare i &amp;quot;filler&amp;quot;&lt;/strong&gt;, ovvero cose come: &amp;quot;cioè, uhm, eh&amp;quot; ecc. Denotano insicurezza.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Raccontare una storia&lt;/strong&gt;. Anche se inventata, è utile per intrattenere e mantenere viva l&amp;#39;attenzione. Ovviamente che sia in qualche modo rilevante all&amp;#39;argomento oggetto della presentazione. Può essere utile anche mischiarla con delle &lt;em&gt;metafore&lt;/em&gt; utili ad illustrare certi concetti e relazioni. Inutile dire che l&amp;#39;effetto è migliore se la storia è divertente.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usare la &lt;a href=&quot;http://it.wikipedia.org/wiki/Retorica&quot;&gt;retorica&lt;/a&gt;&lt;/strong&gt; per essere &lt;em&gt;incisivi e memorabili&lt;/em&gt;. Praticare ad esempio con: contrasto, lista dei tre e soprattutto la &lt;em&gt;pausa&lt;/em&gt;. Fare una pausa prima di esporre un punto importante crea anticipazione e drammaticità: un momento teatrale che mantiene l&amp;#39;attenzione.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Se ci si dimentica qualcosa, andare avanti con la presentazione senza scusarsi o fermarsi per cercare di ricordare.&lt;/strong&gt; Se l&amp;#39;esposizione veicola il &lt;em&gt;messaggio principale&lt;/em&gt;, allora è ok.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Emozionare&lt;/strong&gt;. E&amp;#39; uno dei modi principali e più efficaci per mantenere l&amp;#39;attenzione e far arrivare i concetti a destinazione. Con un pò di pratica diventa facile visto che qualsiasi argomento può essere trattato dal punto di vista &lt;em&gt;umano&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;E&amp;#39; utile anche raccontare aneddoti (soprattutto se personali), umorismo e storie. &lt;strong&gt;Un tocco personale può aiutare molto a rendere una presentazione autentica e interessante&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ENTUSIASMO!&lt;/strong&gt; L&amp;#39;entusiasmo è contagioso. La presentazione deve essere colma di &lt;em&gt;passione&lt;/em&gt;, deve prendere vita e catturare l&amp;#39;attenzione del pubblico facendo perdere al tempo il suo significato.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Creare una sensazione di &lt;em&gt;intimità&lt;/em&gt; con il pubblico&lt;/strong&gt;: dare l&amp;#39;impressione di essere lì per loro e di conoscerli trattandoli come amici. L&amp;#39;atmosfera dovrebbe essere rilassata e amichevole.&lt;/li&gt;
&lt;li&gt;Eventualmente &lt;strong&gt;coinvolgere il pubblico&lt;/strong&gt; trasformando la presentazione in una discussione interattiva. Invitare a fare commenti e portare contributi personali. Chiaramente è possibile solo per chi conosce veramente quello di cui sta parlando ed è in grado di gestire una discussione, diversamente avrà paura di essere colto in fallo. Comunque tutto dipende dal pubblico e dalla natura dell&amp;#39;argomento: non sempre l&amp;#39;oggetto del talk si presta ad una discussione interattiva e a volte l&amp;#39;audience preferisce non essere chiamata in causa.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Humans want to connect. They are built to want to belong. A great presentation is a fire to gather around and share an experience.&amp;quot; --Chris Brogan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Per quanto riguarda le domande, è opportuno avere una &lt;em&gt;policy&lt;/em&gt; per dove, come e quando accettare domande da condividere con il pubblico. Se non si conosce qualche risposta si può reagire in modo diverso a seconda della situazione:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;quot;Non conosco la risposta mi dispiace.&amp;quot;&lt;/li&gt;
&lt;li&gt;Redirigere la domanda a chi può avere la risposta.&lt;/li&gt;
&lt;li&gt;&amp;quot;Ora non so risponderti, non appena conoscerò la risposta la scriverò sul mio blog.&amp;quot;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Presentazione memorabile = informazioni + intrattenimento&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Chiusura&lt;/h3&gt;

&lt;p&gt;E&amp;#39; importante chiudere la presentazione con un sommario che ricapitola i punti principali e &lt;strong&gt;un&amp;#39;ultima, chiara ripetizione del messaggio chiave&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;In the beginning, tell the audience what you&amp;#39;re going to tell them. Then tell them, and be sure to leave time at the end to tell them what you told them. It sounds simple, but it works and they will appreciate it.&amp;quot; --Lehr, J.H&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Il pubblico deve avere la sensazione di aver ottenuto qualcosa dalla presentazione e deve avere delle informazioni &lt;em&gt;pronte all&amp;#39;uso&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Infrangere le regole&lt;/h2&gt;

&lt;p&gt;Tutto quello che ho illustrato sono consigli e linee guida, ma &lt;em&gt;tutte le regole possono essere infrante&lt;/em&gt; e a volte devono esserlo: le interazioni umane sono qualcosa di troppo complesso e dinamico da poter essere gestito da un insieme di regole ferree seguite senza usare la testa.&lt;/p&gt;

&lt;p&gt;Sia un principiante che un esperto possono non rispettarne qualcuna, la differenza sta nella &lt;em&gt;conoscenza&lt;/em&gt;: l&amp;#39;esperto conosce le regole che infrange e sa spiegare il perchè lo fa, un principiante semplicemente no.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Per infrangere efficacemente le regole bisogna prima conoscerle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Conclusioni&lt;/h2&gt;

&lt;p&gt;Ricapitoliamo i punti importanti:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un buon discorso è &lt;em&gt;intrattenimento&lt;/em&gt; e informazioni. Bisogna imparare a comunicare.&lt;/li&gt;
&lt;li&gt;Per fare una buona presentazione è essenziale una estensiva &lt;em&gt;preparazione&lt;/em&gt; che va fatta lontano dal PC.&lt;/li&gt;
&lt;li&gt;Ogni presentazione deve presentare 1-5 idee chiave e organizzare un discorso lineare, logico e conciso attorno ad esse.&lt;/li&gt;
&lt;li&gt;Una presentazione è essenzialmente un discorso, le slide sono un accessorio non necessario. Se vengono realizzare, che siano fatte con semplicità e stile.&lt;/li&gt;
&lt;li&gt;Ogni presentazione deve essere un&amp;#39;esibizione colma di &lt;em&gt;entusiasmo&lt;/em&gt; e in grado di appassionare l&amp;#39;audience. Imparare ad esibirsi e a creare un&amp;#39;atmosfera intima sono ingredienti fondamentali delle presentazioni memoriabili.&lt;/li&gt;
&lt;li&gt;All&amp;#39;inizio anticipare quello di cui si parlerà e alla fine dell&amp;#39;esposizione ricapitolare i messaggi importanti.&lt;/li&gt;
&lt;li&gt;Se possibile, dare precedenza alle dimostrazioni piuttosto che alle descrizioni.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Approfondimenti&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.garrreynolds.com/Presentation/index.html&quot;&gt;Presentation Tips by Garr Reynolds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.presentationzen.com/&quot;&gt;Presentation Zen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/communication/how-to-give-a-great-speech-part-1-preparation.html&quot;&gt;How to give a great speech, Part 1: Preparation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/communication/how-to-give-a-great-speech-part-2-delivery.html&quot;&gt;How to give a great speech, Part 2: Delivery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/communication/presentation-masterclass-part-1-introduction.html&quot;&gt;Presentation Masterclass - Part 1: Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/communication/5-key-questions-when-planning-your-presentation-presentation-masterclass-part-2.html&quot;&gt;Presentation Masterclass - Part 2: 5 Key Questions When Planning Your Presentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/communication/six-ways-to-transform-your-presentation.html&quot;&gt;Six Ways To Transform Your Presentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/communication/4-effective-presentation-techniques.html&quot;&gt;4 Effective Presentation Techniques&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://howto.lifehack.org/wiki/Presentation&quot;&gt;Presentation HowTo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/communication/present-like-a-rockstar.html&quot;&gt;Present Like A Rockstar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/lifehack/my-best-presentation-tricks.html&quot;&gt;My Best Presentation Tricks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/communication/18-tips-for-killer-presentations.html&quot;&gt;18 Tips for Killer Presentations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lifehack.org/articles/technology/10-tips-for-more-effective-powerpoint-presentations.html&quot;&gt;10 Tips for More Effective PowerPoint Presentations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://headrush.typepad.com/creating_passionate_users/2006/07/a_few_more_pres.html&quot;&gt;A few more Presentation How To&amp;#39;s&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Lehr, J.H., 1985, &lt;a href=&quot;http://geology.wwu.edu/rjmitch/stoning.pdf&quot; title=&quot;Let there be stoning!&quot;&gt;Let there be stoning!&lt;/a&gt;, Ground Water, v. 23, no. 2, p. 162-165&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.canspice.org/2005/08/01/oscon-2005-the-conway-channel-first-half/&quot;&gt;OSCON 2005: Presentation Aikido, Damian Conway, first half&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.canspice.org/2005/08/01/oscon-2005-presentation-aikido-damian-conway-second-half/&quot;&gt;OSCON 2005: Presentation Aikido, Damian Conway, second half&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>User Stories Applied, capitolo 2</title>
   <link href="http://manuelp.github.com/agile/2009/10/30/user-stories-applied-2.html"/>
   <updated>2009-10-30T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/agile/2009/10/30/user-stories-applied-2</id>
   <content type="html">&lt;p&gt;Continua l&amp;#39;esplorazione della tecnica delle &lt;a href=&quot;http://en.wikipedia.org/wiki/User_story&quot;&gt;user stories&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Per capire meglio che cosa sono le user stories bisogna capire cosa &lt;em&gt;non&lt;/em&gt; sono mettendole in contrasto con le altre tecniche di raccolta dei requisiti (use cases, specifiche dei requisiti software IEEE 830 e interactive design scenarios).&lt;/p&gt;

&lt;h2&gt;IEEE 830&lt;/h2&gt;

&lt;p&gt;Lo standard IEEE 830 documenta un modo di esprimere le specifiche di un software, principalmente attraverso una gerarchia di requisiti nella forma &amp;quot;&lt;em&gt;Il sistema dove...&lt;/em&gt;&amp;quot;. Un esempio:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;4-6) The system shall allow a room to be reserved with a credit card.
4-6-1) The system shall accept Visa, MasterCard and American Express cards.
4-6-2) The system shall charge the credit card the indicated rate for all nights of the stay before the reservation is confirmed.
4-6-3) The system shall give the user a unique confirmation number.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Specifiche a questo livello di dettaglio sono tediose, prone a errori e &lt;em&gt;molto costose in termini di tempo&lt;/em&gt;. Per sistemi di media grandezza non sono rari documenti di specifica di 300 pagine... estremamente noiose. la conseguenza è che in realtà gli sviluppatori li guardano appena, ma senza leggerli approfonditamente.&lt;/li&gt;
&lt;li&gt;Documenti di questo tipo spingono a pensare ai dettagli implementativi ma &lt;strong&gt;rendono molto difficile avere una visione d&amp;#39;insieme&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;Non importa quanto impegno si mette nel documentare fin nei minimi particolari le caratteristiche del sistema. &lt;strong&gt;Non appena l&amp;#39;utente ha di fronte il software, quasi invariabilmente avrà idee diverse (e migliori)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Le specifiche in questa forma si concentrano sugli &lt;em&gt;attributi del sistema&lt;/em&gt; invece che sulle &lt;em&gt;esigenze dell&amp;#39;utente&lt;/em&gt;. Si viene spinti a considerare il documento di specifica come una &amp;quot;checklist&amp;quot; delle cose da realizzare, e quindi a dichiarare terminato un progetto quando tutti questi requisiti sono soddisfatti. E quando l&amp;#39;utente modifica le sue richieste, la cosa viene classificata come un cambiamento di &lt;em&gt;scope&lt;/em&gt;. In realtà &lt;strong&gt;un softwarè veramente terminato quando l&amp;#39;utente è pienamente soddisfatto&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Use cases&lt;/h2&gt;

&lt;p&gt;In generale uno use case è una descrizione generalizzata dell&amp;#39;interazione tra il sistema e degli attori (che possono essere utenti o altri sistemi).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uno use case in forma estesa contiene dettagli su un&amp;#39;interazione con in più dei &amp;quot;percorsi alternativi&amp;quot; che costituiscono degli &lt;em&gt;scenari&lt;/em&gt; alternativi, in genere per gestire errori. In realtà &lt;strong&gt;uno use case esteso è praticamente equivalente ad una storia con i relativi test di accettazione (che prevedono anche i casi alternativi)&lt;/strong&gt;. Ma...&lt;/li&gt;
&lt;li&gt;Le principali differenze sono la &lt;em&gt;longevità&lt;/em&gt;, la &lt;em&gt;completezza&lt;/em&gt; e lo &lt;em&gt;scopo&lt;/em&gt;: mentre uno use case rappresenta un accordo tra l&amp;#39;utente e il team di sviluppo fatto per essere valido e normativo (a volte gli use case vengono considerati obblighi contrattuali) per tutta la durata del progetto, una &lt;strong&gt;storia rappresenta una conversazione da intrattenere con il cliente e usualmente è utilizzato principalmente ai fini di planning (release, iterazioni)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Gli use case, nella loro forma estesa, sono più soggetti ad essere utilizzati per contenere dettagli sull&amp;#39;interfaccia utente. Il che è chiaramente un male vista la volatilità del design di quest&amp;#39;ultima. Questo è un problema per cui Constantine e Lockwood hanno proposto una soluzione: &lt;em&gt;essential use cases&lt;/em&gt;, ovvero una forma di use case ridotta contenente solo: &lt;strong&gt;intenzioni dell&amp;#39;utente&lt;/strong&gt; e &lt;strong&gt;responsabilità del sistema&lt;/strong&gt;, avvicinandoli molto alle storie.&lt;/li&gt;
&lt;li&gt;Vista la volatilità dei requisiti software, organizzare un contratto attorno a requisiti a questo livello di dettaglio non fa altro che creare difficoltà: &lt;strong&gt;spinge a realizzare il software che l&amp;#39;utente ha chiesto, non quello di cui ha bisogno&lt;/strong&gt;, infatti l&amp;#39;utente raramente ha le idee chiare fin dall&amp;#39;inizio su quello che vuole.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;No matter how much thinking, thinking and thinking we do we can never fully specify a non-trivial system upfront.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Scenari di interazione&lt;/h2&gt;

&lt;p&gt;Uno scenario è in pratica una &amp;quot;storia&amp;quot; (non nel senso di user story) contenente contesto, attori, obiettivi, azioni ed eventi. Si tratta di una descrizione in forma discorsiva di un&amp;#39;interazione di attori umani in un particolare contesto che hanno determinati obiettivi.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Essendo una descrizione discorsiva e in forma di racconto, molti dettagli sono lasciati fuori percui è comunque necessaria una conversazione con il cliente per chiarirli.&lt;/li&gt;
&lt;li&gt;Un singolo scenario ha uno &lt;em&gt;scope&lt;/em&gt; decisamente maggiore di una storia, infatti da uno scenario tipico si possono ricavare diverse storie di solito.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>User Stories Applied, cap. 1</title>
   <link href="http://manuelp.github.com/agile/2009/10/30/user-stories-applied-1.html"/>
   <updated>2009-10-30T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/agile/2009/10/30/user-stories-applied-1</id>
   <content type="html">&lt;p&gt;Inizio con questo post una tradizione alla &lt;a href=&quot;http://www.markhneedham.com/blog/tag/book-club/&quot;&gt;Mark Needham&lt;/a&gt; nella quale i annoterò i punti salienti di libri, paper e presentazioni che mi ritroverò a visionare. Questo principalmente per il fatto che il modo migliore per imparare qualcosa (e sapere se lo si è capito realmente) è &lt;a href=&quot;http://www.markhneedham.com/blog/2009/04/21/learning-through-teaching/&quot;&gt;insegnarlo&lt;/a&gt; a qualcun altro.&lt;/p&gt;

&lt;p&gt;Per esigenze di lavoro ho cominciato a documentarmi sul project management e alla raccolta di requisiti, principalmente in ambito Agile, e mi sono trovato in contatto con l&amp;#39;idea delle &lt;em&gt;user stories&lt;/em&gt;. Il libro che mi sono procurato al riguardo e che sto leggendo attualmente è: &lt;em&gt;&amp;quot;User Stories Applied&amp;quot;&lt;/em&gt; di Mike Cohn.&lt;/p&gt;

&lt;p&gt;Cominciamo con il primo capitolo, intitolato &amp;quot;Groundwork&amp;quot;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ciò che è espresso a parole può essere ambiguo e impreciso. Qualsiasi espressione scritta di requisiti lascerà &lt;em&gt;qualcosa&lt;/em&gt; di ambiguo o imprecisato. Basti pensare a frasi come: &lt;em&gt;&amp;quot;Deve essere possibile inserire password di 127 caratteri.&amp;quot;&lt;/em&gt; Che cosa vuol dire &lt;em&gt;possono&lt;/em&gt;? Significa che in certi casi non è necessario? E devono essere di 127 caratteri? Di più? E di meno? Scendendo sempre più nei particolari non migliora di molto la situazione, ci saranno sempre dei &amp;quot;punti ciechi&amp;quot; e dei particolari mancanti di cui ci si accorge solo durante lo svilupo. &lt;em&gt;L&amp;#39;unica specifica veramente completa in ogni sua parte è il codice sorgente&lt;/em&gt;. Ma &lt;strong&gt;tutta questa confusione semplicemente scompare se si sposta il focus dallo scrivere i requisiti al parlarne&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Spesso i clienti che richiedono un certo software non hanno le idee chiare e &lt;em&gt;non possono&lt;/em&gt; fornire requisiti chiari, stabili e completi fin dall&amp;#39;inizio. Di conseguenza anche se l&amp;#39;analista funzionale è estremamente preciso e diligente nello stilare use case estremamente completi, tutto questo lavoro potrebbe rivelarsi comunque incompleto o semplicemente inesatto rispetto le &lt;em&gt;reali&lt;/em&gt; esigenze del committente. Una volta che il cliente ha qualcosa di funzionante sotto gli occhi sarà in posizione migliore di dire ciò di cui ha bisogno. &lt;strong&gt;Occorre evitare di fare il classico errore di realizzare ciò che il cliente chiede piuttosto che quello di cui ha bisogno.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;user story&lt;/strong&gt; (storia utente) non è altro che una piccola funzionalità che ha valore per l&amp;#39;utente finale. Tradizionalmente scritta su un cartoncino è una semplice frase che indica una funzionalità richiesta &lt;em&gt;dal punto di vista dell&amp;#39;utente&lt;/em&gt; (quindi storie come &amp;quot;Deve essere realizzato in Java&amp;quot; &lt;em&gt;non è&lt;/em&gt; una storia), dovrebbero essere abbastanza piccole da poter essere implementate nel giro di mezza giornata o pochi giorni da uno o due sviluppatori.&lt;/li&gt;
&lt;li&gt;Quando una storia si rivela troppo grande (ad esempio &lt;em&gt;&amp;quot;L&amp;#39;utente deve poter effettuare una prenotazione&amp;quot;&lt;/em&gt;), si definisce &lt;em&gt;Epic&lt;/em&gt; e viene suddivisa in due o più storie più piccole.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Una storia, più che definire una funzionalità la rappresenta&lt;/strong&gt;. Il modo corretto di pensare alle user stories: è come dei &amp;quot;promemoria&amp;quot; di una conversazione da fare con l&amp;#39;utente.&lt;/li&gt;
&lt;li&gt;E&amp;#39; importante capire le &lt;em&gt;aspettative&lt;/em&gt; dell&amp;#39;utente per ogni storia: annotare queste aspettative sotto forma di &lt;strong&gt;test di accettazione&lt;/strong&gt;. L&amp;#39;obiettivo è stabilire dei criteri secondo i quali si potrà dichiarare una storia &amp;quot;completa&amp;quot;. Anche qui non si tratta di essere subito precisi e completi, la precisione verrà raggiunta quando sarà il momento.&lt;/li&gt;
&lt;li&gt;Secondo la definizione di Ron Jeffries, una storia è costituita da tre aspetti: &lt;strong&gt;Card, Conversation e Confirmation&lt;/strong&gt;. Ovvero, la forma fisica della storia (index card), la conversazione che rappresenta e i test di accettazione per sapere quando è completa.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Behavioural-Driven Development</title>
   <link href="http://manuelp.github.com/blog/2009/08/30/behavioural-driven-development.html"/>
   <updated>2009-08-30T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2009/08/30/behavioural-driven-development</id>
   <content type="html">&lt;p&gt;Il &lt;em&gt;Behavioural Driven Development&lt;/em&gt; (&lt;a href=&quot;http://en.wikipedia.org/wiki/Behavior_Driven_Development&quot; title=&quot;Behaviour Driven Development&quot;&gt;BDD&lt;/a&gt;) è essenzialmente il &lt;a href=&quot;http://en.wikipedia.org/wiki/Test_Driven_Development&quot; title=&quot;Test Driven Development&quot;&gt;TDD&lt;/a&gt; fatto correttamente. Il problema è che troppo spesso il TDD è portato avanti in maniera scorretta, principalmente a causa dell&amp;#39;eccessivo &lt;em&gt;focus&lt;/em&gt; sull&amp;#39;aspetto di testing.&lt;/p&gt;

&lt;h2&gt;Perchè Behaviour-Driven?&lt;/h2&gt;

&lt;p&gt;Come &lt;a href=&quot;http://dannorth.net/introducing-bdd&quot; title=&quot;Introducing BDD&quot;&gt;illustrato&lt;/a&gt; da Dan North, il TDD è un&amp;#39;ottimo stile di sviluppo ma è molto facile fraintenderlo focalizzandosi troppo sui test di unità creando un falso senso di sicurezza:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That’s not to say that testing isn’t intrinsic to TDD – the resulting set of methods is an effective way of ensuring your code works. However, if the methods do not comprehensively describe the behaviour of your system, then they are lulling you into a false sense of security.&lt;br/&gt;--Dan North&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Molte delle domande che possono sorgere nella mente di un principiante, ad esempio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Che cosa devo testare?&lt;/li&gt;
&lt;li&gt;Come chiamo questo test?&lt;/li&gt;
&lt;li&gt;In che modo posso testare questa caratteristica?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tutte queste domande, trovano &amp;quot;magicamente&amp;quot; una risposta quando si smette di pensare al &lt;em&gt;testing&lt;/em&gt; e ci si focalizza sul &lt;em&gt;comportamento&lt;/em&gt; che un sistema deve avere.&lt;/p&gt;

&lt;p&gt;Ecco quindi che il BDD si configura prima di tutto come un &amp;quot;re-branding&amp;quot; del TDD (portato avanti tra gli altri da &lt;a href=&quot;http://blog.daveastels.com/files/BDD_Intro.pdf&quot; title=&quot;BDD Intro&quot;&gt;Dave Astels&lt;/a&gt;) e un mutamento di prospettiva per far &amp;quot;afferrare&amp;quot; più facilmente il modo corretto di operare con questa metodologia.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I found the shift from thinking in tests to thinking in behaviour so profound that I started to refer to TDD as BDD, or behaviour- driven development.&lt;br/&gt;--Dan North&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Una conseguenza di questo approccio, è che non è più necessario nè raccomandato avere una classe di test per ogni classe di codice di produzione (ad esempio: &lt;em&gt;Queue&lt;/em&gt; e &lt;em&gt;QueueTest&lt;/em&gt;). Piuttosto di organizzare i &amp;quot;test&amp;quot; per classe interessata, si raggruppano le &amp;quot;specifiche di comportamento&amp;quot; in base alle &lt;em&gt;fixture&lt;/em&gt; (o contesti) nei quali si trovano ad operare.&lt;/p&gt;

&lt;h2&gt;I Vantaggi&lt;/h2&gt;

&lt;p&gt;Enfatizzare il comportamento sul testing provoca un mutamento nel modo di pensare e produce alcuni vantaggi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Si parte dai &lt;em&gt;requisiti&lt;/em&gt;, dalle features da implementare invece che dalle singole classi. Si adotta quindi un approccio top-down che guida la progettazione in base alle caratteristiche richieste. Come conseguenza si aderisce naturalmente al principio &lt;a href=&quot;http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It&quot; title=&quot;You Aren&amp;#39;t Gonna Need It&quot;&gt;YAGNI&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Si sottolinea l&amp;#39;aspetto di &lt;em&gt;design&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Si ottengono delle &lt;strong&gt;specifiche&lt;/strong&gt; che hanno il vantaggio di essere &lt;em&gt;eseguibili&lt;/em&gt;, e che quindi possono essere fatte girare contro la base di codice per verificarne l&amp;#39;aderenza ai requisiti fissati (ecco il testing)&lt;/li&gt;
&lt;li&gt;Permettono lo sviluppo di un &lt;a href=&quot;http://www.c2.com/cgi/wiki?UbiquitousLanguage&quot; title=&quot;Ubiquitous Language&quot;&gt;ubiquitous language&lt;/a&gt; (ovvero di un linguaggio comune tra gli sviluppatori, la parte business e il cliente), integrandosi con il &lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-driven_design&quot; title=&quot;Domain Driven Design&quot;&gt;DDD&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inoltre, seguendo la metodologia BDD si ottengono sia delle specifiche eseguibili (test funzionali e di sistema) sia dei test di unità (applicando la verifica del &lt;em&gt;comportamento&lt;/em&gt; alle singole classi).&lt;/p&gt;

&lt;h2&gt;Strumenti&lt;/h2&gt;

&lt;p&gt;Trattandosi di TDD &amp;quot;fatto come si deve&amp;quot;, è possibile utilizzare qualsiasi libreria che supporti il testing come l&amp;#39;onnipresente xUnit. &lt;/p&gt;

&lt;p&gt;Tuttavia, sono stati sviluppati dei framework che incorporano in concetti del BDD sostituendo ad esempio le parole &amp;quot;test&amp;quot; con &amp;quot;behaviour&amp;quot; o &amp;quot;specification&amp;quot; ad esempio, e fornendo molte altre caratteristiche interessanti come &lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;DSL&lt;/a&gt; appositamente sviluppati (ad esempio usando groovy in &lt;a href=&quot;http://www.easyb.org/&quot;&gt;easyb&lt;/a&gt;) o &lt;a href=&quot;http://martinfowler.com/bliki/FluentInterface.html&quot;&gt;interfacce fluide&lt;/a&gt; (popolarizzate dal pioniere &lt;a href=&quot;http://rspec.info/&quot;&gt;RSpec&lt;/a&gt;), e integrazione di librerie per il &lt;a href=&quot;http://en.wikipedia.org/wiki/Mock_object&quot;&gt;mocking&lt;/a&gt; come &lt;a href=&quot;http://www.jmock.org/&quot;&gt;JMock&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Per Java, ho trovato questi framework più o meno utilizzabili:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://jbehave.org/&quot;&gt;JBehave2&lt;/a&gt;: dal &amp;quot;fondatore&amp;quot; stesso del BDD&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/instinct/&quot;&gt;Instinct&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jdave.org/&quot;&gt;JDave&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sono tutti costruiti al di sopra di JUnit 4, possono quindi di essere fatti girare in un qualunque IDE (oltre che da CLI o Ant ovviamente).&lt;/p&gt;

&lt;h2&gt;Esperienza personale&lt;/h2&gt;

&lt;p&gt;Nel progetto di ingegneria del software a cui ho lavorato abbiamo utilizzato estensivamente l&amp;#39;approccio TDD, rispettando molto il rapporto 1-1 tra classi di test e di codice di produzione.&lt;/p&gt;

&lt;p&gt;Non c&amp;#39;è stato molto focus sul comportamento del sistema nel suo insieme, e nemmeno nei test di integrazione e di sistema. Fortunatamente abbiamo fatto uno studio approfondito e un&amp;#39;attenta progettazione durante tutto il processo di sviluppo, facendo attenzione a modularizzare il più possibile (il TDD ha aiutato in questo senso) quindi l&amp;#39;integrazione non è stato un problema molto grave.&lt;/p&gt;

&lt;p&gt;Probabilmente però, se fossimo partiti dal principio creando delle &lt;em&gt;specifiche&lt;/em&gt;, e usandole per guidare lo sviluppo distribuendo la progettazione lungo il processo e realizzando il prodotto &lt;em&gt;feature-per-feature&lt;/em&gt; creando una versione/demo rilasciabile dopo ogni iterazione, sarebbe stato molto meglio.&lt;/p&gt;

&lt;h2&gt;Update (26/10/2009)&lt;/h2&gt;

&lt;p&gt;Un paio di articolo di Naresh Jain chiariscono molto bene gli effetti e il significato del BDD:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://blogs.agilefaqs.com/2009/10/26/goodbye-simplicity-im-object-obsessed/&quot;&gt;Goodbye Simplicity: I&amp;#39;m Object Obsessed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blogs.agilefaqs.com/2009/06/15/there-is-no-spoon-objects/&quot;&gt;There is No Spoon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Automazione!</title>
   <link href="http://manuelp.github.com/metaprogramming/2009/08/06/automazione.html"/>
   <updated>2009-08-06T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/metaprogramming/2009/08/06/automazione</id>
   <content type="html">&lt;p&gt;Una cosa risaputa è che un buon programmatore deve essere &lt;em&gt;pigro&lt;/em&gt;. Ma di una pigrizia particolare: &lt;em&gt;perchè svolgere a mano ogni compito ripetitivo che può essere svolto altrettanto bene e molto più velocemente da una macchina?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nella mia situazione, complice anche il fatto che sto imparando &lt;a href=&quot;http://ruby-lang.org/it/&quot;&gt;Ruby&lt;/a&gt;, ho automatizzato diverse cose. In particolare, scrivo su un altro &lt;a href=&quot;http://viasenzanome.wordpress.com/&quot;&gt;blog&lt;/a&gt; di sviluppo personale e per un certo periodo ho avuto un dominio apposito con un blog servito dal software &lt;a href=&quot;http://www.s9y.org/&quot; title=&quot;Serendipity Weblog System&quot;&gt;Serendipity&lt;/a&gt; che dopo un anno di attività ho chiuso per ritornare a wordpress.&lt;/p&gt;

&lt;p&gt;Purtroppo (mea culpa) non avevo effettuato il backup del vecchio blog se non tramite uno &amp;quot;snapshot&amp;quot; del sito, quindi mi sono ritrovato con circa un&amp;#39;ottantina di post sotto forma di file html che volevo importare su wordpress. Inutile dire che farlo a mano sarebbe stata un&amp;#39;impresa non da poco...&lt;/p&gt;

&lt;p&gt;Così in un paio di giorni (e un paio di tentativi) ho implementato un programmino di tipo &lt;em&gt;scraper&lt;/em&gt; che per ogni post salvato sotto forma di file html, ne estrae: post, titolo, data di pubblicazione e commenti con relative date, nomi ed eventuali link. Il tutto ripulendo il risultato da blocchi non necessari.&lt;/p&gt;

&lt;p&gt;Con il primo tentativo ho usato estensivamente le espressioni regolari per identificare ed estrarre le aree desiderate, ma si è rivelato un compito abbastanza lungo e anche se alla fine funzionava per alcuni post c&amp;#39;erano dei problemi. Mi serviva una libreria che fosse a conoscenza dell&amp;#39;html e mi consentisse di farne il parsing.&lt;/p&gt;

&lt;p&gt;Con il secondo tentativo, ho utilizzato una stupenda libreria che mi ha permesso di selezionare esattamente i contenuti desiderati e anche di effettuare modifiche: &lt;a href=&quot;http://wiki.github.com/why/hpricot&quot; title=&quot;hpricot&quot;&gt;hpricot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Risultato: una quindicina di minuti circa per postare sul blog originale circa 80 post con la data corretta e tutti i commenti! &lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Overloading in Ruby</title>
   <link href="http://manuelp.github.com/ruby/2009/08/01/overloading-in-ruby.html"/>
   <updated>2009-08-01T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/ruby/2009/08/01/overloading-in-ruby</id>
   <content type="html">&lt;p&gt;A differenza di linguaggi come Java e C++, Ruby &lt;em&gt;non supporta direttamente l&amp;#39;overloading di metodi e costruttori&lt;/em&gt;. Il che è abbastanza grave quando si dimostra necessario disporre di più costruttori con un numero diverso di argomenti.&lt;/p&gt;

&lt;p&gt;Una soluzione in certi casi potrebbe essere quella di usare un design-pattern come il &lt;em&gt;factory method&lt;/em&gt;. In tutti gli altri, fortunatamente, è abbastanza semplice emulare l&amp;#39;overloading grazie al supporto di ruby alle liste di argomenti di lunghezza variabile.&lt;/p&gt;

&lt;p&gt;Un esempio, tratto da &lt;a href=&quot;http://rubylearning.com/satishtalim/ruby_overloading_methods.html&quot;&gt;rubylearning&lt;/a&gt; per chiarire il concetto:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# The Rectangle constructor accepts arguments in either  &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# of the following forms:  &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   Rectangle.new([x_top, y_left], length, width)  &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   Rectangle.new([x_top, y_left], [x_bottom, y_right])  &lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Rectangle&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;  
      &lt;span class=&quot;c1&quot;&gt;# modify this to raise exception, later  &lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'This method takes either 2 or 3 arguments'&lt;/span&gt;  
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;  
        &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Two arguments'&lt;/span&gt;  
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
        &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Three arguments'&lt;/span&gt;  
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;  
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;  
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;Rectangle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;Rectangle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Integrazione Continua</title>
   <link href="http://manuelp.github.com/development/2009/07/27/integrazione-continua.html"/>
   <updated>2009-07-27T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/development/2009/07/27/integrazione-continua</id>
   <content type="html">&lt;p&gt;Terminato oggi un progetto di dimensioni importanti (con ottimi risultati), è tempo di fare una retrospettiva.&lt;/p&gt;

&lt;p&gt;Nel nostro team abbiamo implementato uno stile di sviluppo &lt;a href=&quot;http://en.wikipedia.org/wiki/Test-driven_development&quot; title=&quot;Test-Driven Development&quot;&gt;test-driven&lt;/a&gt;, ma non abbiamo predisposto alcun server di build automatizzato. In principio, anche se interessante, sembrava ridondante... Abbiamo ugualmente portato a termine il progetto, ma se avessimo utilizzato una soluzione di questo tipo, avremmo avuto una serie di vantaggi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Enforcing dell&amp;#39;approccio test-driven&lt;/strong&gt;: nonostante fosse stato stabilito di scrivere i test prima e per ogni funzionalità, in qualche caso non si è rispettata questa decisione. Probabilmente un sistema che compilasse i sorgenti a ogni &lt;em&gt;commit&lt;/em&gt;, che facesse girare tutti i test &lt;strong&gt;automaticamente&lt;/strong&gt; e inviasse un&amp;#39;email a tutti in caso di errori sarebbe stato un aiuto in questo senso.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pacchettizzazione&lt;/strong&gt;: come ambiente di sviluppo abbiamo utilizzato &lt;a href=&quot;http://www.eclipse.org/&quot; title=&quot;Eclipse SDK&quot;&gt;Eclipse&lt;/a&gt;, che assolve egregiamente i suoi compiti compilando automaticamente i sorgenti ad ogni modifica (segnalando eventuali errori di compilazione) e fornendo un&amp;#39;interfaccia a &lt;a href=&quot;http://www.junit.org/&quot; title=&quot;JUnit&quot;&gt;JUnit&lt;/a&gt; per i test. Ma non abbiamo tenuto conto della pacchettizzazione del prodotto finito (&amp;quot;lo faremo alla fine quando sarà ora&amp;quot;). Chiaramente alla fine è stato fatto, ma se avessimo avuto un ciclo di vita &lt;em&gt;evolutivo&lt;/em&gt; con un buon numero di piccole iterazioni e un server di build che si sarebbe occupato di creare una versione pacchettizzata pronta per essere distribuita &lt;em&gt;ad ogni commit&lt;/em&gt;, la vita sarebbe stata molto più semplice. &lt;em&gt;Se il deployment è continuo, è facile attuarlo. Se non lo è, allora probabilmente ci sono brutte sorprese all&amp;#39;orizzonte...&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La lezione è stata imparata.&lt;/p&gt;

&lt;h2&gt;Update: 09/08/2009&lt;/h2&gt;

&lt;p&gt;Per approfondire il discorso sull&amp;#39;integrazione continua, è &lt;em&gt;illuminante&lt;/em&gt; l&amp;#39;&lt;a href=&quot;http://www.martinfowler.com/articles/continuousIntegration.html&quot;&gt;articolo&lt;/a&gt; di Martin Fowler.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Ruby - code blocks, coroutines e closures</title>
   <link href="http://manuelp.github.com/development/2009/07/11/ruby-codeblocks-coruotines-closures.html"/>
   <updated>2009-07-11T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/development/2009/07/11/ruby-codeblocks-coruotines-closures</id>
   <content type="html">&lt;p&gt;Ruby si ispira abbastanza al Perl (purtroppo, l&amp;#39;ho usato un po&amp;#39; ma non mi è mai piaciuto come linguaggio), ma nonostante questo mi sono sforzato di andare avanti a studiarlo. Uno è in grado di giudicare le potenzialità di un linguaggio solo conoscendolo e avendolo utilizzato, questo vale specialmente per quei linguaggi che forniscono &lt;em&gt;features&lt;/em&gt; che non si conoscono e che richiedono un modo di pensare diverso. &lt;/p&gt;

&lt;p&gt;Bisogna respingere la sensazione di &amp;quot;scomodità&amp;quot; che si prova all&amp;#39;inizio ed entrare nell&amp;#39;ottica giusta prima di poterne apprezzare le potenzialità ed esprimere un giudizio informato e non basato unicamente su simpatie/antipatie.&lt;/p&gt;

&lt;h1&gt;Un linguaggio molto dolce&lt;/h1&gt;

&lt;p&gt;Ruby, a differenza di Python e similmente al Perl, fornisce una gran quantità di &lt;em&gt;zucchero sintattico&lt;/em&gt; che porta ad avere più modi diversi per fare una stessa cosa. Infatti molti &amp;quot;entusiasti&amp;quot; del linguaggio parlano spesso di come imparino sempre nuovi modi più eleganti, concisi ed espressivi per esprimere certi concetti (e questo, almeno nel caso del Perl, spesso a discapito della leggibilità).&lt;/p&gt;

&lt;p&gt;Non so ancora se sia una cosa positiva o meno, su questo sospendo il giudizio in attesa di acquisire una conoscenza più approfondita.&lt;/p&gt;

&lt;h1&gt;Coroutines e code-blocks&lt;/h1&gt;

&lt;p&gt;Un paio di features interessanti che fornisce Ruby sono le &lt;em&gt;coroutines&lt;/em&gt; e i &lt;em&gt;code-blocks&lt;/em&gt;, che permettono (tra le altre cose) di implementare in maniera molto concisa ed espressiva degli iteratori e dei &amp;quot;blocchi di codice&amp;quot; da eseguire sotto un controllo transazionale.&lt;/p&gt;

&lt;p&gt;In un linguaggio &amp;quot;tradizionale&amp;quot; come Java, per iterare sugli elementi di una classe collezione si può procede ad esempio così:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lista&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;();&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lista&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lista&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Questo modo di iterare su una collezione è familiare a chi è abituato ad usare linguaggi come C++, Java o anche Python.&lt;/p&gt;

&lt;p&gt;Ruby, attraverso l&amp;#39;uso dei &lt;em&gt;code-blocks&lt;/em&gt;, permette di iterare in modo diverso:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;vi&quot;&gt;@lista&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;vi&quot;&gt;@lista&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;elemento&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;elemento&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Il che è anche abbastanza leggibile una volta fatta l&amp;#39;abitudine:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;    lista: per ogni elemento, scrivilo sulla console
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;.&lt;/p&gt;

&lt;h2&gt;Cosa sono i &lt;em&gt;code block&lt;/em&gt; e le &lt;em&gt;coroutines&lt;/em&gt;?&lt;/h2&gt;

&lt;p&gt;Un &lt;em&gt;code-block&lt;/em&gt; non è altro che un blocco di codice (incredibilmente), delimitato da parentesi graffe o da &lt;em&gt;do-end&lt;/em&gt; che non viene eseguito immediatamente, ma viene messo da parte per essere eseguito in un secondo momento. &lt;/p&gt;

&lt;p&gt;Questo code-block deve essere adiacente ad una chiamata a un metodo, la quale può cedere il controllo al code-block ogni volta che lo desidera tramite il costrutto &lt;code&gt;yield&lt;/code&gt; tutte le volte che lo desidera, eventualmente passandogli parametri e ricevendone.&lt;/p&gt;

&lt;p&gt;A tutti gli effetti il metodo e il code-block sono &lt;em&gt;coroutines&lt;/em&gt;, ovvero funzioni che lavorano &amp;quot;insieme&amp;quot; passandosi la palla l&amp;#39;una con l&amp;#39;altra. La cosa interessante è che a un metodo che utilizza un code-block esterno, può essere passato un blocco qualunque di istruzioni. E&amp;#39; un concetto simile ma più potente e versatile dei puntatori a funzione del C. &lt;/p&gt;

&lt;h3&gt;Esempio: iteratori&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;times&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Questo codice si legge:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;    Per 3 volte: stampa la stringa &quot;Hello, world!&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;times&lt;/code&gt; è la chiamata all&amp;#39;omonimo metodo fornito dal numero 3 (essendo Ruby un linguaggio completamente ad oggetti, è un oggetto di tipo intero) a cui viene associato un code-block che effettua la stampa. Il metodo &lt;code&gt;times&lt;/code&gt; non fa altro che richiamare tante volte &lt;code&gt;yield&lt;/code&gt; quanto è il valore che rappresenta l&amp;#39;oggetto su cui viene richiamato il metodo.&lt;/p&gt;

&lt;p&gt;Si può ottenere lo stesso effetto di prima con una funzione &lt;em&gt;ad-hoc&lt;/em&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call_block&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;call_block&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Un code-block può ricevere parametri dalla routine da cui viene invocata tramite &lt;code&gt;yield&lt;/code&gt;, e similmente riceverne al ritorno, trasformando &lt;code&gt;yield&lt;/code&gt; in una vera e propria chiamata al code-block.&lt;/p&gt;

&lt;p&gt;Inoltre, passando un parametro al code-block, possiamo implementare un iteratore per una classe collezione (analogo al metodo &lt;code&gt;each&lt;/code&gt; del primo esempio) nel modo seguente:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Collezione&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lista&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@collezione&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lista&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@collezione&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@collezione&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;lista&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Collezione&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;lista&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;elemento&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;elemento&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
 

&lt;p&gt;Questo è più o meno il modo in cui sono implementati gli iteratori nella libreria standard di Ruby.&lt;/p&gt;

&lt;p&gt;Diversamente da come illustrato nel design pattern &lt;em&gt;Iterator&lt;/em&gt; della GOF, nel quale l&amp;#39;iteratore è una classe esterna all&amp;#39;oggetto su cui itera e di cui mantiene un riferimento, in Ruby un iteratore viene implementato come un semplice metodo all&amp;#39;interno della classe collezione. Questo a quanto pare rende il mantenere questo tipo di codice più semplice.&lt;/p&gt;

&lt;h3&gt;Esempio: controllo transazionale su file&lt;/h3&gt;

&lt;p&gt;Quando ci si trova a lavorare con dei file (o comunque con delle risorse esterne), è importante anche &lt;em&gt;rilasciare&lt;/em&gt; la risorsa una volta che si è acquisita e si sono effettuate tutte le operazioni necessarie.&lt;/p&gt;

&lt;p&gt;Ad esempio, in Ruby è molto facile leggere il contenuto di un file e stamparlo a video:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;test_file.txt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Anche qui abbiamo usato un code-block (questa volta delimitato da do-end) per iterare sulle linee (delimitate dal carattere &lt;em&gt;newline&lt;/em&gt;) contenute nel file.&lt;/p&gt;

&lt;p&gt;Il difetto di questo approccio è che se ci si dimendica di invocare il metodo &lt;code&gt;close&lt;/code&gt; sul file, questo rimane aperto. Un modo più corretto sarebbe quello di implementare un metodo che apra e chiuda il file, passando il controllo al code-block esterno per processarlo. In questo modo, il metodo che si occupa di aprire il file si occupa anche di chiuderlo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;open_and_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gets&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;open_and_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;test_file.txt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Naturalmente non ho considerato le eccezioni in questo esempio.&lt;/p&gt;

&lt;p&gt;Il risultato è lo stesso, ma ora abbiamo un controllo sulle transazioni su file. Infatti, questo è il comportamento implementato nel metodo &lt;code&gt;File.open&lt;/code&gt;. Se viene fornito un code-block alla chiamata, &lt;code&gt;open&lt;/code&gt; restituisce l&amp;#39;&lt;em&gt;handler&lt;/em&gt; del file al code-block per farlo processare, e al ritorno chiude il file aperto. &lt;/p&gt;

&lt;h1&gt;Closures&lt;/h1&gt;

&lt;p&gt;Un code-block associato ad un metodo può essere memorizzato insieme al &lt;em&gt;contesto&lt;/em&gt; dal quale viene passato per essere invocato in un secondo momento. Per fare questo deve essere convertito in un oggetto &lt;code&gt;Proc&lt;/code&gt; (abbreviazione di &lt;em&gt;procedure&lt;/em&gt;) al cui interno contiene tutte le informazioni sul contesto in cui viene &lt;em&gt;definito&lt;/em&gt; (variabili, metodi, costanti, &lt;em&gt;self&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;In questo modo, il code-block può essere utilizzato anche quando il contesto in cui è stato definito non è più presente. Un linguaggio che supporta questa funzionalità si dice che fornisce le &lt;strong&gt;closures&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Un esempio per illustrare il tutto (tratto dal &lt;a href=&quot;http://rubycentral.com/pickaxe/tut_containers.html&quot;&gt;PickAxe&lt;/a&gt;):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;n_times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;La stampa:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;    69
    92
    Hello Hello Hello 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;La funzione &lt;code&gt;lambda&lt;/code&gt; converte il code-block in un oggetto di tipo &lt;code&gt;Proc&lt;/code&gt; che ritorna al chiamante, con la variabile &lt;code&gt;thing&lt;/code&gt; pari al parametro passato alla funzione contenente il code-block stesso. L&amp;#39;oggetto &lt;code&gt;Proc&lt;/code&gt; poi, dispone del metodo &lt;code&gt;call&lt;/code&gt; per eseguire il code-block memorizzato. &lt;/p&gt;

&lt;p&gt;Vediamo qui che, nonostante il parametro &lt;code&gt;thing&lt;/code&gt; passato alla lambda sia ormai fuori dallo &lt;em&gt;scope&lt;/em&gt; della &lt;code&gt;call&lt;/code&gt;, questo è presente perchè memorizzato nell&amp;#39;oggetto &lt;code&gt;Proc&lt;/code&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Ruby - linguaggio interessante</title>
   <link href="http://manuelp.github.com/development/2009/07/10/ruby-linguaggio-interessante.html"/>
   <updated>2009-07-10T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/development/2009/07/10/ruby-linguaggio-interessante</id>
   <content type="html">&lt;p&gt;Ho una certa conoscenza del linguaggio &lt;a href=&quot;http://www.python.org/&quot;&gt;python&lt;/a&gt;, avendolo già utilizzato per dei progetti personali, ma ho deciso di imparare ad utilizzare in modo soddisfacente un buon linguaggio ad alto livello (o di &lt;em&gt;scripting&lt;/em&gt;, anche se non mi piace molto il termine).&lt;/p&gt;

&lt;p&gt;Data la maggior produttività che linguaggi di questo tipo consentono, possono essere utilizzati per un paio di scopi già da subito:
 - prototipazione
 - automazione&lt;/p&gt;

&lt;h1&gt;Quale linguaggio?&lt;/h1&gt;

&lt;p&gt;La risposta sembrerebbe triviale: conosco già un pò di Python, quindi sarebbe naturale scegliere di approfondirne la conoscenza, complice anche il rilascio del nuovo Python 3.&lt;/p&gt;

&lt;p&gt;Ma sono curioso, e ho sentito molto parlare di questo nuovo linguaggio che arriva dal Sol Levante: &lt;a href=&quot;http://www.ruby-lang.org/&quot;&gt;Ruby&lt;/a&gt;. La &lt;em&gt;killer-application&lt;/em&gt; che ne traina la popolarità è senza dubbio &lt;a href=&quot;http://rubyonrails.org/&quot;&gt;Rails&lt;/a&gt; e ci sono troppe persone che rispetto e che hanno una grande esperienza che ne &lt;a href=&quot;http://martinfowler.com/articles/rubyAtThoughtWorks.html&quot;&gt;parlano&lt;/a&gt; molto bene (&lt;a href=&quot;http://www.pragmaticprogrammer.com/&quot;&gt;I Pragmatici&lt;/a&gt;, &lt;a href=&quot;http://www.objectmentor.com&quot;&gt;Robert Martin&lt;/a&gt; a.k.a &amp;quot;Uncle Bob&amp;quot; e &lt;a href=&quot;http://martinfowler.com/&quot;&gt;Martin Fowler&lt;/a&gt; tra gli altri) per far finta di nulla. &lt;/p&gt;

&lt;p&gt;Questo nonostante il &lt;a href=&quot;http://www.artima.com/weblogs/viewpost.jsp?thread=141312&quot;&gt;parere&lt;/a&gt; di Bruce Eckel (di fama &amp;quot;Thinking in [C++|Java]&amp;quot;) che invece ha scelto Python come suo nuovo &amp;quot;linguaggio preferito&amp;quot;. Al di là di &lt;a href=&quot;http://blog.ianbicking.org/ruby-python-power.html&quot;&gt;confronti&lt;/a&gt; feature-a-feature e &lt;a href=&quot;http://www.cafeaulait.org/oldnews/news2005December8.html&quot;&gt;opinioni&lt;/a&gt; sullo stile di design, sono entrambi linguaggi in evoluzione (come dimostrano Python 3 e Ruby 1.9) e che possono essere appetibili a palati diversi, quindi l&amp;#39;unico modo valido per scegliere il &amp;quot;proprio&amp;quot; è sporcarsi le mani.&lt;/p&gt;

&lt;h1&gt;Conclusione&lt;/h1&gt;

&lt;p&gt;Credo che darò un&amp;#39;occhiata a questo linguaggio e che nel frattempo lo userò per implementare un pò di automazione in quello che faccio ogni giorno, in ogni caso avrò imparato qualcosa e fatto esperienza.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Assert first!</title>
   <link href="http://manuelp.github.com/development/2009/06/27/assert-first.html"/>
   <updated>2009-06-27T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/development/2009/06/27/assert-first</id>
   <content type="html">&lt;p&gt;Attualmente sto terminando la lettura del libro &lt;em&gt;&amp;quot;Test-Driven Development By Example&amp;quot;&lt;/em&gt; di Kent Beck, ed è in mia modesta opinione una lettura molto istruttiva e utile per chi cerca di imparare questo stile di sviluppo. E&amp;#39; di grande beneficio vedere la tecnica all&amp;#39;opera e seguirne l&amp;#39;utilizzo passo-passo (forse l&amp;#39;unico modo per sviluppare un &lt;em&gt;feel&lt;/em&gt; e assimilarne la mentalità), per poi rifinire la propria comprensione con dei &lt;em&gt;pattern&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ho già utilizzato questa tecnica per un progetto complesso sviluppato in un team (oltre che altri side-project personali) e quindi ho una seppur minima esperienza in proposito, ma ci sono ancora diverse finezze, tecniche e pattern che posso applicare per migliorare la mia capacità di sviluppare sistemi guidato dai test.&lt;/p&gt;

&lt;p&gt;Un&amp;#39;idea nuova che non ho mai utilizzato è quella di &lt;strong&gt;scrivere &lt;em&gt;prima&lt;/em&gt; gli assert in un test&lt;/strong&gt;. La motivazione di questo accorgimento deriva dal vedere i test come un modo per guidare lo sviluppo delle funzionalità che un sistema deve avere. &lt;/p&gt;

&lt;p&gt;In pratica, un &lt;em&gt;sistema&lt;/em&gt; è composto da diverse &lt;em&gt;funzionalità&lt;/em&gt;, ognuna delle quali deve essere soggetta a diversi &lt;em&gt;test&lt;/em&gt;, ognuno dei quali a sua volta contiene delle &lt;em&gt;asserzioni&lt;/em&gt;. La funzione delle asserzioni è molteplice, ma quelle che ci interessano in questa sede sono essenzialmente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Qual&amp;#39;è la risposta corretta?&lt;/li&gt;
&lt;li&gt;Come posso controllarla?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cominciare a scrivere un test partendo dalle asserzioni (che normalmente in un test completo si collocano alla fine del test-case: test pattern &lt;em&gt;arrange-do-check&lt;/em&gt;) fissiamo subito quali sono le funzionalità sotto test, qual&amp;#39;è la loro forma e sintassi e come devono rispondere. A partire da questa conoscenza possiamo costruire il test-case scrivendo tutte le operazioni necessarie per ottenere quel risultato.&lt;/p&gt;

&lt;h1&gt;Un esempio&lt;/h1&gt;

&lt;p&gt;(Tratto da: &lt;em&gt;&amp;quot;Test-Driven Development By Example&amp;quot;&lt;/em&gt;, Kent Beck)&lt;/p&gt;

&lt;p&gt;Supponiamo di voler comunicare con un altro sistema attraverso un socket. Quando abbiamo terminato la comunicazione il socket deve essere chiuso e deve essere stata trasmessa e ricevuta con successo la stringa &amp;quot;abc&amp;quot;.&lt;/p&gt;

&lt;p&gt;Cominciamo con le asserzioni:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testCompleteTransaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isClosed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Il &lt;em&gt;reply&lt;/em&gt; viene da un socket:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testCompleteTransaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;Buffer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isClosed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Il socket lo creiamo connettendoci al server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testCompleteTransaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;Socket&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Socket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defaultPort&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;Buffer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isClosed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;E infine (o in principio) dobbiamo connetterci al server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testCompleteTransaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;Server&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;defaultPort&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;Socket&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Socket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defaultPort&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;Buffer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isClosed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</content>
 </entry>
 
 <entry>
   <title>Campagna per il pensionamento di IE6</title>
   <link href="http://manuelp.github.com/web/2009/06/11/campagna-pensionamento-ie6.html"/>
   <updated>2009-06-11T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/web/2009/06/11/campagna-pensionamento-ie6</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.bringdownie6.com/&quot;&gt;
   &lt;img src=&quot;/images/bdie6.png&quot; alt=&quot;logo della campagna bring down IE6&quot; style=&quot;float:right&quot;/&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo periodo sto studianto le tecnologie web per un progetto a
cui partecipo, e non c&amp;#39;è libro sul CSS in cui mi imbatta che non
contenga quasi ad ogni capitolo un riferimento a come qualche
versione di &lt;em&gt;Internet Explorer&lt;/em&gt; (almeno la versione 6 e precedenti)
interpreti erroneamente, o addirittura manchi totalmente del
supporto a, molte delle funzionalità richieste per il moderno web.&lt;/p&gt;

&lt;p&gt;Si parla di proprietà CSS e anche di bug veri e propri che
costringono gli sviluppatori e i designer di siti web a spendere
un&amp;#39;incredibile quantità di tempo a sviluppare &lt;em&gt;hacks&lt;/em&gt; per
costringere IE a renderizzare la pagina correttamente come tutti
gli altri browser (moderni o meno).&lt;/p&gt;

&lt;p&gt;IE6 è un browser vecchio di otto anni ormai, ma purtroppo una fetta
ancora non trascurabile del mercato (i dati parlano di una percentuale
di circa il 20% delle connessioni totali), probabilmente perlopiù
costituita da utenti business su macchine (ad esempio equipaggiate con
windows 2000) che non possono fare un upgrade. E questo è &lt;strong&gt;un vero e
proprio ostacolo&lt;/strong&gt; allo sviluppo del web, essenzialmente per due
ragioni:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gli sviluppatori&lt;/strong&gt; di siti devono spendere molto tempo (circa un
terzo del tempo totale) a cercare di aggirare i bug e le mancanze
di IE6 quando il sito viene renderizzato già perfettamente da tutti
gli altri browser (perchè più rispettosi degli standard). &lt;em&gt;In altre
parole sono un bel pò di soldi spesi ad aggirare le mancanze di un
browser obsoleto&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gli utenti&lt;/strong&gt; non possono godere appieno delle nuove potenzialità del
web. Provate ad andare su Facebook, o ad usare GMail o 37Signals
con IE6...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ecco perchè è nata una [campagna][bdie6] per spingere l&amp;#39;upgrade a browser più
moderni (anche ad un&amp;#39;altra versione di IE, solo più recente). Dalla
dichiarazione d&amp;#39;intenti della campagna (la traduzione è mia, ora sapete
chi incolpare per gli errori):&lt;/p&gt;

&lt;p&gt;[bdie6]: http://www.bringdownie6.com/ &amp;quot;campagna: Bring Down IE6&amp;quot;    &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;La premessa è semplice: Internet Explorer 6 è antiquato, non
supporta standard web chiave, e dovrebbe essere pensionato. Questo
non riguarda l&amp;#39;essere anti-Microsoft, piuttosto riguarda la mancanza
di sviluppo del mercato dei browser da parte di Microsoft. Con IE7/8
non disponibili per Windows 2000, IE6 conta circa per un 20%
dell&amp;#39;uso del web, principalmente da parte di utenti business. I
clienti fanno pressioni sui designer per &amp;quot;contringere&amp;quot; i siti a
funzionare con IE6, e i designer, non volendo perdere affari,
obbediscono, usando trucchetti e aggirando i problemi. Questa è una
perdita di tempo e denaro. Microsoft deve sistemare questa
situazione, i designer devono unirsi, e noi dobbiamo passare oltre.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Il dover avere a che fare con sistemi &lt;em&gt;legacy&lt;/em&gt; non è una cosa nuova,
accade continuamente ed è una conseguenza dell&amp;#39;avere un mercato con
una grande inerzia ai cambiamenti. Ma quando questo significa solo uno
spreco di soldi e di tempo come in questo caso, evitabile in modo
&lt;a href=&quot;http://www.getfirefox.com/&quot; title=&quot;Scarica Mozilla Firefox&quot;&gt;piuttosto&lt;/a&gt; &lt;a href=&quot;http://www.google.com/chrome&quot; title=&quot;Scarica Google Chrome&quot;&gt;semplice&lt;/a&gt;, allora occorre spingere per andare avanti e
disfarsi di una tecnologia obsoleta.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;IE6 is the new Netscape 4. The hacks needed to support IE6 are
increasingly viewed as excess freight. Like Netscape 4 in 2000, IE6 is
perceived to be holding back the web.&amp;quot; &lt;br/&gt;
--&lt;a href=&quot;http://www.zeldman.com/&quot; title=&quot;Il sito personale di Jeffrey Zeldman&quot;&gt;Jeff Zeldman&lt;/a&gt;, standards guru&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Web Software Engineering?</title>
   <link href="http://manuelp.github.com/web/2009/06/07/web-software-engineering.html"/>
   <updated>2009-06-07T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/web/2009/06/07/web-software-engineering</id>
   <content type="html">&lt;p&gt;Ultimamente sto facendo pratica con la programmazione orientata al web (come
noterai dall&amp;#39;argomento dei post precedenti).&lt;/p&gt;

&lt;p&gt;La mia impressione è che mentre per il software tradizionale abbiamo ormai una
certa esperienza e conosciamo molti &lt;em&gt;pattern&lt;/em&gt; e &lt;em&gt;best-practices&lt;/em&gt; da applicare,
nel caso della programmazione web &lt;a href=&quot;http://www.e-gineer.com/articles/design-patterns-in-web-programming.phtml&quot; title=&quot;Articolo di Nathan Wallace&quot;&gt;non è proprio così&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ci sono alcune soluzioni e metodologie di sviluppo mutuate dalla controparte
stand-alone che possiamo &lt;a href=&quot;http://www.clientcide.com/best-practices/jquery-and-the-ajax-experience-programming-to-the-pattern-and-what-really-makes-one-framework-different-from-another/&quot;&gt;applicare&lt;/a&gt;, alcuni principi che rimangono utili
(riuso, interoperabilità, estendibilità, ecc.) ma ci sono anche nuove sfide da
affrontare e molte cose da scoprire che sono peculiari di questo &amp;quot;ambiente di
sviluppo&amp;quot;.&lt;/p&gt;

&lt;p&gt;Se l&amp;#39;ingegneria del software è una disciplina giovane,
l&amp;#39;applicazione di questa disciplina al web lo è ancora di più. Il
web è una piattaforma che consente possibilità non facilmente disponibili per
il software desktop: probabilmente siamo solo all&amp;#39;inizio e, secondo la mia
attuale ingenua visione, il futuro si rivelerà decisamente interessante :) &lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Google Wave!</title>
   <link href="http://manuelp.github.com/web/2009/06/07/google-wave-un-anteprima.html"/>
   <updated>2009-06-07T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/web/2009/06/07/google-wave-un-anteprima</id>
   <content type="html">&lt;p&gt;C&amp;#39;è &lt;em&gt;molto&lt;/em&gt; &lt;a href=&quot;http://www.google.it/search?q=google+wave&quot; title=&quot;Pagine su Google Wave&quot;&gt;fermento&lt;/a&gt; dietro il fenomeno &lt;a href=&quot;http://wave.google.com/&quot; title=&quot;Google Wave&quot;&gt;Google Wave&lt;/a&gt; che potrebbe &lt;strong&gt;&lt;a href=&quot;http://wave.google.com/help/wave/about.html&quot; title=&quot;About Google Wave&quot;&gt;rivoluzionare&lt;/a&gt; il modo di comunicare e collaborare online&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Bando alle ciance ed ecco la presentazione ufficiale:&lt;/p&gt;

&lt;p&gt;&lt;object width=&quot;560&quot; height=&quot;340&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/v_UyVmITiYQ&amp;hl=it&amp;fs=1&amp;&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/v_UyVmITiYQ&amp;hl=it&amp;fs=1&amp;&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;560&quot; height=&quot;340&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;Sarà rilasciato al pubblico nel corso di quest&amp;#39;anno, ma sono già disponibili le &lt;a href=&quot;http://code.google.com/apis/wave/&quot; title=&quot;Google Wave API&quot;&gt;API&lt;/a&gt; per integrare Wave con le proprie applicazioni e siti web e il sito dedicato al &lt;a href=&quot;http://waveprotocol.org/&quot; title=&quot;Wave Federation Protocol&quot;&gt;protocollo&lt;/a&gt; sottostante.&lt;/p&gt;

&lt;p&gt;Si prospettano tempi eccitanti :)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Cos'è AJAX?</title>
   <link href="http://manuelp.github.com/web/2009/06/06/cose-ajax.html"/>
   <updated>2009-06-06T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/web/2009/06/06/cose-ajax</id>
   <content type="html">&lt;p&gt;AJAX è l&amp;#39;acronimo di &lt;em&gt;Asynchronous Javascript And XML&lt;/em&gt; e indica una tecnica per
permettere di costruire applicazioni web paragonabili a quelle stand-alone che
utilizziamo normalmente.&lt;/p&gt;

&lt;h1&gt;L&amp;#39;utilità di AJAX&lt;/h1&gt;

&lt;p&gt;Un&amp;#39;applicazione web tradizionale solitamente costruisce una pagina web che
invia al client. Questo compie delle azioni (riempie form, clicca dei link,
ecc.) che vengono inviate al server come richieste http, il quale le elabora e
costruisce una nuova pagina web che ritrasmette al client.&lt;/p&gt;

&lt;p&gt;Questo modello funziona, ma ha l&amp;#39;inconveniente di essere &lt;em&gt;sincrono&lt;/em&gt;: da quando
l&amp;#39;utente invia una richiesta a quando il server risponde con una nuova pagina,
l&amp;#39;utente non può far altro che aspettare. &lt;/p&gt;

&lt;p&gt;Il meccanismo funziona per un web che è stato pensato per gli ipertesti ma non
è più sufficiente per le esigenze moderne di applicativi costruiti sul web
stesso. Applicativi che necessitano di essere &lt;em&gt;responsivi&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Alcuni esempi di applicazioni web molto usate costruite con questa tecnica
sono: &lt;a href=&quot;http:///www.gmail.com/&quot; title=&quot;GMail&quot;&gt;GMail&lt;/a&gt;, &lt;a href=&quot;http://maps.google.com/&quot; title=&quot;Google Maps&quot;&gt;Google Maps&lt;/a&gt; e &lt;a href=&quot;http://docs.google.com/&quot; title=&quot;Google Docs&quot;&gt;Google Docs&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;Da cosa è costituito&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;XHTML e CSS: per la &lt;a href=&quot;http://adaptivepath.com/publications/essays/archives/000266.php&quot;&gt;presentazione&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.scottandrew.com/weblog/articles/dom_1&quot;&gt;DOM&lt;/a&gt;: per il layout dinamico e l&amp;#39;interazione con la pagina&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www-106.ibm.com/developerworks/xml/library/x-xslt/?article=xr&quot;&gt;XML e XSLT&lt;/a&gt;: scambio e manipolazione dati&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.xml.com/pub/a/2005/02/09/xml-http-request.html&quot;&gt;XMLHttpRequest&lt;/a&gt;: recupero asincrono dei dati&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.crockford.com/javascript/javascript.html&quot;&gt;Javascript&lt;/a&gt;: collante per tutte le tecnologie precedenti&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;Come funziona&lt;/h1&gt;

&lt;p&gt;AJAX è stato creato per consentire alle applicazioni web un dialogo &lt;em&gt;asincrono&lt;/em&gt;
tra client e server minimizzando così il tempo di risposta percepito
dall&amp;#39;utente.&lt;/p&gt;

&lt;p&gt;In pratica si tratta di interporre tra il browser del client e la rete nella
quale si trova il server un &lt;em&gt;motore AJAX&lt;/em&gt;, che consente all&amp;#39;utente di
interagire con l&amp;#39;applicazione web direttamente senza aspettare la risposta del
server.&lt;/p&gt;

&lt;h2&gt;Dialogo client/server asincrono&lt;/h2&gt;

&lt;p&gt;Per certi compiti come la validazione dell&amp;#39;input e l&amp;#39;elaborazione di alcune
informazioni, il motore AJAX può cavarsela da solo. In tutti gli altri casi in
cui è richiesta una risposta dal server, è il motore stesso che si occupa del
dialogo consentendo all&amp;#39;utente di continuare ad interagire con l&amp;#39;applicazione
mentre si è in attesa della risposta.&lt;/p&gt;

&lt;p&gt;Il dialogo poi si svolge solitamente attraverso frammenti XML, senza
il bisogno di ricaricare (e ritrasmettere attraverso la rete) l&amp;#39;intera pagina.&lt;/p&gt;

&lt;p&gt;E&amp;#39; questo in sostanza che consente al sistema di fornire all&amp;#39;utente un tempo di
risposta inferiore, simile a quello di un&amp;#39;applicazione desktop. Qui però &lt;strong&gt;la
velocità di un applicativo non è più determinata principalmente dalla velocità
del sistema, ma dalla velocità della rete.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;La maggiore sfida che Ajax pone davanti ai nostri occhi non riguarda la
risoluzione dei problemi tecnici da esso derivati, ma il dimenticare tutte le
limitazioni che riguardavano il Web, per lanciarsi verso la creazione di
applicazioni robuste, veloci e sempre più simili alle applicazioni
Desktop. &lt;br/&gt;
--Jesse James Garrett, &lt;a href=&quot;http://adaptivepath.com/publications/essays/archives/000385.php&quot;&gt;Ajax: a new approach to web applications&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;Credits&lt;/h1&gt;

&lt;p&gt;Grazie a Daniele Simonin per la sua &lt;a href=&quot;http://read.melodycode.com/tutorials/158/ajax_un_nuovo_approccio_per_le_applicazioni_web.html&quot;&gt;traduzione&lt;/a&gt; dell&amp;#39;&lt;a href=&quot;http://adaptivepath.com/publications/essays/archives/000385.php&quot;&gt;articolo&lt;/a&gt; di Jesse James Garrett.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Riflessioni sul cloud computing</title>
   <link href="http://manuelp.github.com/web/2009/06/05/riflessioni-sul-cloud-computing.html"/>
   <updated>2009-06-05T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/web/2009/06/05/riflessioni-sul-cloud-computing</id>
   <content type="html">&lt;p&gt;Ultimamente si fa un gran parlare di &lt;a href=&quot;http://it.wikipedia.org/wiki/Cloud_computing&quot; title=&quot;Cloud Computing secondo wp&quot;&gt;Cloud Computing&lt;/a&gt;, e di come questo
&amp;quot;nuovo&amp;quot; modo di intendere il software come un servizio (&lt;a href=&quot;http://en.wikipedia.org/wiki/Software_as_a_Service&quot; title=&quot;Software As A Service&quot;&gt;SaaS&lt;/a&gt;) possa essere
conveniente o meno.&lt;/p&gt;

&lt;h1&gt;I pro&lt;/h1&gt;

&lt;p&gt;I vantaggi di un modello del genere sono presto detti: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;non c&amp;#39;è alcun bisogno di predisporre datacenter&lt;/li&gt;
&lt;li&gt;non occorre occuparsi del &lt;em&gt;deployment&lt;/em&gt; e della messa in sicurezza&lt;/li&gt;
&lt;li&gt;non occorre pagare personale interno che li amministri&lt;/li&gt;
&lt;li&gt;tutto il software è direttamente accessibile mediante il browser&lt;/li&gt;
&lt;li&gt;i dati sono nella &lt;em&gt;cloud&lt;/em&gt; e accessibili (previa autenticazione) da qualunque
parte del mondo e da qualunque pc&lt;/li&gt;
&lt;li&gt;basta un pc depotenziato come un netbook per accedere a questi servizi (anche
computazionalmente intensi)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quindi i software sono forniti come un servizio, unitamente alla loro gestione
per cui un utente non occorre che si preoccupi di altre problematiche aldilà
del loro utilizzo. Si tratta di un ulteriore passo verso l&amp;#39;&lt;em&gt;outsourcing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Esempi di questi servizi sono &lt;a href=&quot;http://www.gmail.com&quot; title=&quot;GMail&quot;&gt;GMail&lt;/a&gt; e &lt;a href=&quot;http://www.facebook.com&quot; title=&quot;Facebook&quot;&gt;Facebook&lt;/a&gt;, che sono diventati
molto popolari e che hanno aumentato di molto l&amp;#39;efficienza e la produttività
(almeno per quanto riguarda GMail).&lt;/p&gt;

&lt;h1&gt;I contro&lt;/h1&gt;

&lt;p&gt;Ma se da una parte il cloud computing è molto comodo perchè solleva dalla
necessità di installazioni e configurazioni varie, dall&amp;#39;altra fa sorgere un
problema di fiducia e di sicurezza in generale, come fa notare
&lt;a href=&quot;http://www.schneier.com/blog/archives/2009/06/cloud_computing.html&quot; title=&quot;Articolo di Bruce Schneier sul Cloud Computing&quot;&gt;Bruce Schneier&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Sicurezza&lt;/h2&gt;

&lt;p&gt;Mentre posso gestire autonomamente il software installato in locale
predisponendo misure di sicurezza come firewall e ambienti di esecuzione
controllata, nel caso di SaaS sono completamente in balia del provider di quel
software.&lt;/p&gt;

&lt;p&gt;Senza contare che se uso un software a codice chiuso e che viene eseguito per
di più su macchine remote, non posso essere sicuro che il servizio in questione
non faccia di più di quello che dichiara. Di conseguenza sarei portato a
fidarmi di più di un servizio basato su software &lt;em&gt;open-source&lt;/em&gt; e di &lt;em&gt;standard condivisi&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Privacy&lt;/h2&gt;

&lt;p&gt;Se utilizzo il cloud computing, utilizzo un software in cui immetto i miei dati
che vengono memorizzati in maniera distribuita su server del gestore del
servizio. In pratica sto a tutti gli effetti fornendo miei dati a una compagnia
esterna che può essere o meno affidabile. Non ho nessun controllo sulle misure
di sicurezza di quella compagnia che potrebbe anche avere accesso ai miei
dati, o che potrebbe essere compromessa con relativo furto di informazioni.&lt;/p&gt;

&lt;p&gt;E se quella compagnia ad esempio va in &lt;a href=&quot;http://www.eweekeurope.co.uk/news/cloud-computing-forerunner-facing-bankruptcy-772&quot; title=&quot;Articolo di eweekeurope&quot;&gt;bancarotta&lt;/a&gt; o subisce dei guasti, posso &lt;a href=&quot;http://www.techcrunch.com/2009/01/03/journalspace-drama-all-data-lost-without-backup-company-deadpooled/&quot; title=&quot;Articolo su TechCrunch&quot;&gt;perdere
completamente i miei dati&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Inoltre, se i servizi sono accentrati in un&amp;#39;unica piattaforma, &lt;strong&gt;un&amp;#39;eventuale
compromissione e furto d&amp;#39;identità potrebbero causare danni molto ingenti&lt;/strong&gt;. Prova
a immaginare a un ipotetico servizio che fornisse al tempo stesso email,
piattaforma per lo sviluppo di documenti, blog, gruppi di discussione e
conversazioni in tempo reale (suona familiare?). Immagina che venga
compromesso e che qualche persona senza scrupoli si impadronisca del tuo account. A
quel punto avrebbe accesso alle tue email, documenti e contatti e le sue azioni
avrebbero una portata enorme sia sulla tua vita lavorativa che personale...&lt;/p&gt;

&lt;p&gt;Certo, possono essere adottate misure di sicurezza come crittografia (sia a
livello di connessione con https che di storage con AES ad esempio),
autenticazione e backup. Ma il punto rimane che il controllo ultimo sulla
configurazione e controllo del sistema rimane al fornitore. &lt;strong&gt;E i tuoi dati sono
in quel sistema&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;Lock-in&lt;/h2&gt;

&lt;p&gt;Quando i dati risiedono su server di terze parti, oltre alle problematiche
della sicurezza e della privacy occorre preoccuparsi della &lt;strong&gt;portabilità&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Non basta che il fornitore abbia una buona infrastruttura di sicurezza, usi la
crittografia, e abbia dei sistemi di backup. Occorre che i dati che io immetto
nel sistema li possa recuperare in ogni momento e integralmente, e devo essere
sicuro che quando li cancello vengano eliminati realmente (non come nel caso di
&lt;a href=&quot;http://punto-informatico.it/2602790/PI/Commenti/niente-privacy-benvenuti-facebook.aspx&quot; title=&quot;La finta cancellazione di Facebook&quot;&gt;Facebook&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Si tratta in altre parole di avere il controllo completo sui propri dati, in
caso contrario subiamo l&amp;#39;odioso &lt;em&gt;vendor lock-in&lt;/em&gt; che stiamo solo ora
cominciando a superare nel campo delle suite office e delle pubbliche
amministrazioni.&lt;/p&gt;

&lt;h1&gt;Pay-per-use&lt;/h1&gt;

&lt;p&gt;Non potendolo classificare come pro o contro, c&amp;#39;è comunque da considerare questo
aspetto.&lt;/p&gt;

&lt;p&gt;Il cloud computing permette nuovi modelli di business, tra i quali c&amp;#39;è il
richiedere un corrispettivo per la fornitura di risorse e software in una
cloud. Questo può essere un aspetto positivo per il fornitore e per l&amp;#39;utente
(migliore servizio), ma può anche non esserlo, dipende dai punti di vista.&lt;/p&gt;

&lt;h1&gt;Riflessione&lt;/h1&gt;

&lt;p&gt;Il cloud computing per come è nato ha proprio gli obiettivi di tagliare i costi
di gestione, incrementare la facilità di accesso e la produttività. Però ci sono
anche delle problematiche di sicurezza e di &lt;em&gt;fiducia&lt;/em&gt; che emergono da questa
architettura. &lt;/p&gt;

&lt;p&gt;E&amp;#39; anche vero che si possono avere i vantaggi del Cloud Computing in una
&lt;em&gt;intranet&lt;/em&gt;, mantenendo il controllo sui propri dati e conservando la comodità
della centralizzazione di accesso e utilizzando storage e risorse di calcolo distribuite. 
Ma al costo di sacrificare l&amp;#39;accesso globale (a meno di non predisporre VPN) e di
re-introdurre i costi di gestione di un datacenter. &lt;/p&gt;

&lt;p&gt;Bisogna stare attenti di chi fidarsi e per cosa. I meccanismi del mercato
dovrebbero spingere i fornitori a erogare un servizio di qualità, ma &lt;strong&gt;quello che
si guadagna in comodità e risparmio, lo si può perdere in privacy,
sicurezza e flessibilità&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Trust is a concept as old as humanity, and the solutions are the same as they
have always been. Be careful who you trust, be careful what you trust them
with, and be careful how much you trust them. Outsourcing is the future of
computing. Eventually we&amp;#39;ll get this right, but you don&amp;#39;t want to be a
casualty along the way.&lt;br/&gt;
--Bruce Schneier&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>JDK7 - piattaforma modulare multi-linguaggio</title>
   <link href="http://manuelp.github.com/java/2009/06/04/jdk7-piattaforma-modulare-multilinguaggio.html"/>
   <updated>2009-06-04T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/java/2009/06/04/jdk7-piattaforma-modulare-multilinguaggio</id>
   <content type="html">&lt;p&gt;Secondo un articolo di &lt;a href=&quot;http://infoworld.com/print/77919&quot;&gt;InfoWorld&lt;/a&gt;, la nuova
nuova versione del JDK Sun adotterà un design più modulare che supporterà la
versione 7 del linguaggio Java. E questo porterà, secondo Mark Reinhold
(ingegnere principale dietro Java SE e &lt;a href=&quot;http://openjdk.java.net/&quot; title=&quot;OpenJDK&quot;&gt;OpenJDK&lt;/a&gt;) a una serie di vantaggi.&lt;/p&gt;

&lt;h2&gt;Classpath will be dead&lt;/h2&gt;

&lt;p&gt;La modularità verrà raggiunta attraverso il progetto &lt;a href=&quot;http://www.w3.org/Jigsaw/&quot; title=&quot;Progetto Jigsaw&quot;&gt;Jigsaw&lt;/a&gt;, che permetterà
agli sviluppatori di sviluppare i propri moduli e di eliminare la necessità del
&lt;em&gt;classpath&lt;/em&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Class path is dead,&amp;quot; Reinhold said.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Un JDK per domarli tutti &lt;/h2&gt;

&lt;p&gt;La modularizzazione potrebbe portare anche ad
una singola versione di Java, dato la capacità di un sistema del genere di
adattarsi all&amp;#39;ambiente in cui si trova ad essere eseguito.&lt;/p&gt;

&lt;h2&gt;Piattaforma multi-linguaggio&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;We&amp;#39;re working to define a modular form of the Java platform and its
implementation; we&amp;#39;re working to evolve the Java Virtual  Machine into a true,
multilingual universal runtime for high-level languages; and finally, we&amp;#39;re
doing things to make developers more productive,&amp;quot; said Mark Reinhold,
principal engineer for Java SE and OpenJDK.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aspetto per me decisamente più importante. Per come la vedo io, l&amp;#39;uso di un
ambiente di esecuzione per &lt;em&gt;codice managed&lt;/em&gt; che permetta a programmi scritti in
linguaggi diversi di comunicare e cooperare tra loro, in un&amp;#39;ambiente comune e
con un set standard di librerie, è una carta vincente.&lt;/p&gt;

&lt;p&gt;Già ora esistono soluzioni simili, le più famose delle quali sono il &lt;a href=&quot;http://en.wikipedia.org/wiki/Common_Language_Runtime&quot;&gt;CLR&lt;/a&gt;
della piattaforma .Net e appunto il JRE che già ora supporta un gran numero di
linguaggi anche molto diversi tra loro come &lt;a href=&quot;http://www.scala-lang.org/&quot; title=&quot;Scala&quot;&gt;Scala&lt;/a&gt;, &lt;a href=&quot;http://groovy.codehaus.org/&quot; title=&quot;Groovy&quot;&gt;Groovy&lt;/a&gt;,
&lt;a href=&quot;http://clojure.org/&quot; title=&quot;Clojure&quot;&gt;Clojure&lt;/a&gt;, &lt;a href=&quot;http://www.jython.org/&quot; title=&quot;Jython&quot;&gt;Jython&lt;/a&gt; e &lt;a href=&quot;http://jruby.codehaus.org/&quot;&gt;JRuby&lt;/a&gt; per citarne alcuni.&lt;/p&gt;

&lt;h2&gt;Crescente uso delle annotazioni&lt;/h2&gt;

&lt;p&gt;Per facilitare il compito dei &lt;em&gt;checker statici&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Conclusioni&lt;/h2&gt;

&lt;p&gt;Con queste nuove modifiche la piattaforma Java potrebbe diventare a tutti gli
effetti un ambiente di esecuzione in grado di supportare una gran varietà di
necessità, linguaggi e stili di sviluppo, il tutto garantendone
l&amp;#39;interoperabilità e l&amp;#39;esecuzione controllata.&lt;/p&gt;

&lt;p&gt;Tutte caratteristiche che secondo me potrebbero diventare irrinunciabili in
molti settori.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>L'importanza della pianificazione</title>
   <link href="http://manuelp.github.com/management/2009/06/02/l-importanza-della-pianificazione.html"/>
   <updated>2009-06-02T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/management/2009/06/02/l-importanza-della-pianificazione</id>
   <content type="html">&lt;blockquote&gt;
&lt;p&gt;Proceed from a plan, whether that plan is in your head, on the back of a
cocktail napkin, or on a wall-sized printout from a CASE tool.&lt;br/&gt;
--&amp;quot;The Pragmatic Programmer&amp;quot;, Andrew Hunt, David Thomas&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Iniziare un progetto senza uno straccio di piano è una ricetta per il
fallimento, o quantomeno per un&amp;#39;efficientissima fonte di mal di testa.&lt;/p&gt;

&lt;p&gt;Non si tratta di pianificare ogni minimo dettaglio fin dal principio. Questo è
controproducente (al di là di casi particolari come i programmi che equipaggiano
lo space shuttle). Ma non si tratta nemmeno dell&amp;#39;estremo opposto: procedere,
praticamente, &lt;em&gt;a caso&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Alcuni proponenti dell&amp;#39;approccio &lt;a href=&quot;http://it.wikipedia.org/wiki/Metodologia_agile&quot;&gt;agile&lt;/a&gt; erroneamente portano all&amp;#39;estremo il
concetto di &lt;a href=&quot;http://en.wikipedia.org/wiki/Self-organization&quot;&gt;self-organization&lt;/a&gt;, sostenendo in maniera più o meno implicita
una generale antipatia per la pianificazione. &lt;/p&gt;

&lt;h1&gt;Tecnologia&lt;/h1&gt;

&lt;p&gt;Nell&amp;#39;ambito tecnologico possiamo vedere questa &amp;quot;lotta&amp;quot; ad esempio a livello di
progettazione. &lt;/p&gt;

&lt;p&gt;Da una parte abbiamo i proponenti del &lt;a href=&quot;http://en.wikipedia.org/wiki/Big_Design_Up_Front&quot; title=&quot;Big Design Up-Front&quot;&gt;BDUF&lt;/a&gt;, che sostengono una specifica
completa e dettagliata &lt;em&gt;prima di cominciare a codificare&lt;/em&gt;. Il che nella
stragrande maggioranza dei casi significa perdere tempo in dettagli minuziosi
basati su assunzioni non verificate, per poi scoprire che la soluzione non
funziona o che ce ne sono di migliori e più eleganti, a cui non si arriva se
non avendo sott&amp;#39;occhio il codice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Life is what happens to you while you are busy making other plans.&lt;br/&gt;
--John Lennon&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dall&amp;#39;altra abbiamo certi &amp;quot;agilisti&amp;quot; (partigiani) che aborriscono qualsiasi
forma di pianificazione e preferiscono lanciarsi nella codifica &amp;quot;lasciando che
il design si riveli ed evolva da sè grazie ai test&amp;quot;. Uhm...&lt;/p&gt;

&lt;p&gt;Come fa notare &lt;a href=&quot;http://blog.objectmentor.com/articles/2009/04/25/the-scatology-of-agile-architecture&quot; title=&quot;The Scatology of Agile Architecture&quot;&gt;Uncle Bob&lt;/a&gt;, in questa situazione come in tantissime
altre, &lt;strong&gt;la verità sta nel mezzo&lt;/strong&gt;. Un pò di pianificazione all&amp;#39;inizio (senza
arrivare agli estremi del BDUF), permette di capire meglio il problema e
impostare una soluzione decente, senza rischiare di ficcarsi in un vicolo cieco
da cui è molto difficile uscire. &lt;/p&gt;

&lt;p&gt;Inoltre ci sono determinate cose che &lt;strong&gt;devono&lt;/strong&gt; essere fissate up-front. Ad
esempio, io mi sono ritrovato a lavorare ad un progetto di un sistema
&lt;em&gt;distribuito&lt;/em&gt; di simulazione, composto da diversi moduli che comunicavano in
modo concorrente e tramite rete, ognuno progettato e realizzato da una parte
del nostro team. E&amp;#39; stato necessario definire: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;architettura generale&lt;/li&gt;
&lt;li&gt;interfacce di comunicazione&lt;/li&gt;
&lt;li&gt;tipi di dato condivisi&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Senza definire queste cose a priori non saremmo riusciti a lavorare in
parallelo e ci saremmo pestati i piedi a vicenda rallentando l&amp;#39;intero progetto.&lt;/p&gt;

&lt;h1&gt;Management&lt;/h1&gt;

&lt;p&gt;Lo stesso concetto vale a livello di management, come ho verificato sulla mia
pelle. &lt;/p&gt;

&lt;p&gt;Anche qui si presenta il concetto di &lt;em&gt;self-organizing team&lt;/em&gt;, ma è comunque
necessario stabilire delle linee guida e delle regole (meglio se condivise e
adottate su base consensuale), che andranno sì modificate e integrate &amp;quot;in
corsa&amp;quot;, ma che sono comunque necessarie per una &lt;a href=&quot;/metaprogramming/2009/05/30/importanza-di-comunicare.html&quot;&gt;comunicazione
efficace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Avere un piano a livello di management significa poter &lt;strong&gt;identificare le
priorità&lt;/strong&gt; (&lt;em&gt;infrastruttura&lt;/em&gt;, &lt;em&gt;interfacce&lt;/em&gt;, user stories, ecc.), poter
allocare risorse, pianificare costi e tempi di massima (ad esempio:
&lt;em&gt;project velocity&lt;/em&gt; di &lt;a href=&quot;http://www.extremeprogramming.org/&quot;&gt;XP&lt;/a&gt;) e &lt;strong&gt;coordinare il team&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;C&amp;#39;è un modo per affrontare con successo anche il progetto più gigantesco e
complesso: &lt;strong&gt;fare un passo alla volta&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;: &amp;quot;voglio un di sistema di elaborazione di dati scientifici
che si appoggia su CUDA pronto tra quattro mesi&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;B&lt;/strong&gt;: &amp;quot;comincia a studiare CUDA per una settimana e fai qualche prototipo,
poi faremo un meeting per buttare giù qualche bozza di architettura e stimare i
costi&amp;quot;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quale delle due alternative ti motiva di più ed è più utile?&lt;/p&gt;

&lt;h1&gt;Conclusione&lt;/h1&gt;

&lt;p&gt;Sia in ambito tecnologico che in ambito gestionale occorre trovare un
equilibrio tra &lt;em&gt;pianificazione&lt;/em&gt; e &lt;em&gt;auto-organizzazione&lt;/em&gt;, perchè ognuno dei due
elementi è necessario alla buona riuscita di un progetto e di un team di
sviluppo.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>L'importanza di comunicare</title>
   <link href="http://manuelp.github.com/metaprogramming/2009/05/30/importanza-di-comunicare.html"/>
   <updated>2009-05-30T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/metaprogramming/2009/05/30/importanza-di-comunicare</id>
   <content type="html">&lt;p&gt;Non basta avere una buona idea, bisogna anche saperla &amp;quot;vendere&amp;quot;. C&amp;#39;è una
concezione comune secondo cui &amp;quot;una buona idea si vende da sola&amp;quot; ma purtroppo
non è sempre vero: basta guardarsi attorno per vedere delle &lt;em&gt;ottime&lt;/em&gt; idee
che non hanno riscosso un grande successo a causa di una &amp;quot;cattiva campagna di
marketing&amp;quot;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Una buona idea è un&amp;#39;orfana senza una comunicazione efficace.&lt;br/&gt;
-- &amp;quot;The Pragmatic Programmer&amp;quot;, Andrew Hunt, David Thomas&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inoltre spendiamo buona parte delle nostre giornate comunicando (memo, email,
discussioni con colleghi e management, interviste col committente, proposte
di miglioramento, ecc.) per cui vale la pena farlo bene.&lt;/p&gt;

&lt;p&gt;Personalmente mi sono trovato in molte situazioni in cui ho dovuto fare
attenzione al modo in cui comunicavo per sostenere la validità del mio punto di
vista. Ad esempio quando ho proposto il VCS Mercurial al team con il quale ho
sviluppato un progetto all&amp;#39;università per ingegneria del software, o tutte le
volte che abbiamo fatto delle presentazioni ai docenti del medesimo corso.&lt;/p&gt;

&lt;h1&gt;Come comunicare efficacemente&lt;/h1&gt;

&lt;p&gt;In &amp;quot;The Pragmatic Programmer&amp;quot; gli autori dedicano un capitolo a come comunicare
efficacemente, in cui danno alcuni consigli che applicherò ai post di questo
stesso blog e che riassumo qui.&lt;/p&gt;

&lt;h2&gt;Sapere cosa dire&lt;/h2&gt;

&lt;p&gt;Punto fondamentale e ovvio, ma troppo spesso ci si ritrova a digitare
&amp;quot;Introduzione&amp;quot; e a cominciare a scrivere senza avere un&amp;#39;idea precisa di quello
che si vuole comunicare.&lt;/p&gt;

&lt;p&gt;E&amp;#39; utile quindi &lt;strong&gt;pianificare&lt;/strong&gt; quello che si vuole dire, ad esempio scrivendo
un&amp;#39;&lt;em&gt;outline&lt;/em&gt; e modificandola finché la risposta alla domanda &amp;quot;questo comunica
quello che sto cercando di dire?&amp;quot; è sì.&lt;/p&gt;

&lt;h2&gt;Adattare il messaggio all&amp;#39;audience&lt;/h2&gt;

&lt;p&gt;Ogni idea può essere presentata in modi diversi a seconda dell&amp;#39;audience: ve ne
sono di diverse con bisogni, interessi e capacità differenti. E&amp;#39; quindi
importante personalizzare il messaggio affinché sia recepito correttamente da
chi sta ascoltando.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We&amp;#39;ve all sat in meetings where a development geek glazes over the eyes of the
vice president of marketing with a long monologue on the merits of some arcane
technology. This isn&amp;#39;t communicating: it&amp;#39;s just talking, and it&amp;#39;s
annoying.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Occorre avere una chiara idea di chi ascolterà il nostro messaggio e delle sue
caratteristiche. Le seguenti domande possono aiutare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Che cosa vuoi che imparino?&lt;/li&gt;
&lt;li&gt;Qual&amp;#39;è il loro interesse in quello che hai da dire?&lt;/li&gt;
&lt;li&gt;Quanto sono sofisticati?&lt;/li&gt;
&lt;li&gt;Quanti dettagli vogliono?&lt;/li&gt;
&lt;li&gt;Chi vuoi che faccia propria l&amp;#39;informazione?&lt;/li&gt;
&lt;li&gt;Come puoi motivarli ad ascoltarti?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inoltre occorre adottare uno &lt;strong&gt;stile di comunicazione&lt;/strong&gt; adatto. L&amp;#39;interlocutore
preferisce andare dritto ai fatti oppure conversare? Preferisce uno stile
formale o uno più sciolto? &lt;/p&gt;

&lt;p&gt;Capire queste cose è importante per far recepire al meglio il messaggio.&lt;/p&gt;

&lt;h2&gt;Scegliere il momento giusto&lt;/h2&gt;

&lt;p&gt;Non ogni momento è il momento giusto. L&amp;#39;interlocutore può avere fretta, altro
da fare o semplicemente può non essere dell&amp;#39;umore giusto. Una parte del capire
le esigente dell&amp;#39;audience consiste nel capire le loro priorità, nel dubbio è
sempre meglio chiedere: &lt;em&gt;&amp;quot;è un buon momento per parlarti di ...?&amp;quot;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Questo, almeno in un blog, non è un problema visto la natura intrinsecamente
on-demand del mezzo di comunicazione :)&lt;/p&gt;

&lt;h2&gt;Cura l&amp;#39;apparenza&lt;/h2&gt;

&lt;p&gt;E&amp;#39; uno sbaglio fare affidamento solo sul contenuto di un documento senza badare
alla presentazione. L&amp;#39;aspetto è una caratteristica importante che concorre a
veicolare efficacemente un&amp;#39;idea. &lt;strong&gt;Contenuto e aspetto devono essere curati
in sinergia.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TIP 10:&lt;/strong&gt; &amp;quot;It&amp;#39;s Both What You Say and the Way You Say It&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alcuni suggerimenti per documenti:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;usa un sistema di impaginazione che produca risultati gradevoli: ad esempio
&lt;a href=&quot;http://www.latex-project.org/&quot; title=&quot;Homepage del LaTeX Project&quot;&gt;LaTeX&lt;/a&gt;, XHTML+CSS con eventualmente qualche exporter in PDF come
&lt;a href=&quot;http://xmlgraphics.apache.org/fop/&quot; title=&quot;Apache FOP&quot;&gt;FOP&lt;/a&gt;, &lt;a href=&quot;http://www.docbook.org/&quot; title=&quot;DocBook: The Definitive Guide&quot;&gt;DocBook&lt;/a&gt;, o anche qualche word-processor che supporti gli
stylesheets.&lt;/li&gt;
&lt;li&gt;usa lo &lt;em&gt;spell-checking&lt;/em&gt;, prima automatico e poi manualmente
(verifica &lt;em&gt;walkthrough&lt;/em&gt;) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br/&gt; &lt;/p&gt;

&lt;h2&gt;Coinvolgi l&amp;#39;audience&lt;/h2&gt;

&lt;p&gt;Un altro suggerimento (che non ho mai impiegato, mea culpa) è quello di
coinvolgere gli interlocutori nel processo di produzione del documento per
raccogliere feedback e instaurare una proficua relazione di lavoro.&lt;/p&gt;

&lt;p&gt;Cosa che sembra abbia funzionato tra l&amp;#39;altro per la produzione di libri interi
come &lt;a href=&quot;http://book.realworldhaskell.org/&quot; title=&quot;Real World Haskell&quot;&gt;Real World Haskell&lt;/a&gt; e &lt;a href=&quot;http://programming-scala.labs.oreilly.com/&quot;&gt;Programming Scala&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ragione per cui ho adottato questo approccio per il presente blog: nonostante
il suo aspetto/layout sia ancora un work-in-progress è online e il
&lt;a href=&quot;http://github.com/manuelp/manuelp.github.com/tree/master&quot;&gt;repository&lt;/a&gt; dei suoi sorgenti è liberamente accessibile (in lettura) e
pubblicato con licenza &lt;a href=&quot;http://creativecommons.org/licenses/by-sa/2.5/it/&quot; title=&quot;CC 2.5 Attribution-Share Alike&quot;&gt;CreativeCommons&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Inoltre, nel caso di comunicazioni verbali è utile trasformare l&amp;#39;esposizione in
una sessione interattiva, ad esempio facendo domande e chiedendo di riassumere
quello che si è appena detto.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Desktop-search in KDE 4.2</title>
   <link href="http://manuelp.github.com/amministrazione/2009/05/27/desktop-search-kde4.html"/>
   <updated>2009-05-27T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/amministrazione/2009/05/27/desktop-search-kde4</id>
   <content type="html">&lt;p&gt;Da parte mia, una volta provata la funzionalità di &lt;em&gt;desktop search&lt;/em&gt; è
diventata irrinunciabile. E&amp;#39; un utilissimo strumento per utilizzare il
proprio computer con &lt;em&gt;efficienza&lt;/em&gt; e significa avere tutti i propri
dati e applicazioni letteralmente a portata di dita.&lt;/p&gt;

&lt;p&gt;Niente più gerarchie di cartelle annidate e menu incastrati uno
dentro l&amp;#39;altro come una matrioska. I dati memorizzati nel computer
vengono indicizzati da un motore di ricerca e ogni file è
raggiungibile non solo ricercando il suo nome, ma anche il suo
contenuto. Possiamo aprire documenti, filmati, musica, applicazioni e
chi più ne ha più ne metta in pochi secondi e dovunque si trovino su
disco.&lt;/p&gt;

&lt;p&gt;I vantaggi sono innegabili: io per esempio mi sono sempre trovato a
dover gestire molti file (la maggior parte dei quali inutili) e a
concepire sempre nuovi sistemi di archiviazione. Con il desktop search
posso mettere tutto dentro una sola cartella (ad esempio &amp;quot;Archivio&amp;quot;) e
raggiungere qualsiasi file al suo interno non appena ne ho bisogno,
senza dover navigare alcuna gerarchia.&lt;/p&gt;

&lt;h1&gt;Piattaforme&lt;/h1&gt;

&lt;p&gt;Per MacOS abbiamo il migliore (mi dicono):
&lt;a href=&quot;http://quicksilver.en.softonic.com/mac&quot;&gt;Quicksilver&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Per Windows ci sono &lt;a href=&quot;http://desktop.google.com/it/&quot;&gt;Google Desktop&lt;/a&gt; e
&lt;a href=&quot;http://www.launchy.net/&quot;&gt;Launchy&lt;/a&gt; (meno sofisticato
di Google Deskop).&lt;/p&gt;

&lt;p&gt;Su piattaforma Linux, per Gnome c&amp;#39;è &lt;a href=&quot;http://do.davebsd.com/&quot;&gt;GNOME Do&lt;/a&gt; e, per
KDE,
&lt;a href=&quot;http://nepomuk.semanticdesktop.org/&quot;&gt;Nepomuk&lt;/a&gt; con il suo Strigi.&lt;/p&gt;

&lt;h1&gt;Usare Nepomuk con Ubuntu 9.04&lt;/h1&gt;

&lt;p&gt;Sfortunatamente Nepomuk non è ancora pronto per un&amp;#39;utilizzo di
produzione e attualmente è abilitabile con facilità solo il &lt;em&gt;rating&lt;/em&gt; e
le annotazioni per i file.&lt;/p&gt;

&lt;p&gt;Nonostante questo, con qualche passaggio manuale possiamo abilitare
anche il motore di indicizzazione (Strigi), che poi potremo utilizzare
con &lt;em&gt;Dolphin&lt;/em&gt; o &lt;em&gt;krunner&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ecco i passaggi necessari:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Installare il backend di Strigi &lt;em&gt;sesame&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;sudo aptitude install soprano-backend-sesame
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Attenzione&lt;/strong&gt;: sarà necessario installare anche la la JRE!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aprire il pannello:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;System Settings &amp;gt; Advanced &amp;gt; Desktop Search
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;attivare &lt;em&gt;&amp;quot;Enable Nepomuk Semantic Desktop&amp;quot;&lt;/em&gt; e &lt;strong&gt;disabilitare&lt;/strong&gt;
&lt;em&gt;&amp;quot;Enable Strigi Desktop File Indexer&amp;quot;&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Eliminare i dati correnti di Nepomuk:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;rm -Rf ~/.kde/share/apps/nepomuk
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configurare Strigi per usare il backend sesame nel file:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;~/.kde/share/config/nepomukserverrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;e modificando la linea del backend nella sezione &lt;em&gt;[main Settings]&lt;/em&gt;
come segue:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;Used Soprano Backend=sesame2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sfortunatamente, in Ubuntu Jaunty Jackalope sesame è linkato al
file &lt;em&gt;libjvm.so&lt;/em&gt;, che però viene cercato nella posizione standard
&lt;em&gt;/usr/lib&lt;/em&gt; quando invece in Ubuntu si trova in un&amp;#39;altra posizione:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;locate libjvm.so
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;nel mio caso:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;/usr/lib/gcj-4.2-81/libjvm.so
/usr/lib/gcj-4.3-90/libjvm.so
/usr/lib/jvm/java-1.5.0-gcj-4.3-1.5.0.0/jre/lib/i386/client/libjvm.so
/usr/lib/jvm/java-1.5.0-gcj-4.3-1.5.0.0/jre/lib/i386/server/libjvm.so
/usr/lib/jvm/java-6-openjdk/jre/lib/i386/cacao/libjvm.so
/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client/libjvm.so
/usr/lib/jvm/java-6-openjdk/jre/lib/i386/server/libjvm.so
/usr/lib/jvm/java-6-sun-1.6.0.13/jre/lib/i386/client/libjvm.so
/usr/lib/jvm/java-6-sun-1.6.0.13/jre/lib/i386/server/libjvm.so
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;basta fare un link alla libreria &lt;em&gt;server&lt;/em&gt; in /usr/lib, ad esempio:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-&quot; data-lang=&quot;&quot;&gt;ln -s  /usr/lib/jvm/java-6-openjdk/jre/lib/i386/server/libjvm.so \
/usr/lib/libjvm.so
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tornare nel pannello &amp;quot;System Settings&amp;quot; nella sezione &amp;quot;Desktop Search&amp;quot; (vedi
punto 2), e nella tab &amp;quot;Advanced Settings&amp;quot;  selezionare quali directory far
indicizzare da Strigi.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abilitare Nepomuk e Strigi. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A questo punto dovrebbe comparire l&amp;#39;icona di Nepomuk nella task-list: ciò vuol
dire che è partita l&amp;#39;indicizzazione. &lt;/p&gt;

&lt;h1&gt;Uso di Nepomuk&lt;/h1&gt;

&lt;p&gt;Il modo più semplice e diretto per usare Nepomuk è con &lt;em&gt;krunner&lt;/em&gt;: &lt;strong&gt;Alt+F2&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nell&amp;#39;area di inserimento che compare al centro dello schermo si possono:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lanciare applicazioni&lt;/li&gt;
&lt;li&gt;cercare in contatti, bookmarks, file, documenti recenti, cronologia di
navigazione &lt;/li&gt;
&lt;li&gt;eseguire calcoli&lt;/li&gt;
&lt;li&gt;esplorare certe cartelle con dolphin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E altro ancora, il tutto scrivendone il nome o anche una parte (krunner effettua
il pattern matching). &lt;/p&gt;

&lt;p&gt;krunner funziona anche senza Nepomuk e Strigi, ma con questi ultimi possiamo
anche cercare &lt;em&gt;all&amp;#39;interno&lt;/em&gt; dei propri file, con tutti i vantaggi che questo
comporta.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Hello world!</title>
   <link href="http://manuelp.github.com/blog/2009/05/19/hello-world.html"/>
   <updated>2009-05-19T00:00:00+00:00</updated>
   <id>http://manuelp.github.com/blog/2009/05/19/hello-world</id>
   <content type="html">&lt;p&gt;Ecco il primo post di questo mio nuovo blog! Finalmente mi sono deciso
ad aprirlo, utilizzando il servizio &lt;a href=&quot;http://pages.github.com/&quot;&gt;GitHub Pages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Si parte con un design molto minimale, creato a partire da quello di
   &lt;a href=&quot;http://github.com/mojombo/&quot;&gt;Tom Preston-Werner&lt;/a&gt;, il creatore di
   &lt;a href=&quot;http://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt; e co-fondatore di
   &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Gli scopi di questo blog sono molteplici:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per imparare qualcosa non basta leggere: metterlo in pratica e
cercare di
&lt;a href=&quot;http://www.markhneedham.com/blog/2009/04/21/learning-through-teaching/&quot;&gt;insegnarlo&lt;/a&gt;
è uno dei metodi migliori per apprendere. Quindi questo è un posto
in cui insegno prima di tutto a me stesso, e poi rendo anche
disponibili questi lavori per aiutare che volesse intraprendere la
stessa strada &lt;/li&gt;
&lt;li&gt;Per condividere esperienze e instaurare dialoghi
con persone che lavorano nel mio stesso campo&lt;br&gt;&lt;/li&gt;
&lt;li&gt;Last but not least, fare un pò di pratica con il web-design e
pubblicare un sito in una maniera molto comoda e interessante :)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;
</content>
 </entry>
 
 
</feed>