<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>A view from the hill - Programming</title>
    <link>http://hillview.1on.de/</link>
    <description>Blogging Holgers little world</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.3.1 - http://www.s9y.org/</generator>
    <pubDate>Mon, 09 Nov 2009 08:28:12 GMT</pubDate>

    <image>
        <url>http://hillview.1on.de/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: A view from the hill - Programming - Blogging Holgers little world</title>
        <link>http://hillview.1on.de/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>There's nothing left to see</title>
    <link>http://hillview.1on.de/archives/157-Theres-nothing-left-to-see.html</link>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/157-Theres-nothing-left-to-see.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=157</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=157</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    Via &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=623&amp;amp;entry_id=157&quot;  onmouseover=&quot;window.status=&#039;http://lambda-the-ultimate.org/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://lambda-the-ultimate.org/&quot;&gt;Lambda the Ultimate&lt;/a&gt; I came across an interesting article &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=624&amp;amp;entry_id=157&quot;  onmouseover=&quot;window.status=&#039;http://lambda-the-ultimate.org/node/3668&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://lambda-the-ultimate.org/node/3668&quot;&gt;On data abstraction, revisited&lt;/a&gt; by William Cook, written for OOPSLA&#039;09. It carefully dissects abstract data types from objects. All theoretical considerations aside that distinguish ADTs and objects, there is one common characteristics given by Cook: you can&#039;t inspect the concrete representation of the data you&#039;re abstracting. This is in itself interesting and reminded me of two rather practical things. &lt;br /&gt;
&lt;br /&gt;
First of all, I was reminded of a section in Bob Martins &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=625&amp;amp;entry_id=157&quot;  onmouseover=&quot;window.status=&#039;http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882&quot;&gt;Clean code development&lt;/a&gt; which discussed the idea that you should on the one hand follow the rule &quot;Tell, don&#039;t ask&quot; and on the other hand have data access objects that don&#039;t have much, if any behaviour besides providing data. This is obviously directly related to Cooks article: if you want data abstraction, you shouldn&#039;t really provide any way to allow other objects/methods to access the internal representation. This somewhat also forbids getters as this is likely to lead to leaky abstraction, since more often than not programmers simply return the value of some data field, directly exposing the representation chosen. Now, please note that this does not necessarily follow from Cooks article, as it is possible to design getters in such a way that you can return whatever you want for a getter method, i.e., you can return a desired return type or an object satisfying a particular interface. For me, the relevant point here is the way of thinking about the kind of object at hand: do I want some behaviour (aka Cooks objects) or do I want a data sink. In the former case, and in line with what is suggested in the clean code book, it is arguably the best way to tell the object to do what is necessary rather than to inspect (get) the data it holds and do it externally in some other object/method. But even in the latter case, I think it is important to give great attention to hiding the internal representation from external access and to only allow very focussed access to the data itself. It could and has been argued that restricting the access to the stored data via getter methods is tedious (see e.g. the discussion in &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=626&amp;amp;entry_id=157&quot;  onmouseover=&quot;window.status=&#039;http://tomayko.com/writings/getters-setters-fuxors&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://tomayko.com/writings/getters-setters-fuxors&quot;&gt;getters/setters/fuxors&lt;/a&gt;) and that allowing public access to members is allright, but looking at the issue from a data abstraction point of view it simply boils down to the question whether you want or need data abstraction or not.&lt;br /&gt;
&lt;br /&gt;
Second, I&#039;ve recently seen these two postings on the merits of the &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=627&amp;amp;entry_id=157&quot;  onmouseover=&quot;window.status=&#039;http://pypi.python.org/pypi/zope.component&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://pypi.python.org/pypi/zope.component&quot;&gt;Zope Component Architecture&lt;/a&gt;: &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=628&amp;amp;entry_id=157&quot;  onmouseover=&quot;window.status=&#039;http://mockit.blogspot.com/2009/11/emperors-new-clothes.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://mockit.blogspot.com/2009/11/emperors-new-clothes.html&quot;&gt;The emperors new clothes&lt;/a&gt; and the reply &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=629&amp;amp;entry_id=157&quot;  onmouseover=&quot;window.status=&#039;http://faassen.n--tree.net/blog/view/weblog/2009/11/06/0&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://faassen.n--tree.net/blog/view/weblog/2009/11/06/0&quot;&gt;The success of the ZCA&lt;/a&gt;. Malthe asks why one should use the ZCA to override the use of a particular implementation with another instead of using some kind of reloading (or rather says that the latter is the preferrable approach). Relating this to Cooks article, Malthe could be paraphrased roughly as: we have ADTs all over the place and we only should allow only one implementation per ADT (this is what the type system would guarantee in other systems). If you want another implementation (of some interface, as Cook shows for his objects), you should reload the object defintion with the one you want. The use of the ZCA, however, is directly related to the very idea of object oriented programming in the way Cook defines it: you only have interfaces that are the relevant defining characteristics of objects (values) and hence, the use of the ZCA is &lt;b&gt;the&lt;/b&gt; way to deal with multiple implentations in Zope (or Python). For me, all I can say is that I&#039;m happy that the ZCA and hence the ability to easily intermingle multiple implementations is there (then again, with me reading computer science theoretic articles I&#039;m arguably not of the angry web designer type whose benefit Malthe is arguing for).&lt;br /&gt;
&lt;br /&gt;
There is another, more puzzling aspect of the article to me. After some considerations, I have to conclude that of all OO languages I happen to know, it&#039;s really only Java that seems to be object oriented in Cooks view of the world. This is because in Java, you can define a method to return objects satisfying an interface. In addition, in dynamically typed languages like Python, Ruby, or CLOS, you could try to come away with &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=630&amp;amp;entry_id=157&quot;  onmouseover=&quot;window.status=&#039;http://en.wikipedia.org/wiki/Duck_typing&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://en.wikipedia.org/wiki/Duck_typing&quot;&gt;duck typing&lt;/a&gt;, but it&#039;s arguably only Python which tries to take it to the heart (for instance in CLOS, most values you&#039;re gonna deal with are non-CLOS values and you even have an ETYPECASE statement, which is a switch-statement on type distinction). Funny enough, Cook finishes his Smalltalk analysis with the statement that &quot;one conclusion you could draw from this analysis is that the untyped lambda calculus was the first object-oriented language&quot;. But besides the point how some language is &quot;more OO&quot; than another, there is also to the point that in order to program truly object-oriented, you shouldn&#039;t (and in Cooks world really can&#039;t) rely on type checks, because the whole point of using objects as data abstraction is to rely on behaviour.&lt;br /&gt;
&lt;br /&gt;
ObTitle: &lt;i&gt;Dial M for Murder&lt;/i&gt;, &quot;Fiction of her dreams&quot; 
    </content:encoded>

    <pubDate>Mon, 09 Nov 2009 09:28:12 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/157-guid.html</guid>
    <category>clean code development</category>
<category>oop</category>
<category>python</category>
<category>zope</category>

</item>
<item>
    <title>Magic theatre not for everybody</title>
    <link>http://hillview.1on.de/archives/154-Magic-theatre-not-for-everybody.html</link>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/154-Magic-theatre-not-for-everybody.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=154</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=154</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    If you just stumbled over this blog entry searching for what the heck all that buzzing about agile methods amounts to, I may have unfortunate news for you: An agile approach to development might for a lot of people all over the world, but may be not  for &lt;strong&gt;you&lt;/strong&gt;. For starters, take a look at the &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=614&amp;amp;entry_id=154&quot;  onmouseover=&quot;window.status=&#039;http://agilemanifesto.org/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://agilemanifesto.org/&quot;&gt;agile manifesto&lt;/a&gt; and its &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=615&amp;amp;entry_id=154&quot;  onmouseover=&quot;window.status=&#039;http://agilemanifesto.org/principles.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://agilemanifesto.org/principles.html&quot;&gt;principles&lt;/a&gt;. These have quite a lot of implications, directly translating into presuppositions about you, if you wanted to participate in an agile development project.&lt;br /&gt;
&lt;br /&gt;
Now, perhaps you&#039;re the well communicating, team oriented developer type who happens to work in a surrounding which you respect and general feel well motivated. But real life experience with your typical geek or ex-geek-turned-professional-developer suggests that having a hard time with direct communication, face-to-face, happening very often with those pesky guys and girls you don&#039;t really like is a more likely scenario (&quot;Eeek, those business and marketing people&quot; anybody?). Now, you might say, baah, I know some communication is a necessary evil of professional software development, but maybe I can get away with my old habits of trading documents (specs, bug reports, etc.) against direct communication, since that is the trusted old way and what do you mean by face-to-face communication being more effective? Everybody hates those horrible meetings eating up all your time, right?&lt;br /&gt;
&lt;br /&gt;
The point is that if you&#039;re wanting to go agile you should better soon adapt your view or else you won&#039;t see any of the promised benefits of all of those agile processes. Agile development is &lt;strong&gt;not&lt;/strong&gt; &lt;em&gt;only&lt;/em&gt; about using test driven design, timeboxing, iterations and releasing often. More than anything else, agility is about how people effectively interact with each other as quickly and direct as possible in order to come to solutions. To me, this basically boils down mainly to three issues: adaptability to (changing) situations, an open mind toward communication and taking responsibility for the project at hand.&lt;br /&gt;
&lt;br /&gt;
Being lazy, sticking bone-headed to &quot;trusted paths&quot;, not seeking confrontation when it&#039;s needed, avoiding communication because of being too busy &quot;doing&quot; is the anti-pattern to agility. You could keep a product and sprint backlog, present new features every other week to your customer and even use continuous integration and still would be muddling in pseudo agile, doomed to fail water. What I would suggest is that you should revisit the agile manifesto and think about what those principles might imply for you and your current behaviour. Let&#039;s try an example: If you find that you might end up pointing fingers at your customer (or product owner to use the terminology from Scrum) because he won&#039;t behave as demanded in the agile manifesto, you should reconsider if that fits in with what the agile manifesto demands of you: you wouldn&#039;t do the project any good. You would build up frontiers where there should be a single team including the target of your pointed finger. This is not to say that you shouldn&#039;t point out the defect, no communication about problems is another all too familiar reason for frustration and lack of commitment. What is necessary is direct communication and finding a way that works for all people involved.&lt;br /&gt;
&lt;br /&gt;
Let me sum up this posting: if you&#039;re interested in agile approaches to software development, that&#039;s fine. If you don&#039;t feel comfortable about what this might imply for you, that&#039;s fine too. But it might also tell you that agile development approaches might not work for you.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Update:&lt;/i&gt; Irionically, I stumbled via &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=616&amp;amp;entry_id=154&quot;  onmouseover=&quot;window.status=&#039;http://www.infoq.com/news/2009/10/agiles-one-essential-ingredient&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.infoq.com/news/2009/10/agiles-one-essential-ingredient&quot;&gt;Infoq&lt;/a&gt; about &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=618&amp;amp;entry_id=154&quot;  onmouseover=&quot;window.status=&#039;http://blog.criticalresults.com/2009/10/23/essential-humility/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://ow.ly/wgac&quot;&gt;the one essential agile ingrediment&lt;/a&gt; which says all about it much nicer than I ever could have done, only that Mark Schumann shows the confidence that agile works for the most part whereas I hold the more pessimistic view that it&#039;s not going to work for some, but for exactly the same reasons.&lt;br /&gt;
&lt;br /&gt;
ObTitle: Hermann Hesse, &quot;Steppenwolf&quot;&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Thu, 22 Oct 2009 18:38:00 +0200</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/154-guid.html</guid>
    <category>agile</category>
<category>project management</category>

</item>
<item>
    <title>Version control and testing</title>
    <link>http://hillview.1on.de/archives/149-Version-control-and-testing.html</link>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/149-Version-control-and-testing.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=149</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=149</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
     &lt;img src=&quot;http://clean-code-developer.de/attachment/wiki/CcdStempel/dotnetpro%20ccd%20stempel2%20almost%20half%20size%20banner.gif?format=raw&quot; align=&quot;right&quot; alt=&quot;clean code development&quot; /&gt;What have version control and testing to do with each other? Well, first of all, both are common virtues in the &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=594&amp;amp;entry_id=149&quot;  onmouseover=&quot;window.status=&#039;http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/&quot;&gt;clean code&lt;/a&gt; community. What you&#039;ll find is that both virtues are important on their own ground: version control provides a safety guard in that you can roll back to prior versions if you accidently introduce problems in your code. Testing (automated unit tests) provides a safety guard, too, because you can do regression testing when you work with your code. These are both fine goals but seemingly have little to do with each other.&lt;br /&gt;
&lt;br /&gt;
But in reality they do. For sake of argument, let&#039;s take a step back and assume that you have to work in an environment of several developers where neither of these things exists. What will you likely see? What we all have seen several years ago. Commented out code blocks, redundant and often misleading or outdated comments, timestamps with comments cluttered all over the code. And frightened developers that feared each minor change because of the miriad of subtle side effects it might have, let alone major changes to core components. It&#039;s an environment in which refactorings as welll as extensions are very hard and expensive, which results in frightened overworked developers and frustrated managers.&lt;br /&gt;
&lt;br /&gt;
So, what happens when you introduce only one of those virtues? Say, we introduce version control. Now, every change gets documented, except that documenting every change requires, from the developers point of view, documentation at the wrong point. They can&#039;t see the documented changes and the reason for these changes in the source, they see it only in the version control system -- iff they add a change message with every change at all. Much more likely is that you will see commit messages such as &quot;.&quot; or &quot;bug fix&quot;, and the same old mess of timestamps, outdated comments and commented out code as before. Why is that? Because your developers are now not as frightened as they used to be (because they can now rely on the version control system to fall back to older versions), but they still have the same need to understand and document the code. And the commit log is both &quot;too far away&quot; from the code and &quot;out of it&#039;s purpose&quot; for this task: the commit log shouldn&#039;t document what the code is supposed to do, only when something was implemented to behave in a particular way.&lt;br /&gt;
&lt;br /&gt;
This is where a development (unit) test suite comes into the picture: you document every required behaviour in tests. With every change to the code, you also update the test. As a developer, you can now look into your test suite to see what the code is supposed to do. Now developers will likely become much more confident with their changes, because they can run the tests and see what happens (hopefully next to immediately) without requiring time- and resource-consuming manual tests. &lt;br /&gt;
&lt;br /&gt;
But what about documenting the changes to the code? Well, you should simply document any changes in the commit message of your version control system, because it&#039;s now no longer necessary to keep the entire version history in mind to understand what the current code state is supposed to do. You have the tests that tell you what the code should do.  The commit log now only serves the purpose of documenting what has changed over time and is no longer required to understand what the code should do. So you don&#039;t have to keep the clutter in your code, resulting in much cleaner source code files.&lt;br /&gt;
&lt;br /&gt;
Summary: Taken together, the whole of version control and testing adds up to more than a simple addition of their own values. 
    </content:encoded>

    <pubDate>Fri, 24 Jul 2009 10:30:05 +0200</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/149-guid.html</guid>
    <category>clean code development</category>
<category>tdd</category>
<category>version control</category>

</item>
<item>
    <title>I guess I'll hang out my tears to dry</title>
    <link>http://hillview.1on.de/archives/145-I-guess-Ill-hang-out-my-tears-to-dry.html</link>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/145-I-guess-Ill-hang-out-my-tears-to-dry.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=145</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=145</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    There seems to be a &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=583&amp;amp;entry_id=145&quot;  onmouseover=&quot;window.status=&#039;http://gilesbowkett.blogspot.com/2009/05/what-killed-smalltalk-my-balls.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://gilesbowkett.blogspot.com/2009/05/what-killed-smalltalk-my-balls.html&quot;&gt;roaring&lt;/a&gt; &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=584&amp;amp;entry_id=145&quot;  onmouseover=&quot;window.status=&#039;http://pab-data.blogspot.com/2009/05/what-killed-smalltalk-sometimes-balls.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://pab-data.blogspot.com/2009/05/what-killed-smalltalk-sometimes-balls.html&quot;&gt;discussion&lt;/a&gt; &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=585&amp;amp;entry_id=145&quot;  onmouseover=&quot;window.status=&#039;http://www.cincomsmalltalk.com/blog/blogView?showComments=true&amp;amp;printTitle=Smalltalk:_Our_Death_has_been_Exaggerated&amp;amp;entry=3419278263&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.cincomsmalltalk.com/blog/blogView?showComments=true&amp;printTitle=Smalltalk:_Our_Death_has_been_Exaggerated&amp;entry=3419278263&quot;&gt;about&lt;/a&gt; a &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=591&amp;amp;entry_id=145&quot;  onmouseover=&quot;window.status=&#039;http://railsconf.blip.tv/file/2089545/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://railsconf.blip.tv/file/2089545/&quot;&gt;talk by Robert &quot;Uncle Bob&quot; Martin&lt;/a&gt; at this years RailsConf, which mainly seems to be concerned with the question (raised by a quote appointed to Ward Cunningham) whether languages such as Smalltalk make it too easy to create a mess. Languages such as C++ would penalize the mess at least by longer compile times. &lt;br /&gt;
&lt;br /&gt;
As Giles points out that&#039;s an old argument, which I too have heard too often in the past about dynamic languages, regardless whether we&#039;re talking Smalltalk, Ruby, Lisp, Python or Perl. And the anti-dote was always the current idiot language of the date, i.e. Visual Basic at its high time, Java or C# (for those who considered C or C++ to be too dangerous). Please note that I&#039;m not at all saying that users of those languages are idiots, but those languages are particularly claimed to be usable by idiots, too. This approach to languages or to their classification does a great job of misrepresenting programmers regardless of the language of their choice. It makes the bold claim that there are programmers that are idiots and that it&#039;s possible to design a language that even those idiots can do their jobs. And the exaggeration is that its only good business sense to enforce the use of those languages for all development projects, because, as we all know, there are more idiots than intelligent programmers out there, right?&lt;br /&gt;
&lt;br /&gt;
The only problem with this claim is that human stupidity is probably the only thing larger than the universe, if you make something idiot proof, nature will quickly make a better idiot. To put it a little less cynical, to err is human. And there is value in people making mistakes. As for instance, &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=587&amp;amp;entry_id=145&quot; title=&quot;http://de.wikipedia.org/wiki/Tom_DeMarco&quot;  onmouseover=&quot;window.status=&#039;http://de.wikipedia.org/wiki/Tom_DeMarco&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;&gt;Tom DeMarco&lt;/a&gt; claims in his book &quot;Slack&quot; it&#039;s a particular good way to learn. Bob Martin tries to sell excessive testing (which isn&#039;t particular surprising, giving his &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=588&amp;amp;entry_id=145&quot;  onmouseover=&quot;window.status=&#039;http://en.wikipedia.org/wiki/Robert_Cecil_Martin&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://en.wikipedia.org/wiki/Robert_Cecil_Martin&quot;&gt;background&lt;/a&gt;) as one safety guard to which James Robertson responds that this is not always necessary:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Yes, tests are useful. But, the debugger is not something to be feared. Rather, it&#039;s a great tool to be used in order to have the computer do all the memory work for you. I can get a lot more done by working with decent tools like the Smalltalk debugger than I can by assuming the doc is good and writing tests that just help me a whole lot less than you might think. &lt;/blockquote&gt; &lt;br /&gt;
&lt;br /&gt;
I can relate to this quote, being a fan of &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=589&amp;amp;entry_id=145&quot;  onmouseover=&quot;window.status=&#039;http://hillview.bugwriter.net/archives/99-Interactive-development-gets-more-popular.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://hillview.bugwriter.net/archives/99-Interactive-development-gets-more-popular.html&quot;&gt;interactive development&lt;/a&gt; that languages like Lisp or Smalltalk made popular. But I think James is missing the point: tests are not only helpful during development. Sure, using an interactive approach helps getting the code run but does it help to come up with a clean design? Looking back at some code, I can assure you it doesn&#039;t, quite to the contrary it&#039;s a way to get a working solution &lt;emph&gt;quickly&lt;/emph&gt;, not &lt;emph&gt;cleanly&lt;/emph&gt;. This doesn&#039;t make the debugger or the &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=590&amp;amp;entry_id=145&quot;  onmouseover=&quot;window.status=&#039;http://en.wikipedia.org/wiki/REPL&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://en.wikipedia.org/wiki/REPL&quot;&gt;REPL&lt;/a&gt; less valuable: using it you can quickly establish your tests, debug your tests, whatever. This is exactly where the value of dynamic languages shines and those &quot;silver-bullet&quot; idiot languages are still behind, regardless of their shiny  IDEs.&lt;br /&gt;
&lt;br /&gt;
But the real point summing up the discussion so far is the old Frederick Brooks quote: There is no silver bullet. It&#039;s good to be careful and to use the tools at your hands to help you avoid the big mistakes. As Paul Graham puts it for OOP: &quot;For programs that would have ended up as spaghetti anyway, the object-oriented model is good: they will at least be structured spaghetti.&quot; But in the end you have to learn how to avoid the mess in the first place and no language and no tool can do that for you.&lt;br /&gt;
&lt;br /&gt;
ObTitle: &lt;i&gt;Dexter Gordon&lt;/i&gt;, &quot;Ballads&quot; 
    </content:encoded>

    <pubDate>Mon, 11 May 2009 08:55:33 +0200</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/145-guid.html</guid>
    <category>lisp</category>
<category>perl</category>
<category>python</category>
<category>ruby</category>
<category>tdd</category>

</item>
<item>
    <title>Testing and terminology confusion </title>
    <link>http://hillview.1on.de/archives/133-Testing-and-terminology-confusion.html</link>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/133-Testing-and-terminology-confusion.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=133</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=133</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    I may be rather late to the game, but over the last one and a half years, I&#039;ve become quite addicted to writing tests during my development tasks. I&#039;ve had wanted to dig into test-driven development for quite some time, but it was the seamless integration of &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=529&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html&quot;&gt;Test::Unit&lt;/a&gt;, Ruby&#039;s unit testing module, in Eclipse that got me going initially. I then did some unit testing with Common Lisp packages and am currently heavily using &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=530&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://pyunit.sourceforge.net/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://pyunit.sourceforge.net/&quot;&gt;pyunit&lt;/a&gt; and &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=531&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://docs.python.org/library/doctest.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://docs.python.org/library/doctest.html&quot;&gt;python doctests&lt;/a&gt; (mostly in the context of &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=532&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://pypi.python.org/pypi/zope.testing&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://pypi.python.org/pypi/zope.testing&quot;&gt;zope testing&lt;/a&gt;).  Writing tests has become my second development nature: It gives you that warm fuzzy feeling that you have that little safety net while modifying code. &lt;br /&gt;
&lt;br /&gt;
However, there are times when terminology comes along and gives you a headache. A terminology I&#039;ve learned about during the last year is the difference between unit testing, integration tests and functional tests (for an overview see &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=533&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://en.wikipedia.org/wiki/Software_testing&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://en.wikipedia.org/wiki/Software_testing&quot;&gt;wikipedia on software testing&lt;/a&gt;). But as you can see for instance in this &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=534&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://weblog.jamisbuck.org/2006/3/9/integration-testing-in-rails-1-1&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://weblog.jamisbuck.org/2006/3/9/integration-testing-in-rails-1-1&quot;&gt;article on integration tests in Rails&lt;/a&gt;, it&#039;s not always easy to agree on what means what -- Jamis and/or the Rails community seem to have the integration/functional distinction entirely backwards from what, for instance, the &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=535&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://wiki.zope.org/zope2/Testing&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://wiki.zope.org/zope2/Testing&quot;&gt;Zope community (on testing)&lt;/a&gt; thinks. &lt;br /&gt;
&lt;br /&gt;
Now, one might argue that terminology doesn&#039;t matter much given that you do write tests at all, but it&#039;s not so easy. For instance, if your &quot;unit test&quot; of a given class requires  another class, is that still unit testing or is it integration testing?  Does it even make sense to talk about unit-testing a class? A class on its own isn&#039;t that interesting after all, it&#039;s its integration and interoperation with collaborateurs were the semantics of a class and its methods become interesting. Hence, shouldn&#039;t you rather test a specific &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=536&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://en.wikipedia.org/wiki/Behavior_Driven_Development&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://en.wikipedia.org/wiki/Behavior_Driven_Development&quot;&gt;behaviour&lt;/a&gt;, which probably involves those other classes? And what now, if your code only makes sense when run on top of a specific framework (Zope, Rails, you name it)? Michael Feathers argues convincingly in his &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=550&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://www.artima.com/weblogs/viewpost.jsp?thread=126923&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.artima.com/weblogs/viewpost.jsp?thread=126923&quot;&gt;set of unit testing rules&lt;/a&gt; that any such tests are probably something else. &lt;br /&gt;
&lt;br /&gt;
Ultimately these questions directly pertain to two aspects: code granularity and code dependencies -- and remember, test code is code after all. These are directly related, of course: if your code is very fine-grained, it&#039;s much more likely that it will also be much more entangled (although the dependency might be abstracted with the help of interfaces or some such, you still have the dependency as such). And as a consequence, your test code will have to mimick these dependencies. On the contrary, if your code blocks are more coarse-grained (i.e. cover a greater aspect of funcionality), you might have less (inter-)dependencies, but you won&#039;t be able to test functionality on a more fine-grained level.  As Martin Fowlers excellent article &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=544&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://martinfowler.com/articles/mocksArentStubs.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://martinfowler.com/articles/mocksArentStubs.html&quot;&gt;Mocks aren&#039;t stubs&lt;/a&gt; discusses in detail, one way to loosen these connections between code and tests is to use &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=539&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://en.wikipedia.org/wiki/Mock_object&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://en.wikipedia.org/wiki/Mock_object&quot;&gt;mock objects&lt;/a&gt; or stubs. Fowlers article also made clear to me that I&#039;ve used the term &quot;mock object&quot; wrongly in my post on &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=540&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://hillview.bugwriter.net/archives/121-Unit-tests-with-mockups-in-Lisp.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://hillview.bugwriter.net/archives/121-Unit-tests-with-mockups-in-Lisp.html&quot;&gt;mock objects in Common Lisp&lt;/a&gt;: dynamically injecting an object/function/method (as a replacement for a collaborator required for the &quot;code under test&quot;) that returns an expected value means using a stub, not a mock -- another sign of not clearly enough defined terminology (btw, the terminology Fowler is using is that of G. Mercezaos &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=557&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://xunitpatterns.com/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://xunitpatterns.com/&quot;&gt;xunit patterns book&lt;/a&gt;).  &lt;br /&gt;
&lt;br /&gt;
It&#039;s worth keeping these things apart because of their different impact on test behaviour: mocks will force you to think about behaviour whereas stubs focus on &#039;results&#039; of code calls (or object state if you think in terms of objects being substituted). As a result, when you change the behaviour of the code under test (say you&#039;re changing code paths in order to optimize code blocks) this might (mocks) or might not (stubs) result in changes to the test code. &lt;br /&gt;
&lt;br /&gt;
It&#039;s also worth thinking about mocks and stubs because they also shed a new light on the question of test granularity: when you&#039;re substituting real objects in either way, you&#039;re on your way to much more fine-grained tests, which implies that you loosen the dependency of your tests: You can now modify the code of your collaborateur class without the test for your code under test breaking. Which brings us back full circle to the distinction between unit tests and integration tests: you now might have perfect unit tests, but now you&#039;re forced to additionally tests the integration of all the bits and pieces. Otherwise you might have all unit tests succeed but your integrated code still fails. Given this relationship, it seems immediately clear that 100% test coverage might not be the most important issue with unit tests: you might have 100% unit test success, but 100% integration failure at the same time -- if you don&#039;t do continuous integration and integration tests, of course. Now what&#039;s interesting is that it might be possible to check test coverage on code paths, but it might not be easy to check integration coverage. I would be interested to learn about tools detailing such information.&lt;br /&gt;
&lt;br /&gt;
Recently I had another aha moment with regard to testing terminology: Kevlin Henney&#039;s presentation at this years german conference on object oriented programming, the &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=542&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://www.sigs-datacom.de/sd/kongresse/oop_2009/index.php&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.sigs-datacom.de/sd/kongresse/oop_2009/index.php&quot;&gt;OOP 2009&lt;/a&gt;, on &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=543&amp;amp;entry_id=133&quot;  onmouseover=&quot;window.status=&#039;http://www.sigs-datacom.de/sd/kongresse/oop_2009/program.php?cat=session&amp;amp;ID=47&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.sigs-datacom.de/sd/kongresse/oop_2009/program.php?cat=session&amp;ID=47&quot;&gt;know your units: TDD, DDT, POUTing and GUTs&lt;/a&gt;: tdd is test driven development, of course. The other ones might be not so obvious: &quot;guts&quot; are just good unit tests and &quot;pout&quot; is &quot;plain old unit testing&quot;. I saw myself doing tdd, but come to think of it, I&#039;m mostly applying a combination of tdd, pout (after the fact testing) and ddt: defect driven testing. I find the introduction of a term for testing after the code has been written interesting because it provides a way to talk about how to introduce testing in the first place. Especially defect driven testing, the idea to write a test to pinpoint and overcome an erroneous  code path, might be a very powerful way to introduce the habit of regularly writing (some) tests for an existing large code base. So you avoid the pitfall of never being able to test &quot;all this lots of code because there is never the time for it&quot; and you might also motivate people to try writing test before code. And on this level, it might at first not be that relevant to make the distinction between integration and unit tests to clear: start out with whatever is useful. &lt;br /&gt;
&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Fri, 06 Feb 2009 11:11:40 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/133-guid.html</guid>
    <category>tdd</category>

</item>
<item>
    <title>Core wars</title>
    <link>http://hillview.1on.de/archives/125-Core-wars.html</link>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/125-Core-wars.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=125</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=125</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    Drew Campsie &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=505&amp;amp;entry_id=125&quot;  onmouseover=&quot;window.status=&#039;http://common-lisp.net/pipermail/bese-devel/2009-January/006566.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;external link: mailing list announcement&quot;&gt;announces ucw-core&lt;/a&gt;, the next generation of &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=506&amp;amp;entry_id=125&quot;  onmouseover=&quot;window.status=&#039;http://common-lisp.net/project/ucw/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://common-lisp.net/project/ucw/&quot;&gt;Uncommon Web&lt;/a&gt;, a continuation-based framework for web applications written in Common Lisp. It&#039;s the first major announcement since Drew took over development lead of ucw and it seems to focus on establishing a core library of basic technology on top of which other functionality can be implemented (e.g. functionality like those offered by the ucw-ajax). To me as a UCW user this sounds like great news, since I had the impression that ucw seemed to linger in a state of void over the last year or so.&lt;br /&gt;
&lt;br /&gt;
But even more interesting is that ucw just seems to follow a certain trend. For instance, according to the &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=507&amp;amp;entry_id=125&quot;  onmouseover=&quot;window.status=&#039;http://yehudakatz.com/2008/12/23/rails-and-merb-merge/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://yehudakatz.com/2008/12/23/rails-and-merb-merge/&quot;&gt;announcement that Ruby on Rails and Merb will merge&lt;/a&gt;, one goal is that &lt;quote&gt;Rails will be retrofitted to make it easy to start with a “core” version of Rails (like Merb’s current core generator), that starts with all modules out, and makes it easy to select just the parts that are important for your app&lt;/quote&gt;. The main aspect of such development (at least I hope so) seems to be best described by one of &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=508&amp;amp;entry_id=125&quot;  onmouseover=&quot;window.status=&#039;http://docs.djangoproject.com/en/dev/misc/design-philosophies/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://docs.djangoproject.com/en/dev/misc/design-philosophies/&quot;&gt;Django design goals&lt;/a&gt;): &lt;quote&gt;A fundamental goal of Django’s stack is loose coupling and tight cohesion. The various layers of the framework shouldn’t “know” about each other unless absolutely necessary.&lt;/quote&gt; The python folks have even gone so far as to write down a &lt;emph&gt;web server gateway interface specification&lt;/emph&gt; (&lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=509&amp;amp;entry_id=125&quot;  onmouseover=&quot;window.status=&#039;http://wsgi.org/wsgi/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://wsgi.org/wsgi/&quot;&gt;WSGI&lt;/a&gt;, a quite minimalistic specification).&lt;br /&gt;
&lt;br /&gt;
It will be interesting to see whether there&#039;s going to be even more unification, maybe even across language diffferences. I&#039;m not too certain that such an unification would necessarily be a good aim; as always there are probably as many benefits as downsides to it. For instance, a common specification certainly lowers the learning curve for people switching frameworks while at the same time may stiffle further development. Then there&#039;s the fact that the different frameworks have different approaches which are certainly reflected in their APIs: for instance, Django explicitly tries to avoid magic at all cost while there&#039;s traditionally a lot of magic going on behind the scenes of a Rails application. I&#039;m also not sure where exactly one should draw the line between common &quot;core&quot; functionality and additional &quot;batteries&quot;. As an application designer it&#039;s probably most important that there is such a line at all so that you can easily pick your poison without having to buy everything.&lt;br /&gt;
&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Thu, 08 Jan 2009 21:48:00 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/125-guid.html</guid>
    <category>lisp</category>
<category>python</category>
<category>ruby</category>
<category>ucw</category>
<category>web development</category>

</item>
<item>
    <title>You're wondering now</title>
    <link>http://hillview.1on.de/archives/124-Youre-wondering-now.html</link>
            <category>Media</category>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/124-Youre-wondering-now.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=124</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=124</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=503&amp;amp;entry_id=124&quot;  onmouseover=&quot;window.status=&#039;http://herbsutter.wordpress.com/2008/12/31/the-2008-media-inflection-meet-dr-web-the-new-gorilla/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://herbsutter.wordpress.com/2008/12/31/the-2008-media-inflection-meet-dr-web-the-new-gorilla/&quot;&gt;Herb Sutter announces&lt;/a&gt; that &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=504&amp;amp;entry_id=124&quot;  onmouseover=&quot;window.status=&#039;http://www.ddj.com/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.ddj.com/&quot;&gt;Dr.Dobbs Journal&lt;/a&gt;  is permanently suspending print publication and going web-only as of January 2009. I&#039;ve used to be a long-time subscriber of DDJ -- several not-so-excited friends that recently helped moving into our new flat are my witnesses. Actually, I&#039;ve stopped my subscription (and we&#039;re talking about a way to expensive subscription via a German importer, here) roughly one or two years ago, since I couldn&#039;t keep up with my reading but occasionally I&#039;ve regret that I no longer receive it. Now, it seems to me like the last printed programming related magazine is going down the drain -- sorry, you Java and PHP magazines floating around, but your content isn&#039;t nearly as interesting as what DDJ had as it was ultimately the mix of different topic and opionated editorials that made DDJ so unique. Perhaps now I should hurry and finally buy the DDJ developer library dvd covering 21 years of DDJ articles.  I&#039;ll keep an eye on what will happen to DDJ as a web publication. 
    </content:encoded>

    <pubDate>Fri, 02 Jan 2009 09:18:33 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/124-guid.html</guid>
    <category>literature</category>
<category>media</category>

</item>
<item>
    <title>python-mode vs. slime</title>
    <link>http://hillview.1on.de/archives/122-python-mode-vs.-slime.html</link>
            <category>Emacs</category>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/122-python-mode-vs.-slime.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=122</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=122</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    I&#039;ve become a python programmer, too, lately, due to a job change. Python is a fine language so far, although to me it&#039;s mostly just like Ruby, though with even less functional flavour. However, just as with Ruby, I&#039;m really missing &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=490&amp;amp;entry_id=122&quot; title=&quot;http://common-lisp.net/project/slime&quot;  onmouseover=&quot;window.status=&#039;http://common-lisp.net/project/slime&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;&gt;slime&lt;/a&gt;, the superior lisp interaction mode for Emacs, when hacking python code. I could now start to write down a list of things I&#039;m missing (which I&#039;ve intended to do), however, Andy Wingo spares me the hassle, as he has just written an &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=491&amp;amp;entry_id=122&quot; title=&quot;http://wingolog.org/archives/2006/01/02/slime&quot;  onmouseover=&quot;window.status=&#039;http://wingolog.org/archives/2006/01/02/slime&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;&gt;excellent article on slime from a python programmers view&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
However, I would like to elaborate a little on the main difference for me: the client/server socket approach of slime. Let me briefly recapulate what this implies: slime consists of two parts, a client written in Emacs lisp and a server written in Common Lisp (AFAIK there is at least also an implementation for clojure, maybe also one for some scheme implementation). In order to use slime in it&#039;s full glory, it&#039;s hence required that you have a common lisp process running which in turn runs the slime server part. If you now fire up slime, you&#039;ll get an interaction buffer over which you can access the REPL of the lisp process, which in python would be the interpreter prompt. You can then interact with the lisp process, evaluating pieces of code from your lisp source code buffer directly in the connected lisp process. What is incredibly useful for me is that you can not only start a new lisp process but also connect to an already running lisp process, given that it has the slime server started (this is obviously mainly useful if the lisp implementation you use has multi-threading capabilities). I use it to connect to a running web server application, which I can then inspect, debug and modify. Modification includes redefinition of functions, macros and classes, which of course is also a particular highlight of Common Lisp. I would like to cite a comment of the reddit user &quot;fionbio&quot; he made wrt. to the linked article: &lt;cite&gt;In fact, Python language wasn&#039;t designed with lisp-style interactive development in mind. In CL, you can redefine (nearly) anything you want in a running program, and it just does the right thing. In Python, there are some problems, e.g. instances aren&#039;t updated if you modify their class. Lisp programmers often, though not always, refer to various things (functions, classes, macros, etc.) using symbols, while Python programs usually operate with direct references, so when you update parts of your program you have much higher chances that there will be a lot of references to obsolete stuff around.&lt;/cite&gt;&lt;br /&gt;
&lt;br /&gt;
To complement &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=492&amp;amp;entry_id=122&quot;  onmouseover=&quot;window.status=&#039;http://bc.tech.coop/blog/081209.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://bc.tech.coop/blog/081209.html&quot;&gt;Bill clementsons excellent article series on slime&lt;/a&gt; a little, I&#039;m going to describe how I&#039;m using/configuring python-mode to make it match my expectations a little closer. Essentially I would like to access my python process just as I would with slime/Common Lisp, but that&#039;s not possible. The reason, btw., is nearly unchanged: I need to code on a web server app (written in Zope) which may not even run on the same machine I&#039;m developing on.  Let&#039;s first cover the simple stuff: To enable a reasonable command interface to the python interpreter, I require the ipython emacs library. If the python interpreter runs locally, I also use py-complete, so that I can complete my code at least a little. Unfortunately, this breaks when the python interpreter doesn&#039;t run locally, because the py-complete needs to setup some things in the running python process, which it does by writing to a local temp file and feeding it to the python process. Unfortunately, the code in py-complete lacks customizability, i.e., you can&#039;t specify where that temp file should be located -- I should be able to come up with a small patch in the near future, which I will add below. Finally, I also require doctest-mode as a support for writing doctests, but that&#039;s not really relevant. &lt;br /&gt;
&lt;br /&gt;
Now, on to the more involved stuff: I introduce some new variables and a new function &lt;code&gt;py-set-remote-python-environment&lt;/code&gt;, which  uses the those variables to do a remote call (via ssh) to python. This at least allows me to do things like setting py-remote-python-command to &quot;/home/schauer/zope/foo-project/bin/instance&quot; and py-remote-python-command-args to &quot;debug&quot;, so that I can access a remote debug shell of my current zope product. That alone will only allow me to fire up and access the remote python, so I could now develop the code locally, having it executed remote. More typical though is that you would also want to keep the code on the remote machine, too: for this I use &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=496&amp;amp;entry_id=122&quot;  onmouseover=&quot;window.status=&#039;http://www.gnu.org/software/tramp/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.gnu.org/software/tramp/&quot;&gt;tramp&lt;/a&gt;, a package for remotely accessing files/directories from within emacs. In combination, this allows me to edit and execute the code on the remote machine. It is still nowhere near what is possible with slime, but at least it allows me to persue my habit of incremental and interactive development from within my usual emacs installation (i.e., it doesn&#039;t require me to deal with any Emacs related hassle on the remote machine). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
&lt;code&gt;
;;; python-stuff.el --- python specific configuration

(when (locate-library &quot;ipython&quot;)
  (require &#039;ipython))

(when (locate-library &quot;doctest-mode&quot;)
  (require &#039;doctest-mode))

(defvar py-remote-connect-command &quot;ssh&quot;
  &quot;*Command for connecting to a remote python, typically \&quot;ssh\&quot;&quot;)
(defvar py-remote-connection-args &#039;(&quot;user@remotemachine&quot;)
  &quot;*List of strings of connection options.&quot;)
(defvar py-remote-python-command &quot;python&quot;
  &quot;*Command to execute for python&quot;)
(defvar py-remote-python-command-args &#039;(&quot;-i&quot;)
  &quot;*List of strings arguments to be passed to `py-remote-python-command`.&quot;)
(defvar py-remote-python-used nil
  &quot;Remember if remote python is used.&quot;)

(defun py-set-remote-python-environment ()
  (interactive)
  (let ((command-args (append py-remote-connection-args 
			      (list py-remote-python-command)
			      py-remote-python-command-args)))
    (setq py-python-command py-remote-connect-command)
    (setq py-python-command-args command-args))
  (setq py-remote-python-used t))

(when (locate-library &quot;py-complete&quot;)
  (autoload &#039;py-complete-init &quot;py-complete&quot;)
  (defun my-py-complete-init ()
    &quot;Init py-complete only if we&#039;re not using remote python&quot;
    (if (not py-remote-python-used)
        (py-complete-init)))
  (add-hook &#039;python-mode-hook &#039;my-py-complete-init))

&lt;/code&gt;
&lt;/pre&gt;&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Wed, 10 Dec 2008 10:52:44 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/122-guid.html</guid>
    <category>emacs</category>
<category>lisp</category>
<category>python</category>

</item>
<item>
    <title>Unit tests with mockups in Lisp</title>
    <link>http://hillview.1on.de/archives/121-Unit-tests-with-mockups-in-Lisp.html</link>
            <category>Lisp</category>
    
    <comments>http://hillview.1on.de/archives/121-Unit-tests-with-mockups-in-Lisp.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=121</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=121</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    One of the bigger practical problems with &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=485&amp;amp;entry_id=121&quot;  onmouseover=&quot;window.status=&#039;http://en.wikipedia.org/wiki/Unit_testing&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://en.wikipedia.org/wiki/Unit_testing&quot;&gt;unit testing&lt;/a&gt; is isolating the test coverage. Say, you want to test a piece of code from the middle (business) layer. Let&#039;s assume further the piece of code under consideration makes some calls to lower level code to retrieve some data. The problem of test coverage isolation is now that if you &quot;simply&quot; call your function, you are implicitly also testing the lower level code, which you shouldn&#039;t: if that lower level code gets modified in an incorrect way, you would suddenly see your middle level code fail although there was no change made to it. Let&#039;s explore ways to avoid the problems in Common Lisp.&lt;br /&gt;
&lt;br /&gt;
There is a very good reason why you would &lt;i&gt;also&lt;/i&gt; want to have such test dependencies to ensure your middle level code still works if the lower level code is extended or modified. But that is no longer unit testing: you are then doing so-called integration tests which are related, but still different beasts. &lt;br /&gt;
&lt;br /&gt;
Now, I was facing exactly the typical dreaded situation: I extended an application right above the database access layer which had not seen much tests yet. And of course, I didn&#039;t want to go the long way (which I will eventually have to go anyway) and set up a test database with test data, write setup and tear-down code for the db etc. The typical suggestion (for the xUnit crowd) is to use mock objects which brings us finally on topic. &lt;br /&gt;
I was wondering if there are any frameworks for testing with mock objects in Lisp, but a quick search didn&#039;t turn up any results (please correct me if I&#039;ve missed something). After giving the issue a little thought, it seemed quite clear why there aren&#039;t any: probably because it&#039;s easy enough to use home-grown solutions such as mine.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll use &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=486&amp;amp;entry_id=121&quot;  onmouseover=&quot;window.status=&#039;http://www.cliki.net/xlunit&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.cliki.net/xlunit&quot;&gt;xlunit&lt;/a&gt; as the test framework, but that&#039;s not relevant. Let&#039;s look at some sample code we&#039;ll want to test:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&lt;pre&gt;
(defun compare-data (data &amp;connection)
  (let ((dbdata (retrieve-data-by-id (id data))))
    (when (equal (some-value data)
                (some-db-specific-value dbdata))
         t)))
&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The issue is with &lt;code&gt;retrieve-data-by-id&lt;/code&gt; which is our interface to the lower level database access.&lt;br /&gt;
And note that we&#039;ll use some special functions on the results, too, even if they may just be accessors.&lt;br /&gt;
Let&#039;s assume the following test code:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&lt;pre&gt;
(use-package :xlunit)

(defclass comp-data-tc (test-case)
  ((testdata :accessor testdata :initform (make-test-data))))

(def-test-method comp-data-test ((tc comp-data-tc))
  (let ((result (compare-data (testdata tc))))
    (assert-equal result t)))
&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Now the trouble is: given the code as it is now, the only way to succeed the test is to make sure that &lt;code&gt;make-test-data&lt;/code&gt; returns an object whose values match values in the database you&#039;re going to use when &lt;code&gt;compare-data&lt;/code&gt; get&#039;s called. You&#039;re ultimately tying your test code (especially the result of &lt;code&gt;make-test-data&lt;/code&gt;) to a particular state of a particular database, which is clearly unfortunate. To overcome that problem, we&#039;ll use mock objects and mock functions. Let&#039;s define a mock-object &lt;code&gt;mock-data&lt;/code&gt; and a &lt;code&gt;mock-retrieve-data&lt;/code&gt; function, which will simply return a single default mock object.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&lt;pre&gt;
(defclass mock-data ()
  ((id :accessor id :initarg :id :initform 0)
   (val :accessor some-db-specific-value :initarg :val :initform &quot;foo-0&quot;))))

(defun mock-retrieve-data (testcase)
  (format t &quot;Establish mock for retrieve-data&quot;)
  (lambda (id)
      (format t &quot;mock retrieve-data id:~A~%&quot;)
      (find-if #&#039;(lambda (elem
			(when (equal (id elem) id)
			  elem))
                    (testdbdata testcase))))
&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Why that mock-retrieve-data returns a closure will become clear in a second, after we&#039;ve answered the question how these entirely different named object and function can be of any help. The answer lies in CLs facility to assign different values (or better said) definitions to variables (or better said to function slots of symbols). What we&#039;ll do is to simply assign the function definition we&#039;ve just created as the function to use when &lt;code&gt;retrieve-data&lt;/code&gt; is going to be called. This happens in the setup code of the test case:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&lt;pre&gt;
(defclass comp-data-tc (test-case)
  ((testdata :accessor testdata :initform (make-test-data))
   (testdbdata :accessor testdbdata)
   (func  :accessor old-retrieve-func)))

(defmethod set-up ((tc comp-data-tc))
  ; set up some test data
  (dotimes (number 9)
    (setf (testdbdata tc)
             (append 
                  (list 
                      (make-instance &#039;mock-data 
                            :id number 
                            :value (concatenate &#039;string &quot;value-&quot; number)))
                 (testdbdata tc))))
  ; establish our mock function
  (when (fboundp &#039;retrieve-data)
    (setf (old-retrieve-func tc)
             (fdefinition &#039;retrieve-data))))
  (setf (fdefinition &#039;retrieve-data)
           (mock-retrieve-data tc)))

(defmethod tear-down ((tc comp-data-tc))
   ; After the test has run, re-establish the old definition
   (when (old-retrieve-func tc)
      (setf (fdefinition &#039;retrieve-data)
           (old-retrieve-func tc))))
&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
You can now see why mock-retrieve-data returns a closure: by this way, we can hand the data we establish for the test case down to the mock function without resorting to global variables.&lt;br /&gt;
&lt;br /&gt;
Now, the accessor &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=487&amp;amp;entry_id=121&quot;  onmouseover=&quot;window.status=&#039;http://www.lispworks.com/documentation/HyperSpec/Body/f_fdefin.htm&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.lispworks.com/documentation/HyperSpec/Body/f_fdefin.htm&quot;&gt;fdefinition&lt;/a&gt; comes in extremely handy here: we use it to assign a different function definition to the symbol &lt;code&gt;retrieve-data&lt;/code&gt; which will then be called during the unit-test of &lt;code&gt;compare-data&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&lt;pre&gt;
..Establish mock for retrieve-data
mock retrieve-data id: 0
F
Time: 0.013


There was 1 failure: ...
&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
There is also &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=488&amp;amp;entry_id=121&quot;  onmouseover=&quot;window.status=&#039;http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_1.htm&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot; title=&quot;http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_1.htm&quot;&gt;symbol-function&lt;/a&gt; which could be applied similarly and which might be used to tackle macros and special operators. However, the nice picture isn&#039;t as complete as one would like it: methods aren&#039;t covered, for instance. And it probably also won&#039;t work if the function to mock is used inside a macro. There are probably many more edge cases not covered by the simple approach outlined above. Perhaps lispers smarter than me have found easy solutions for these, too, in which case I would like to learn more about them.&lt;br /&gt;
&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Tue, 11 Nov 2008 19:41:55 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/121-guid.html</guid>
    <category>lisp</category>
<category>tdd</category>

</item>
<item>
    <title>The release warp</title>
    <link>http://hillview.1on.de/archives/119-The-release-warp.html</link>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/119-The-release-warp.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=119</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=119</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    The Release Warp Lyrics &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It&#039;s astounding, time is fleeting&lt;br /&gt;
Madness takes its toll&lt;br /&gt;
But listen closely, not for very much longer&lt;br /&gt;
I&#039;ve got to keep control&lt;br /&gt;
&lt;br /&gt;
I remember doing the Release Warp&lt;br /&gt;
Drinking those moments when&lt;br /&gt;
The blackness would hit me and the void would be calling&lt;br /&gt;
Let&#039;s do the release warp again...&lt;br /&gt;
Let&#039;s do the release warp again!&lt;br /&gt;
&lt;br /&gt;
It&#039;s just a bug to the left&lt;br /&gt;
And then an error to the right&lt;br /&gt;
With your hands on your keys&lt;br /&gt;
You bring your fixes in tight&lt;br /&gt;
But it&#039;s the pelvic thrust that really drives you insane,&lt;br /&gt;
Let&#039;s do the Release Warp again!&lt;br /&gt;
&lt;br /&gt;
It&#039;s so dreamy, oh fantasy free me&lt;br /&gt;
So you can&#039;t find me, no not at all&lt;br /&gt;
In another dimension, with capitalistic intention&lt;br /&gt;
Well-secluded, I see all&lt;br /&gt;
With a bit of a mind flip&lt;br /&gt;
You&#039;re there in the bug slip&lt;br /&gt;
And nothing can ever be the same&lt;br /&gt;
You&#039;re spaced out on sensation, like you&#039;re under sedation&lt;br /&gt;
Let&#039;s do the Release Warp again!&lt;br /&gt;
&lt;br /&gt;
Well I was typing down the plan just a-having a think&lt;br /&gt;
When a snake of a marketeer gave me an evil wink&lt;br /&gt;
He shook me up, he took me by surprise&lt;br /&gt;
He had a business plan and the devil&#039;s eyes.&lt;br /&gt;
He stared at me and I felt a change&lt;br /&gt;
Time meant nothing, never would again&lt;br /&gt;
Let&#039;s do the Release Warp again!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(... with sincere apologies to The Rocky Horror Picture Show by Richard O&#039;Brien) 
    </content:encoded>

    <pubDate>Fri, 17 Oct 2008 08:24:47 +0200</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/119-guid.html</guid>
    <category>fun</category>

</item>
<item>
    <title>UCW leadership change</title>
    <link>http://hillview.1on.de/archives/108-UCW-leadership-change.html</link>
            <category>Lisp</category>
    
    <comments>http://hillview.1on.de/archives/108-UCW-leadership-change.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=108</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=108</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    In case you&#039;re interested in continuation-based web development with Common Lisp, it might be of interest to learn that &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=456&amp;amp;entry_id=108&quot;  onmouseover=&quot;window.status=&#039;http://common-lisp.net/pipermail/bese-devel/2008-April/003221.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://common-lisp.net/pipermail/bese-devel/2008-April/003221.html&quot;&gt;Drew Campsie has voluntered to take over UCW development&lt;/a&gt;. Marco Baringer, initiator and maintainer of &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=457&amp;amp;entry_id=108&quot;  onmouseover=&quot;window.status=&#039;http://common-lisp.net/project/ucw/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://common-lisp.net/project/ucw/&quot;&gt;UncommonWeb&lt;/a&gt; (aka UCW) &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=458&amp;amp;entry_id=108&quot;  onmouseover=&quot;window.status=&#039;http://common-lisp.net/pipermail/bese-devel/2008-April/003232.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://common-lisp.net/pipermail/bese-devel/2008-April/003232.html&quot;&gt;seemed somwhat relieved&lt;/a&gt; that finally somebody with more time on his hand steps up to take over. &lt;br /&gt;
&lt;br /&gt;
That Marco hadn&#039;t had the time to keep pushing UCW is quite obvious from the mailing list archive. Lately Attila Lendvai seemed to me (an innocent external observer) to had pushed UCW foreward, however, as he &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=459&amp;amp;entry_id=108&quot;  onmouseover=&quot;window.status=&#039;http://common-lisp.net/pipermail/bese-devel/2008-April/003228.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://common-lisp.net/pipermail/bese-devel/2008-April/003228.html&quot;&gt;Attila announced&lt;/a&gt;, he wants to go into a different direction than Drew.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve been using ucw-dev during the last two years and the current situation really called for a change, in my opinion. UCWs main problem, as I observe it, is lacking documentation and clearly stated goals which way UCW will go. The automatically extracted documentation doesn&#039;t contain information how the bits fit together and &lt;strong&gt;all&lt;/strong&gt; tutorials are a) incomplete, b) outdated as far as they are targetting ucw-dev, whereas development has mainly happened in ucw-ajax. However, it was not all clear that ucw-ajax really would become the main line of UCW. &lt;br /&gt;
&lt;br /&gt;
I like UCWs component architecture a lot and will eagerly follow what is going to happen. With two prominent developers such as Marco and Attila more or less leaving the project, it will be interesting to see with how much activity development will happen from now on.&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Wed, 30 Apr 2008 22:06:42 +0200</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/108-guid.html</guid>
    <category>lisp</category>
<category>ucw</category>
<category>web development</category>

</item>
<item>
    <title>Escaping from sql-reader-syntax in CL-SQL</title>
    <link>http://hillview.1on.de/archives/100-Escaping-from-sql-reader-syntax-in-CL-SQL.html</link>
            <category>Lisp</category>
    
    <comments>http://hillview.1on.de/archives/100-Escaping-from-sql-reader-syntax-in-CL-SQL.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=100</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=100</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    This post is mainly a reference post about a particular topic whose solution wasn&#039;t immediately obvious to me from the docs to CL-SQL. Using CL-SQL with (enable-sql-reader-syntax), I had written a routine that looks basically likes this:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&lt;pre&gt;
(defun data-by-some-criteria (criteria &amp;key (dbspec +db-spec+)  (dbtype +db-type+))
  (with-database (db dbspec :database-type dbtype :if-exists :old)
    (let (dbresult)
      (if criteria
	  (setq dbresult
		(select &#039;some-model &#039;other-model
			:where [and [= [some.criteria] criteria]
			            [= [some.foreign_id] [other.id]]]
			:order-by &#039;([other.name] [some.foreign_id] 
				          [year] [some.name])
			:database db))
          (setq dbresult
		(select &#039;some-model &#039;other-model
			:where [and [null [some.criteria]]
			            [= [some.foreign_id] [other.id]]]
			:order-by &#039;([other.name] [some.foreign_id] 
				          [year] [some.name])
			:database db))
      (when dbresult
	(loop for (some other) in dbresult
	      collect some)))))
&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
This is ugly because the only difference between those two select statements is the check for the criteria, but I had no idea how to combine the two select statements into one, because it&#039;s not possible to embed lisp code (apart from symbols) into an sql-expression (i.e. the type of arguments for :where or :order etc.).&lt;br /&gt;
&lt;br /&gt;
With the next requirement things would become far worse: The order-by statement needs to get more flexible so that it is possible to sort results by year first. Given the approach shown above this would result in at least four select statements, which is horrible. So, naturally I wanted a single select statement with programmatically obtained  :where and :order-by sql expressions.&lt;br /&gt;
&lt;br /&gt;
Step 1: It occured to me that it should be possible to have the arguments in a variable and simply refer to the variable. E.g., using a more simple example:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&lt;pre&gt;
(let (where-arg)
  (if (exact-comp-needed)
      (setq where-arg &#039;[= [column] someval])
      (setq where-arg &#039;[like [column] someval]))
  (select &#039;model :where where-arg))
&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
So I could now have my two different where-args and two different order-args and use a single select statement. Main problem solved. &lt;br /&gt;
&lt;br /&gt;
Step 2: But for the :where arg in my original problem, only a small fraction of the sql-expression differs. So how do I avoid hard coding the entire value of where-arg? How can I combine some variable part of an sql-expression with some fixed parts? I.e, ultimately I want something like:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&lt;pre&gt;
(let (comp-op where-arg)
  (if (exact-comp-needed)
      (setq comp-op &#039;=)
      (setq comp-op &#039;like))
  (setq where-arg &#039;[ &amp;lt;put comp-op here&amp;gt; [column1] someval])
  (select &#039;model :where where-arg))
&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
But with CL-SQL modifying the reader, there seems to be no way to make &amp;lt;put comp-op here&amp;gt; work. I didn&#039;t knew how to get the usual variable evaluation into the sql-expression, or how to escape from CL-SQL&#039;s sql-reader-syntax to normal lisp evaluation.  &lt;br /&gt;
&lt;br /&gt;
Somewhere in the back of my head where was that itch that CL-SQL might offer some low-level access to sql expressions. And indeed it does. There are two useful functions, sql-expression and sql-operation. sql-operation &quot;returns an SQL expression constructed from the supplied SQL operator or function operator and its arguments args&quot; (from the cl-sql docs), and we can supply the operator and its arguments from lisp -- which is exactly what I want.&lt;br /&gt;
&lt;br /&gt;
Now, the nice thing is that it&#039;s easy to mix partly handcrafted sql expressions with CL-SQL special sql syntax constructs that will be automatically handled by the reader (if you enable it only via enable-sql-reader-syntax, of course). I.e., for &amp;lt;put comp-op here&amp;gt; we can use sql-operation, but the rest stays essentially the same:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&lt;pre&gt;
(let (where-arg)
  (if (exact-comp-needed)
      (setq where-arg (sql-operation &#039;= [column1] someval))
      (setq where-arg (sql-operation &#039;like [column1] someval)))
  (select &#039;model &#039;other-model  :where where-arg))
&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Now, coming back to my original problem, based on this approach I can split out the common part of the :where and :order arguments and combine those with the varying parts as needed and hand them down to a single select statement. Problem solved.&lt;br /&gt;
&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Fri, 22 Feb 2008 12:04:50 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/100-guid.html</guid>
    <category>cl-sql</category>
<category>lisp</category>

</item>
<item>
    <title>Interactive development gets more popular</title>
    <link>http://hillview.1on.de/archives/99-Interactive-development-gets-more-popular.html</link>
            <category>Programming</category>
    
    <comments>http://hillview.1on.de/archives/99-Interactive-development-gets-more-popular.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=99</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=99</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    It&#039;s interesting to see that more and more environments for interactive development are popping up. If you&#039;re wondering what I&#039;m refering to, it&#039;s what has traditionally been labelled as an interpreter: you get some kind of prompt like in a command shell and can directly enter and run program constructs.  In Ruby, irb is the tool to use, whereas most, if not all, Common Lisp systems provide you a REPL whenever you start-up the system. &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=398&amp;amp;entry_id=99&quot;  onmouseover=&quot;window.status=&#039;http://en.wikipedia.org/wiki/REPL&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://en.wikipedia.org/wiki/REPL&quot;&gt;REPL&lt;/a&gt; is an abbreviation for read-eval-print-loop and this pretty much sums up how interactive development works: you enter some code into the system, and as soon as you hit enter (i.e. finish up the particular line of code), the system will read and evaluate it (&quot;interpret&quot; it, although CL systems may also compile it automatically), presenting you with  the results. &lt;br /&gt;
&lt;br /&gt;
To me, this seems like more people come to understand that the classic edit-compile-debug cycle of traditional compiled languages like C isn&#039;t particular well-suited to a bottum-up programming style, as advocated by the agile programming hype.  Where is the beef? I&#039;ve been told that the reason why the asian folk don&#039;t use forks and knives when dining stems from the opinion that when dining one merely wants to eat, while all handcrafting (like slicing the meat) belongs to the a-priori cooking. The edit-compile-debug cycle tends to produce code more akin to the western steak style, while interactive development tends to produce smaller code parts, all well prepared (read: tested) from the beginning, so you don&#039;t end up with bloody interiors as easily. That&#039;s because of two reasons, I think: In an interactive environment testing a piece of code is cheap and easy. Hack up a small routine and enter it. Next step: call the routine with some sample data. No need to compile. In case there&#039;s an error, you&#039;ll be thrown into the debugger right away. With the traditional edit-compile-debug cycle, you&#039;re gonna edit the code, save it, call the compiler, edit another piece of code testing it, compile that, too, run that and only then you&#039;ll see if it succeeds. This might scare developers from running such tests to often and in result to produce larger routines/code blocks. Second reason: in the interactive environment you&#039;ll typically have somewhat less comfort then in a full-blown editor. So I&#039;m arguing that the slight discomfort will help you in keeping things small because then you&#039;ll not gonna need far reaching edit support.&lt;br /&gt;
&lt;br /&gt;
There is, however, a price to pay: For starters, because your interactive system provides you with a single environment during development, it&#039;s easy to mess it up. That&#039;s different with the traditional edit-compile-debug cycle where every time you compile you run the code in a clean environment. This means, old code refering to refactored functions will result in (usually: compilation)  errors whereas in interactive development you may miss some spot in need for modification because the old refactored code is still around.&lt;br /&gt;
Second, when fiddling with some functions, it may happen that one hacks up several variants, maybe with only slightly differing names or argument lists, so it may happen you forget some crucial code when  finally saving your carefully crafted solution (where saving here typically means copy it over to some editor, not saving an image as you may do in Smalltalk or Lisp). Another thing is that one has to be careful not to confuse bottum-up interactive development with hacking without thinking or design-less programming. This threat is all to common because with an interactive environment it&#039;s just so easy to get started. Unfortunately, without thinking you&#039;ll soon end up with problems one and two and even worse, it&#039;s likely that after a little while nobody (including you, the author) will be able to maintain the resulting code. But if you&#039;re aware of the potential pitfalls, interactive development is a nice way to do explorative programming which avoids a lot of time consuming labour you have to do with the traditional edit-compile-debug cycle.&lt;br /&gt;
&lt;br /&gt;
As a side-note, environments offering incremental compilation like Eclipse aim at a similar goal, but only go  half the way as they only take care of the edit-compile part. Only when one combines that with a test-driven development style you arrive at a similar point, because now the test code, when automatically run, will take care of immediately running the code in question (the eval/print part as far as testing the code is concerned).&lt;br /&gt;
&lt;br /&gt;
To finally come to the reason for this blog post, I was pleased to learn about the &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=399&amp;amp;entry_id=99&quot;  onmouseover=&quot;window.status=&#039;http://www.sukria.net/perlconsole.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://www.sukria.net/perlconsole.html&quot;&gt;Perl Console&lt;/a&gt;, which is &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=400&amp;amp;entry_id=99&quot;  onmouseover=&quot;window.status=&#039;http://www.sukria.net/en/archives/2007/08/29/why-i-wrote-perl-console-or-why-i-dont-use-perl-e-1-d/&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://www.sukria.net/en/archives/2007/08/29/why-i-wrote-perl-console-or-why-i-dont-use-perl-e-1-d/&quot;&gt;not the same as the Perl debugger&lt;/a&gt;. I&#039;m eager to try it out, although I&#039;m sure that interactive development with a repl and the executable brain dump that Perl code usually is, is a highly dangerous mix. &lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Update:&lt;/u&gt; There is also &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=401&amp;amp;entry_id=99&quot;  onmouseover=&quot;window.status=&#039;http://chainsawblues.vox.com/library/post/a-perl-read-excute-print-loop-repl.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://chainsawblues.vox.com/library/post/a-perl-read-excute-print-loop-repl.html&quot;&gt;a series of articles about implementing a REPL in Perl&lt;/a&gt; which may be of interest.&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Fri, 25 Jan 2008 10:14:07 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/99-guid.html</guid>
    <category>lisp</category>
<category>perl</category>

</item>
<item>
    <title>Twentieth century boys</title>
    <link>http://hillview.1on.de/archives/98-Twentieth-century-boys.html</link>
            <category>Lisp</category>
    
    <comments>http://hillview.1on.de/archives/98-Twentieth-century-boys.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=98</wfw:comment>

    <slash:comments>5</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=98</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    This is just a minor rambling inspired by a &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=389&amp;amp;entry_id=98&quot;  onmouseover=&quot;window.status=&#039;http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/ef6822230da2c706/d448366d4a559cad#d448366d4a559cad&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;recent thread on cll&quot;&gt;recent thread on cll&lt;/a&gt; about the ups and downs of using Rails. What I find really overwhelming is the lack of proofs that other (typically Lisp-based) frameworks really have so much benefit over the established more traditional frameworks (e.g. Rails, Zope, plain PHP, ...). All I can see is starter documents, tutorials etc. that show how to program yet another blog or reddit clone in some particular framework. I miss fair comparisons and detailed discussions why and where exactly that one particular way of doing things has benefits. And especially with regard to those reddit clone prototypes: AFAICT, reddit was far beyond implementing some half-baked prototype (in Lisp) when they decided to switch (to Python). Yes, for demo purposes reinventing the wheel with some unround edges might be acceptable, but in reality only rolling wheels will be sold and this is where the challenge is.&lt;br /&gt;
&lt;br /&gt;
I believe that while it&#039;s nice that frameworks help with implementing your 500 line application, they really need to show their value with large applications. Where is a discussion of a large on-line shopping system in, say, UCW and CL-SQL, with secure shopping over SSL, login handling, input validation, distribution over multiple servers etc.?  Now, I&#039;m not suggesting that UCW, Weblocks etc. can&#039;t be used to build such websites, but it would be nice to see a much more in-depth explanation/discussion/comparison of how to do it. That would also help increase the credibility of Lisp or at least, of lispers discussing (other) web frameworks. 
    </content:encoded>

    <pubDate>Tue, 22 Jan 2008 19:04:00 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/98-guid.html</guid>
    <category>cl-sql</category>
<category>lisp</category>
<category>web development</category>

</item>
<item>
    <title>CLOS Video in German/auf Deutsch</title>
    <link>http://hillview.1on.de/archives/96-CLOS-Video-in-Germanauf-Deutsch.html</link>
            <category>German</category>
            <category>Lisp</category>
    
    <comments>http://hillview.1on.de/archives/96-CLOS-Video-in-Germanauf-Deutsch.html#comments</comments>
    <wfw:comment>http://hillview.1on.de/wfwcomment.php?cid=96</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://hillview.1on.de/rss.php?version=2.0&amp;type=comments&amp;cid=96</wfw:commentRss>
    

    <author>nospam@example.com (Holger Schauer)</author>
    <content:encoded>
    In case you&#039;re interested in object-oriented programming in Lisp and happen to speak German, you&#039;ll be happy to learn that &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=379&amp;amp;entry_id=96&quot; title=&quot;http://p-cos.blogspot.com/2007/12/reflection-in-potsdam.html&quot;  onmouseover=&quot;window.status=&#039;http://p-cos.blogspot.com/2007/12/reflection-in-potsdam.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;&gt;Pascal Costanza&lt;/a&gt; of ContextL and AspectL fame (apart of his postings to cll), has given a &lt;a href=&quot;http://hillview.1on.de/exit.php?url=aHR0cDovL3d3dy50ZWxlLXRhc2suZGUvcGFnZTUwX2xlY3R1cmUzMzUyLmh0bWw8YnIgLz4NCg==&amp;amp;entry_id=96&quot;  onmouseover=&quot;window.status=&#039;http://www.tele-task.de/page50_lecture3352.html&amp;lt;br /&amp;gt;
&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://www.tele-task.de/page50_lecture3352.html&quot;&gt;talk about CLOS&lt;/a&gt;, the Common Lisp Object System at the Hasso-Plattner Institut, Potsdam. And while we&#039;re at it, Pascal also has a very interesting &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=380&amp;amp;entry_id=96&quot;  onmouseover=&quot;window.status=&#039;http://p-cos.blogspot.com/2007/12/origin-of-advice.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://p-cos.blogspot.com/2007/12/origin-of-advice.html&quot;&gt;blog post about the origins of the advice facility&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
German:&lt;br /&gt;
Falls Dich, lieber Leser, interessiert, wie man objekt-orientiert in Lisp programmiert, solltest Du Dich darüber freuen, dass &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=379&amp;amp;entry_id=96&quot;  onmouseover=&quot;window.status=&#039;http://p-cos.blogspot.com/2007/12/reflection-in-potsdam.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://p-cos.blogspot.com/2007/12/reflection-in-potsdam.html&quot;&gt;Pascal Costanza&lt;/a&gt;, bekannt durch ContextL und AspectL (abgesehen von seinen Postings in cll), einen &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=382&amp;amp;entry_id=96&quot;  onmouseover=&quot;window.status=&#039;http://www.tele-task.de/page50_lecture3352.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://www.tele-task.de/page50_lecture3352.html&quot;&gt;Vortrag in Deutsch über CLOS&lt;/a&gt;, dem Common Lisp Object System, am Hasso Plattner Institut in Potsdam gehalten hat. Und weil wir gerade dabei sind, Pascal hat außerdem einen sehr interessanten &lt;a href=&quot;http://hillview.1on.de/exit.php?url_id=380&amp;amp;entry_id=96&quot;  onmouseover=&quot;window.status=&#039;http://p-cos.blogspot.com/2007/12/origin-of-advice.html&#039;;return true;&quot; onmouseout=&quot;window.status=&#039;&#039;;return true;&quot;  title=&quot;http://p-cos.blogspot.com/2007/12/origin-of-advice.html&quot;&gt;Blogeintrag über die Geschichte von &#039;advice&#039;&lt;/a&gt;.&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Thu, 20 Dec 2007 00:40:02 +0100</pubDate>
    <guid isPermaLink="false">http://hillview.1on.de/archives/96-guid.html</guid>
    <category>lisp</category>

</item>

</channel>
</rss>