<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3022969446495862761</id><updated>2012-01-10T10:16:45.915+01:00</updated><category term='ruby'/><category term='arm'/><category term='fpga'/><category term='freebsd vdsl'/><category term='midi java sysex max'/><category term='javascript'/><category term='clojure'/><category term='bknr'/><category term='secd'/><category term='forth fpga hardware'/><category term='lisp'/><category term='forth'/><category term='hardware'/><title type='text'>netzhansa</title><subtitle type='html'>Lisp, Forth and Hardware.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>52</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1373366104575303783</id><published>2012-01-10T07:55:00.002+01:00</published><updated>2012-01-10T10:16:45.922+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup: Tuesday 24 January 8 pm at co.up</title><content type='html'>&lt;p&gt;
You are kindly invited to the next Berlin Lispers Meetup, an informal
gathering for anyone interested in Common Lisp and other languages in the
Lisp family.
&lt;/p&gt;
Berlin Lispers Meetup&lt;br/&gt;
Tuesday January 24, 2012&lt;br/&gt;
&lt;b&gt;8 pm&lt;/b&gt; onwards&lt;br/&gt;
&lt;b&gt;co.up (bell: Upstream Agile)&lt;/b&gt;, Adalbertstraße 7, 10999 Berlin
(U-Bahn Kottbusser Tor)&lt;br/&gt;
&lt;p&gt;
There will be two presentations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;"Further notes on sparql processing" by James Anderson and Arto
Bendiken who are affiliated with Datagraph, Inc.&lt;/li&gt;
&lt;li&gt;"A suggestion for parentheses representation in a Common Lisp IDE"
by Nuno Rocha.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Please join for another evening of parentheses!
&lt;/p&gt;
&lt;p&gt;
Twitter: &lt;a href="https://twitter.com/#!/BerlinLispers"&gt;@BerlinLispers&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1373366104575303783?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1373366104575303783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2012/01/berlin-lispers-meetup-tuesday-24.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1373366104575303783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1373366104575303783'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2012/01/berlin-lispers-meetup-tuesday-24.html' title='Berlin Lispers Meetup: Tuesday 24 January 8 pm at co.up'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-3746959345663901385</id><published>2011-12-11T12:15:00.001+01:00</published><updated>2011-12-11T15:24:26.693+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Learning Ruby, and Ruby vs. Lisp</title><content type='html'>The company I work for has a lot of legacy Ruby code, and as Ruby
  has become kind of a mainstream language, I decided to get a book
  about it and learn how it works.
  &lt;p&gt;
    As my learning resource, I chose &lt;a
    href="http://shop.oreilly.com/product/9780596516178.do"&gt;The Ruby
    Programming language by David Flanagan and Yukihiro Matsumoto&lt;/a&gt;
    as that receives great customer reviews, covers Ruby 1.8.7 and 1.9
    and is authoritative because the language creator is one of the
    authors.
  &lt;/p&gt;
  &lt;p&gt;
    The book makes a good read in general.  There are plenty of code
    examples, but not too much to obscure the prose.  What I found
    first interesting, later annoying, was the frequent use of words
    like "complex", "complicated", "confusing", "surprising" or
    "advanced" to describe features of the language.  I'd rather
    decide myself about using such attributes to describe something
    that I've just learned.
  &lt;/p&gt;
  &lt;p&gt;
    Having spent so much time with Common Lisp, I almost forgot that
    programming languages usually evolve over the years.  Ruby is no
    exception, and the fact that there are significant differences
    between Ruby 1.8.7 and Ruby 1.9 kind of bothers me - I'll probably
    never write code in Ruby 1.8.7, but the differences between the
    two versions seem to be rather subtle and I'm curious to see how
    much that is going to be a bother in the future, working with
    legacy code.
  &lt;/p&gt;
  &lt;p&gt;
    The common theme for Ruby seems to be succinctness.  This comes at
    the expense of making the syntax rather complex, with several
    special case rules required to solve ambiguities.  I don't have
    the practice to judge whether this is a problem, but from the
    book, it seems there are quite some things to remember.
  &lt;/p&gt;
  &lt;p&gt;
    It seems that Ruby started off as a purely object oriented
    language and only later discovered that function-oriented
    programming is nice, too.  The deep roots of object orientation
    made it rather hard to actually get free functions (which are not
    member functions of an object) integrated.  Contrary to what I am
    used to, member functions are not a special case of free
    functions, but rather something quite different.  It requires
    explicit conversion steps to convert a member function into a free
    function (called procs in Ruby), and invocation syntax is also
    different between the two.  Again, the description may sound worse
    than it is in practice.
  &lt;/p&gt;
  &lt;p&gt;
    What I really liked was the generalization of code blocks into
    fibers.  Ruby does not have full coroutines, but the restricted
    form that is available is generalized well and seems like it could
    be useful for building pretty wild asynchronous systems.  Also, it
    is nice that the bindings of closures can be accessed.
  &lt;/p&gt;
  &lt;p&gt;
    But then, Ruby is an interpreted language and this fact is
    re-stated throughout the book.  With Just In Time compilation,
    this could become a non-problem, but I'm not sure how well Ruby
    can be optimized due to its very dynamic nature.  Just to see how
    fast it is compared to Common Lisp, I &lt;a
    href="https://gist.github.com/1459896#file_sudoku.lisp"&gt;implemented&lt;/a&gt; the Sudoku
    solver from chapter 1 of the Ruby book in CL and gave the two
    implementations a &lt;a
    href="http://i1-games.softpedia-static.com/screenshots/1-3712_2.jpg"&gt;puzzle&lt;/a&gt;
    to solve.  It took the Ruby solver 0.890 CPU seconds (Ruby
    1.9.2p290), whereas the Lisp solver (Clozure CL 1.7) used 0.087
    CPU seconds to solve the puzzle.  Ten times slower, whatever
    you'll make of that.
  &lt;/p&gt;
  &lt;p&gt;
    In the book, it is mentioned how little code the Sudoku solver
    actually uses.  This is true, but then, the Lisp version is not
    longer.  It does not seem as if adding syntax is actually the best
    way to add the possibility to write succinct programs to a
    language, and the price of the complex grammar is rather high.
  &lt;/p&gt;
  &lt;p&gt;
    Writing the CL solver, I found myself not writing tests again and
    then poking around in problems of my implementation without
    knowing what works and what does not.  As I want to practice more
    TDD, I stepped back and added tests.  This led me to solve a
    problem that I had with my previous attempts to practice TDD in
    Lisp - I do not want to export all the symbols that the tests
    exercise from the packages that I use, but I also don't want to
    import the unit testing library into my own library packages.
    Thus, I wrote a &lt;a
    href="https://gist.github.com/1459896#file_sudoku_test.lisp"&gt;deftestpackage&lt;/a&gt;
    macro that creates a new package to contain the tests that I write
    and automatically imports all symbols from the package being
    tested.  That way, I can easily keep tests and library source
    separate and don't need to qualify internal symbols in the tests.
  &lt;/p&gt;
  &lt;p&gt;
    My overall takeaway on the Ruby is this:  Ruby seems to be a
    language that has grown from being purely object oriented to
    supporting functional programming.  That growth was not completely
    natural, and it seems that if Ruby is not used as a pure object
    oriented language, the syntax becomes rather messy and hard to
    grasp.  This is similar to C++, which in its first versions was
    relatively nice (I hear you "ow"!), but has grown into into an
    incomprehensible mess once people recognized how templates can be
    abused for metaprogramming.
  &lt;/p&gt;
  &lt;p&gt;
    I can see the appeal of Ruby, but there seems little it has to
    offer to me that Common Lisp cannot provide.  The lack of a formal
    specification and the ugly grammar put me off.  Then again I'm
    pretty sure that Ruby is more enjoyable than many other popular
    languages.  I'm looking forward to see my theoretical conceptions
    be shaken by actual practice.
  &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-3746959345663901385?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/3746959345663901385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/12/learning-ruby-and-ruby-vs-lisp.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3746959345663901385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3746959345663901385'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/12/learning-ruby-and-ruby-vs-lisp.html' title='Learning Ruby, and Ruby vs. Lisp'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-6481568058081760363</id><published>2011-12-05T10:28:00.001+01:00</published><updated>2011-12-05T20:21:58.527+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Global Day of Code Retreat with Lisp</title><content type='html'>Last Saturday, I attended the Global Day of Code Retreat.  I found
  out about the event in my Twitter stream, and when I signed up for
  the event, I did not have much of an idea of what it would be about,
  except code.  With some research, I found that it would be a day of
  using Test Driven Development practices to improve on coding style
  and quality.  Fair enough I thought, got myself a book on TDD (which
  I have always wanted to do more) and reserved my seat, which was
  free.
  &lt;p&gt;
    The event was hosted by &lt;a
    href="http://immobilienscout24.de/"&gt;immobilienscout24&lt;/a&gt; and
    sponsored by &lt;a href="http://nokia.com/"&gt;Nokia&lt;/a&gt;.  Sponsoring
    included catering, and as the day started at 8:00am, the
    availability of a breakfast was very welcome.  The crowd consisted
    of some 30 hackers.  An informal poll showed that most of them
    were either using Java or Ruby as their first language, a few were
    into JavaScript.  One guy said that C++ was his primary language,
    and I was the only Common Lisp hacker.
  &lt;/p&gt;
  &lt;p&gt;
    The format of the all-day event consisted of six sessions of 45
    minutes.  In every session, people would form new pairs and
    implement parts of &lt;a
    href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life"&gt;Conway's
    Game of Life&lt;/a&gt; using TDD practices.  For each session, the pair
    chooses a specific challenge or goal to solve.  At the end of the
    session, every pair deletes their code, discusses what they
    learned and then joins the group to share their thoughts.
  &lt;/p&gt;
  &lt;p&gt;
    The focus of the goals and challenges was on TDD practices.  For
    about a half of the participants, TDD was already part of their
    daily work routine.  The other half had heard of TDD, like myself,
    and joined to learn about it in the event.  For me, this was one
    of the bigger takeways.  I found it very helpful to pair with
    people that practice TDD in order to learn how they'd go about to
    write a test before they'd write an implementation.  It seems that
    the TDD school favors a very small test granularity.  As was
    explained by the organizer of the meeting, one would write very
    small tests that exercise very small aspects of the production
    code initially, and then build up on that.
  &lt;/p&gt;
  &lt;p&gt;
    In the six sessions, I used Java, JavaScript and Common Lisp.  For
    Java, the organizers had come up with a skeleton project that
    included a unit testing environment (jUnit?).  For JavaScript, I
    had prepared a simple browser based environment with QUnit, for
    Common Lisp I used Clozure CL and the simple &lt;a
    href="http://bknr.net/trac/browser/trunk/thirdparty/unit-test/unit-test.lisp"&gt;unit-test&lt;/a&gt;
    library that I have used in the past.
  &lt;/p&gt;
  &lt;p&gt;
    Here are some observations:
  &lt;/p&gt;
  &lt;h2&gt;The Java dudes travel with heavy baggage&lt;/h2&gt;
  &lt;p&gt;
    &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ&lt;/a&gt; was the most
    popular IDE among the Java folks that I've talked to.  I am split
    between admiration and disgust when it comes to what seems common
    practice in the Java world.  I'm used to write code by thinking
    about what I want to write, then typing the stuff that I've
    thought about.  With Java and IntelliJ, the process is more
    interactive with the IDE, i.e. the programmer types a few
    characters, the IDE displays some menu to choose from or
    automatically adds code and so on.  This is nice when the IDE
    automatically recognizes, say, that you are using a name of a
    class that has not yet been defined or imported and then offers
    you to either import a package that defines a class of the name
    that you've typed, or to create a class skeleton (including all
    the boilerplate and ceremony that Java wants) for you.
  &lt;/p&gt;
  &lt;p&gt;
    While this appears to be convenient, it also does not always work.
    In both of my Java sessions, the IDE got confused in some way or
    another, which was not fatal, but still annoyed me.  Also, the
    static nature of Java slowed us down.  For one, even though Java
    does have all the nice data structures (we wanted to use a set of
    coordinates), we wasted a lot of the short session times
    converting data types and supplying boilerplate that allowed us to
    actually put coordinate objects into a set.  Also, file based
    compilation took time - Not minutes, but seconds.  I was assured
    that one would use libraries and code generators in production
    code and that desktop machines were faster in compiling, but I
    still can't really relate Java to Agile, in the sense of the word.
  &lt;/p&gt;
  &lt;p&gt;
    Also, the use of code generators in IntelliJ makes me wonder how
    one maintains such code.  How can one actually distinguish between
    what was carefully crafted and what was pasted, from templates, by
    the IDE?  In my eyes, this is like copy and paste programming with
    the copy step optimized into templates.  I'm not the first to say
    that and it does not come as a surprise either, but it was an
    interesting experience for me nevertheless.
  &lt;/p&gt;
  &lt;h2&gt;Pair programming is fun&lt;/h2&gt;
  &lt;p&gt;
    Being a remote consultant, I rarely have the chance to interact
    over code with other programmers.  This was something I found
    enjoyable to practice, even in languages and environments that I'm
    not familiar with.  It is amazing how vastly different the
    approaches to implementing a relatively simple thing can be, and
    compared to code reviews - in particular if they're done by email
    - it is much easier to make suggestions in a constructive
    way.  In that respect, writing code that is supposed to be deleted
    also helps concentrating on the essence as no sense of code
    ownership is developed.
  &lt;/p&gt;
  &lt;p&gt;
    I found the pair programming experience significantly impacted by
    the fact that programmers use different coding environments.
    Working on an unfamiliar keyboard and with an unfamiliar IDE is a
    real productivity killer.  I'd hope that in a team that pairs
    regularly, the work environments are more standardized than they
    have been on this event.  I was using Emacs for my Lisp and
    JavaScript sessions, and my partners had a hard time getting
    along.  What I found rather interesting was that the guys who
    wrote JavaScript in my Emacs always mimiced what their IDE would
    do for them.  Rather then writing "if (foo) { doSomething()",
    they'd type "if (foo) {}", then navigate into the braces with the
    cursor to code along.  This is kind of curious because it seems
    that the balancing of parentheses, brackets and braces is much
    more of a chore in other languages, to the point where people slow
    themselves down a lot if not aided by an IDE to the balancing for
    them.  We Lispers, with only the parentheses to keep track of,
    have a much easier life, in particular with Emacs doing the
    indentation for us.
  &lt;/p&gt;
  &lt;h2&gt;Is TDD the kool aid?&lt;/h2&gt;
  &lt;p&gt;
    In some sense, I am sceptical about TDD.  Testing is a great idea,
    and doing it in a disciplined fashion certainly helps writing
    better quality software.  Also, automated tests are really the
    best way to prepare software for change.  But, and this is where
    this Saturday could not convince me, I don't believe that spending
    time on writing very fine grained unit tests for every aspect of
    of a program helps preparing it better for refactoring
    and change.  I think that testing against external requirements is
    the real key to writing programs that can be changed facing
    changing requirements, and that it should be possible to relate
    every test to some requirement.  I must admit that one
    Saturday of TDD does not give me sufficient experience to judge, though.
  &lt;/p&gt;
  &lt;h2&gt;Common Lisp and TDD&lt;/h2&gt;
  &lt;p&gt;
    Some of the TDD discipline probably owes to development cycle in
    statically compiled languages.  Where we Common Lispers have a
    rather incremental style and do our testing interactively in the
    repl, developers in languages like Java or C++ write larger chunks
    of code before they plug it together to do something meaningful.
    Such environments give the developer less insight into the
    run-time behavior of a running system, and tests are a way to make
    sure that more of the interactions of the system components are
    actually exercised.
  &lt;/p&gt;
  &lt;p&gt;
    I am not claiming that an interactive development environment
    makes testing less useful.  In such an environment, though, it is
    common to write and test a function in small, iterative cycles.
    Furthermore, through the use of a tracing facility, the dynamic
    bahavior of a system can be observed at any time, without the need
    to touch or recompile the code.
  &lt;/p&gt;
  &lt;p&gt;
    In any case, this was a very nice experience and I'll go to a Code
    Retreat again, if I can.  For that, I'll probably prepare myself
    for Java tools better in order to get more out of pair programming.
  &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-6481568058081760363?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/6481568058081760363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/12/global-day-of-code-retreat-with-lisp.html#comment-form' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6481568058081760363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6481568058081760363'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/12/global-day-of-code-retreat-with-lisp.html' title='Global Day of Code Retreat with Lisp'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-3007943475929831190</id><published>2011-10-30T21:58:00.000+01:00</published><updated>2011-10-30T21:58:34.700+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Hunchentoot v1.2.0 released</title><content type='html'>&lt;p&gt;
After over a year of no releases, Hunchentoot v1.2.0 is out.  It incorporates a large number of changes from various people and is the first release that I have made as the maintainer of Hunchentoot.  There have been a fair number of changes, many of them contributed by Hunchentoot's users.  Thank you all for that!
&lt;/p&gt;
&lt;p&gt;
The release tarball is available here:  &lt;a href="https://github.com/downloads/edicl/hunchentoot/hunchentoot-1.2.0.tar.gz"&gt;https://github.com/downloads/edicl/hunchentoot/hunchentoot-1.2.0.tar.gz&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
This is my first release, and as such it is likely that I'm not yet up to the release standards that Edi has set forth.  Please report any problems you may have with the new version to the Hunchentoot mailing list.  I will try to resolve problems quickly and possible make a new minor release for each major problem found.
&lt;/p&gt;
&lt;p&gt;
The development repository for Hunchentoot is now hosted on &lt;a href="https://github.com/edicl/hunchentoot"&gt;github&lt;/a&gt;.  If you want to contribute, it would be appreciated if you could submit your patches through github, too.
&lt;/p&gt;
&lt;p&gt;
Here is a list of changes:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add www/ directory with default file tree that is being served&lt;/li&gt;
&lt;li&gt;Add error template mechanism and improve error reporting in general.&lt;/li&gt;
&lt;li&gt;Improve automatic testing, SBCL kludge to support asdf:test-op&lt;/li&gt;
&lt;li&gt;Allegro CL modern mode fixes&lt;/li&gt;
&lt;li&gt;Fix bugs in serving partial responses&lt;/li&gt;
&lt;li&gt;Limit maximum number of threads that Hunchentoot creates (Dan Weinreb, Scott McKay)&lt;/li&gt;
&lt;li&gt;Export fixes (Gordon Sims, Andrey Moskvitin)&lt;/li&gt;
&lt;li&gt;Factor out easy-handler logic into separate acceptor subclass&lt;/li&gt;
&lt;li&gt;Export two session functions (Nico de Jager)&lt;/li&gt;
&lt;li&gt;Allow no Content-Type header (Chaitanya Gupta)&lt;/li&gt;
&lt;li&gt;Patch for compilation with ECL (Sohail Somani)&lt;/li&gt;
&lt;li&gt;Fix DEFINE-EASY-HANDLER for multiple acceptors (Nicolas Neuss)&lt;/li&gt;
&lt;li&gt;Revived *SHOW-LISP-BACKTRACES-P*&lt;/li&gt;
&lt;li&gt;Made sure "100 Continue" is returned even if the client sends "Expect: 100-continue" twice (reported by Gordon Sims)&lt;/li&gt;
&lt;li&gt;Fixed typo in code which interprets transfer encodings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Thank you for your patience!&lt;br/&gt;
Hans
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-3007943475929831190?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/3007943475929831190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/10/hunchentoot-v120-released.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3007943475929831190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3007943475929831190'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/10/hunchentoot-v120-released.html' title='Hunchentoot v1.2.0 released'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-8829850393346023465</id><published>2011-10-16T17:01:00.001+02:00</published><updated>2011-10-16T17:01:09.457+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup: Thursday 20 October 8 pm in St Oberholz</title><content type='html'>&lt;p&gt;
You are kindly invited to the next "Berlin Lispers Meetup", an informal gathering for anyone interested in Lisp, beer or coffee:
&lt;/p&gt;
Berlin Lispers Meetup&lt;br/&gt;
Thursday October 20, 2011&lt;br/&gt;
&lt;b&gt;8 pm&lt;/b&gt; onwards&lt;br/&gt;
&lt;b&gt;St Oberholz, Rosenthaler Straße 72, 10119 Berlin&lt;/b&gt;&lt;br/&gt;
U-Bahn Rosenthaler Platz&lt;br/&gt;
&lt;p&gt;
We will try to occupy a nice table at the floor level, but in case you
don't see us please contact Hans: 0177 512 1024.
&lt;/p&gt;
&lt;p&gt;
Please join for another evening of parentheses!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-8829850393346023465?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/8829850393346023465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/10/berlin-lispers-meetup-thursday-20.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8829850393346023465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8829850393346023465'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/10/berlin-lispers-meetup-thursday-20.html' title='Berlin Lispers Meetup: Thursday 20 October 8 pm in St Oberholz'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-7750265339075543311</id><published>2011-09-27T16:15:00.003+02:00</published><updated>2011-09-27T16:15:59.836+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Finding Changes to Quicklisped Software</title><content type='html'>&lt;p&gt;
In my current project, I'm working with Allegro CL in modern mode. Modern mode is a non-standard mode supporting mixed-case symbols in the reader.  This means that in modern mode, the two literal symbols :foo and :FOO are different things.  This is different from other lisps, that convert names of literal symbols read to uppercase before interning them.  This is why :foo, :Foo and :FOO all mean the same :FOO, by default.
&lt;/p&gt;
&lt;p&gt;
I am using the excellent &lt;a href="http://www.quicklisp.org/"&gt;Quicklisp&lt;/a&gt; package management utility to pull all dependencies that a certain package needs.  With ACL in modern mode, though, I had to fix several libraries that used all-caps symbol literals (like #:FOO, NIL etc.).  The fixes were mostly trivial, but when I had all the stuff running that I wanted, I had modified several of the libraries that I had installed with Quicklisp.
&lt;/p&gt;
&lt;p&gt;
I am planning to import all the external libraries into git repositories and not use Quicklisp in production.  I still want to be able to easily update to new upstream versions and also send the changes that I made myself upstream.  To make the process of finding what I've changed easier, I envisioned a tool that tells me which of the libraries that I had installed with Quicklisp have local changes, and what these changes were.  I asked Zach Beane for help, and he promptly came up with a small function called QDIFF that performs a diff between Quicklisp's base version and the locally extracted version of a library.  I hacked the tool slightly to make it work with Allegro CL and iterate over all locally installed systems.  It is available as a &lt;a href="https://gist.github.com/1245001"&gt;gist&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Zach supplied a SBCL specific way to run the diff command.  I added one based on ASDF:RUN-SHELL-COMMAND, which apparently prefixes all output lines with "; ".  I don't like that, but I also did not want to pull in a shell compatibility layer into this self-contained thing.
&lt;/p&gt;
&lt;p&gt;
I praised Quicklisp in the past, but there is nothing wrong with doing it again.  Open Source Common Lisp has become so much better with it, and I need to thank Zach again for being so passionate about making the Common Lisp world better!  Thanks, Zach!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-7750265339075543311?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/7750265339075543311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/09/finding-changes-to-quicklisped-software.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/7750265339075543311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/7750265339075543311'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/09/finding-changes-to-quicklisped-software.html' title='Finding Changes to Quicklisped Software'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1233292121388675660</id><published>2011-08-30T11:12:00.004+02:00</published><updated>2011-08-30T11:24:42.007+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Ediware moving to github</title><content type='html'>&lt;p&gt;I have been more or less the primary maintainer for the &lt;a href="http://weitz.de/hunchentoot/"&gt;Hunchentoot&lt;/a&gt; web server written in Common Lisp for several years now.  Its primary Author, Edi Weitz, has been doing Lispworks related work and release engineering, but he now intends to step down from that role, too.&lt;/p&gt; 
&lt;p&gt;In order to open up development and encourage hacking and extending Hunchentoot, we have decided to move the development from the aging BKNR Subversion repository to &lt;a href="https://github.com/edicl/hunchentoot"&gt;github&lt;/a&gt;.  That will make it easier to fork new versions, integrate patches, discuss code changes and track issues.&lt;/p&gt;
&lt;p&gt;Together with Hunchentoot, a bunch of other libraries written by Edi Weitz have been moved to the &lt;a href="https://github.com/edicl/"&gt;edicl organization on github&lt;/a&gt;.  The list is not complete and currently consists of libraries that I have used or hacked in the past.  Feel free to &lt;a href="mailto:edicl@netzhansa.com"&gt;let us know&lt;/a&gt; if you'd like some other of Edi's libraries to be relocated.&lt;/p&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1233292121388675660?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1233292121388675660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/08/ediware-moving-to-github.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1233292121388675660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1233292121388675660'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/08/ediware-moving-to-github.html' title='Ediware moving to github'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-749383147473246304</id><published>2011-05-12T20:59:00.000+02:00</published><updated>2011-05-13T22:53:36.348+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Orphaned (?) projects on common-lisp.net</title><content type='html'>&lt;p&gt;
&lt;a href="http://common-lisp.net/"&gt;common-lisp.net&lt;/a&gt; has moved to a new (virtual) box and in the process, we are cleaning up a little.  One particular thing came to my attention: The maintainers of a number of projects can no longer be reached under the email address that they have registered with, so moderation requests bounce (to me).  Either these projects have gone stale (even the maintainer lost interest), it is an oversight, or it is just an error that should be fixed.  So, please check the list below and let me (hans.huebner@gmail.com) know if you know how to reach the maintainer(s).  Projects that we don't get any replies for will eventually have their mailing lists be closed.  Thank you for your help!
&lt;/p&gt;
&lt;p&gt;
List of projects:
&lt;ul&gt;
&lt;li&gt;cffi&lt;/li&gt;
&lt;li&gt;cl-magick&lt;/li&gt;
&lt;li&gt;cl-match&lt;/li&gt;
&lt;li&gt;cl-mpd&lt;/li&gt;
&lt;li&gt;cl-soap&lt;/li&gt;
&lt;li&gt;cl-stm&lt;/li&gt;
&lt;li&gt;ecl&lt;/li&gt;
&lt;li&gt;elephant&lt;/li&gt;
&lt;li&gt;gecol&lt;/li&gt;
&lt;li&gt;morphologie&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-749383147473246304?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/749383147473246304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/05/orphaned-projects-on-common-lispnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/749383147473246304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/749383147473246304'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/05/orphaned-projects-on-common-lispnet.html' title='Orphaned (?) projects on common-lisp.net'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-728508161640340017</id><published>2011-05-06T11:16:00.001+02:00</published><updated>2011-05-06T11:20:41.872+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Tuesday May 17, 2011: Christian Pape</title><content type='html'>Title: Berlin Lispers Meetup&lt;br/&gt;
Date: Tuesday May 17, 2011&lt;br/&gt;
Time: 7pm onwards&lt;br/&gt;
Venue: co.up, Adalbertstr. 7-8, 10999 Berlin&lt;br/&gt;
Transport: U-Bahn Kottbusser Tor, Kreuzberg&lt;br/&gt;
Admission: Free&lt;br/&gt;
&lt;p&gt;
You are kindly invited to the next "Berlin Lispers Meetup", an informal gathering for anyone interested in Lisp, beer or coffee, organized by Hans Hübner and Willem Broekema.
&lt;/p&gt;
&lt;p&gt;
We are glad to have Christian Pape as speaker, talking about:
&lt;/p&gt;
&lt;p&gt;
 "A homegrown not yet finished minimal toolkit to build desktop like
web interfaces to applications. Focus is on code reusability,
simplicity, fallback to non-Ajax, fallback to a more conventional
non-desktop like web interface and mainly learning how all this stuff
works."
&lt;/p&gt;
&lt;p&gt;
Note the new location: co.up is a coworking space very close to Kottbusser Tor. On the Adalbertstr, enter the space at number 7-8. Then walk across the parking space until you have a row of letter boxes on the right. There is the entrance to the stairs and elevator. In case of problems call Willem: 0151 419 222 72.
&lt;/p&gt;
&lt;p&gt;
Thanks go to Franz Inc., the maker of Allegro Common Lisp and the AllegroGraph Web 3.0 database, for sponsoring the Berlin Lispers meetups.
&lt;/p&gt;
&lt;p&gt;
Please join for another evening of parentheses!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-728508161640340017?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/728508161640340017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/05/berlin-lispers-meetup-tuesday-may-17.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/728508161640340017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/728508161640340017'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/05/berlin-lispers-meetup-tuesday-may-17.html' title='Berlin Lispers Meetup - Tuesday May 17, 2011: Christian Pape'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1652709485865237229</id><published>2011-04-17T22:14:00.002+02:00</published><updated>2011-04-17T23:08:08.206+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Tuesday April 19, 2011</title><content type='html'>Title: Berlin Lispers Meetup&lt;br/&gt;
Date: Tuesday April April 19, 2011&lt;br/&gt;
Time: 7pm onwards&lt;br/&gt;
Venue: co.up, Adalbertstr. 7-8, 10999 Berlin&lt;br/&gt;
Transport: U-Bahn Kottbusser Tor, Kreuzberg&lt;br/&gt;
Admission: Free&lt;br/&gt;
&lt;p&gt;
You are kindly invited to the next "Berlin Lispers Meetup", an informal gathering for anyone interested in Lisp, beer or coffee, organized by Hans Hübner and Willem Broekema.
&lt;/p&gt;
&lt;p&gt;
There will be no presentations, so this is a good opportunity to catch up with everyone.
&lt;/p&gt;
&lt;p&gt;
Note the new location: co.up is a coworking space very close to Kottbusser Tor. On the Adalbertstr, enter the space at number 7-8. Then walk across the parking space until you have a row of letter boxes on the right. There is the entrance to the stairs and elevator. In case of problems call Willem: 0151 419 222 72.
&lt;/p&gt;
&lt;p&gt;
Thanks go to Franz Inc., the maker of Allegro Common Lisp and the AllegroGraph Web 3.0 database, for sponsoring the Berlin Lispers meetups.
&lt;/p&gt;
&lt;p&gt;
Please join for another evening of parentheses!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1652709485865237229?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1652709485865237229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/04/berlin-lispers-meetup-tuesday-april-19.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1652709485865237229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1652709485865237229'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/04/berlin-lispers-meetup-tuesday-april-19.html' title='Berlin Lispers Meetup - Tuesday April 19, 2011'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-4689096621814995300</id><published>2011-03-15T12:20:00.003+01:00</published><updated>2011-03-15T12:25:55.285+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lisp Meetup - Today</title><content type='html'>Sorry for the short notice.  Please note the new location.&lt;br/&gt;
&lt;br/&gt;
Title: Berlin Lispers Meetup&lt;br/&gt;
Date: Tuesday March 15, 2011&lt;br/&gt;
Time: 7pm onwards&lt;br/&gt;
Venue: co.up, Adalbertstr. 7-8, 10999 Berlin&lt;br/&gt;
Transport: U-Bahn Kottbusser Tor, Kreuzberg&lt;br/&gt;
Admission: Free&lt;br/&gt;
&lt;br/&gt;
You are kindly invited to the next "Berlin Lispers Meetup", an
informal gathering for anyone interested in Lisp, beer or coffee,
organized by Hans Hübner and Willem Broekema.&lt;br/&gt;
&lt;br/&gt;
We are happy to announce the presentation by Willem Broekema:
 "The Lisp reader and printer: from reader macros to pretty printing"&lt;br/&gt;
&lt;br/&gt;
Note the new location: co.up is a coworking space very close to
Kottbusser Tor. From the road, walk on until you have a row of
briefcases on the right, that's the entrance to the stairs and
elevator. In case of problems call Willem: 0151 419 222 72.

Thanks go to Franz Inc., the maker of Allegro Common Lisp and the
AllegroGraph Web 3.0 database, for sponsoring the Berlin Lispers
meetups.

Please join for another evening of parentheses!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-4689096621814995300?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/4689096621814995300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2011/03/berlin-lisp-meetup-today.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/4689096621814995300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/4689096621814995300'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2011/03/berlin-lisp-meetup-today.html' title='Berlin Lisp Meetup - Today'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-236402570885067971</id><published>2010-12-01T22:09:00.002+01:00</published><updated>2010-12-01T22:11:10.222+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Tuesday December 7, 2010</title><content type='html'>Title: Berlin Lispers Meetup&lt;br/&gt;
Date: Tuesday December 7, 2010&lt;br/&gt;
Time: 7pm onwards&lt;br/&gt;
Venue: New Thinking Store, Tucholskystr. 48, 10117 Berlin&lt;br/&gt;
Transport: U-Bahn Oranienburger Tor, S-Bahn Oranienburger Straße&lt;br/&gt;
Admission: Free&lt;br/&gt;
&lt;p&gt;
You are kindly invited to the next "Berlin Lispers Meetup", an
informal gathering for anyone interested in Lisp, beer or coffee,
organized by Hans Hübner and Willem Broekema.
&lt;/p&gt;
&lt;p&gt;
We are happy to announce a presentation by &lt;em&gt;Kilian Sprotte&lt;/em&gt;:
 &lt;em&gt;"Lazy Evaluation for Computer-Aided Composition -- from PWGL to PWCLIM"&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Thanks go to Franz Inc., the maker of Allegro Common Lisp and the
AllegroGraph Web 3.0 database, for sponsoring the meeting by paying
for the venue, so that admission can be free.
&lt;/p&gt;
&lt;p&gt;
Please join for another evening of parentheses!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-236402570885067971?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/236402570885067971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/12/berlin-lispers-meetup-tuesday-december.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/236402570885067971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/236402570885067971'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/12/berlin-lispers-meetup-tuesday-december.html' title='Berlin Lispers Meetup - Tuesday December 7, 2010'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-441185087794761986</id><published>2010-10-31T18:21:00.001+01:00</published><updated>2010-10-31T18:23:53.673+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Tuesday November 2, 2010</title><content type='html'>Title: Berlin Lispers Meetup&lt;br/&gt;
Date: Tuesday November 2, 2010&lt;br/&gt;
Time: 7pm onwards&lt;br/&gt;
Venue: New Thinking Store, Tucholskystr. 48, 10117 Berlin&lt;br/&gt;
Transport: U-Bahn Oranienburger Tor, S-Bahn Oranienburger Straße&lt;br/&gt;
Admission: Free&lt;br/&gt;
&lt;p&gt;
You are kindly invited to the next "Berlin Lispers Meetup", an
informal gathering for anyone interested in Lisp, beer or coffee,
organized by Hans Hübner and Willem Broekema.
&lt;/p&gt;
&lt;p&gt;
We are happy to announce two presenters:
&lt;/p&gt;
&lt;p&gt;
- James Anderson will talk about "Control"&lt;br/&gt;
- Christian Pape, who describes himself as "non-programmer", will talk
about his successful use of Common Lisp at work
&lt;/p&gt;
&lt;p&gt;
At the last meetup we had an organizational hiccup which made us end
up in a cozy Italian restaurant; this time we'll surely be in the New
Thinking Store again.
&lt;/p&gt;
&lt;p&gt;
Thanks go to Franz Inc., the maker of Allegro Common Lisp and the
AllegroGraph Web 3.0 database, for sponsoring the meeting by paying
for the venue, so that admission can be free.
&lt;/p&gt;
&lt;p&gt;
Please join for another evening of parentheses!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-441185087794761986?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/441185087794761986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/10/berlin-lispers-meetup-tuesday-november.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/441185087794761986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/441185087794761986'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/10/berlin-lispers-meetup-tuesday-november.html' title='Berlin Lispers Meetup - Tuesday November 2, 2010'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-8373494895098235597</id><published>2010-10-19T14:20:00.002+02:00</published><updated>2010-10-19T14:26:20.230+02:00</updated><title type='text'>Raumpflege</title><content type='html'>Sollte jemand sich in Berlin mit dem Gedanken tragen, das Unternehmen "Bärliner Putzteufel" beauftragen zu wollen, so seid gewarnt:  Die Leistungsbereitschaft der Mitarbeiter ist gering, aber im Stellen hoher Rechnungen ist der Inhaber Volker Brunemann sehr beflissen.  Von Freundlichkeit und Entgegenkommen bei Kundenunzufriedenheit kann man nur träumen.  Ich kann zwar kein anderes Reinigungsunternehmen empfehlen, aber die "Bärliner Putzteufel" sind es sicher nicht.

Ja, klar.  Schon der Name hätte mich skeptisch machen sollen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-8373494895098235597?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/8373494895098235597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/10/raumpflege.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8373494895098235597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8373494895098235597'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/10/raumpflege.html' title='Raumpflege'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-8434408240531332624</id><published>2010-10-11T16:40:00.001+02:00</published><updated>2010-10-11T16:41:43.047+02:00</updated><title type='text'>Postbank saugt</title><content type='html'>&lt;p&gt;Ich bin Business-Kunde bei der Postbank, und auf meiner letzten Monatsabrechnung fand ich einen Posten "Zinsen und Gebühren" in Höhe von 66 Euro.  Ich dachte mir:  "Das ist ja viel", und schrieb eine (autorisierte und so weiter) Email an die Postbank mit der Bitte, mir diesen Posten doch mal aufzuschlüsseln.  Als ich nach 10 Tagen noch keine Antwort hatte, habe ich mal nachgefragt.  Einen Tag später erhielt ich die Antwort, daß meine Frage nicht so ohne weiteres beantwortet werden könne, und sie daher an die "Fachabteilung" zur Bearbeitung weiter geleitet wurde.  Ich glaube, ich brauche ganz schnell eine andere Bank.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-8434408240531332624?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/8434408240531332624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/10/postbank-saugt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8434408240531332624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8434408240531332624'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/10/postbank-saugt.html' title='Postbank saugt'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-378938110629705132</id><published>2010-09-30T22:30:00.002+02:00</published><updated>2010-10-01T14:32:46.931+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Tuesday October 5, 2010 - James Anderson &amp; Marijn Haverbeke</title><content type='html'>&lt;pre&gt;Title: Berlin Lispers Meetup
Date: Tuesday October 5, 2010
Time: 7pm onwards
Venue: New Thinking Store, Tucholskystr. 48, 10117 Berlin
Transport: U-Bahn Oranienburger Tor, S-Bahn Oranienburger Straße
Admission: Free

You are kindly invited to the next "Berlin Lispers Meetup", an
informal gathering for anyone interested in Lisp, beer or coffee,
organized by Hans Hübner and Willem Broekema.

We are happy to announce two presenters:

- James Anderson: "Control"
- Marijn Haverbeke: "CL-JavaScript, a JS-to-CL compiler"

The attentive reader might note that these are the same speakers as at
the September meeting. Unfortunately there were not many people
attending that meeting, perhaps due to a lack of promotion form our
side. We are grateful the presenters are willing to talk one more time.

&lt;b&gt;Update: This time, Marijn Haverbeke will talk about &lt;a href="http://github.com/akapav/js"&gt;CL-JavaScript&lt;/a&gt;.&lt;/b&gt;  

Thanks go to Franz Inc., the maker of Allegro Common Lisp and the
AllegroGraph Web 3.0 database, for sponsoring the meeting by paying
for the venue, so that admission can be free.

Please join for another evening of parentheses!
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-378938110629705132?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/378938110629705132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/09/berlin-lispers-meetup-tuesday-october-5.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/378938110629705132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/378938110629705132'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/09/berlin-lispers-meetup-tuesday-october-5.html' title='Berlin Lispers Meetup - Tuesday October 5, 2010 - James Anderson &amp; Marijn Haverbeke'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-466137190724923424</id><published>2010-09-02T22:01:00.004+02:00</published><updated>2010-09-03T17:53:41.243+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Quicklisp - The upcoming solution to Common Lisp's "library problem"</title><content type='html'>&lt;p&gt;
  We're all tired of hearing that Common Lisp is all nice, but it has
  a library problem.  True, many of the open source libraries written
  in Common Lisp are half-baked, incomplete, unmaintained and
  tasteless.  But this is true with libraries in all languages, so 
  that can't be the real problem.  The real problem, as I see it, is 
  that until now, there was no universally good way of installing a 
  library and all of its dependencies.
&lt;/p&gt;
&lt;p&gt;
  The existing, widely deployed solutions (asdf-install and clbuild)
  require external tools to work, depend on the availability of
  diverse servers in the internet, and do not have something like a
  central maintainer who ensures that things are always in basically
  working order.  Also, these solutions are rather unportable, as they
  depend on external tools and a Unixish environment which is not
  available everywhere.
&lt;/p&gt;
&lt;p&gt;
  My personal solution to this problem, until now, was to have a
  Subversion repository that contains all the libraries that any of my
  projects need.  Some of these came from release tarballs, some from
  other revision control repositories, and maintenance was manual.
  Whenever I started a new project, I brought some of those libraries
  up to date, coped with any (new) dependencies, lost backwards
  compatibility with my older projects etc.  This kind of sucked, but
  it had the beauty that both development and deployment ended up
  being relatively easy.  All that was required was a svn checkout
  from my repository, and I was all set on a new machine.
&lt;/p&gt;
&lt;p&gt;
  Recently, Zach Beane was fed up enough to do something about this:
  He created &lt;a href="http://quicklisp.org"&gt;Quicklisp&lt;/a&gt;, a
  self-contained, centrally managed, cloud hosted Lisp library system
  which aims to run everywhere and provide users with a one-stop
  solution for the "library problem".  Quicklisp is in an early alpha
  stage, but having tried it, I must say that I am pleased and
  impressed.  Finally, Common Lisp can also become a glue language
  like Python and Perl.
&lt;/p&gt;
&lt;p&gt;
  I tried Quicklisp today because Twitter has notified me that basic
  http authentication for applications will no longer be supported.
  Instead, one is now supposed to
  use &lt;a href="http://oauth.net/"&gt;OAuth&lt;/a&gt; to authenticate requests
  sent to Twitter.  This required my reaction.
&lt;/p&gt;
&lt;p&gt;
  About two years ago, I have written a small gateway program that
  forwards new postings to &lt;a href="http://planet.lisp.org/"&gt;Planet
  Lisp&lt;/a&gt; to &lt;a href="http://twitter.com/planet_lisp"&gt;Twitter&lt;/a&gt;.
  At the time, I was rather frustrated with Common Lisp and thus took
  the gateway as an opportunity
  to &lt;a href="http://netzhansa.blogspot.com/2008/10/trying-clojure.html"&gt;try
  Clojure&lt;/a&gt;.  Today, I looked at the source of the gateway again to
  find out what it would take to make it use OAuth instead of basic
  http authentication.  As the gateway was the only program I have
  written in Clojure so far, and I was not really that eager to extend
  it to OAuth.  I tried for a few minutes, but found that my old
  program did not run with the current Clojure version right away, so
  I would have to basically start setting up a Clojure development
  environment from scratch in order to be able to use an existing, open
  source OAuth library.
&lt;/p&gt;
&lt;p&gt;
  Instead, I thought I'd give Quicklisp a spin.  After all, parsing
  some XML and sending HTTP requests are no big deal in Common Lisp
  either, and an OAuth library is available, too.  With Quicklisp, all
  it should take was write some glue code to
  connect &lt;a href="http://weitz.de/drakma/"&gt;DRAKMA&lt;/a&gt;, &lt;a href="http://common-lisp.net/project/cxml/"&gt;CXML&lt;/a&gt;, &lt;a href="http://weitz.de/cl-ppcre/"&gt;cl-ppcre&lt;/a&gt;
  and &lt;a href="http://github.com/skypher/cl-oauth"&gt;cl-oauth&lt;/a&gt;.
  Installing the bunch should be a matter of loading quicklisp.lisp,
  then typing &lt;tt&gt;(ql:quickload `("drakma" "cxml" "cl-ppcre"
  "cl-oauth"))&lt;/tt&gt; and watching the show scroll by.
&lt;/p&gt;
&lt;p&gt;
  And hey, it worked right away.  I even embedded a web server in the
  gateway application so that it can be monitored by the system status
  monitors provided by my hosting provider.  All in all, rewriting the
  thing in Common Lisp and deploying it took no longer than two hours,
  and &lt;a href="http://paste.lisp.org/display/114195"&gt;the source&lt;/a&gt; is not significantly longer than the Clojure version
  either.  Furthermore, the new gateway properly deals with non-ASCII
  characters.  Embarrassingly, the Clojure gateway was buggy in that
  respect and never properly twittered the titles of my own blog
  posts.  Thanks, Zach!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-466137190724923424?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/466137190724923424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/09/quicklisp-upcoming-solution-to-common.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/466137190724923424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/466137190724923424'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/09/quicklisp-upcoming-solution-to-common.html' title='Quicklisp - The upcoming solution to Common Lisp&apos;s &quot;library problem&quot;'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-8359910640653507594</id><published>2010-06-28T14:59:00.003+02:00</published><updated>2010-06-28T15:28:13.843+02:00</updated><title type='text'>By all means, choose a distinct name for your program</title><content type='html'>&lt;p&gt;
"I love screen".  "screen?", you ask, "do you love &lt;i&gt;your&lt;/i&gt; screen or screen in general, like in sun screen?".  And right you are, screen is not a name, it is not even a very distinctive noun as it is so ambiguous.  So, when I say "I love screen", I'm talking about the &lt;a href="http://www.gnu.org/software/screen/"&gt;program&lt;/a&gt; that Oliver Laumann wrote like 23 years ago and that is probably the open source program that I have used for the longest time (basically, since it was first released).
&lt;/p&gt;
&lt;p&gt;
Now, as much as I love screen, I hate its name.  I guess that Oliver and his room mate pondered how to name the program for a while, maybe even for a new hours or days, and then went "Damn fuck it, we're just unimaginative hacker dudes, round corners are not yet invented, creative design folks avoid us like the plague (and we like it that way), let's call the darn thing &lt;i&gt;screen&lt;/i&gt; and go on hacking."
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;DON'T DO THAT, SERIOUSLY&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;
Whatever name you choose for your program, make sure that it is not a word.  If you absolutely want to use real words, choose at least two of them that never occur together anywhere else.  Better yet, invent a word.  Use Google to validate your name.  Use something stupid.  Get on with it.
&lt;/p&gt;
&lt;p&gt;
I'm writing this because the poor choice of naming for screen bites me every day.  screen has a serious bug.  Sometimes, one of the screens (sic!) hangs.  It then never recovers, and once one of the screens (yaaah!) hangs, it does not take long until the whole session ceases to work.  In the end, even trying to reattach the session hangs.
I think I do have basic Google skills, but so far I have failed to find anyone having the same problem.  I can't imagine that I would be the only person to have this problem, but the name of the program makes it impossible to find that person.
&lt;/p&gt;
&lt;p&gt;
You are making the life of your users much much easier if you give your programs names that are distinctive and unique.  Yes, Ryan Gahl and Aycan Gulez, I'm looking at you today while I write this. :)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-8359910640653507594?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/8359910640653507594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/06/by-all-means-choose-distinct-name-for.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8359910640653507594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8359910640653507594'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/06/by-all-means-choose-distinct-name-for.html' title='By all means, choose a distinct name for your program'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-7788740791107716018</id><published>2010-06-17T10:33:00.009+02:00</published><updated>2010-06-17T10:50:47.228+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>How to convert your old-style Symbolics keyboard to USB</title><content type='html'>&lt;p&gt;Peter got in touch with me because he tried to follow my &lt;a href="http://netzhansa.blogspot.com/2009/04/how-to-convert-your-symbolics-keyboard.html"&gt;instructions how to convert a Symbolics keyboard to USB&lt;/a&gt; with his old-style keyboard and he failed.  He assumed, and that was what I would have assumed, that the color coding of the internal cabling of the old and new keyboards would match, but they don't.  Here is a table that shows the pinout for both keyboard types:
&lt;/p&gt;
&lt;table border="2"&gt;
 &lt;thead&gt;
  &lt;tr&gt;
   &lt;th colspan="2"&gt;New Style&lt;/th&gt;
   &lt;th colspan="2"&gt;Old Style&lt;/th&gt;
   &lt;th rowspan="2"&gt;Function&lt;/th&gt;
   &lt;th rowspan="2"&gt;Teensy&lt;br/&gt;Pin&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th&gt;Pin#&lt;/th&gt;
   &lt;th&gt;Color&lt;/th&gt;
   &lt;th&gt;Pin#&lt;/th&gt;
   &lt;th&gt;Color&lt;/th&gt;
  &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
  &lt;tr&gt;
   &lt;td&gt;1&lt;/td&gt;
   &lt;td&gt;blue&lt;/td&gt;
   &lt;td&gt;8&lt;/td&gt;
   &lt;td&gt;white&lt;/td&gt;
   &lt;td&gt;GND&lt;/td&gt;
   &lt;td&gt;GND&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;2&lt;/td&gt;
   &lt;td&gt;yellow&lt;/td&gt;
   &lt;td&gt;&lt;/td&gt;
   &lt;td&gt;black&lt;/td&gt;
   &lt;td&gt;not&lt;/td&gt;
   &lt;td&gt;connected&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;3&lt;/td&gt;
   &lt;td&gt;green&lt;/td&gt;
   &lt;td&gt;2&lt;/td&gt;
   &lt;td&gt;red&lt;/td&gt;
   &lt;td&gt;5V&lt;/td&gt;
   &lt;td&gt;5V&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;4&lt;/td&gt;
   &lt;td&gt;red&lt;/td&gt;
   &lt;td&gt;3&lt;/td&gt;
   &lt;td&gt;green&lt;/td&gt;
   &lt;td&gt;DIN&lt;/td&gt;
   &lt;td&gt;D4&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;5&lt;/td&gt;
   &lt;td&gt;black&lt;/td&gt;
   &lt;td&gt;1&lt;/td&gt;
   &lt;td&gt;yellow&lt;/td&gt;
   &lt;td&gt;CLK&lt;/td&gt;
   &lt;td&gt;D5&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;6&lt;/td&gt;
   &lt;td&gt;white&lt;/td&gt;
   &lt;td&gt;5&lt;/td&gt;
   &lt;td&gt;blue&lt;/td&gt;
   &lt;td&gt;CLR&lt;/td&gt;
   &lt;td&gt;D6&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-7788740791107716018?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/7788740791107716018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/06/how-to-convert-your-old-style-symbolics.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/7788740791107716018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/7788740791107716018'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/06/how-to-convert-your-old-style-symbolics.html' title='How to convert your old-style Symbolics keyboard to USB'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1967856649755860905</id><published>2010-05-29T10:18:00.003+02:00</published><updated>2010-05-29T10:38:49.564+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='arm'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Embracing the ARM</title><content type='html'>&lt;p&gt;
  Last year, I worked on a project
  for &lt;a href="http://visomat.com"&gt;visomat inc.&lt;/a&gt; which involved
  interfacing to a LED matrix display so that it could display some
  video.  We had some latency problems and at one stage we decided to
  try out DMX instead of Ethernet as interface techniquce, hoping that
  we'd get better results that way.  The idea was to feed the LED
  matrix, which consisted of 12 power supplies/controllers, with 12
  DMX interfaces to make sure that data arrives at the LEDs
  synchronously.
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="http://en.wikipedia.org/wiki/DMX512"&gt;DMX&lt;/a&gt; is an asynchronous serial protocol running at 250 kbits per
  second.  I decided to try using an AVR microcontroller running at 16
  Mhz and have it bit-bang the data out of a parallel port.  For each
  bit, 64 machine cycles would be available which should be enough to
  set the port bits and also grab incoming data out of the USB
  interface that we wanted to use to interface to the host.
&lt;/p&gt;
&lt;p&gt;
  I built a prototype of the interface and we made some promising
  experiments with it, but in the end we found that the visual latency
  problems were not fixed.  The problem was really in how the LED
  hardware worked and could not be repaired on the feeding side.  The
  prototype went onto the shelf and we stuck with Ethernet for that
  project.
&lt;/p&gt;
&lt;p&gt;
  A few weeks ago, I discussed the project with a friend of mine and
  we thought that it'd be cool to turn the 16 port DMX interface into a
  product.  We found someone who would want to use it in an OEM
  setting, and I made bringing the hardware to product level my
  weekend project.
&lt;/p&gt;
&lt;h1&gt;Good bye AVR, hello ARM&lt;/h1&gt;
&lt;p&gt;
  The AVR based solution proved to be problematic, though.  Even
  though the CPU has enough processing headroom, the lack of RAM
  requires that the data is fed into the interface "just in time".
  Any variance in the USB input data stream could result in visible
  hickups in the DMX streams.  Getting it to work seemed like
  possible, but require too much work in the end.  Thus, I decided to
  turn to using more capable hardware which would also give the DMX
  interface network connectivity and more local intelligence.
&lt;/p&gt;
&lt;p&gt;
  As new platform, I chose the ARM9
  based &lt;a href="http://sysbas.com/j-Products/default3.asp?sNum=4&amp;oNum=55&amp;uNum=102"&gt;Eddy-S4M&lt;/a&gt;
  board produced by the Korean
  manufacturer &lt;a href="http://eng.sysbas.com/default_e.asp"&gt;SystemBase&lt;/a&gt;.
  These boards are distributed
  by &lt;a href="http://www.trenz-electronic.de/"&gt;trenz electronic&lt;/a&gt;
  who I've found to be quick and reliable in the past.
&lt;/p&gt;
&lt;p&gt;
  Linux is the standard operating system on Eddy-S4M.  I'm not a huge
  Linux fan, so I spent some time to find an alternative operating
  system, but neither &lt;a href="http://ecos.sourceware.org/"&gt;eCos&lt;/a&gt;,
  nor &lt;a href="http://www.freertos.org/"&gt;FreeRTOS&lt;/a&gt;
  or &lt;a href="http://rtems.com/"&gt;RTEMS&lt;/a&gt; seemed to be ported to the
  AT91SAM9260 CPU with a free development system.  As I was into
  application development, I decided not to port or write an operating
  system myself.  Running on the bare hardware was not an option
  either as I need a working TCP stack in order to interface to the
  host.
&lt;/p&gt;
&lt;p&gt;
  SystemBase calls their Linux port "lemonix".  It appears to be a
  relatively plain linux-2.6.20 with real-time
  patches, &lt;a "href=http://www.busybox.net/"&gt;BusyBox&lt;/a&gt; and a bunch
  of C applications to control startup and configuration.  The
  userland and kernel source code is available from SystemBase after
  registration, but the kernel tree that they make available is
  incomplete and needs to be augmented by some files that are
  available from
  a &lt;a href="http://code.google.com/p/eddy-linux/"&gt;Google group&lt;/a&gt; so
  that it can be built.  Getting the cross compilation environment to
  run on my Ubuntu 9.10 box worked flawlessly, and after removing the
  whole Eddy application stuff and most of the SystemBase drivers from
  the file tree I ended up with a relatively sane Linux that I could
  cross compile and install on the Eddy hardware through tftp.
&lt;/p&gt;
&lt;h1&gt;Making it fast&lt;/h1&gt;
&lt;p&gt;
  Back to the DMX interface, I was now faced with a system that gave
  me about 400 machine cycles for each DMX bit sent.  That should be
  plenty of time to get out some bits to the ports.  The bit timing
  would be achived by a timer interrupt every 4 microseconds.  Even
  with interrupt handling overhead, this should leave enough headroom
  for TCP processing.
&lt;/p&gt;
&lt;p&gt;
  The ARM architecture specifies two interrupts.  The normal, vectored
  interrupt system is used by Linux and mapped to its own, portable
  interrupt architecture, ignoring the vectoring facilities that the
  hardware provides.  The second, fast interrupt system (FIQ) that the
  ARM provides is not used by Linux, and it seemed like a good fit to
  my requirements.  The FIQ is interesting because when the FIQ
  handler is entered, the CPU automatically switches six registers to
  a distinct bank.  These six registers can then just be used without
  the need to save or restore them to the stack.  Even though the FIQ
  is not used by Linux itself, ARM-Linux provides for an interface so
  that drivers can use it.  FIQ support was missing in lemonix, but it
  was trivial to backport.
&lt;/p&gt;
&lt;p&gt;
  Writing a FIQ interrupt in ARM assembly was straightforward.  The
  driver bottom half set up the FIQ register set and enabled the timer
  interrupt, the FIQ handler set the port bits and incremented the
  pointers accordingly.
&lt;/p&gt;
&lt;h1&gt;Reducing jitter&lt;/h1&gt;
&lt;p&gt;
  When looking at the output ports with the logic analyzer, though, I
  could see variations in bit edges in the order of one microsecond,
  which is beyond what the DMX receivers would be able to tolerate.
  These variations were visible even when the FIQ handler just set the
  port bits without writing any real data.  The source for this
  jitter, as it turned out, was virtual address translation.  The ARM9
  CPU includes a MMU and all software, including interrupt handlers,
  uses virtual addressing, even to access I/O ports.  The virtual
  address maps are stored in SDRAM due to their size, and the hardware
  automatically traverses these maps if an address can not be found in
  the translation lookaside buffers in the MMU.  So in the FIQ
  handler, when the output port address was not present in the TLB,
  the MMU would access the SDRAM, and SDRAM random access is rather
  slow.
&lt;/p&gt;
&lt;p&gt;
  Thus, I had to change the FIQ handler so that it never accesses the
  SDRAM, either directly (by reading the data buffer) or indirectly
  (by causing TLB misses).  The AT91SAM9260 CPU has two internal SRAMs
  that are accessible in two machine cycles, and I use one of those as
  a data buffer.  In order to prevent TLB misses, indivdual TLB
  entries can be locked down so that they're never removed by the MMU
  automatically.  Thus, my driver locks down the I/O and the SRAM
  buffer addresses that the FIQ handler accesses.
&lt;/p&gt;
&lt;h1&gt;Reducing jitter even more&lt;/h1&gt;
&lt;p&gt;
  Even with the TLBs locked down, I still saw some jitter in the
  leading edges of the DMX bytes.  The cause for this were variations
  in interrupt response times, as that depends on the instruction
  being interrupted.  The variations were below one microsecond, but
  that was long enough to bring the serial decoding routine in my
  logic analyzer out of sync.  Wanting to play it safe, I decided to
  remove that jitter as well by synchronizing on the timer value
  inside of the FIQ handler:  Instead of just banging out the next bit
  as fast as possible, the FIQ handler now waits until the
  free-running timer that triggered the interrupt reaches a certain
  value.  That way, the effective FIQ response time is made mostly
  constant.
&lt;/p&gt;
&lt;h1&gt;Wow, 2010!&lt;/h1&gt;
&lt;p&gt;
  In the last few years, I have been using various AVR CPUs for my
  embedded projects.  It is a great CPU that is easy to use and fast,
  and the advent
  of &lt;a href="http://www.fourwalledcubicle.com/LUFA.php"&gt;LUFA&lt;/a&gt; and
  &lt;a href="http://www.pjrc.com/teensy/"&gt;Teensy&lt;/a&gt; made my life a lot
  easier, as I was freed from USB serial dongles and driver
  installation.  But then, being able to process serious amounts of
  data is nice, too, and this is were 8 bits just don't suffice.  ARM
  based boards are cheap nowadays, and I'm looking forward to
  embedding JavaScript or maybe even Common Lisp in one of my future
  projects.  When speed is needed, I can always fall back to C and
  assembler.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1967856649755860905?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1967856649755860905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/05/embracing-arm.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1967856649755860905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1967856649755860905'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/05/embracing-arm.html' title='Embracing the ARM'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-2745895832779415733</id><published>2010-05-27T12:38:00.001+02:00</published><updated>2010-05-27T12:47:27.747+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Location change</title><content type='html'>&lt;p&gt;
Unfortunately, the New Thinking Store is not available this month, so
we'll have the Lisp Machine workshop in Hans' office at 18:00 hours.
Seating is limited, so if you're rather up for beers and chats, we'll
meet at "I Due Forni" at about 21:00 hours.
&lt;/p&gt;
&lt;p&gt;
Here is the location info:
&lt;/p&gt;
&lt;p&gt;
Hans' Office&lt;br/&gt;
Schönhauser Allee 177&lt;br/&gt;
10119 Berlin&lt;br/&gt;
Tel. 030 4431 9642&lt;br/&gt;
"Sauna" signpost, across the alley, first floor, blue door, knock.
&lt;/p&gt;
&lt;p&gt;
I Due Forni&lt;br/&gt;
Schönhauser Allee 12&lt;br/&gt;
10119 Berlin
&lt;/p&gt;
&lt;p&gt;
Despite the large difference in house numbers, the two locations are
just across the street.  Here is a &lt;a href="http://maps.google.de/maps/ms?ie=UTF8&amp;hq=&amp;hnear=Sch%C3%B6nhauser+Allee+177,+Berlin+10119+Berlin&amp;gl=de&amp;ei=BUz-S7GsMoO8lQev4KnqCQ&amp;ved=0CBcQ8gEwAA&amp;t=h&amp;hl=en&amp;msa=0&amp;msid=108551878475517540240.000487910c2441f80b953&amp;ll=52.531369,13.411871&amp;spn=0.002092,0.004125&amp;z=18"&gt;map&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-2745895832779415733?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/2745895832779415733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/05/berlin-lispers-meetup-location-change.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/2745895832779415733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/2745895832779415733'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/05/berlin-lispers-meetup-location-change.html' title='Berlin Lispers Meetup - Location change'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-8622603233102640442</id><published>2010-05-26T20:56:00.003+02:00</published><updated>2010-05-26T21:00:44.615+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Tuesday June 1, 2010 - Lisp machines!</title><content type='html'>&lt;p&gt;
Title: Berlin Lispers Meetup&lt;br/&gt;
Date: Tuesday June 1, 2010&lt;br/&gt;
Time: 7pm onwards&lt;br/&gt;
Venue: New Thinking Store, Tucholskystr. 48, 10117 Berlin&lt;br/&gt;
Transport: U-Bahn Oranienburger Tor, S-Bahn Oranienburger Straße
&lt;/p&gt;
&lt;p&gt;
You are kindly invited to the next "Berlin Lispers Meetup", an
informal gathering for anyone interested in Lisp, beer or coffee,
organized by Hans Hübner and Willem Broekema.
&lt;/p&gt;
&lt;p&gt;
Continuing our series of meetings with presentations, the upcoming
Berlin Lisp Meetup will be in New Thinking Store once more. We are
happy to announce the theme:
&lt;/p&gt;
&lt;h2&gt;
Lisp machine session - When Lisp was &lt;i&gt;really&lt;/i&gt; cool
&lt;/h2&gt;
&lt;p&gt;
This month's Lisp meetup is about Lisp machines - Computers, that were
made to run Lisp exclusively, with their makers so proud that the
handbook started with the sentence "Welcome to Genera - The best
software development environment available".
&lt;/p&gt;
&lt;p&gt;
This will be a hands-on session.  We'll have Symbolics MacIvory II to
show, and we're going to play a little with the Linux based virtual
Lisp machine.  If you have a 64 bit Linux laptop, you can give it a
spin, too.
&lt;/p&gt;
&lt;p&gt;
We will start at 19:00 hours, admission is free.
&lt;/p&gt;
&lt;p&gt;
Thanks go to Franz Inc., the maker of Allegro Common Lisp and the
AllegroGraph Web 3.0 database, for sponsoring the meeting by paying
for the venue.
&lt;/p&gt;
&lt;p&gt;
Please join for another evening of parentheses!
&lt;/p&gt;
&lt;p&gt;
P.S.: If you are interested in giving a Lisp-related presentation on
one of our next meetings, please &lt;a href="mailto:hans.huebner@gmail.com"&gt;get in touch&lt;/a&gt;!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-8622603233102640442?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/8622603233102640442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/05/berlin-lispers-meetup-tuesday-june-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8622603233102640442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8622603233102640442'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/05/berlin-lispers-meetup-tuesday-june-1.html' title='Berlin Lispers Meetup - Tuesday June 1, 2010 - Lisp machines!'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-9175584100122385445</id><published>2010-04-18T22:54:00.008+02:00</published><updated>2010-04-19T09:14:45.668+02:00</updated><title type='text'>Hacking a USB Infrared receiver</title><content type='html'>&lt;p&gt;
  Our living room Hi-Fi setup needs a MP3 player that is always
  available, easy to use and, first and foremost, allows us to import
  all the CDs that we have easily and without effort.  I've always
  wanted to do that using our FreeBSD based home server, but none of
  the ripping solutions really worked the way I wanted and triggered
  my desire to hack them to my liking.  Finally, I gave in and pulled
  out the aging and unused PowerBook of my wife.  After all, iTunes
  matches my requirements easily, and as I can treat is as piece of
  Stereo equipment, I'm willing to put my &lt;a href="http://www.youtube.com/watch?v=Nx7v815bYUw"&gt;dislike for Apple Computers&lt;/a&gt;
  to the side.
&lt;/p&gt;
&lt;p&gt;
  The problem with the PowerBook is that it does not have an IR
  receiver.  We have
  a &lt;a href="http://www.logitech.com/en-us/remotes/universal_remotes/devices/4738"&gt;Logitech
  Harmony Remote 515&lt;/a&gt; that we use to control the rest of our
  entertainment stuff, and we'd like to control the MP3 player with
  it, too.  I could not find a cheap, ready-to-go solution easily, so
  I decided to throw together something myself using
  a &lt;a href="http://www.pjrc.com/teensy/"&gt;Teensy&lt;/a&gt; and
  a &lt;a href="http://www.datasheetcatalog.org/datasheets/134/301155_DS.pdf"&gt;Vishay
  TSOP1836 IR receiver&lt;/a&gt; module that I found on a surplus board that
  I found in a box on my shelf.
&lt;/p&gt;
&lt;p&gt;
  The goal was to create an IR receiver that acts as a USB keyboard.
  The key codes that are sent should be useable to set up
  some &lt;a href="http://www.macosxtips.co.uk/index_files/craete-your-own-keyboard-shortcuts.html"&gt;global
  keyboard shortcuts&lt;/a&gt; in MacOS X that would control iTunes to our
  liking.
&lt;/p&gt;
&lt;h2&gt;Hardware&lt;/h2&gt;
&lt;p&gt;
  The TSOP1836 IR receiver module does the IR carrier decoding and
  interfaces easily with the AVR using one input port.  I hooked up
  my &lt;a href="http://www.pctestinstruments.com/"&gt;Logicport&lt;/a&gt; logic
  analyzer (excellent product, I write this as a satisfied customer)
  to the output of the IR receiver and tried a few remotes that I had
  to see whether the 36 kHz that that the receiver assumes as the
  carrier frequency would be common.  I was lucky, both the remote of
  our Onkyo Amp and the remote control that came with the Altium
  Nanoboard 3000 transmitted at that carrier frequency, and both of
  them used
  the &lt;a href="http://www.sbprojects.com/knowledge/ir/nec.htm"&gt;NEC
  protocol&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="http://www.pjrc.com/teensy/"&gt;Teensy&lt;/a&gt; is a
  microcontroller board based on an
  ATMEL &lt;a href="http://www.atmel.com/dyn/Products/product_card.asp?part_id=4097"&gt;AT90USB162&lt;/a&gt;
  AVR chip.  It comes in a DIL24 form factor, so it is easy to
  integrate into breadboards.  A neat thing about it is
  the &lt;a href="http://www.pjrc.com/teensy/loader.html"&gt;flashing
  utility&lt;/a&gt; that looks good, works very well and is unintrusive.
  The compile/upload/test cycle with the Teensy loader is very short.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://picasaweb.google.com/lh/photo/YTNrymSaTTS4LEy2uAXtNEN8FTf2bOBiRARUfvBL6y4?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_D-N9Vy-Hm3M/S8uDBlTXqII/AAAAAAAAGgc/PeNztepj6MA/s400/IMG_0479.jpg" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Software&lt;/h2&gt;
&lt;p&gt;
  I have
  used &lt;a href="http://www.fourwalledcubicle.com/LUFA.php"&gt;LUFA&lt;/a&gt; as
  USB stack on Teensy in the past to implement a
  &lt;a href="http://netzhansa.blogspot.com/2009/04/reimplementing-symbolics-keyboard.html"&gt;adapter
    for Symbolics keyboards&lt;/a&gt;, and I decided to use it again.  I was
    pleased to find that LUFA has made great progress since I last
    used it.  There are more examples, the class drivers have been
    separated from the demo code, and the cheapish task scheduler is
    not longer used by the examples that I used.
&lt;/p&gt;
&lt;p&gt;
  I tried to make the USB implementation of the adapter offer two end
  points: A keyboard endpoint that sends the translated key codes when
  remote keys are pressed, and a serial or CDC endpoint that would be
  used to configure the adapter in order to make it possible to
  configure it to whatever remote is available.  Unfortunately, I
  found that MacOS
  X &lt;a href="http://lists.apple.com/archives/usb/2010/Jan/msg00007.html"&gt;does
  not accept devices with multiple endpoints&lt;/a&gt; as standard
  serial/CDC device, so I abandoned the idea of configurability.
  Instead, I made the adapter work with the Altium remote and a
  statically compiled translation table.
&lt;/p&gt;
&lt;p&gt;
  To find out the codes that the remote sends, I wrote a version of
  the adapter that acts as a serial device.  Using that information, I
  set up the translation table in the HID keyboard version of the
  firmware.
&lt;/p&gt;
&lt;p&gt;
  When I tried setting up some global keyboard shortcuts for iTunes, I
  learned that iTunes does not really support global short cut keys,
  presumably to "protect the user".  Using a the free &lt;a href="http://www.apple.com/downloads/macosx/ipod_itunes/sizzlingkeys.html"&gt;SizzlingKeys&lt;/a&gt;
  utility, I was able to achieve what I wanted, though.
&lt;/p&gt;
&lt;p&gt;
  The source code for the two Teensy firmwares
  is &lt;a href="http://github.com/hanshuebner/ir-usb-kbd"&gt;available in
  my github repository&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-9175584100122385445?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/9175584100122385445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/04/our-living-room-hi-fi-setup-needs-mp3.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/9175584100122385445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/9175584100122385445'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/04/our-living-room-hi-fi-setup-needs-mp3.html' title='Hacking a USB Infrared receiver'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_D-N9Vy-Hm3M/S8uDBlTXqII/AAAAAAAAGgc/PeNztepj6MA/s72-c/IMG_0479.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1737493805616302226</id><published>2010-03-29T21:54:00.004+02:00</published><updated>2010-03-30T15:19:01.428+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Tuesday April 6, 2010 - Samir Sekkat</title><content type='html'>&lt;p&gt;
Title: Berlin Lispers Meetup&lt;br/&gt;
Date: Tuesday April 6, 2010&lt;br/&gt;
Time: 7pm onwards&lt;br/&gt;
Venue: New Thinking Store, Tucholskystr. 48, 10117 Berlin&lt;br/&gt;
Map: &lt;a href="http://tinyurl.com/yk3nzdj"&gt;Google Map&lt;/a&gt;&lt;br/&gt;
Transport: U-Bahn Oranienburger Tor, S-Bahn Oranienburger Straße
&lt;/p&gt;&lt;p&gt;
You are kindly invited to the sixth "Berlin Lispers Meetup", an
informal gathering for anyone interested in Lisp, beer or coffee,
organized by Willem Broekema and Hans Hübner.
&lt;/p&gt;
&lt;p&gt;
Continuing our series of meetings with presentations, the upcoming
Berlin Lisp Meetup will be in &lt;a href="http://newthinking-store.de/"&gt;New Thinking Store&lt;/a&gt; once more.  We are happy to announce a talk held (in German language) by Samir Sekkat:
&lt;/p&gt;&lt;p&gt;
&lt;b&gt;Your Life In Plain Text / Stress-free productivity&lt;/b&gt;&lt;br/&gt;
&lt;i&gt;The elisp-based org-mode package&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
How to organize your daily life using Org-Mode (which is an emacs
package) as a tool and Getting Things Done as methodology.
&lt;/p&gt;
&lt;p&gt;
Quote: I'm having the same feeling for org-mode that I did when I first
learned to really program and use emacs.  [Jeffery Travis on his Twitter
feed.]
&lt;/p&gt;
&lt;p&gt;
Links:&lt;br/&gt;
&lt;a href="http://orgmode.org/"&gt;http://orgmode.org/&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://orgmode.org/worg/org-quotes.php"&gt;http://orgmode.org/worg/org-quotes.php&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://members.optusnet.com.au/~charles57/GTD/gtd_workflow.html"&gt;http://members.optusnet.com.au/~charles57/GTD/gtd_workflow.html&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
We will start at 19:00 hours, admission is free.
&lt;/p&gt;

&lt;p&gt;
Thanks go to &lt;a href="http://franz.com/"&gt;Franz Inc.&lt;/a&gt;, the maker of Allegro
Common Lisp and the Allegrograph Web 3.0 database for sponsoring the
meeting by paying for the venue.
&lt;/p&gt;&lt;p&gt;
Please join for another evening of parentheses!
&lt;/p&gt;&lt;p&gt;
P.S.:  If you are interested in given a Lisp related presentation on
one of our next meetings, please &lt;a href="mailto:hans.huebner@gmail.com"&gt;get in touch&lt;/a&gt;!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1737493805616302226?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1737493805616302226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/03/berlin-lispers-meetup-tuesday-april-6.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1737493805616302226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1737493805616302226'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/03/berlin-lispers-meetup-tuesday-april-6.html' title='Berlin Lispers Meetup - Tuesday April 6, 2010 - Samir Sekkat'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-6187917590281988915</id><published>2010-02-22T11:12:00.006+01:00</published><updated>2010-02-26T16:24:23.663+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Clojure Slides from February Berlin Lispers Meetup</title><content type='html'>&lt;p&gt;
Stefan Richter, our speaker at the February Berlin Lispers Meetup, has made the slides of his presentation &lt;a href="http://www.slideshare.net/smartrevolution/how-a-clojure-pet-project-turned-into-a-fullblown-cloudcomputing-webapp"&gt;available on line&lt;/a&gt;.  Enjoy, and see you &lt;a href="http://netzhansa.blogspot.com/2010/02/berlin-lispers-meetup-tuesday-march-2.html"&gt;next week&lt;/a&gt;!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-6187917590281988915?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/6187917590281988915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/02/clojure-sliders-from-february-berlin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6187917590281988915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6187917590281988915'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/02/clojure-sliders-from-february-berlin.html' title='Clojure Slides from February Berlin Lispers Meetup'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-6592394255117515812</id><published>2010-02-11T15:09:00.004+01:00</published><updated>2010-02-11T15:14:32.107+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Tuesday March 2, 2010 - Luke Gorrie &amp; Edi Weitz</title><content type='html'>&lt;p&gt;
Title: Berlin Lispers Meetup&lt;br/&gt;
Date: Tuesday March 2, 2010&lt;br/&gt;
Time: 7pm onwards&lt;br/&gt;
Venue: New Thinking Store, Tucholskystr. 48, 10117 Berlin&lt;br/&gt;
Map: &lt;a href="http://tinyurl.com/yk3nzdj"&gt;Google Map&lt;/a&gt;&lt;br/&gt;
Transport: U-Bahn Oranienburger Tor, S-Bahn Oranienburger Straße
&lt;/p&gt;&lt;p&gt;
You are kindly invited to the fifth "Berlin Lispers Meetup", an
informal gathering for anyone interested in Lisp, beer or coffee,
organized by Willem Broekema and Hans Hübner.
&lt;/p&gt;

&lt;p&gt;
As our last meeting at the New Thinking Store was a great success
(so we think), we will have the March meetup there, too.  We have
two presentations scheduled:
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://lukego.livejournal.com/"&gt;Luke Gorrie&lt;/a&gt; will give a talk titled "a new adventure using Lisp to optimize
TCP performance over 3G/HSPA networks for fun and profit".
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://weitz.de/"&gt;Edi Weitz&lt;/a&gt; will give his talk "Lisp in the Real World[tm] - Using a
sophisticated language for mundane tasks".
&lt;/p&gt;&lt;p&gt;
We will start at 19:00 hours, admission is free.
&lt;/p&gt;

&lt;p&gt;
Thanks go to &lt;a href="http://franz.com/"&gt;Franz Inc.&lt;/a&gt;, the maker of Allegro
Common Lisp and the Allegrograph Web 3.0 database for sponsoring the
meeting by paying for the venue.
&lt;/p&gt;&lt;p&gt;
Please join for another evening of parentheses!
&lt;/p&gt;&lt;p&gt;
P.S.:  If you are interested in given a Lisp related presentation on
one of our next meetings, please &lt;a href="mailto:hans.huebner@gmail.com"&gt;get in touch&lt;/a&gt;!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-6592394255117515812?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/6592394255117515812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/02/berlin-lispers-meetup-tuesday-march-2.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6592394255117515812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6592394255117515812'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/02/berlin-lispers-meetup-tuesday-march-2.html' title='Berlin Lispers Meetup - Tuesday March 2, 2010 - Luke Gorrie &amp; Edi Weitz'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-4428871316468373337</id><published>2010-02-02T12:54:00.005+01:00</published><updated>2010-02-02T13:24:01.448+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freebsd vdsl'/><title type='text'>Telekom VDSL mit FreeBSD</title><content type='html'>&lt;p&gt;
Da ich meinen DSL-Anschluß im Büro mit ein paar anderen Freelancern teile, habe ich kürzlich von vorher Congster ADSL zu Telekom VDSL-25 gewechselt.  Als Router verwende ich nun einen Rechner mit FreeBSD-7.2, der VDSL-Anschluß wird mit einem Modem Speedport 300HS realisiert.  Da der VDSL-Uplink auf einem gesonderten VLAN aus dem Modem kommt, ist eine zweite Netzwerkkarte nicht zwingend erforderlich.  Ich habe das Modem einfach ans LAN gehängt und auf dem FreeBSD-Router ein VLAN-Interface konfiguriert, das für den Internetzugang mit PPPoE verwendet wird.
&lt;/p&gt;
&lt;p&gt;
Konfiguriert ist das ganze wie folgt
&lt;/p&gt;
&lt;h2&gt;Änderungen in /etc/rc.conf&lt;/h2&gt;
&lt;tt&gt;
# VLAN-Interface konfigurieren, bge0 ist mein Ethernet-Interface.  Ggf. anpassen.&lt;br/&gt;
cloned_interfaces="vlan0"&lt;br/&gt;
ifconfig_vlan0="vlan 7 vlandev bge0"&lt;br/&gt;
# IP-Paketforwarding anschalten&lt;br/&gt;
gateway_enable="YES"&lt;br/&gt;
# PPP-Client automatisch starten&lt;br/&gt;
ppp_enable="YES"&lt;br/&gt;
ppp_mode="ddial"&lt;br/&gt;
ppp_nat="YES"&lt;br/&gt;
ppp_profile="telekom"&lt;br/&gt;
&lt;/tt&gt;
&lt;/p&gt;
&lt;h2&gt;Eintrag in /etc/ppp/ppp.conf&lt;/h2&gt;
&lt;tt&gt;
telekom:&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set device PPPoE:vlan0&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set authname AAAAAAAAAAAATTTTTTTTTTTT0001@t-online.de&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set authkey KKKKKKKK&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set dial&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set login&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set log phase tun command&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set ifaddr 10.0.0.1/0 10.0.0.2/0&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;add default HISADDR&lt;br/&gt;
&lt;/tt&gt;
&lt;p&gt;
Wie üblich ist AAAAAAAAAAAA durch die Telekom-Anschlusskennung, TTTTTTTTTTTT durch die T-Online-Kennung und KKKKKKKK durch das Kennwort zu ersetzen.  (Könnte die Telekom bitte irgendwann mal die BTX-Vergangenheit tief unter der Erde verbuddeln und die Autorisierung auf ein benutzerfreundliches Verfahren umstellen?  Danke!)
&lt;/p&gt;
&lt;p&gt;
Das war's.  Reboot und die FreeBSD-Box routet.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-4428871316468373337?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/4428871316468373337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/02/telekom-vdsl-mit-freebsd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/4428871316468373337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/4428871316468373337'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/02/telekom-vdsl-mit-freebsd.html' title='Telekom VDSL mit FreeBSD'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-8347994856262805711</id><published>2010-01-29T11:53:00.005+01:00</published><updated>2010-01-29T20:51:46.846+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup: February 2, 2010 - Different time and location - Clojure presentation</title><content type='html'>&lt;p&gt;
Title: Berlin Lispers Meetup&lt;br/&gt;
Date: Tuesday February 2, 2010&lt;br/&gt;
Time: 7pm onwards&lt;br/&gt;
Venue: New Thinking Store, Tucholskystr. 48, 10117 Berlin&lt;br/&gt;
Map: &lt;a href="http://tinyurl.com/yk3nzdj"&gt;Google Map&lt;/a&gt;&lt;br/&gt;
Transport: U-Bahn Oranienburger Tor, S-Bahn Oranienburger Straße
&lt;/p&gt;&lt;p&gt;
You are kindly invited to the third "Berlin Lispers Meetup", an
informal gathering for anyone interested in Lisp, beer or coffee,
organized by Willem Broekema and Hans Hübner.
&lt;/p&gt;&lt;p&gt;
This time, the meeting will take place in the New Thinking Store (see address above), as we have a presentation by Stefan Richter of
&lt;a href="http://freiheit.com/"&gt;freiheit.com&lt;/a&gt; who will talk about a Cloud-deployed web application
written in &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;.  The full title of his presentation is
&lt;/p&gt;&lt;p&gt;
How a Clojure pet project turned into a full-blown cloud-computing
web-app.&lt;br/&gt;Or:&lt;br/&gt;What are the differences between a Clojure web-app and one
written in Java or Common Lisp?
&lt;/p&gt;&lt;p&gt;
Stefan will give his talk in German or English, depending on the
preference of the audience.  It will start at 19:00h.
&lt;/p&gt;&lt;p&gt;
Thanks go to &lt;a href="http://franz.com/"&gt;Franz Inc.&lt;/a&gt;, the maker of Allegro
Common Lisp and the Allegrograph Web 3.0 database for sponsoring the
meeting by paying for the venue.
&lt;/p&gt;&lt;p&gt;
Please join for another evening of parentheses (and brackets this time)!
&lt;/p&gt;&lt;p&gt;
P.S.:  If you are interested in given a Lisp related presentation on
one of our next meetings, please &lt;a href="mailto:hans.huebner@gmail.com"&gt;get in touch&lt;/a&gt;!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-8347994856262805711?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/8347994856262805711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/01/title-berlin-lispers-meetup-date.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8347994856262805711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8347994856262805711'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/01/title-berlin-lispers-meetup-date.html' title='Berlin Lispers Meetup: February 2, 2010 - Different time and location - Clojure presentation'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-7514350826553987049</id><published>2010-01-23T21:04:00.006+01:00</published><updated>2010-01-23T21:31:54.866+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='midi java sysex max'/><title type='text'>Max for Live, Java, MIDI, Windows and Sysex</title><content type='html'>&lt;p&gt;
Recently, I have spent some of my free time hacking some Java to provide &lt;a href="http://cycling74.com/products/maxforlive/"&gt;Max for Live&lt;/a&gt; patchers direct access to the MIDI ports of my machine.  Usually, one would be restricted to the MIDI data that Live has previously processed, which restricts it in many ways.
&lt;/p&gt;
&lt;p&gt;
I have not spent too much time hacking Java in my life, but the times I have done it for various smaller hacks, it was a nice overall experience.  This time, I was particularily impressed by Eclipse for its automated source code formatting facility that is widely configurable.  I tweaked the settings a little to match my prefered squirly brace style, and then had Eclipse beautify my (and imported) source code with a single key stroke.  Also, I like Eclipse's ability to automatically locate unknown classes and add required import statements with a single click.  This makes working with examples from documentation rather easy.  I still like Emacs, but I must admit that it is rather baroque when compared to what Eclipse can do.
&lt;/p&gt;
&lt;p&gt;
Getting the Max external to interface to the MIDI subsystem that Java provides was rather easy, and I was mostly done after 2-3 hours of hacking.  Sadly, sending Sysex strings to the MIDI controller that I used for testing did not work reliably.  Naturally, I thought that the problem was with my lack of MIDI, Java and Max skills, so I spent quite some time trying out various implementation strategies, without success.
&lt;/p&gt;
&lt;p&gt;
Finally, I figured that what did not work was sending Sysex messages, and only sometimes (i.e. it appeared as if the first message came through and then some following messages where not transmitted).  Google finally pointed me to a &lt;a href="http://www.ucapps.de/jsynthlib.html"&gt;web page by Thorsten Klose&lt;/a&gt; where, at the end, he describes the behavior as being a bug in the Java MIDI library.  The problem is that when sending Sysex messages, the Java library remembers the size of largest Sysex message sent and uses that for all subsequent Sysex messages, even if they are shorter.  My workaround is to close and re-open the MIDI device if a Sysex string to be sent is shorter than the previous one.  This is kind of ugly, but it works for me.  The workaround that Thorsten suggest has the problem that it does not stop Java from sending long messages, which reduces MIDI throughput to a point that was unacceptable for me.
&lt;/p&gt;
&lt;p&gt;
I'm posting this in the hopes that it saves the next person seeing the problem some time.  If you are interested in the Max for Live MIDI external, it is available &lt;a href="http://netzhansa.com/jmidi.zip"&gt;here&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-7514350826553987049?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/7514350826553987049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/01/java-midi-windows-and-sysex.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/7514350826553987049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/7514350826553987049'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/01/java-midi-windows-and-sysex.html' title='Max for Live, Java, MIDI, Windows and Sysex'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-8607847180271981241</id><published>2010-01-03T13:55:00.001+01:00</published><updated>2010-01-03T13:57:32.069+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Berlin Lispers Meetup - Tuesday January 5, 2010</title><content type='html'>&lt;pre&gt;
Title: Berlin Lispers Meetup
Date: Tuesday January 5, 2010
Time: 8pm onwards
Venue: St. Oberholz, Rosenthaler Straße 72a, 10119 Berlin
Transport: U-Bahn Rosenthaler Platz

You are kindly invited to the third "Berlin Lispers Meetup", an
informal gathering for anyone interested in Lisp, beer or coffee,
organized by Willem Broekema and Hans Hübner.

Please join for another evening of parentheses!
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-8607847180271981241?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/8607847180271981241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2010/01/berlin-lispers-meetup-tuesday-january-5.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8607847180271981241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/8607847180271981241'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2010/01/berlin-lispers-meetup-tuesday-january-5.html' title='Berlin Lispers Meetup - Tuesday January 5, 2010'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1197916835488040125</id><published>2009-09-07T23:04:00.001+02:00</published><updated>2009-09-07T23:05:36.447+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Admittedly, I like JavaScript</title><content type='html'>&lt;p&gt;
  Call me pervert, but I find writing JavaScript enjoyable.  The
  aspect that I like most about it is its dynamicism.  Certainly, the
  syntax is ugly, but
  the &lt;a href="http://code.google.com/p/js2-mode/"&gt;js2-mode&lt;/a&gt; for
  Emacs makes writing JavaScript much less painful.
&lt;/p&gt;
&lt;p&gt;
  My addiction for JavaScript made me accept a project to create an
  artists' portfolio website that has no commercial value, but gave me
  lots of opportunity to play around with client-side coding.  I
  decided that I want to put all data into a JSON encoded data
  structure and use a client-side content management system to edit
  and update the database.
  I &lt;a href="http://netzhansa.blogspot.com/2009/04/javascript-everywhere-using-axiom-stack.html"&gt;originally
  intended&lt;/a&gt; to write the required server-side components for the
  CMS in JavaScript, too, but that idea went down the drain as it made
  deployment of the whole thing a lot harder.  Thus, the server-side
  components are now reduced to the bare minimum and are written in
  perl, so that a cheap web host can be used both for deploying both
  the web site and the CMS.
&lt;/p&gt;
&lt;p&gt;
  One common problem with client-side JavaScript is flow control with
  long-running operations.  JavaScript is single threaded, so in order
  to maintain UI responsiveness, functions may not block waiting for
  network responses.  Thus, whenever a UI wants to interact with the
  server and then resume operating, things get tricky.  There are
  libraries like &lt;a href="http://chumsley.org/jwacs/"&gt;jwacs&lt;/a&gt;, which
  is a preprocessor which implements first-class continuations, and
  &lt;a href="http://www.cs.umd.edu/~jfoster/papers/cs-tr-4923.pdf"&gt;Arrows&lt;/a&gt;,
  which is a "generalization of Monads", but these either make debugging
  hard through the use of a preprocessor or are incomplete.
&lt;/p&gt;
&lt;p&gt;
  My approach to the problem is to use closures to manually establish
  the continuation, and callbacks to invoke these continuations when
  appropriate.  While being dissatisfying in the intellectual sense,
  the approach works for the applications that I'm using them in.
&lt;/p&gt;
&lt;p&gt;
  Sure, I'd rather have macros instead of having to control evaluation
  through closures.  But then, this is still better than any old
  static language that requires me to cram everything into classes and
  objects, forcing me to either make all design changes upfront or to
  use sophisticated refactoring wizardry to get dynamicism on the
  source code level.  Oh well, or maybe I should rather give up on
  Emacs :)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1197916835488040125?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1197916835488040125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2009/09/admittedly-i-like-javascript.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1197916835488040125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1197916835488040125'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2009/09/admittedly-i-like-javascript.html' title='Admittedly, I like JavaScript'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-6550541543116711359</id><published>2009-04-27T08:24:00.001+02:00</published><updated>2009-04-27T08:25:24.255+02:00</updated><title type='text'>Javascript Everywhere - Using Axiom Stack</title><content type='html'>&lt;!-- -*- XML -*- --&gt;
&lt;p&gt;
  A friend of mine asked me to help her with creating a portfolio
  website for a friend of hers, who is an artist.  The site will be
  somewhat similar to &lt;a href="http://quickhoney.com/"&gt;QuickHoney's
    web site&lt;/a&gt;:  It will be Javascript based, relatively simple in
  terms of layout, and self maintainable, i.e. the artist will be able
  to add and update the website without the need for HTML programming.
&lt;/p&gt;
&lt;p&gt;
  The site will be hosted on a cheap, no-frills shared web host.  On
  the server, it will consist of static files.  The portfolio data set
  - Projects, descriptions, dates - will be stored
  in &lt;a href="http://json.org/"&gt;JSON&lt;/a&gt; formatted files.
  Manipulation of the data set will be done with a special Javascript
  application for content management.
&lt;/p&gt;
&lt;p&gt;
  The site will contain various media data:  Photos, MP3 audio tracks,
  videos hosted by a video hoster.
&lt;/p&gt;
&lt;p&gt;
  Some parts of the content management tasks cannot be performed by
  Javascript in the browser:
  &lt;ul&gt;
    &lt;li&gt;Image manipulation, in particular rescaling.&lt;/li&gt;
    &lt;li&gt;Provide information about MP3 audio tracks&lt;/li&gt;
    &lt;li&gt;Fetching video information from the video hoster&lt;/li&gt;
    &lt;li&gt;Uploading data to the web hoster&lt;/li&gt;
  &lt;/ul&gt;
  These tasks require some program that runs outside of the browser;
  obviously, they are performed by a http server running on the
  artist's box.
&lt;/p&gt;
&lt;p&gt;
  My first impulse was to implement these functions in Common Lisp.
  Image manipulation is easy, using Edi Weitz' excellent
  &lt;a href="http://weitz.de/cl-gd/"&gt;CL-GD&lt;/a&gt; library.  MP3 information
  should be easy enough to read using Peter Seibel's code
  from &lt;a href="http://gigamonkeys.com/book/"&gt;Practical Common
  Lisp&lt;/a&gt;.  Parsing information from the video hoster would be easy,
  as that information is available both in XML and JSON formats, and
  Gilbert Baumann's and David
  Lichteblau's &lt;a href="http://common-lisp.net/project/cxml/"&gt;Closure
    XML Parser&lt;/a&gt; which I enjoy to use a lot.  Lastly, uploading data
  to the web host should be possible
  using &lt;a href="http://www.cliki.net/CL-FTP"&gt;CL-FTP&lt;/a&gt; which I had
  not used before.
&lt;/p&gt;
&lt;h1&gt;Exit Common Lisp&lt;/h1&gt;
&lt;p&gt;
  I spent a few evenings hacking CL-FTP so that it fits my library set
  and trying to find a sufficiently complete MP3 parsing library,
  played with dumping images so that startup times would be short.  In
  between, I played with &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;, HTML
  and CSS to get the user visible parts of the site into shape.
  Sadly, I made much better progress and had a lot more fun hacking
  Javascript than fooling around with Common Lisp and incomplete
  libraries.  At one point, I decided that I need to make more
  progress and that I should reconsider my strategy for the CMS
  server.
&lt;/p&gt;
&lt;p&gt;
  I decided that my second choice for the CMS server language would be
  Javascript.  I'd rather write both client and server in Common Lisp,
  but that is not how the world looks like.
&lt;/p&gt;
&lt;h1&gt;Enter Javascript&lt;/h1&gt;
&lt;p&gt;
  I spent a few hours shopping for server-side Javascript solutions.
  The open source Javascript based web servers are either based
  on
  the &lt;a href="http://www.mozilla.org/js/spidermonkey/"&gt;SpiderMonkey&lt;/a&gt;
  or the &lt;a href="http://www.mozilla.org/rhino/"&gt;Rhino&lt;/a&gt; Javascript
  implementations, both by the Mozilla foundation.  SpiderMonkey is
  written in C, thus extending it requires libraries using the C
  calling convention.  Rhino is written in Java, and it gives
  Javascript applications direct access to libraries written in Java.
  As I am developing on Windows, but the artist is using a Mac, Rhino
  looked a lot more attractive.
&lt;/p&gt;
&lt;p&gt;
  After looking at some project web pages picked from the Wikipedia
  entry
  on &lt;a href="http://en.wikipedia.org/wiki/Server-side_JavaScript"&gt;Server-side
  Javascript&lt;/a&gt;, I decided to
  give &lt;a href="http://www.axiomstack.com/"&gt;Axiom Stack&lt;/a&gt; a spin.  I
  chose it because it is a real Javascript framework (using
  Prototypes, not mimicking classes), has easy-to-follow getting
  started documentation, provides for persistent objects similar to the
  &lt;a href="http://bknr.net/"&gt;BKNR datastore&lt;/a&gt; and has active
  support.
&lt;/p&gt;
&lt;p&gt;
  My application is not quite typical for applications implemented
  with Axiom Stack.  Usually, the server would be used by the site's
  users, too.  My server manipulates the static files that make up the
  web site, and is basically a slave to the CMS application that runs
  in the browser.  Thus, I am not using Axiom Stack's persistent
  object store in this application.
&lt;/p&gt;
&lt;h1&gt;Enslave Java&lt;/h1&gt;
&lt;p&gt;
  I have never developed a very friendly relationship to Java, despite
  the fact that when I chose to use it for one reason or another, I
  had no trouble with it.  Java is great, as long as someone else
  writes code in it.  Being able to call Java from Javascript is
  really nice, though, as there are so many libraries out there.  In
  Rhino, Java libraries can be just used.  Thus, as Axiom Stack has no
  "native" MP3 reading facilities, I grabbed
  a &lt;a href="http://developer.berlios.de/projects/javamp3/"&gt;Java MP3
  library&lt;/a&gt; off the net and used that:
  &lt;pre&gt;
importPackage(Packages.de.vdheide.mp3);

function sound_list () {
    var dir = '../../../files/sound/';

    return MochiKit.Base.map(
        function (filename) {
            var pathname = dir + filename;
            var mp3 = new MP3File(pathname);
            return { filename: filename,
                     title: id3.getTitle(),
                     length: mp3.getLength() }
        },
        (new axiom.SystemFile(dir)).list(/\.mp3$/i) || []);
}
&lt;/pre&gt;
  The function &lt;b&gt;importPackage&lt;/b&gt; can be used to import a Java
  package into the current name space.  Java objects can be
  instantiated like Javascript object using the &lt;b&gt;new&lt;/b&gt; operator.
  Strings and numbers returned by Java can be handled like any other
  Javascript object.  I particularily like the fact that what you see
  above really is all code that is required to use a Java library.  No
  interface generator or mapping layer is needed.  At the same time, I
  can continue to use &lt;a href="http://mochikit.org"&gt;MochiKit&lt;/a&gt;,
  which is a Javascript library that I like for its nice functional
  programming abstractions.
&lt;/p&gt;
&lt;h1&gt;Hacking away&lt;/h1&gt;
&lt;p&gt;
  Since I have solved my server problem, I have made great progress
  with the application.  Switching between client-side and server side
  programming is really easy now.  No more procastinating because the
  other side's mindset does not happen to be there.  No more
  accidential typing of "the other" syntax.
&lt;/p&gt;
&lt;p&gt;
  Though I must say, I'm glad to have a Lisp job, too! :)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-6550541543116711359?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/6550541543116711359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2009/04/javascript-everywhere-using-axiom-stack.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6550541543116711359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6550541543116711359'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2009/04/javascript-everywhere-using-axiom-stack.html' title='Javascript Everywhere - Using Axiom Stack'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-4991506499844826819</id><published>2009-04-06T20:53:00.011+02:00</published><updated>2010-06-17T10:50:34.145+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>How to convert your Symbolics keyboard to USB</title><content type='html'>&lt;p&gt;I spent another hour finishing up the Teensy based Symbolics keyboard converter. The software now works as well as the PS/2 version, and uses the same keyboard translation table generation tool. Converting a keyboard should now be doable for anyone who has basic soldering skills.&lt;/p&gt;  &lt;p&gt;What you'll need: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://pjrc.com/teensy/index.html"&gt;Teensy&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;USB cable (B type) &lt;/li&gt;    &lt;li&gt;6-pin .1'' header &lt;/li&gt;    &lt;li&gt;Some wire &lt;/li&gt; &lt;/ul&gt; First, you need to program the Teensy with the &lt;a href="http://bknr.net/svn/trunk/projects/symbolics-keyboard/teensy-firmware/symbolics.hex"&gt;Firmware .hex file&lt;/a&gt;. Don't worry about customizing the firmware right now. If you decide that you want it to work differently than my version, you can update it later.   &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Get five pieces of wire, about 5 inches long. Solder them to the 6 pin header, leaving pin 2 unconnected. Connect the other ends to the teensy.    &lt;table&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;th&gt;pin #&lt;/th&gt;          &lt;th&gt;color&lt;/th&gt;          &lt;th&gt;teensy pad&lt;/th&gt;          &lt;th&gt;function&lt;/th&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;blue&lt;/td&gt;          &lt;td&gt;GND&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;&lt;/td&gt;          &lt;td&gt;(not connected)&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;green&lt;/td&gt;          &lt;td&gt;5V&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;red&lt;/td&gt;          &lt;td&gt;D4&lt;/td&gt;          &lt;td&gt;DIN&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;5&lt;/td&gt;          &lt;td&gt;black&lt;/td&gt;          &lt;td&gt;D5&lt;/td&gt;          &lt;td&gt;CLK&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;6&lt;/td&gt;          &lt;td&gt;white&lt;/td&gt;          &lt;td&gt;D6&amp;lt;&lt;/td&gt;          &lt;td&gt;CLR&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;i&gt;Yes, 5V and GND were swapped in my original post, sorry and thanks to Gene Diveglia for reporting&lt;/i&gt;&lt;/p&gt;   &lt;a href="http://picasaweb.google.com/lh/photo/uGA9pX-6E4KSRpEfwGuQUw?feat=embedwebsite"&gt;&lt;img height="399" src="http://lh5.ggpht.com/_D-N9Vy-Hm3M/Sdu6UGStPXI/AAAAAAAAC2w/q1Uz7drpfN4/s800/IMGP2969.jpg" width="600" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Open the Symbolics keyboard by removing the five screws at the bottom. Carefully remove the small PCB that sits on the larger one, unplug the spiral cable.&amp;#160; Using a tool like a large screwdriver, remove the strain relief by pushing it to the outside of the case. Remove the cable, take off the strain relief. Using a pliers, cut out some of the plastic so that the part can be used for the round USB cable. &lt;a href="http://picasaweb.google.com/lh/photo/qL1y-Tv2nU9pPO7WFC_Nww?feat=embedwebsite"&gt;&lt;img height="399" src="http://lh3.ggpht.com/_D-N9Vy-Hm3M/Sdu6LWmWyLI/AAAAAAAAC1s/WU0pnBuR2zo/s800/CIMG1201.JPG" width="600" /&gt;&lt;/a&gt;&lt;a href="http://picasaweb.google.com/lh/photo/-ktbZGozQ6KPrY0TCv-5hQ?feat=embedwebsite"&gt;&lt;img height="399" src="http://lh6.ggpht.com/_D-N9Vy-Hm3M/Sdu6N0LfmSI/AAAAAAAAC14/AY7AbdXXTQA/s800/IMGP2965.jpg" width="600" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Using a sharp knife, make the B type connector of the USB cable as small as possible. &lt;a href="http://picasaweb.google.com/lh/photo/tdbHnK7iwWR6_uZdwleS-Q?feat=embedwebsite"&gt;&lt;img height="399" src="http://lh6.ggpht.com/_D-N9Vy-Hm3M/Sdu6QLOii0I/AAAAAAAAC2U/dr27t7Iu4_c/s800/IMGP2966.jpg" width="600" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://picasaweb.google.com/lh/photo/E2v1k7_CqKo8wlKw7qv6Hg?feat=embedwebsite"&gt;&lt;img height="399" src="http://lh4.ggpht.com/_D-N9Vy-Hm3M/Sdu6SflvhdI/AAAAAAAAC2g/EyfweMKCQfE/s800/IMGP2967.jpg" width="600" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Put the strain relief onto the USB cable, about 4 inches away from the scaled down B connector. Using a tool, firmly put it back into the keyboard case. Fixate the cable to the bottom shell of the case like shown. Connect the Teensy to the USB cable, plug the header into the keyboard PCB. &lt;a href="http://picasaweb.google.com/lh/photo/7wKHXJO-BtMUrsoxch-fCg?feat=embedwebsite"&gt;&lt;img height="399" src="http://lh4.ggpht.com/_D-N9Vy-Hm3M/Sdu6WeSHpwI/AAAAAAAAC28/SP7PX7N76pY/s800/IMGP2972.jpg" width="600" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Put some protective plastic around the Teensy so that it does not short circuit anything on the keyboard PCB. &lt;a href="http://picasaweb.google.com/lh/photo/0Fu16Dwwu3i9p5FOf-QjfA?feat=embedwebsite"&gt;&lt;img height="399" src="http://lh3.ggpht.com/_D-N9Vy-Hm3M/Sdu6YsctECI/AAAAAAAAC3I/58FlrM13c-I/s800/IMGP2973.jpg" width="600" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Finally, reassemble the keyboard. It should be easy to put the daughter PCB back onto the main PCB and fit the two shells together. You're done. &lt;a href="http://picasaweb.google.com/lh/photo/mU7GDCinL_4mUFoHv_W5Bw?feat=embedwebsite"&gt;&lt;img height="399" src="http://lh4.ggpht.com/_D-N9Vy-Hm3M/Sdu6acXfzNI/AAAAAAAAC3U/49P-zvQzV3A/s800/IMGP2976.jpg" width="600" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Make sure that you've read the &lt;a href="http://bknr.net/svn/trunk/projects/symbolics-keyboard/teensy-firmware/README.txt"&gt;README.txt&lt;/a&gt; file for the converter firmware. Note that if you want to convert your old-style keyboard, you need to know that the internal color coding of the cables is different with those keyboards.  This &lt;a href="http://netzhansa.blogspot.com/2010/06/how-to-convert-your-old-style-symbolics.html"&gt;blog post&lt;/a&gt; has a table with the information that you need.  Have fun! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-4991506499844826819?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/4991506499844826819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2009/04/how-to-convert-your-symbolics-keyboard.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/4991506499844826819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/4991506499844826819'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2009/04/how-to-convert-your-symbolics-keyboard.html' title='How to convert your Symbolics keyboard to USB'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_D-N9Vy-Hm3M/Sdu6UGStPXI/AAAAAAAAC2w/q1Uz7drpfN4/s72-c/IMGP2969.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-5564779055516986266</id><published>2009-04-05T23:13:00.004+02:00</published><updated>2009-04-05T23:51:24.813+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Reimplementing the Symbolics Keyboard Adapter with Teensy</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_D-N9Vy-Hm3M/Sdkm44l_uxI/AAAAAAAAC08/5FbjnUye3a4/s1600-h/CIMG1177.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_D-N9Vy-Hm3M/Sdkm44l_uxI/AAAAAAAAC08/5FbjnUye3a4/s320/CIMG1177.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5321327193421232914" /&gt;&lt;/a&gt;
&lt;p&gt;
In a &lt;a href="http://www.avrfreaks.net/index.php?name=News&amp;file=article&amp;sid=722"&gt;recent post&lt;/a&gt; on the AVR Freaks blog, Teensy, a new AVR based development board was announced.  At $19, it is rather cheap and it comes with an on-chip USB controller.  The neat thing about this is that applications are not restricted to some sort of serial emulation protocol, as Arduino-like boards with a separate, FTDI chip base USB controller, are.  Instead, Teensy has a full USB 2.0 controller available to the application, and it comes with libraries that makes implementing custom USB keyboard controllers that require no special drivers very easy.
&lt;/p&gt;
&lt;p&gt;
I was a little unsatisfied with the state of the &lt;a href="http://www.kbdbabel.org/"&gt;kbdbabel&lt;/a&gt; based Symbolics keyboard adapter.  The adapter works so far, but there are still some caps lock related bugs and I don't know 8051 assembler.  Thus, I decided to give Teensy a first spin by implementing the protocol adapter in C, utilizing the Teensy HID USB keyboard library.  As I did the protocol analysis for the Symbolics keyboard years ago, implementing that part was easy enough.  I did make some mistakes with respect to accessing program memory on the AVR which took me several hours to sort out, but in the end, I now have a neat little program that runs on a Teensy and that requires no external circuitry to convert a Symbolics keyboard to a USB keyboard.  Just solder on a few wires, flash the Teensy, replace the RJ11 cable by an USB cable and off you go.
&lt;/p&gt;
&lt;p&gt;
I'll still support the kbdbabel based Symbolics adapter, but for users who want to hook up a Symbolics keyboard to a modern, USB equipped system, I now recommend getting a Teensy.  I'm willing to do the conversion for those who don't have soldering skills, but the shipping will not be cheap.  If you want the Teensy firmware, let me know.
&lt;/p&gt;
&lt;p&gt;
Next on my list:  Make Teensy talk MIDI.  If you've done it already, please share what you know.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-5564779055516986266?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/5564779055516986266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2009/04/reimplementing-symbolics-keyboard.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/5564779055516986266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/5564779055516986266'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2009/04/reimplementing-symbolics-keyboard.html' title='Reimplementing the Symbolics Keyboard Adapter with Teensy'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_D-N9Vy-Hm3M/Sdkm44l_uxI/AAAAAAAAC08/5FbjnUye3a4/s72-c/CIMG1177.JPG' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-2014326408315735629</id><published>2009-03-15T21:34:00.003+01:00</published><updated>2009-03-16T10:42:02.616+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='forth fpga hardware'/><title type='text'>Rekonstrukt Progress:  MIDI Drum Machine, Turnkey Application Support</title><content type='html'>&lt;p&gt;
  I made quite some progress on rekonstrukt during the last few weeks,
  and I can happily report that this whole "build a system from
  scratch" has not turned into a full time occupation, but is very
  doable as an after work thing.  I'd certainly be interested in
  lifting the effort to a more, say, professional scale in the future,
  but for the time being, it is nice to both have something to play
  with in the evening and still maintain a family and a professional
  life.
&lt;/p&gt;
&lt;h1&gt;Implementing a MIDI drum machine in hardware&lt;/h1&gt;
&lt;p&gt;
  One of the application areas that I am currently interested in is
  music hardware.  I'm into electronic music, and even though I am not
  much of an artist (that'd be hardly compatible with a family and a
  professional life), I like playing around with and building gear.
  For a start, I created
  a &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/vhdl/midi.vhd?spec=svn127&amp;r=127"&gt;drum machine in VHDL&lt;/a&gt;.  It is a very simple 8 track, 16 beats drum
  machine, but it runs fully autonomous and requires no CPU, other
  than for setting up the pattern, tempo and notes.  Suffice to say,
  the drum machine is clocked tightly.  There is no interrupt latency
  to consider, and the CPU is free for the user interface.
&lt;/p&gt;
&lt;p&gt;
  This is an interesting experiment in that what I have basically done
  is create
  a &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/vhdl/midi.vhd?spec=svn127&amp;r=127#252"&gt;special purpose processor&lt;/a&gt; that plays rythms.  This processor is very
  restricted, but it performs the task that it has been created for
  efficiently and without a lot of overhead.  Certainly, the same
  thing can be done in software and development times might have been
  shorter, yet the real time aspect of the problem makes the details
  rather hard to get right.
&lt;/p&gt;
&lt;p&gt;
  The drum machine is rather limited, though, as it can only play 16th
  notes.  I may be implementing a MIDI file player in VHDL in the
  future, which will be able to play tracks of arbitary complexity.
  The 16th structured grid of the drum machine will then only be
  implemented in software.
&lt;/p&gt;
&lt;h1&gt;Turnkey application support&lt;/h1&gt;
&lt;p&gt;
  The drum machine actually works well and makes real noises, but
  getting the software into the running rekonstrukt system on the FPGA
  started to bother me.  There were two ways of getting Forth words
  into the FPGA: One could either add them to the code that is cross
  compiled and placed in ROM, or one could upload the source code
  through the serial port onto the running FPGA.  Putting random code
  into ROM, in addition to the limited amount of space available, has
  the down side that variables cannot be created in the usual Forth
  way, by just defining a word and leaving some space in the word's
  body free as storage for the variable value.  Instead, variables in
  ROM need to be explictly allocated in RAM, which is at least
  cumbersome.  Uploading through the serial port is not a viable
  option for deploying applications - After all, the device needs to
  work when switched on.
&lt;/p&gt;
&lt;p&gt;
  The easiest way to load data into the rekonstrukt system is to
  include it in the FPGA configuration bitstream as initialization
  vector for the FPGA.  Block RAM that is used to implement both the
  ROM and the RAM of rekonstrukt, and block RAM can be initialized
  from the configuration bitstream.
&lt;/p&gt;
&lt;p&gt;
  The binary image for the ROM is created using cross compilation on
  the host system.  The contents of the RAM blocks that are used for
  the rekonstrukt system RAM is normally not considered by Maisforth.
  During system startup, the dictionary pointer is normally
  initialized so that new words are created in RAM right above the 768
  bytes that are reserved for system use.
&lt;/p&gt;
&lt;p&gt;
  In order to support loading application code into rekonstrukt with
  the FPGA bitstream, I modified the &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/maisforth/targ601.f?spec=svn127&amp;r=127#1931"&gt;COLD&lt;/a&gt;
  word which is called to initialize the Forth system.  COLD now calls
  the new &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/maisforth/targ601.f?spec=svn127&amp;r=127#1889"&gt;DICT-FROM-RAM&lt;/a&gt; word which checks whether the RAM contains application code
  (consisting of dictionary entries in the Forth vocabulary) and, if
  so, includes these words in the dictionary of the starting Forth
  system.  In addition, I implemented a new TURNKEY vectored word that
  is called upon system startup.  The default TURNKEY action prints
  the version and copyright herald and then enters the text
  interpreter loop.  Applications can implement whatever code in their
  turnkey word.
&lt;/p&gt;
&lt;p&gt;
  To create a FPGA configuration bitstream with RAM initialization
  vectors with application code, I modified the usim mc6809 simulator
  so that it can dump a core image of the running simulated Forth
  system to a file on the host.  Dumping a core can be initiated from
  Forth.  I have
  implemented &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/usim/main.cc?spec=svn127&amp;r=127#185"&gt;hooks
  to the SWI2 (Software Interrupt 2) instruction&lt;/a&gt; so that the Forth
  can "call back" into the host, initiating the file dump.  This
  process can be fully automated, so creating preinitialized FPGA
  bitstreams is possible from
  the &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/forth/Makefile?spec=svn127&amp;r=127"&gt;Makefile&lt;/a&gt;
  in the forth/ subdirectory of the rekonstrukt source tree.
&lt;/p&gt;
&lt;p&gt;
  To sum up: It is now possible to create FPGA configuration
  bitstreams containing the hardware description, the Forth core and
  the application code and have the application run automatically
  after the bitstream has been loaded.  I am still using block RAM for
  all of rekonstrukt's memory, so a lot of the block RAM resources of
  the FPGA are currently consumed.  My next plan is to port
  rekonstrukt to
  the &lt;a href="http://www.em.avnet.com/spartan3a-evl"&gt;Avnet Spartan-3A Evaluation Kit&lt;/a&gt;.  At $49, this board is cheap and Avnet also
  offers
  a &lt;a href="http://www.em.avnet.com/evk/home/0,1707,RID%253D0%2526CID%253D51264%2526CCD%253DUSA%2526SID%253D32214%2526DID%253DDF2%2526LID%253D32232%2526PRT%253D0%2526PVW%253D%2526BID%253DDF2%2526CTP%253DEVK,00.html"&gt;1 Megabyte SRAM add-on board&lt;/a&gt;, costing $20.  I will try to
  implement a small boot loader that fits into 1 block RAM which
  initializes the external SRAM from either the serial or the parallel
  Flash ROM.  That way, most of the block RAM will be available to the
  application.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-2014326408315735629?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/2014326408315735629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2009/03/rekonstrukt-progress-midi-drum-machine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/2014326408315735629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/2014326408315735629'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2009/03/rekonstrukt-progress-midi-drum-machine.html' title='Rekonstrukt Progress:  MIDI Drum Machine, Turnkey Application Support'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-641343312309965966</id><published>2009-03-03T11:11:00.003+01:00</published><updated>2009-03-03T11:36:08.280+01:00</updated><title type='text'>Der Chaos Computer Club feiert seinen großartigen Erfolg!</title><content type='html'>&lt;p&gt;
Heute hat das Bundesverfassungsgericht seine Entscheidung zu der Klage zweier Bürger gegen den Einsatz von Wahlcomputern bei der Bundestagswahl 2005 bekanntgegeben.  Dieser Einsatz war nicht rechtmäßig, und der CCC bejubelt dies nun als großartigen Erfolg seiner Kampagne.  Über das Urteil selbst möchte ich mir als Nichtjurist keine größeren Gedanken machen, über das Gejubel des CCC jedoch schon:
&lt;/p&gt;
&lt;p&gt;
Der CCC versteht sich ja als sowas wie das NGO der Computer-Experten.  In der Öffentlichkeit wird er als kompetent, engagiert und politsch wachsam wahrgenommen.  Wann immer es gilt, die angeblichen bürgerlichen Rechte von Menschen im Netz zu schützen, erklärt sich der CCC für zuständig.  So auch hier:  Ausgehend von einer Aktion holländischer Hacker wurde eine Kampagne gegen Wahlcomputer losgetreten:  Wahlcomputer seien grundsätzlich schlecht, weil nicht transparent, und deswegen gehören sie verboten.  In einigen Bundesländern ist das schon passiert, und jetzt scheint es auch im Bund bald so weit zu sein:  Wahlen in Deutschland haben mit Stift und Zettel zu geschehen, denn alles andere, wir wissen es dank der fleißigen Hacker, ist "unsicher".
&lt;/p&gt;
&lt;p&gt;
Als Konsequenz dürfen wir also in Zukunft nicht darauf hoffen, mehr direkte Demokratie mit Hilfe elektronischer Verfahren zu realisieren.  Diskutieren, ja.  Entscheiden?  Nur mit Stimmzetteln.  Und das haben wir nun ausgerechnet den Leuten zu verdanken, die am Liebsten an Ihren Computern herumhängen, sich ihr Leben mit dem Internet organisieren und sich mehr und mehr über die elektronischen Medien definieren.
&lt;/p&gt;
&lt;p&gt;
Herzlichen Glückwunsch, lieber CCC!
&lt;/p&gt;
&lt;p&gt;
P.S.: Weniger polemisch und fundierter hat Till Westermeyer seine Gedanken zu diesem Thema &lt;a href="http://blog.till-westermayer.de/index.php/2009/03/03/wahlcomputer-urteil/"&gt;veröffentlicht&lt;/a&gt;.  Danke dafür!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-641343312309965966?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/641343312309965966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2009/03/der-chaos-computer-club-feiert-seinen.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/641343312309965966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/641343312309965966'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2009/03/der-chaos-computer-club-feiert-seinen.html' title='Der Chaos Computer Club feiert seinen großartigen Erfolg!'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-3018056676119796346</id><published>2009-02-27T21:33:00.003+01:00</published><updated>2009-02-27T21:59:29.792+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fpga'/><category scheme='http://www.blogger.com/atom/ns#' term='forth'/><title type='text'>Hardware/Software Co-Design - What it means with rekonstrukt</title><content type='html'>&lt;p&gt;One of my primary goals with the &lt;a href="http://code.google.com/p/rekonstrukt/"&gt;rekonstrukt&lt;/a&gt; project is to create a hardware/software co-design environment that cuts down on turnaround times and gives me, the designer, flexibility to test and try out things at various levels.  Here is what this means in practice:&lt;/p&gt;
&lt;p&gt;rekonstrukt consists of the MC6809 microprocessor running Maisforth.  The microprocessor can be implemented in three ways:
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;In the usim software emulator, which is written in C++ and runs on my workstation.  In this mode, the emulator needs be extended in C++ if I want to emulate more of the hardware that the real implementation provides.  This mode has  fast turnaround times (the simulated 6809 is way faster than the real hardware) and is useful to try out algorithms, learn Forth and the like.  It is not timing accurate.&lt;/li&gt;
&lt;li&gt;In the Active-HDL simulator, again running on my workstation.  In this mode, the actual VHDL implementation of rekonstrukt is simulated.  The simulation is still fast enough to run small pieces of actual Forth code.  It is a good mode to pinpoint hardware and timing issues, and Active-HDL has great flexibility with respect to setting breakpoints and inspecting the simulated state, which helps a great deal with diagnosing issues.&lt;/li&gt;
&lt;li&gt;On the FPGA.  The interactive nature of Forth means that this way is often most productive.  By actually trying out things, I can quickly gain confidence in my design or explore ideas, getting immediate feedback.  In this mode, the logic analyzer is the crucial tool to verify waveforms and timings, and it is not that suitable for pinpointing problems that are inside the FPGA.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In all three modes, it is possible to recompile the Forth kernel and put it into operation in a few seconds.  The usim simulator directly works with the ROM image that the cross compiler generates, the VHDL simulator can load a pre-initialized ROM image in VHDL format, and the new ROM image can also be merged with a completely synthesized FPGA bit stream.  Thus, synthesizing the hardware is required only when changes need to be tried out on the real hardware.  Trying out firmware changes only requires running the Forth cross compiler and restarting the simulator or downloading the bitstream to the target hardware.&lt;/p&gt;
&lt;p&gt;Synthesizing rekonstrukt on my workstation takes about 10 minutes, but as the design is split into partitions, changes to individual parts of the hardware does not require a full synthesis run.  Incremental runs take only about 3 minutes.  Sure, I'd love to see that be faster, but it is bearable&lt;/p&gt;
&lt;p&gt;I love this shit :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-3018056676119796346?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/3018056676119796346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2009/02/hardwaresoftware-co-design-what-it.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3018056676119796346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3018056676119796346'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2009/02/hardwaresoftware-co-design-what-it.html' title='Hardware/Software Co-Design - What it means with rekonstrukt'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1326345512812771135</id><published>2009-02-22T22:37:00.004+01:00</published><updated>2009-02-22T23:24:07.304+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fpga'/><category scheme='http://www.blogger.com/atom/ns#' term='forth'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>ACIA fixed, S3E SK sucks</title><content type='html'>&lt;p&gt;In the last two weeks, I was making good progress with my attempt to fully support the Spartan-3E starter kit by Maisforth.  I had to improve my SPI controller slightly so that it works better for programming the serial Flash, worked on implementing the (ancient) standard Block I/O vocabulary so that the serial Flash can be used like a floppy disk in the old days and almost got the beautiful &lt;a href="http://www.complang.tuwien.ac.at/forth/vibe-2.1ans.fs"&gt;vibe&lt;/a&gt; full screen block editor to work.&lt;/p&gt;
&lt;p&gt;One thing that was began to bother me a lot was the development cycle for Forth programs:  I use Emacs to edit stuff, then copy and paste it to the real hardware.  As my programs grow, this begins to take considerable time, but for some reason I could not send the data through the serial port at full speed:  Maisforth reproduceably lost characters, and I had to insert a small delay after each character sent which made uploads slow.  Too slow.&lt;/p&gt;
&lt;p&gt;Thus, I went to pinpoint the reason for this character loss.  At first, I thought that what I saw was a problem related to the lack of flow control.  The serial port on the Spartan-3E Starter Kit is only equipped with RX and TX signals, so no hardware flow control is possible and software flow control is not implemented.  After some investigation and experiments it became clear to me, though, that the problem was not flow control related.  Both hardware (RTS/CTS) and software (XON/XOFF) flow control work under the assumption that data is buffered in larger chunks, but my character loss happened even when I sent short bursts at full speed to the FPGA.&lt;/p&gt;
&lt;p&gt;The problem really was related to the lack of double buffering in the transmitter of the System09 UART.  This meant that the transmitter signalled the "transmit buffer full" condition for the whole duration of the actual send operation, even though the data had already been copied from the transmit buffer to the shift register.  As the serial port echo in Maisforth is generated by Forth itself, processing of every character and sending it back out through the serial port introduced a pause between every character echoed, which quickly caused problems when characters to be echoed came in at full serial port speed.&lt;/p&gt;
&lt;p&gt;The fix for the problem was to introduce double buffering.  As soon as the character to be transmitted has been copied over to the transmitter shift register, the UART module now signals the host that the transmit buffer is available for the next character to be sent.  This made the problem disappear as Forth echo processing can now take place while the previous character echo is transmitted.  Given the slow serial port and the high clock rate of System09, there now is plenty of time for all processing needed.&lt;/p&gt;
&lt;h2&gt;The Spartan-3E Starter Kit sucks&lt;/h2&gt;
&lt;p&gt;Well, not really.  It is a nice cheap board with a good load of on-board peripherals, useful documentation and nice example designs, but it also has severe limitations:  The on-board FPGA is a XC3S500E, which has 40 kByte of block RAM.  In my current Maisforth setup, I use 16k for the Forth kernel ROM, 16k for RAM, and 6k for the VGA controller.  This leaves only 2k free, so that makes playing with table based waveform synthesis really hard.  What I hoped for was that I could put the Forth kernel and the board support Forth library into the parallel NOR flash of the S3ESK and map the Flash into the 6809 address space.&lt;/p&gt;
&lt;p&gt;The show stopper for this plan is the fact that data bit 0 of the NOR flash is shared with the SPI bus data signal.  Thus, one can either access the flash or the SPI, but not both at the same time.  Seemingly, the idea is to copy the contents of the NOR flash into SDRAM and then run from there, but I'm still reluctant to try getting the SDRAM to work.  The easy path is blocked, though, and maybe using SDRAM is the best option.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1326345512812771135?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1326345512812771135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2009/02/acia-fixed-s3e-sk-sucks.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1326345512812771135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1326345512812771135'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2009/02/acia-fixed-s3e-sk-sucks.html' title='ACIA fixed, S3E SK sucks'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1681803399950674590</id><published>2009-02-15T12:38:00.004+01:00</published><updated>2009-02-15T12:43:45.887+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fpga'/><category scheme='http://www.blogger.com/atom/ns#' term='forth'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Rekonstrukt - A "New" Forth Machine</title><content type='html'>&lt;p&gt;
I have been a Fan of Forth since the 1980ies, and when I picked up my FPGA stuff a few weeks, I decided to put some more effort into getting a complete Forth based FPGA system to run before turning back to the &lt;a href="http://vaxbusters.org/workshop/secd.xml"&gt;SECD reimplementation project&lt;/a&gt;.  This new Forth machine is called "Rekonstrukt", and I have created a &lt;a href="http://code.google.com/p/rekonstrukt/"&gt;Google Code project&lt;/a&gt; to publish the source code.
&lt;/p&gt;
&lt;p&gt;
My last FPGA productivity rush ended with Maisforth running on the &lt;a href="http://www.xilinx.com/products/devkits/HW-SPAR3E-SK-US-G.htm"&gt;Spartan-3E Starter Kit&lt;/a&gt;.  Maisforth is a ANS-like 8 bit Forth originally written by Albert Nijhof for the somewhat obscure &lt;a href="http://en.wikipedia.org/wiki/Motorola_6809"&gt;MC6809&lt;/a&gt; based computer called "Maiskastje" built by a &lt;a href="http://www.forth.hccnet.nl/homegb.html"&gt;dutch computer club&lt;/a&gt; a few years ago.  Porting Maisforth to &lt;a href="http://members.optushome.com.au/jekent/system09/index.html"&gt;System09&lt;/a&gt; was rather easy; all that was needed was a little tweaking of the serial I/O routines so that the System09 MC6850-lookalike serial port was properly handled.
&lt;/p&gt;
&lt;p&gt;
My next goal is to support most of the Hardware that the Spartan-3E Starter Kit has to offer by Forth.  This will require some VHDL hacking in order to implement the low level interfaces as well as implementing Forth libraries.
&lt;/p&gt;
&lt;h2&gt;Implementing a SPI controller&lt;/h2&gt;
&lt;p&gt;
I started by implementing an &lt;a href="http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus"&gt;SPI&lt;/a&gt; interface.  SPI is a serial bus protocol for moderately high speed connections between devices inside one system.  On the Spartan-3E board, the &lt;a href="http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1155,C1001,C1158,P2420,D1295"&gt;analog capture unit&lt;/a&gt;, &lt;a href="http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1154,C1009,C1121,P7596,D5359"&gt;analog preamplifier&lt;/a&gt;, &lt;a href="http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1155,C1005,C1156,P2048,D2170"&gt;digital to analog converter&lt;/a&gt;, &lt;a href="http://www.numonyx.com/Documents/Datasheets/M25P16.pdf"&gt;serial flash&lt;/a&gt; and platform flash chips are all connected to one shared SPI bus.  It would be possible to operate this bus by bit-banging in software, but this would be rather slow.  In hardware, it is easily possible to operate the SPI bus at a bit rate of 10 Mhz.
&lt;/p&gt;
&lt;p&gt;
While other open source VHDL SPI controllers exist, none of them easily interfaced with the "proprietary" bus protocol of System09.  I took this as an opportunity to freshen up my VHDL and FPGA design skills.  Again, I learned that it does not make sense to synthesize to the real hardware before simulation has shown that the design basically works, but that successful simulation does not automatically mean that the design works in the real hardware.  With the help of some regulars in the #fpga IRC channel on &lt;a href="http://freenode.net/irc_servers.shtml"&gt;freenode.net&lt;/a&gt;, I got the SPI controller to run.
&lt;/p&gt;
&lt;h2&gt;Implementing vectorized I/O in Maisforth&lt;/h2&gt;
&lt;p&gt;
System09 comes with a VGA controller that provides for a 80x25 text console, named vdu8.  vdu8 is register based, i.e. to write a character onto the screen, the host CPU needs to write the screen position where the character should go into the cursor address registers, then write the character to be shown into the data registers.  In order to make vdu8 useable as I/O device for Forth, a small terminal emulator is needed that interprets standard control sequences like Linefeed, Carriage Return and Backspace properly so that it can be used to handle EMIT calls.
&lt;/p&gt;
&lt;p&gt;
The VGA console should be useable as an alternative to the serial console and switching between the two should be possible at run time.  The common technique to achieve that is to make the words that need to be switched between alternative implementations be vectored, or "deferred" words.  What this means is that a pointer to the word that actually implements the word is stored in the word that is being called by the system, and this pointer can be modified at run time in order to switch to the desired implementation.
&lt;/p&gt;
&lt;p&gt;
Normally, the Forth compiler performs a name lookup when compiling a word, not when executing it.  Thus, once a word has been compiled, the addresses of the words that are being called are fixed, and the implementations of these words cannot be changed in retrospect. 
&lt;/p&gt;
&lt;p&gt;
For normal, RAM based operation, implementing deferred words is quite simple:

&lt;/p&gt;&lt;pre&gt;: alias ( xt -- ) create , does&gt; @ execute ;
: noop ( -- ) ;
: defer ( &lt;name&gt; -- ) ['] noop alias ;
: is ( xt &lt;name&gt; -- ) ' &gt;body ! ;&lt;/name&gt;&lt;/name&gt;&lt;/pre&gt;

&lt;tt&gt;alias&lt;/tt&gt; is used to set up an alias for a word.  &lt;tt&gt;defer&lt;/tt&gt; is used to set up an alias for the do-nothing word &lt;tt&gt;alias&lt;/tt&gt;.  The implementation of such a word can later be changed using the &lt;tt&gt;is&lt;/tt&gt; word.
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
This works well for RAM based Forth in which the &lt;tt&gt;,&lt;/tt&gt; word can be used to compile a number into the dictionary and change that later.  For a ROM based Forth like Maisforth, the default dictionary is read only and as we are interested in vectorizing words that are used by the system, the vectors need to be put somewhere else.  Maisforth provides for a "user space" for this purpose.  The "user space" is located in RAM at the beginning of the address space, and the &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/maisforth/meta601.f?spec=svn28&amp;amp;r=27#513"&gt;&lt;tt&gt;IVEC&lt;/tt&gt;&lt;/a&gt; word can be used to allocate a cell from that space in the cross compiler.  When adding new user vectors, the &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/maisforth/targ601.f?spec=svn28&amp;amp;r=27#5"&gt;&lt;tt&gt;USERBYTES&lt;/tt&gt;&lt;/a&gt; constant needs to be increased so that the cross compiler knows the changed memory layout.  I did not find out how I could get the vectors initialized automatically by the cross compiler, so I added a new &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/maisforth/targ601.f?spec=svn28&amp;amp;r=27#375"&gt;&lt;tt&gt;'EMIT&lt;/tt&gt;&lt;/a&gt; vector initialized to 0 which would be &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/maisforth/targ601.f?spec=svn28&amp;amp;r=27#857"&gt;called in the &lt;tt&gt;(EMIT&lt;/tt&gt;&lt;/a&gt; word, and changed the &lt;a href="http://code.google.com/p/rekonstrukt/source/browse/trunk/maisforth/targ601.f?spec=svn28&amp;amp;r=27#1872"&gt;&lt;tt&gt;COLD&lt;/tt&gt;&lt;/a&gt; word to intialize the &lt;tt&gt;'EMIT&lt;/tt&gt; vector when rekonstrukt starts.
&lt;/p&gt;
&lt;p&gt;
More information about vectorized functions can be found in Leo Brodie's excellent book &lt;a href="http://www.forth.com/starting-forth/index.html"&gt;Starting Forth&lt;/a&gt; in the Chapter &lt;a href="http://www.forth.com/starting-forth/sf9/sf9.html"&gt;Under the Hood&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1681803399950674590?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1681803399950674590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2009/02/new-forth-machine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1681803399950674590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1681803399950674590'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2009/02/new-forth-machine.html' title='Rekonstrukt - A &quot;New&quot; Forth Machine'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-4576628917453518397</id><published>2008-10-02T14:54:00.003+02:00</published><updated>2008-10-02T14:57:38.476+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><title type='text'>Trying Clojure...</title><content type='html'>&lt;p&gt;
  I am becoming increasingly frustrated by Common Lisp's age.  On the
  one hand, history makes it what it is: Mature, well-documented,
  thoroughly understood and practical.  On the other, it fails to keep
  up with current system designs, lacking convenient native support
  for rich data structures, infrastructure access and parallel
  programming.  No programming language choice is without tradeoffs
  and in that respect, and I'll still chose Common Lisp in many
  situations.  Realistically, though, Common Lisp cannot be the only
  language in my tool chest.  For browser work, Javascript is much
  more practical, and for parallel programming, I'm on the lookout.
&lt;/p&gt;
&lt;p&gt;
  On my last visit in Cambridge, I attended
  the &lt;a href="http://xach.livejournal.com/191581.html"&gt;Boston Lisp
  Meeting&lt;/a&gt;.  The presentation scheduled was about the new Lisp
  dialect the &lt;a href="http://clojure.org"&gt;Clojure&lt;/a&gt; by Rich Hickey,
  who is the creator of this language.
&lt;/p&gt;
&lt;p&gt;
  Parallel programming is one of the areas that Clojure wants to make
  easier.  It does so by making all data structure immutable and by
  language-level abstractions for
  &lt;a href="http://clojure.org/concurrent_programming"&gt;concurrent data
  access&lt;/a&gt;.  In that respect, it is similar to Erlang as
  it &lt;b&gt;requires&lt;/b&gt; a functional programming style everywhere.
  Unlike Erlang, which puts almost all operations with side effects
  behind a common message passing interface, Clojure exposes the full
  Java API to programs.  Thus, side effects can be produced
  everywhere, except in algorithms implemented in Clojure.
&lt;/p&gt;
&lt;p&gt;
  Clojure wants to be a Lisp, but it explicitly does not try to be
  backwards compatible.  This opened a rather large design space to
  Rich Hickey, and some of the choices he made really do make sense.
  He &lt;a href="http://clojure.org/reader"&gt;specifies a reader&lt;/a&gt;, yet
  his reader does not intern symbols.  That is a big win, as it allows
  the reader to actually work with arbitary Clojure source files.  In
  Common Lisp, one needs to re-implement a full reader which does not
  intern symbols if one wants to read Common Lisp source files.  This
  is kind of ironic, as the "Code is Data" mantra that we keep
  repeating does not really reflect what is possible in practice.
&lt;/p&gt;
&lt;p&gt;
  Rich managed to make me enthusiastic about Clojure, and I decided to
  give it a spin with a real project that I wanted to conduct anyway:
  I am a &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; user, and I would
  like to be notified of new posts
  to &lt;a href="http://planet.lisp.org/"&gt;Planet Lisp&lt;/a&gt; on Twitter.
  The program would read the Planet's RSS feed using a HTTP request,
  determine if new items have been posted and update the Twitter
  status of the &lt;a href="http://twitter.com/planet_lisp"&gt;Planet
  Lisp&lt;/a&gt; Twitter account that I have set up for this purpose.
&lt;/p&gt;
&lt;h2&gt;Getting the development environment up&lt;/h2&gt;
&lt;p&gt;
  My laptop runs Windows, but I do most of my Lisp development in a
  VMware running FreeBSD.  As Clojure is hosted on the Java virtual
  machine, I decided to avoid the indirection and use Windows as my
  native platform.  &lt;a href="http://github.com/jochu"&gt;Clojure
  support&lt;/a&gt;
  for &lt;a href="http://common-lisp.net/project/slime/"&gt;Slime&lt;/a&gt; is
  available, so I can stay in my familiar environment.  A very recent
  CVS checkout of Slime is required, which took me a little while to
  figure out.
&lt;/p&gt;
&lt;h2&gt;Processing XML&lt;/h2&gt;
&lt;p&gt;
  It took me a another while to discover what the proper way to
  process XML in Clojure is.  An XML parser is included with the base
  distribution, but there is no information in the documentation how
  one would actually work with the data structure that is generated by
  the parser.  For my application, I wanted to iterate over certain
  elements in the XML and extract a few subelements in a loop.  An
  evaluator for XPath expressions would have suited the job, but
  obviously that is not the Clojure way to do it.
&lt;/p&gt;
&lt;p&gt;
  In Clojure, XML does not receive any special treatment.  The parser
  reads it into a tree, and processing is performed using functions
  that process trees.  As simple as it may sound, I had a hard time
  finding a practical example of how this was supposed to
  work.  &lt;a href="http://blog.n01se.net/"&gt;Chris Houser&lt;/a&gt; finally got
  me on the right track when he pointed me to his
  &lt;a href="http://github.com/kevinoneill/clojure-contrib/tree/0f0b3cb13c7aad008f13302027c3bb81a42f6318/zip_filter"&gt;zip_filter&lt;/a&gt;
  package. zip_filter is a tool for filtering data out of trees, and
  it can work with trees produced by Clojure's XML parser.
&lt;/p&gt;
&lt;p&gt;
  Once I had figured this out, things were very easy.  The Planet Lisp
  RSS feed can be read into an XML tree with
  &lt;pre&gt;(clojure.zip/xml-zip (clojure.xml/parse "http://planet.lisp.org/rss20.xml"))&lt;/pre&gt;
  and one can extract data out of the parsed tree using path expressions:
  &lt;pre&gt;(clojure.contrib.zip-filter.xml/xml-&gt; xml :channel :item)&lt;/pre&gt;
  This certainly is concise and elegant, and I like the fact that XML
  is kept out of the program's way.  Note that I've included the
  namespace prefixes in the examples above so that they can be copied
  and pasted.  Normally, one would import these namespaces so that
  shorter or no namespace needs to be specified to access the symbols.
&lt;/p&gt;
&lt;h2&gt;Making HTTP requests&lt;/h2&gt;
&lt;p&gt;
  In order to update the Twitter status, a HTTP POST request to
  Twitter must be made.  A HTTP client which is based on the
  &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/net/ssl/HttpsURLConnection.html"&gt;java.net.HttpsURLConnection&lt;/a&gt;
  class is available from
  the &lt;a href="http://groups.google.com/group/clojure/files"&gt;Files
  section of the Clojure Google Group&lt;/a&gt;.  It is not a polished
  product and required some minor tweaking, but after that, fetching
  something using HTTP is as easy as
  &lt;pre&gt;(http-client/url-do "http://planet.lisp.org/" "GET" {})&lt;/pre&gt;
&lt;/p&gt;
&lt;h2&gt;Reading and writing files&lt;/h2&gt;
&lt;p&gt;
  The Twitter gateway needs to persistently store the list of articles
  that it has found on Planet Lisp in order to decide which of the
  current articles are new.  Clojure is a Lisp and thus can read and
  write its own data structures easily, so all it takes is calling a
  few functions.  As in the XML case, the hard part was figuring out
  what the proper functions are, as the documentation is sparse.  I
  found &lt;a href="http://blog.thinkrelevance.com/"&gt;Stuart Halloway's
  Blog&lt;/a&gt; in which he publishes a number of articles describing how
  the examples from Peter Seibel's
  book &lt;a href="http://gigamonkeys.com/book/"&gt;Practical Common
  Lisp&lt;/a&gt; can be implemented in Clojure.
  The &lt;a href="http://blog.thinkrelevance.com/2008/9/16/pcl-clojure-chapter-3"&gt;Simple
  Database&lt;/a&gt; example pretty much does the same thing that I
  required, so I looked at that.  Unfortunately, the "spit" function
  that is the complement to "slurp" and writes a string to a named
  file did not appear to exist in the clojure namespace.  It took a
  little grepping to find it in clojure.contrib.duck-streams, and
  referenced from there, it works as expected.
&lt;/p&gt;
&lt;h2&gt;Functional glue&lt;/h2&gt;
&lt;p&gt;
  Having all the required components in place, it was time to come up
  with the real code.  As data structures are immutable in Clojure,
  the challenge was to express the required loop so that both the new
  persistent state and the list of new postings would be maintained.
  I came up with a recursive function with two accumulators:
  &lt;pre&gt;(defn poll
  "Poll planet lisp, check for new postings, update Twitter status when new postings have appeared"
  []
  (save-data
   (let [old-data (load-data)
         process
         (fn [items new-data new-items]
           (if items
             (let [item (first items)
                   guid (first (xml-&gt; item :guid text)) ]
               (recur (rest items)
                      (conj new-data guid)
                      (if (old-data guid)
                        new-items
                        (conj new-items (first (xml-&gt; item :title text))))))
             (do
               (maybe-post-twit new-items)
               new-data)))]
     (process (xml-&gt; (feed-to-zip "http://planet.lisp.org/rss20.xml")
                     :channel :item)
              #{} []))))&lt;/pre&gt;
  To Scheme programmers, this style should be familiar.  I find it not
  terrible myself, although one could certainly push things around to
  suit taste.
&lt;/p&gt;
&lt;h2&gt;The Verdict&lt;/h2&gt;
&lt;p&gt;
  I was sceptical when I first read about Clojure.  I am sceptical of
  new languages in general, and new Lisp family members always make me
  think "why?" first.  Rich Hickey's presentation got me interested
  because he gave very good reasoning for his design choices.  He also
  is a very good presenter and could easily withstand an audience of
  die-hard Lispers that included people who have played an active role
  in the creation of Common Lisp.  But that is the singer, not the
  song.
&lt;/p&gt;
&lt;h3&gt;The good&lt;/h3&gt;
&lt;p&gt;
  The fixed reader, vastly improved data structure support, access to
  a host of libraries and concurrency support all make a good case for
  Clojure.  It is Lisp in many respects, and in the uncompromised
  macro facility opens up the extensibility that I am used to from
  Common Lisp.
&lt;/p&gt;
&lt;h3&gt;The bad&lt;/h3&gt;
&lt;p&gt;
  Clojure is not multi-paradigm in the sense that Common Lisp is: A
  functional programming style is required, and there is no way around
  that.  Making the comma be white space is somewhat of an arbitary
  decision, that does not match the other design choices that seem to
  be grounded better.
&lt;/p&gt;
&lt;h3&gt;The ugly&lt;/h3&gt;
&lt;p&gt;
  The error messages that the compiler produces are mostly useless.
  Debugging is hard, as no tracing facility and no breakpoints are
  available - Or maybe they are, but I could not find them in the
  documentation.  The overall immaturity of the language shows
  frequently, and I have spent hours looking for code examples and
  finding my way through something that is very much in flux.
&lt;/p&gt;
&lt;h2&gt;My Conclusion&lt;/h2&gt;
&lt;p&gt;
  I like Clojure, as it seems to fill my need for a language that
  supports concurrency and makes it possible to write modern desktop
  applications, while still being a Lisp.  I will use it for another
  project I have been planning to do in Erlang.  For general
  exploratory development, Clojure is not yet a good choice as the
  development environment is too immature.
&lt;/p&gt;
&lt;p&gt;
  I am not buying Rich Hickey's claim that classic object oriented
  programming is bad because it does not support concurrency.  I begin
  thinking of object oriented systems more as active databases that
  allow modeling of complex, interconnected and persistent data
  structures.  Such structures are managable with a pure sequential
  execution model, and one should refrain from mixing that with tasks
  that are inherently concurrent.
&lt;/p&gt;
&lt;p&gt;
  Finally: My Twitter gateway for Planet Lisp exists, but I have not
  yet been able to deploy it.  Getting Java to run on FreeBSD/amd64
  has proven to be kind of a challenge.  I will have this sorted out
  soon, so feel free to
  follow &lt;a href="http://twitter.com/planet_lisp"&gt;planet_lisp&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-4576628917453518397?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/4576628917453518397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/10/trying-clojure.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/4576628917453518397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/4576628917453518397'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/10/trying-clojure.html' title='Trying Clojure...'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1385604624490074612</id><published>2008-09-27T00:20:00.007+02:00</published><updated>2008-09-27T14:02:40.775+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='secd'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'></title><content type='html'>&lt;h1&gt;Revisiting SECD and the power of Lisp&lt;/h1&gt;
&lt;p&gt;
  While visiting
  the &lt;a href="http://www.icfpconference.org/icfp2008/"&gt;ICFP
  Conference 2008&lt;/a&gt;, I was discussing
  my &lt;a href="http://vaxbusters.org/workshop/secd.xml"&gt;SECD
  microprocessor reimplementation project&lt;/a&gt; with my co-worker
  Kilian.
  The &lt;a href="http://en.wikipedia.org/wiki/SECD_machine"&gt;SECD&lt;/a&gt; is
  a classic virtual machine architecture supporting functional
  programming languages invented by Peter J. Landin in the early
  1960ies.  It is a relatively unusual architecture in that it is
  commonly described by transformations of the machine state
  represented as four registers containing cons cells.  In fact, the
  virtual machine's memory conceptionally consists of linked cons
  cells, not of a vector of words that is addressed by integer
  addresses.  Jia-Huai You of University of Alberta has a good
  &lt;a href="http://www.cs.ualberta.ca/~you/courses/325/Mynotes/Fun/SECD-slides.html"&gt;description
  of how the SECD virtual machine works&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
  Quoting &lt;a href="http://hdl.handle.net/1880/46590"&gt;SECD: DESIGN
    ISSUES&lt;/a&gt;, here is the specification of the SECD virtual machine.
    There is one line for each machine instruction, describing the
    state of the four machine registers before and after the
    particular instruction has been executed:
&lt;/p&gt;
&lt;p&gt;
  &lt;img src="http://vaxbusters.org/secd-instruction-set.gif"/&gt;
&lt;/p&gt;
&lt;p&gt;
  While we were discussing my hardware project, Kilian suggested that
  we should implement a SECD in Common Lisp in order to bridge some
  time that we had until the next break.  Given that Lisp supports
  lists nicely, we chose to use Lisp lists to represent the SECD
  memory.  We first fooled around with imperative code that mimicked
  the required state transformations, but soon realised that it would
  be much easier to directly transform the specification for each
  machine instruction into executable Lisp.  Following common
  practice, we started writing down how we wanted to type in the
  specification for each of the SECD instructions.  As an example, the
  LD instruction would be defined by this:
  &lt;pre&gt;
(define-instr 1 LD
  (s e (LD (m . n) . c) d)
  `((,(locate m n e) . ,s) ,e ,c ,d))&lt;/pre&gt;
  The literal "1" is the op code, the "LD" is the symbolic name of the
  instruction, the first list is the state before the instruction is
  executed (with the four list elements representing the state of the
  four registers), and the rest specifying the code to execute for the
  instruction.  The executed code again returns a four element list
  representing the new state of the machine registers.
&lt;/p&gt;
&lt;p&gt;
  We then wrote a macro to transform this specification syntax into
  Lisp code.  Our DEFINE-INSTR macro uses the first list as an
  argument to DESTRUCTURING-BIND, binding all the names that we then
  use in the transformed state:
  &lt;pre&gt;
(defmacro define-instr (code name pre post)
  (let ((name* (intern (format nil "~A-INSTR" name))))
    `(progn
       (setf (gethash ,code *instr-hash*) ',name*)
       (defun ,name* ()
         (multiple-value-setq (s e c d)
           (destructuring-bind ,pre (list s e c d)
             (assert (= ,name ,code))
             (values-list ,post)))))))&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
  We were quite happy with our virtual machine, and we were able to
  run several of the precompiled SECD "binaries" from the ancient
  &lt;a href="http://vaxbusters.org/lispkit/LKIT-2/"&gt;LispKit software
  collection&lt;/a&gt;.  Getting the macro right and implementing the 21
  instructions took little time, and it was easy to, say, instrument
  the macro for tracing or augmenting it with checks to make sure that
  we got the original syntax right.  It would certainly be possible to
  polish the macro more - for example, having to specify the mnemonic
  of the operation twice is not so pretty.  We just meant to create
  something that we could use to explore the behavior of the SECD
  architecture, so we did not care polishing.
&lt;/p&gt;
&lt;p&gt;
  The next day, I attended an introductory Erlang workshop and as I
  had some prior knowledge of Erlang
  (&lt;a href="http://www.amazon.com/Programming-Erlang-Software-Concurrent-World/dp/193435600X/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1222462533&amp;sr=8-1"&gt;Programming
  Erlang&lt;/a&gt; by Joe Armstrong is a good read), I decided to try
  implementing a SECD VM in Erlang instead of doing the exercises
  suggested by the lecturer.  Erlang has built-in pattern matching, so
  I used a transliteration scheme of the VM specification very similar
  to what I used in Lisp.  Also, Erlang has lists, so representing the
  SECD memory as Erlang lists should be a one to one match, too.
&lt;/p&gt;
&lt;p&gt;
  So, here is the CAR instruction implemented in Erlang:
  &lt;pre&gt;
secd(S = [ [ CAR | _ ] | _ ],
     E,
     [ ?CAR | C ],
     D) -&gt;
    secd([ CAR | S ],
         E,
         C,
         D);&lt;/pre&gt;
  In Erlang, function dispatch is based on pattern matching, and there
  is total flexibility to match structures and bind variables to what
  has matched.  For example, in the implementation of the car
  operation above, we bind the variable S to the previous stack
  contents, and at the same time bind the variable CAR to the car of
  the cons cell that is sitting on top of the stack.
&lt;/p&gt;
&lt;p&gt;
  The Erlang version of the VM grew well, and the source code looked
  as nice as the Lisp version.  Yet, as I tried to implement the
  the RAP instruction, I faced a major stumbling block.
&lt;/p&gt;
&lt;p&gt;
  The RAP instruction is used to support recursive function calls and
  works by replacing a previously created dummy environment on the
  stack, called OMEGA, by one which contains all the functions that
  are visible in the recursive scope.  The specification uses RPLACA
  to denote that replacement operation, and that is what we used in
  our Lisp implementation of SECD, too:
  &lt;pre&gt;
(define-instr 7 RAP
  (((c* . e*) v . s) (om . e) (rap . c) d)
  (progn
    (assert (equal om 'omega))
    `(nil ,(rplaca e* v) ,c* (,s ,e ,c . ,d))))&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
  When trying to implement RAP in Erlang, I got stuck because there
  are no destructive operations on lists.  Not in the standard API,
  and seemingly not in the system API either.  So, the Erlang SECD
  looks nice, only it does not run.  Frankly, our Lisp based SECD
  has bugs, too, and I am not totally sure whether the problem is not
  in the RAP instruction.
&lt;/p&gt;
&lt;p&gt;
  Curiously, getting the RAP instruction right is harder than one
  wants to expect: In the SECD hardware implementation that I worked
  on, I used the original microcode of the SECD chip developed at the
  University of Calgary as part of a verification project.  I found
  two major bugs in this microcode which, ironically, was part of the
  file set that compromises the proof that the SECD hardware
  implementation was correct according to its abstract specification.
  One bug was the garbage collector which did not work at all, and the
  other was in the RAP instruction which did not work either.  I have
  trouble not concluding something regarding academia in general from
  these findings.
&lt;/p&gt;
&lt;p&gt;
  Anyway.... this was another time when I realized how much I like
  Common Lisp and why it will propably not be replaced by another
  language anytime soon.  Common Lisp is teh tool of choice for my
  exploratory programming, as it does not have a terrible lot of
  restrictions, yet supports some advanced programming abstractions.
  There are domains where Common Lisp does not have much to offer,
  though.  Concurrent programming currently is the one area where the
  lack of support in Common Lisp hurts me most.  Erlang may be my
  cure, and I hope to look
  into &lt;a href="http://forum.trapexit.org/viewtopic.php?p=40268#40268"&gt;Lisp
  Flavoured Erlang&lt;/a&gt; in order to spare myself the arcane syntax that
  Erlang provides by default.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1385604624490074612?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1385604624490074612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/09/revisiting-secd-and-power-of-lisp-while.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1385604624490074612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1385604624490074612'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/09/revisiting-secd-and-power-of-lisp-while.html' title=''/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-2755367397549107950</id><published>2008-08-01T10:32:00.006+02:00</published><updated>2011-12-15T12:23:37.308+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='bknr'/><title type='text'>Schema evolution made easy</title><content type='html'>&lt;p&gt;
  Applications age, and with age often comes the desire to change
  things.  One of the more painful aspects of changing a deployed
  application is transforming existing data.  This post shows some of
  the schema evolution techniques that we have used to update
  applications using the &lt;a href="http://bknr.net/"&gt;BKNR
  datastore&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
  With traditional database-based persistence solutions, converting
  existing databases is often done by first exporting the data using
  database tools or specialized exporter software and then importing
  it into the new database schema, possibly converting data while
  reading.  Using explicit export and import steps can be tricky and
  time consuming.  The export side often comes for free, but the
  importer will need to reinstantiate the correct objects in the new
  schema knowing both the export format and the new schema.  Making
  such importers work reliably is an additional task that has no
  additional value, and after having converted the existing databases,
  the code written can typically be thrown away.
&lt;/p&gt;
&lt;p&gt;
  A common technique for making schema evolution less painful is to
  make only additive schema changes.  Old information is preserved,
  and the new code does the conversion either on the fly or in a
  separate conversion run.  This scheme leads to both cruft in the
  database and in the source code, and requires additional data
  cleanup steps to finalize the schema upgrade once the application
  has been migrated to the new code base.  Substantial structural
  changes require more thought in this scheme, in particular if
  database side integrity constraints need to be considered.
&lt;/p&gt;
&lt;p&gt;
  All in all, schema evolution is a messy business.
&lt;/p&gt;
&lt;p&gt;
  Recently, we have been working on extending and updating two of the
  applications that we have developed using the BKNR datastore, and
  the schema evolution problem occured for us to be solved, too.  When
  designing the store, we felt that schema evolution should be easy.
  After all, we have all our data in main memory, so we can always
  load the old data using the old application code, reload the
  application, and implement methods for the relevant CLOS functions
  that are called by the object system when classes are changed.
&lt;/p&gt;
&lt;p&gt;
  In practice, we found the need to load the old code, the data and
  then the new code in succession to be inconvenient.  Keeping the old
  code around in the right places would be rather burdensome, and we
  also had some problems with (our usage of) CLOS in the face of large
  metadata changes.
&lt;/p&gt;
&lt;p&gt;
  As we keep snapshots of our data in a file, we decided that our
  schema evolution process would work by converting the data into the
  new schema while reading the snapshot file.  Our snapshot file
  format contains serialized versions of all persistent CLOS objects
  that constitutes a data store.  For each class used in the snapshot,
  a layout record is present in the snapshot file that contains the
  name of the class and the names of the slots of the class.
&lt;/p&gt;
&lt;p&gt;
  When reading a snapshot file, the object system compares the class
  layout in the snapshot against the class definitions of the running
  code.  Inconsistencies detected are signalled, and restarts are used
  to select schema evolution actions.
&lt;/p&gt;
&lt;p&gt;
  Currently, we support the following schema evolution steps:&lt;ul&gt;
    &lt;li&gt;&lt;em&gt;Class removal&lt;/em&gt;:  When a layout specifies a class that does not exist in the running application, instances of this class can be ignored.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Class renames&lt;/em&gt;:  When a class has been renamed, the new class name can be specified and the reading can be restarted.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Slot removal&lt;/em&gt;:  If a slot named in the snapshot file does not exist in the running code, the slot values of the instances can be ignored.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
  These three options are solely controlled through restarts
  established while reading the snapshot file.  No code needs to be
  written to do these conversions.
&lt;/p&gt;
&lt;p&gt;
  Additionally, we have a slot conversion mechanism: If a slot has
  been renamed or its semantics have been changed, slot values of
  previous software versions can be converted.  In order to do this, a
  method on
  the &lt;a href="http://bknr.net/trac/browser/trunk/bknr/datastore/src/data/object.lisp?rev=3698#L380"&gt;CONVERT-SLOT-VALUE-WHILE-RESTORING
  generic function&lt;/a&gt; must be defined.  It receives the object being
  restored, the name of the slot as specified in the snapshot layout,
  and the value to set.
&lt;/p&gt;
&lt;p&gt;
  The default method of CONVERT-SLOT-VALUE-WHILE-RESTORING simply
  assigns the value provided to the slot with the given name.  A
  specialized method
  could &lt;a href="http://bknr.net/trac/browser/trunk/bknr/web/src/sysclasses/user.lisp?rev=3716#L197"&gt;convert
  the value&lt;/a&gt;
  or &lt;a href="http://bknr.net/trac/browser/trunk/projects/bos/m2/poi.lisp?rev=3708#L215"&gt;assign
  it to a different slot&lt;/a&gt; of the same object.  When reading a class
  layout from the snapshot file that contains an unknown slot name, a
  restart is offered to call CONVERT-SLOT-VALUE-WHILE-RESTORING for
  values of this slot.
&lt;/p&gt;
&lt;p&gt;
  The beauty of this form of schema evolution is that we can easily
  load snapshots from our production systems using new code, without
  any additional required conversion steps.  We can regularily verify
  that our new code works with real data, and can incrementally refine
  our schema evolution process without having to resort to database
  tools or external formats that require special handling.
&lt;/p&gt;
&lt;p&gt;
  One could certainly improve on this, for example by making some of
  the evolution steps automatic so that one does not remember what
  restarts need to be chosen when loading older snapshots.  For the
  moment, these tools serve us well, and it did not take a lot of time
  (and was fun)
  to &lt;a href="https://github.com/hanshuebner/bknr-datastore/commit/3a2081146576881863680da8a74abe3ff2af58a5"&gt;implement&lt;/a&gt;
  them.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-2755367397549107950?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/2755367397549107950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/08/schema-evolution-made-easy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/2755367397549107950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/2755367397549107950'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/08/schema-evolution-made-easy.html' title='Schema evolution made easy'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-3004692134972612</id><published>2008-07-03T13:04:00.003+02:00</published><updated>2008-07-03T13:33:19.120+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Building Load Resilient Web Servers</title><content type='html'>&lt;p&gt;
  One of the bigger challenges with deploying dynamic web servers is
  being able to cope with load peaks that happen when the URL is
  communicated to larger communities in a short time.  I have seen
  several sites
  being &lt;a href="http://en.wikipedia.org/wiki/Slashdot_effect"&gt;slashdotted&lt;/a&gt;
  and collapse under the load, and it is common to blame the underlying
  server technology for crashes; being Lisp lovers, we don't want to
  see that happen for our sites.
&lt;/p&gt;
&lt;h2&gt;Using a caching frontend to reduce backend load&lt;/h2&gt;
&lt;p&gt;
  Following industry practice, we have been using a
  caching &lt;a href="http://en.wikipedia.org/wiki/Reverse_proxy"&gt;reverse
  proxy&lt;/a&gt; in front of our Lisp based dynamic web servers from the
  beginning.  Our choice
  was &lt;a href="http://en.wikipedia.org/wiki/Squid_cache"&gt;Squid&lt;/a&gt;, as
  I had prior experience configuring it and found it to work reliably
  once the configuration was in place.  I was never quite happy with
  that choice, though, because Squid's main operation mode is forward
  proxying.  It has gazillions of configuration options that are not
  needed for a reverse proxy, which made us feel that Squid would not
  be a perfect match for our demands.
&lt;/p&gt;
&lt;p&gt;
  This is not to say that Squid has hurt us
  in any way.  It has served us well during a load peak on
  the &lt;a href="http://create-rainforest.org/"&gt;create-rainforest web
  site&lt;/a&gt;, but as reverse proxying has become very common in the last
  few years, we found it about time to go shopping for a solution that
  might be a better match to our needs.
&lt;/p&gt;
&lt;p&gt;
  We hoped to find a frontend proxy having the following features:
  &lt;ul&gt;
    &lt;li&gt;
      Caching - We want the frontend to cache all content that is
      not session dependent in order to reduce the load on our Lisp
      backend.
    &lt;/li&gt;
    &lt;li&gt;
      Scalable - The frontend must be able to handle loads much larger
      than what we see normally in order to accomodate for peaks.
    &lt;/li&gt;
    &lt;li&gt;
      Request queueing - Ideally, we'd like the frontend to handle all
      concurrency issues and send requests to the backend one after
      the other using a single persistent http connection, maybe with
      pipelining.
    &lt;/li&gt;
  &lt;/ul&gt;
  This set of requirements reduced the available options dramatically,
  and we ended up
  giving &lt;a href="http://varnish-cache.org"&gt;varnish&lt;/a&gt; serious consideration.
&lt;/p&gt;
&lt;h2&gt;Evaluating varnish&lt;/h2&gt;
&lt;p&gt;
  varnish seems to have most of the features that we require: It
  supports caching, has been tested under very high loads and
  supports &lt;a href="http://freebsd.org"&gt;FreeBSD&lt;/a&gt; which is our
  deployment platform.  Varnish has been written
  by &lt;a href="http://people.freebsd.org/~phk/"&gt;Poul-Henning Kamp&lt;/a&gt;
  of FreeBSD fame, so we also found it to be culturally compatible.
&lt;/p&gt;
&lt;p&gt;
  Our evaluation revealed that varnish is under active development and
  support, and we found the developers be very responsive to our bug
  reports and requests.  Its architecture looks well thought out, and
  the configuration language (even if underdocumented) makes the
  request handling process very transparent.
&lt;/p&gt;
&lt;p&gt;
  There are a number of downsides with varnish, though:
  &lt;li&gt;
    &lt;ul&gt;
      Eager cache cleanup policy:  varnish removes objects from its
      cache as soon as they expire.  This means that expired objects
      are always fetched from the backend, even if the previous cached
      copy was still up to date.  It is possible to work around this
      by either hacking varnish to revalidate cached objects before
      expiring them or by not expiring them automatically, but rather
      by explicit purge requests sent from the backend to varnish.
      Both options, while doable, require substantial work.
    &lt;/ul&gt;
    &lt;ul&gt;
      No high load safeguards:  varnish offers no control over the
      number of backend connections established and does not support
      any queuing or backend resource control mechanisms.  This means
      that it will unconditionally try to establish a connection to
      the backend if an object can't be served from the cache.  Once
      the backend reaches saturation, varnish will aggravate the
      situation by sending even more requests to the backend,
      increasing the time to recover from the backend saturation.
    &lt;/ul&gt;
    &lt;ul&gt;
      Threading:  varnish uses threading to schedule requests.  While
      this in principle should not be something negative, threaded
      programs are much harder to debug in practice, and many
      concurrency bugs that threaded code is susceptible to only show
      up after a long time or under certain load patterns which may be
      hard to reproduce.  Admittedly, I am a threads hater, but I am
      writing this here because we found a serious threading race
      condition on the second day of our evaluation which prevented
      varnish from even starting up.  My trust in the code was
      seriously affected by this.
    &lt;/ul&gt;
  &lt;/li&gt;
  When talking to the varnish developers, the problems were
  acknowledged, help to fixable problems was very quick and they told
  us that more advanced features will be develop after the upcoming
  2.0 release of varnish.
&lt;/p&gt;
&lt;p&gt;
  We would have liked to switch to varnish because of the very good
  support and because it is meant to be a web frontend, nothing else.
  Yet, at the current point in time, it does not seem to be mature
  enough to serve our needs.  After having evaluated it, we turned
  back to squid as it seemed to be the only other option.  We found
  that squid meets our requirements for cache cleaning and
  revalidation of cached objects very well.
&lt;/p&gt;
&lt;h2&gt;Making objects cacheable&lt;/h2&gt;
&lt;p&gt;
  Chosing a front end software is only part of what needs to be done
  to make a web system fast and robust enough to withstand high
  loads.  The most important factor is to make the frontend serve a
  large percentage of the incoming requests from its cache and only
  consult the backend server for content that is really dynamic.
  The HTTP/1.1 protocol provides for request and response headers that
  control how content can be cached, and there is little need for
  explicit configuration if these headers are used correctly.
&lt;/p&gt;
&lt;h3&gt;Using If-modified-since&lt;/h3&gt;
&lt;p&gt;
  One way to limit the traffic to the backend is implement the
  &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25"&gt;If-modified-since&lt;/a&gt;
  mechanism.  It is supported
  by &lt;a href="http://weitz.de/hunchentoot"&gt;Hunchentoot&lt;/a&gt; for static
  files by default, and can also
  be &lt;a href="http://weitz.de/hunchentoot/#handle-if-modified-since"&gt;used
  for dynamic&lt;/a&gt; handlers that can check whether a resource has
  changed since it had previously been requested.  Varnish will set
  the If-modified-since header when it requests resources that it
  already has in the cache, so every cacheable resource will normally
  be transfered from the backend to Varnish only once.
&lt;/p&gt;
&lt;h3&gt;Controlling cache refreshing&lt;/h3&gt;
&lt;p&gt;
  Often, resources are dynamic, yet it is not crucial that every
  client sees the absolutely latest version of the resource.  For
  example, in our &lt;a href="http://create-rainforest.org/"&gt;square meter
  sales application&lt;/a&gt;, visitors should always see the current number
  of square meters sold, but it is not vital that this information is
  accurate to the second.  Thus, we want the cache to refresh such
  pages only at a certain interval.  The HTTP/1.1 provides for
  the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3"&gt;cache-control&lt;/a&gt;
  directive and in particular the max-age parameter.  It specifies how
  long a cache may consider a cached resource be valid without
  revalidating with the originating server.  By setting this parameter
  in responses sent by the backend, we can effectively limit the
  maximum refresh rate for dynamic resources that do not need
  completely up to date every time.
&lt;/p&gt;
&lt;h2&gt;Testing realistically&lt;/h2&gt;
&lt;p&gt;
  In order to test the performance of a Web system, it needs better
  tools than the
  often-used &lt;a href="http://en.wikipedia.org/wiki/ApacheBench"&gt;ApacheBench&lt;/a&gt;
  tool, which only tests response times and throughput of a single
  URL.  For meaningful results, one should simulate a user load that
  reflects the load that real users create.  I have been
  using &lt;a href="http://www.joedog.org/JoeDog/Siege"&gt;SIEGE&lt;/a&gt; for
  informal testing often, as it is easy to use, but I have also found
  it a little flakey and prune to random crashes, which made us look
  for more reliable solutions.
&lt;/p&gt;
&lt;p&gt;
  In the &lt;a href="http://freebsd.org/ports/"&gt;FreeBSD ports
  collection&lt;/a&gt;, we
  found &lt;a href="http://tsung.erlang-projects.org/"&gt;tsung&lt;/a&gt;.  Tsung
  is an open-source multi-protocol distributed load testing tool
  written in Erlang, and it has good support for HTTP.  In addition to
  running load tests against web servers and
  generating &lt;a href="http://tsung.erlang-projects.org/screenshots.en.html"&gt;statistics
  reports&lt;/a&gt;, it supports a session recorder that can be used to
  create a log of the URLs that a user visits when browsing a web
  server which can then be directly used to simulate many simultaneous
  users.  As an added bonus, it is possible to capture dynamically
  generated information from web server responses into variables and
  use them in subsequents requests in a session.  This feature can be
  used to generate sale transactions or user registrations in a load
  simulation.
&lt;/p&gt;
&lt;p&gt;
  Using tsung and squid, we were able to tune our Lisp backend so that
  all non-dynamic content is served from the cache, pinpoint a serious
  performance problem and simulate realistic loads.  We are now
  confident that our setup can withstand the next rush of users
  without crashing.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-3004692134972612?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/3004692134972612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/07/building-load-resilient-web-servers.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3004692134972612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3004692134972612'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/07/building-load-resilient-web-servers.html' title='Building Load Resilient Web Servers'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1275849568352387836</id><published>2008-05-29T10:36:00.003+02:00</published><updated>2008-09-27T00:53:39.375+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Hamburg Lisp Meeting</title><content type='html'>Yesterday, there was a Lisp meeting in Hamburg hosted by Stefan Richter at &lt;a href="http://freiheit.com/"&gt;freiheit.com&lt;/a&gt;.  Some 30 men from all over northern Germany attended.  freiheit.com kindly sponsored beverage and barbeque, and the nice weather made staying on the terrace very enjoyable - see &lt;a href="http://www.flickr.com/photos/srichter"&gt;Stefan's photos&lt;/a&gt;.

Two presentations were given:

Edi Weitz talked about &lt;a href="http://piano.aero/"&gt;Piano&lt;/a&gt;, an application which was originally developed under MCL used to design airplanes.  Edi ported Piano to LispWorks on Windows in 40 man days, which is rather impressive given that this not only meant a compiler change, but also a change of graphic environments with different semantics and mechanisms.  We were shown how a Boeing 737-lookalike can be designed with Piano by entering just a dozen parameters.

Rainer Joswig showed off two of his Symbolics Lisp Machines, a NXP1000 and a MacIvory III.  He walked us through his &lt;a href="http://lispm.dyndns.org/news?ID=NEWS-2008-05-05-1"&gt;genealogy of Lisp machines&lt;/a&gt; and then demoed Genera and Dynamic Windows, which still impresses me.  I had brought my Symbolics keyboard and tried most of the stuff on my laptop when he was doing it on the real hardware.  The &lt;a href="http://labs.aezenix.com/lispm/index.php?title=VLM_On_Linux"&gt;VLM on Linux&lt;/a&gt; is by orders of a magnitude faster, and with a real keyboard, it is a lot easier to use.  Several people asked me if I could get them a &lt;a href="http://netzhansa.blogspot.com/2008/05/symbolics-keyboard-on-ps2-port.html"&gt;PS/2 adapter for the Symbolics keyboard&lt;/a&gt;, too, so I think I will need to build a few more.

The evening concluded with music, beers and food, and it was unfortunate that we had to leave early and sober in order to hit the road back to Berlin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1275849568352387836?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1275849568352387836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/05/hamburg-lisp-meeting.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1275849568352387836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1275849568352387836'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/05/hamburg-lisp-meeting.html' title='Hamburg Lisp Meeting'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-7482219263703839105</id><published>2008-05-18T22:20:00.006+02:00</published><updated>2008-09-27T00:53:01.244+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Symbolics Keyboard on PS/2 port</title><content type='html'>I have been busy with hacking Hunchentoot and flexi-streams at daytime during the last few weeks, and wrote a thread-safe version of a simple deterministic profiler for Clozure CL so that I could isolate performance problems.  I'm going to blog about that stuff in a few days, but as that is daytime work, I had to find something else to relax on the weekend.

Thus, I turned my attention to the &lt;a href="http://kbdbabel.org/"&gt;kbdbabel&lt;/a&gt; hardware that I received last week.  A few months ago, I emailed Alexander Kurz, who is the creator of the kbdbabel project, whether he could help me getting a PS/2 adapter for the Symbolics keyboard to work.  At the time, he had created PS/2 adapters for various vintage keyboards and he expressed his interest.  We could not make much progress, though, as he did not have a keyboard and I lacked the knowledge to adopt the 8051 based assembler code to the needs of the Symbolics protocol.  I'm mostly an AVR guy when it comes to microcontrollers.

Alexander was intimidated enough by the &lt;a href="http://images.google.com/images?q=symbolics+keyboard&amp;btnG=Search+Images&amp;um=1&amp;hl=en&amp;client=firefox-a&amp;rls=com.google%3Ade%3Aofficial"&gt;pictures of the various Symbolics keyboards&lt;/a&gt; that he decided to get one and make a kbdbabel for it.  I was more than happy when he contacted me out of the blue a few weeks ago and told me that he now has a solution.

The hardware he sent did not work right away with my Thinkpad, but that was because the Thinkpad's PS/2 port do not quite work like most other PS/2 ports do.  Thus, I had to get a PS/2 to USB adapter for 10 Euros.  With that, the adapter worked as advertised.

&lt;img src="http://vaxbusters.org/symbolics-kbdbabel.jpg" width="800" height="531"/&gt;

I had to complete the keyboard mapping so that all keys in the default Open Genera map are mapped to a key on the Symbolics keyboard.  This means that there are no mappings for several keys (the square, circle and star keys among them).  Supporting those keys will require changing the Open Genera X11 keyboard mapping code, which is something I'll put onto my "weekend projects" list now.

I have not yet tested the adapter with the "slim" keyboard - I only have a 3600 one right now and the two "slim" keyboards I bought from &lt;a href="http://symbolics.com/"&gt;David K. Schmidt&lt;/a&gt; are still in Cambridge and won't be with me until next month.  Contrasted to the 3600 keyboard, the "slim" keyboard is microcontroller based and will most likely require different timing than the TTL based old-style keyboard.  Other than that, the keyboards should be compatible and the adapter should work with both variants.  I'm going to build a few adapters for myself and some friends of mine.  If you want one as well and don't like to do the soldering yourself, &lt;a href="mailto:hans.huebner@gmail.com"&gt;contact me&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-7482219263703839105?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/7482219263703839105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/05/symbolics-keyboard-on-ps2-port.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/7482219263703839105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/7482219263703839105'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/05/symbolics-keyboard-on-ps2-port.html' title='Symbolics Keyboard on PS/2 port'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-1232834830624795189</id><published>2008-04-23T09:27:00.008+02:00</published><updated>2008-04-23T11:20:01.373+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>BKNR at the Boston Lisp Meeting</title><content type='html'>After a &lt;a href="http://weitz.de/eclm2008/"&gt;weekend full of parentheses&lt;/a&gt; in Amsterdam, I attended the &lt;a href="http://ourdoings.com/boston-lisp/2008-04"&gt;Boston Lisp Meeting&lt;/a&gt; hosted at MIT.  Peter Dillinger gave a presentation on the &lt;a href="http://acl2s.peterd.org/acl2s/doc/"&gt;ACL2s&lt;/a&gt;, which is an Eclipse based user interface for the &lt;a href="http://www.cs.utexas.edu/~moore/acl2/"&gt;ACL2 theorem prover&lt;/a&gt;.  I have no background in mathematics and as such, I had to guess my way through the terminology, but the talk was entertaining and even though it somehow does not feel right to see an advanced Common Lisp program be controlled by a lowly Java application, I see the practical aspects of the approach.  Bottom line:  Common Lisp loses when it comes to programming modern user interfaces in general, and I'm not sure that we can do much about that.

The second speech for the evening was my presentation of the BKNR datastore.  I found myself being well received, and the questions from the audience mostly were those that I have been asking myself during the last few years.  I have put &lt;a href="http://bknr.net/pdf/datastore-presentation.pdf"&gt;the slides&lt;/a&gt; online, and I also updated the &lt;a href="http://bknr.net/"&gt;BKNR website&lt;/a&gt; to make the documentation easier to access.  If you have &lt;a href="http://earth.google.com/"&gt;Google Earth&lt;/a&gt; installed, you can play with the (alpha quality) &lt;a href="http://test.createrainforest.org/kml-root/616108"&gt;GE interface&lt;/a&gt; to the BKNR based &lt;a href="http://test.createrainforest.org/en/index"&gt;Samboja Lestari web site&lt;/a&gt;.  If you want, you can have a look at the &lt;a href="http://bknr.net/trac/browser/trunk/projects/bos/"&gt;source code&lt;/a&gt;, too.  Our use of &lt;a href="http://bknr.net/trac/browser/trunk/projects/bos/m2/m2.lisp?rev=3009#L280"&gt;publish&lt;/a&gt;/&lt;a href="http://bknr.net/trac/browser/trunk/projects/bos/m2/map.lisp?rev=2866#L98"&gt;subscribe&lt;/a&gt; for persistent objects may be of interest, as well as the use of &lt;a href="http://www.cis.upenn.edu/~screamer-tools/screamer-intro.html"&gt;Screamer&lt;/a&gt; for brute-force &lt;a href="http://bknr.net/trac/browser/trunk/projects/bos/m2/geometry.lisp?rev=2973#L358"&gt;determination of the largest rectangle&lt;/a&gt; inside an arbitary polygon.  Kilian, who does most of the programming in the BOS project presently, has a background in music composition.  He found it easier to formulate the solution to the problem using constraints rather than using explicit looping.&lt;div&gt;
&lt;/div&gt;&lt;div&gt;The socializing part of the meeting was rather short for me as I am mostly staying on Central European Time while being in Boston, so it felt like past midnight to me.  I met several interesting people anyway,  and I hope that I can synchronize my next visits in Cambridge with the meetings.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-1232834830624795189?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/1232834830624795189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/04/bknr-at-boston-lisp-meteing.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1232834830624795189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/1232834830624795189'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/04/bknr-at-boston-lisp-meteing.html' title='BKNR at the Boston Lisp Meeting'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-223507886530436903</id><published>2008-04-14T12:37:00.003+02:00</published><updated>2008-09-27T00:54:01.411+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Chaosradio Express on Lisp</title><content type='html'>Last week, I have been a guest at Tim Pritlove's Chaosradio Express and he interviewed me about Lisp.  &lt;a href="http://chaosradio.ccc.de/cre084.html"&gt;The podcast&lt;/a&gt; is in german, we talked about how I came to Lisp and what I think it is about.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-223507886530436903?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/223507886530436903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/04/chaosradio-express-on-lisp.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/223507886530436903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/223507886530436903'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/04/chaosradio-express-on-lisp.html' title='Chaosradio Express on Lisp'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-220510114501425057</id><published>2008-03-31T23:32:00.001+02:00</published><updated>2008-04-01T00:07:59.194+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Feature development and getting carried away on Lisp</title><content type='html'>&lt;h2&gt;Customer Demands&lt;/h2&gt;
Recently, I have been spending some weekend and late night hours on extending the &lt;a href="http://quickhoney.com/"&gt;QuickHoney&lt;/a&gt; web system.  The artists want to see the system modernized with RSS feeds and more interaction, and we'll also be adding a shop where both digital and real warez can be bought.

Peter in particular wants to get more feedback, so he asked me to add a "quick feedback" mechanism that visitors can use to send a short textual comment on any of the pictures.  In this post, I'll describe how I added this feature using Javascript, &lt;a href="http://bknr.net/"&gt;BKNR&lt;/a&gt;, &lt;a href="http://common-lisp.net/project/cl-smtp"&gt;CL-SMTP&lt;/a&gt; and &lt;a href="http://www.cliki.net/CL-MIME"&gt;CL-MIME&lt;/a&gt;.

First off, here is a little overview of the QuickHoney web application.  It is a early AJAX style application with one HTML page consisting of a number of layers which are controlled by a Javascript application.  Communication between the Javascript application and the backend server is done through Javascript code snippets that are generated on the server and evaluated inside the client application using IFRAMES.  The user navigates through categories and subcategories to individual pictures.

The backend for the QuickHoney application is written in Common Lisp using the BKNR framework.  It uses the datastore extensively as well as the &lt;a href="http://weitz.de/cl-gd"&gt;cl-gd&lt;/a&gt; image processing library written by Edi Weitz.
&lt;h2&gt;Frontend Functionality&lt;/h2&gt;
The feedback functionality will work on a per-picture basis.  When a picture is displayed, a small "provide feedback" icon will be displayed.  When the user clicks it, a form will be displayed in a layered window.  The form will consist of "From" and "Text" fields and a "Send" button.  The &lt;i&gt;onclick&lt;/i&gt; action of the button is connected to a function that packs the contents of the "From" and "Text" fields into a urlencoded form data string and send it to the server using a POST request:
&lt;pre style="font-size: 0.6em"&gt;
function digg_send()
{
    var d = doXHR("/digg-image/" + current_image.id,
                  { method: 'POST',
                    headers: {"Content-Type":"application/x-www-form-urlencoded"},
                    sendContent: queryString({ from: $('digg_from').value,
                                               text: $('digg_text').value }) })
        .addCallback(function () { alert('sent'); });
    return false;
}
&lt;/pre&gt;
&lt;i&gt;doXHR&lt;/i&gt; and &lt;i&gt;$&lt;/i&gt; are functions from the &lt;a href="http://mochikit.org/"&gt;MochiKit&lt;/a&gt; Javascript library which I like to use for non-GUI-related things for its conciseness and conceptional soundness.

As can be seen in the Javascript snippet above, there is a &lt;b&gt;/digg-image/&lt;/b&gt; handler on the web server that is used to send the feedback.  The URL that is used also consists of the object ID of the image currently displayed.  Every persistent object in the BKNR datastore has a unique object ID, and the &lt;i&gt;FIND-STORE-OBJECT&lt;/i&gt; function can be used to find an object with a certain object ID in the store.
&lt;h2&gt;Implementing a Backend Handler&lt;/h2&gt;
The BKNR web framework makes it easy for applications to declare new handlers which relate to a certain store object.  It provides for a set of handler classes that application handlers can inherit from.  These handler base classes implement request URL parsing and automatically call handler methods with with relevant information from the URL and the request body parsed into Lisp objects.

For the feedback feature, we need to subclass the &lt;i&gt;OBJECT-HANDLER&lt;/i&gt; base class which extracts the object ID out of the URL, uses &lt;i&gt;FIND-STORE-OBJECT&lt;/i&gt; to find the relevant object in the store and then calls the &lt;i&gt;HANDLE-OBJECT&lt;/i&gt; method of the handler to actually handle the request.  The declaration for this handler class looks like this:
&lt;pre style="font-size: 0.6em"&gt;
(defclass digg-image-handler (object-handler)
  ()
  (:default-initargs :object-class 'quickhoney-image))
&lt;/pre&gt;
The &lt;i&gt;:OBJECT-CLASS&lt;/i&gt; initarg can optionally be specified when creating an &lt;i&gt;OBJECT-HANDLER&lt;/i&gt; object to make sure that &lt;i&gt;HANDLE-OBJECT&lt;/i&gt; is only called for objects of that class.  If the object ID in the URL references an object from a different class, an error page is displayed to the user.

The &lt;i&gt;HANDLE-OBJECT&lt;/i&gt; method for the &lt;i&gt;DIGG-IMAGE-HANDLER&lt;/i&gt; class is specialized on both the &lt;i&gt;DIGG-IMAGE-HANDLER&lt;/i&gt; handler class and on the &lt;i&gt;QUICKHONEY-IMAGE&lt;/i&gt; class.  It extracts the form parameters from the request and opens a connection to the SMTP server to send a mail to the owner or owners of the &lt;i&gt;QUICKHONEY-IMAGE&lt;/i&gt;.  The mail itself is a simple HTML mail with a table containing the name of the image, hyperlinked to the online page with the image and the feedback information entered by the user.  Also, a thumbnail of the image is included with the email so that the artist immediately sees what picture the user is raving about.  Modern mailers (like Apple Mail or Google Mail) display images attached in a multipart/mixed MIME mail inline, so there is no need to come up with a fancy HTML mail that references elements included in the same mail body.

This is the source code of the handler:
&lt;pre style="font-size: 0.6em"&gt;
(defmethod handle-object ((handler digg-image-handler) (image quickhoney-image))
  (with-query-params (from text)
    (cl-smtp:with-smtp-mail (smtp "localhost"
                                  "webserver@quickhoney.com"
                                  (remove-duplicates (mapcar #'user-email
                                                             (or (owned-object-owners image)
                                                                 (list (find-user "n")
                                                                       (find-user "p"))))))
      (cl-mime:print-mime
       smtp
       (make-instance
        'cl-mime:multipart-mime
        :subtype "mixed"
        :content (list
                  (make-instance
                   'cl-mime:mime
                   :type "text" :subtype "html"
                   :content (with-output-to-string (s)
                              (html-stream s
                                           (:html
                                            (:head
                                             (:title "Picture comment"))
                                            (:body
                                             (:table
                                              (:tbody
                                               (:tr
                                                ((:td :colspan "2")
                                                 "Comment on picture "
                                                 ((:a :href (make-image-link image))
                                                  (:princ-safe (store-image-name image)))))
                                               (:tr
                                                (:td (:b "From"))
                                                (:td (:princ-safe from))))
                                               (:tr
                                                ((:td :valign "top") (:b "Text"))
                                                (:td (:princ-safe text)))))))))
                  (make-instance
                   'cl-mime:mime
                   :type "image"
                   :subtype (string-downcase (symbol-name (blob-type image)))
                   :encoding :base64
                   :content (flexi-streams:with-output-to-sequence (s)
                              (blob-to-stream image s)))))
       t t))))
&lt;/pre&gt;
For completeness, let me also show you how the handler is entered into the list of handlers of the Quickhoney backend server:
&lt;pre style="font-size: 0.6em"&gt;
(defun publish-quickhoney ()
  (unpublish)
  (make-instance 'website
		 :name "Quickhoney CMS"
		 :handler-definitions `(("/random-image" random-image-handler)
                                 ("/animation" animation-handler)
                                 ("/image-query-js" image-query-js-handler)
                                 ("/login-js" login-js-handler)
                                 ("/clients-js" clients-js-handler)
                                 ("/buttons-js" buttons-js-handler)
                                 ("/edit-image-js" edit-image-js-handler)
                                 ("/upload-image" upload-image-handler)
                                 ("/upload-animation" upload-animation-handler)
                                 ("/upload-button" upload-button-handler)
                                 ("/rss" rss-handler)
                                 ("/admin" admin-handler)
                                 ("/upload-news" upload-news-handler)
                                 &lt;b&gt;("/digg-image" digg-image-handler)&lt;/b&gt;
                                 ("/" template-handler
                                      :default-template "frontpage"
                                      :destination ,(namestring (merge-pathnames "templates/" *website-directory*))
                                      :command-packages (("http://quickhoney.com/" . :quickhoney.tags)
                                                         ("http://bknr.net/" . :bknr.web)))
                                 user
                                 images
                                 ("/static" directory-handler
                                            :destination ,(merge-pathnames #p"static/" *website-directory*))
                                 ("/MochiKit" directory-handler
                                              :destination ,(merge-pathnames #p"static/MochiKit/" *website-directory*))
                                 ("/favicon.ico" file-handler
                                                 :destination ,(merge-pathnames #p"static/favicon.ico" *website-directory*)
                                 :content-type "application/x-icon"))
		 :admin-navigation '(("user" . "/user/")
				     ("images" . "/edit-images")
				     ("import" . "/import")
				     ("logout" . "/logout"))
		 :authorizer (make-instance 'bknr-authorizer)
		 :site-logo-url "/image/quickhoney/color,000000,33ff00"
		 :login-logo-url "/image/quickhoney/color,000000,33ff00/double,3"
		 :style-sheet-urls '("/static/styles.css")
		 :javascript-urls '("/static/javascript.js")))
&lt;/pre&gt;
&lt;h2&gt;Getting Carried Away on Common Lisp&lt;/h2&gt;
As you can see, I had to write little code to implement this functionality.  In fact, the whole thing should have taken no longer than one or two hours, but here is how I found myself getting carried away:

For one, I spent substantial time on refactoring CL-SMTP, as you can read in my last blog entry.  That took a few hours.  For another, I really don't like how mime emails are constructed with &lt;i&gt;MAKE-INSTANCE&lt;/i&gt; in the &lt;i&gt;HANDLE-OBJECT&lt;/i&gt; method above.  I thought that I'd be nice to have a &lt;i&gt;DEFINE-CONSTRUCTOR&lt;/i&gt; macro that created a function to create objects of arbitary classes, but that allows for one or more positional arguments in addition to any of the keyword arguments accepted by &lt;i&gt;MAKE-INSTANCE&lt;/i&gt; for a particular class.

Thus, instead of just coping with the slight ugliness, I &lt;a href="http://paste.lisp.org/display/58367"&gt;tried myself&lt;/a&gt; on a macro.  Simple as it looked, it surely became more complicated as I had to deal with defaulted arguments, and I was stopped from investing any more time into this when I was reminded by cmm that &lt;i&gt;INITIALIZE-INSTANCE&lt;/i&gt; and &lt;i&gt;SHARED-INITIALIZE&lt;/i&gt; can define additional keyword arguments that are accepted by &lt;i&gt;MAKE-INSTANCE&lt;/i&gt;.  Sure, it would be possible to find all applicable methods and extract more acceptable arguments from their lambda lists.  Yet, I felt that I had enough fun for this last weekend and wrapped up the feedback functionality for Quickhoney.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-220510114501425057?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/220510114501425057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/03/feature-development-and-getting-carried.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/220510114501425057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/220510114501425057'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/03/feature-development-and-getting-carried.html' title='Feature development and getting carried away on Lisp'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-3427979753339125966</id><published>2008-03-24T11:49:00.002+01:00</published><updated>2008-03-24T20:10:13.937+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Refactoring CL-SMTP</title><content type='html'>In my recent refactoring of BKNR, I decided that we do no longer want to use any of Franz' open source libraries if we can avoid it.  Even though they work fine in general, hacking them is a pain because they adhere to &lt;a href="http://www.franz.com/~jkf/coding_standards.html"&gt;John Foderaros Common Lisp Coding Standards&lt;/a&gt; which basically say that one should use Franz' own non-standard IF* macro for all conditionals.  I do think that one should be careful with nesting conditionals deeply, but I do not agree with using a macro and spacing as a cure.  If I have code in which conditional nesting exceeds two levels, I refactor to extract conditional code into functions.  That way, functions are kept shorter and the use of names instead of literal code usually makes it easier to understand what's going on.

So my easter goal was to replace Franz' NET.POST-OFFICE SMTP client by &lt;a href="http://common-lisp.net/project/cl-smtp"&gt;CL-SMTP&lt;/a&gt;.  Both clients do not support proper quoting of non-ASCII characters in mail headers, thus the need to hack arose and IF* is nothing I want to get myself used to.

A &lt;a href="http://www.ietf.org/rfc/rfc2821.txt"&gt;SMTP&lt;/a&gt; client really is not that complicated to begin with, and apart from the basic functionality, CL-SMTP already supported &lt;a href="http://www.ietf.org/rfc/rfc2487.txt"&gt;SSL&lt;/a&gt; and &lt;a href="http://www.ietf.org/rfc/rfc2554.txt"&gt;authentication&lt;/a&gt;, which nowadays are two basic requirements.  What it was missing was the possibility to send pre-formatted messages, which is something that I require because I usually make up my own messages, including headers and body, using format strings or &lt;a href="http://www.bobturf.org/software/cl-mime/"&gt;CL-MIME&lt;/a&gt; if I want to send attachments or otherwise need more control over the mail body.

CL-SMTP prove to be a little hackish.  Seemingly, only simple mail sending had originally been planned for, and the API had then been extended multiple times with growing user needs.  There was no layering between the SMTP protocol aspects and the message formatting functionality, both being freely interleaved.  While being simple to use for those use cases that had been planned for, the API was not helpful for my intended use.

In a first round, I simplified the code, collapsed a few common patterns into functions and made the code generally easier to hack on.  I then split the SMTP protocol handling into an exported macro, WITH-SMTP-MAIL, that is used to establish an SMTP connection and create the mail envelope.  The body of the macro invocation is then invoked with a variable bound to the stream connected to the SMTP server.  The existing mail sending functions of CL-SMTP have been converted to use that API, too.

I then incorporated a &lt;a href="http://common-lisp.net/pipermail/cl-smtp-devel/2008-March/000008.html"&gt;patch&lt;/a&gt; that I found in the CL-SMTP mailing list archive so that raw TLS is supported.  The existing TLS functionality worked by connecting to the standard SMTP port, then switching the cleartext connection to encrypted mode by issuing the STARTTLS command.  In contrast, raw TLS works by having an SMTP server listen on a separate port for encrypted connections.  No initial cleartext handshake is required in this operation mode.

Finally, I &lt;a href="http://bknr.net/trac/changeset/2790"&gt;implemented automatic quoting of non-ASCII characters in mail headers&lt;/a&gt; using a specialized stream class.  The &lt;a href="http://sbcl.sourceforge.net/manual/Gray-Streams-examples.html"&gt;Gray Streams Examples in the SBCL manual&lt;/a&gt; are my favoured cheat sheet when implementing special purpose stream classes.

The result of my work is available in the BKNR repository at &lt;a href="http://bknr.net/trac/browser/trunk/thirdparty/cl-smtp/"&gt;svn://svn.bknr.net/svn/trunk/thirdparty/cl-smtp/&lt;/a&gt; in case you want to give it a try right now.

I developed with Clozure CL on my Powerbook and after I committed, our &lt;a href="http://bknr.net/buildbot/"&gt;buildbot&lt;/a&gt; went red for SBCL.  I had named an accessor for my specialized stream class "STREAM" which triggered a package lock violation error on SBCL.  The name was bad, so I changed it to "ENCAPSULATED-STREAM" and saw the buildbot going green for SBCL too.  I love that!

I am now waiting for feedback on the refactorings and extensions.  There are still bugs which need fixing and support for compilers other than CCL and SBCL needs to be verified.  Also, the documentation for CL-SMTP needs to be better, and I think I'll just steal Edis HTML template and write something up myself next week.  Also, an automated test for CL-SMTP would be great, but as this requires a SMTP peer to talk to, I have not really had a good idea how to implement that.  Maybe later on.

I certainly hope that Jan Idzikowski, who is the author and maintainer of CL-SMTP, will accept my patches and make them part of the main distribution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-3427979753339125966?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/3427979753339125966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/03/refactoring-cl-smtp.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3427979753339125966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3427979753339125966'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/03/refactoring-cl-smtp.html' title='Refactoring CL-SMTP'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-6259927855397211948</id><published>2008-03-20T07:16:00.001+01:00</published><updated>2008-03-24T20:10:44.477+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>BKNR is alive</title><content type='html'>Recently, there has been quite some activity in the &lt;a href="http://bknr.net/"&gt;BKNR&lt;/a&gt; &lt;a href="http://svn.bknr.net/svn/trunk/"&gt;repository&lt;/a&gt;.  This is because &lt;a href="http://headcraft.de/"&gt;my company&lt;/a&gt; finally seems to become reality, with a real office, customers and all that.  I even have an employee now, Kilian, who is working full time on BKNR based projects.  I guess we are the only Lisp company in Berlin now!

As I am working for &lt;a href="http://itasoftware.com/"&gt;ITA Software&lt;/a&gt; full time, the fact that I have some more workforce allowed me to attack the long-outstanding major updates for &lt;a href="http://quickhoney.com/"&gt;QuickHoney&lt;/a&gt; and &lt;a href="http://createrainforest.org/"&gt;Create Rainforest&lt;/a&gt;.  Quickhoney will be modernized with a Blog and RSS feed, and we will also implement a shopping system so that one can buy digital and real QuickHoney products.  Create Rainforest will be extended into Google Earth.  Instead of hacking our funny, but close to unusable &lt;a href="http://createrainforest.org/infosystem/en/satellitenkarte.htm"&gt;satellite application&lt;/a&gt;, we will use Google Earth to display and visualize our data.  The old system will stay, but new features will not be added to that.

These commercial projects have lead to several updates to BKNR in the past weeks:

We have finally converted from portable AllegroServe to &lt;a href="http://weitz.de/hunchentoot/"&gt;Hunchentoot&lt;/a&gt; as HTTP server substrate.  Even though AllegroServe performs fine, it written in a very peculiar style which makes hacking it a rather unpleasant experience.  Also, Hunchentoot is better maintained.  In the process, we got away with passing &lt;i&gt;request&lt;/i&gt; arguments throughout the web environment.  The current request is now (only) carried in a special variable, as applications seldomly require access to it.

SBCL and CCL are our current primary development platforms.  I have still not given up on CMUCL completely, but we are waiting for the 19E release before we pick it up again.  I am fed up with working around missing Unicode support, which we require in all our current projects.

We moved away from &lt;a href="http://common-lisp.net/"&gt;common-lisp.net&lt;/a&gt; with our repository and web sites.  The primary reason for this move was that we now have a &lt;a href="http://buildbot.net/"&gt;Buildbot&lt;/a&gt; running &lt;a href="http://bknr.net/buildbot/"&gt;for BKNR&lt;/a&gt;, and I could not quickly get the neccessary infrastructure to run on common-lisp.net - Buildbot is Python based and requires substantial library support to run.

BKNR bugs have been fixed.  Sure enough, there have been quite some of them.  We hope to be better in the future with our continous integration testing and with more unit tests.

Sure enough, I will be moving this Blog to our BKNR based blog system soon.  Until that happened, this is my place to practice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-6259927855397211948?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/6259927855397211948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2008/03/bknr-is-alive.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6259927855397211948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/6259927855397211948'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2008/03/bknr-is-alive.html' title='BKNR is alive'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-3897652291469925557</id><published>2007-08-08T14:50:00.000+02:00</published><updated>2007-08-08T14:57:15.746+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Hardware woes</title><content type='html'>When I put the SECD project aside, it was because I could not get the RAM controller to run.  I felt rather stupid, as the RAM is a very simple asynchronous chip that requires no special timing, yet all my attempts to reliably write the RAM from the 6809 host failed - And as long as that does not work, I can't start any program on the SECD coprocessor.

Today I finally found the source of my problems.  It appears that even though there is an address bit ram_a(0) in the constraints file for the Trenz retrocomputing base board, it is not connected to the RAM.  Supposedly, it is not connected because the RAM works word-wise.

It took writing a standalone RAM tester in VHDL and a lot of staring at the logic analyzer and Chipscope outputs to find out that I actually had an addressing problem.  Also, John Kent was of great help again as he assured me that, prinicipially, the VHDL that accesses the RAM looks right.  He also suggested that I might have a problem related to my constraints file, which appeared to be true.

Now, finally, I can turn to actually getting the LispKit compiler to work and see the fixed hardware garbage collection in action.  Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-3897652291469925557?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/3897652291469925557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2007/08/hardware-woes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3897652291469925557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/3897652291469925557'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2007/08/hardware-woes.html' title='Hardware woes'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3022969446495862761.post-2956566132836036088</id><published>2007-07-29T21:51:00.001+02:00</published><updated>2008-09-27T00:54:23.937+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='secd'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Back to SECD</title><content type='html'>I have finally returned to debugging the &lt;a href="http://vaxbusters.org/workshop/secd.xml"&gt;SECD implementation on the FPGA&lt;/a&gt;.  When I stopped with this, I had problems getting the dual ported RAM controller to run.  The SECD CPU is designed as a coprocessor and relies on a host CPU to set up the program in its memory and to start itself.  Once the program has finished to run, the host CPU reads out the results from the SECD memory.

My host CPU is a 6809, based on &lt;a href="http://members.optushome.com.au/jekent/system09/index.html"&gt;System09 written by John Kent&lt;/a&gt;.  This is a historic coincidence, too, as the original SECD implementation used an 6809 as host CPU, too, at least for the testing.  The 6809 software that has originally been used is not available anymore, so I needed to find a way to quickly write some diagnosis and debugging routines.  System09 is designed to run the FLEX operating system and there is a BASIC interpreter for Flex available, but somehow I did not like that too much.

My first attempt to create a diagnostic monitor was to write a C program and compile it with gcc6809.  This worked, but I did not like the turnaround times too much.  Thus, I tried to find a Forth implementation for the 6809 that I could use as a diagnostics monitor.  My search led me to &lt;a href="http://www.sikkepitje.nl/6809werkgroep/files.html"&gt;Maisforth&lt;/a&gt;, which is a Forth implementation for a custom computer called the "&lt;a href="http://www.sikkepitje.nl/6809werkgroep/fotogalerie.html"&gt;mais kastje&lt;/a&gt;" which was built and used by a group of dutch Forth enthusiasts.  I changed my System09 based 6809 system so that its memory map matches that of the "mais kastje" and hacked the Forth interpreter so that it properly initializes and uses the ACIA serial port in System09.

Getting Maisforth to run was not too hard, but I certainly would not have finished that without the help of the excellent &lt;a href="http://www.pctestinstruments.com/"&gt;Logicport logic analyzer&lt;/a&gt; that I have bought earlier this year.  Logicport is a PC based logic analyzer that retails at $389, with 34 channels, complex triggering and 500 Mhz sample rate.  The Windows software is very usable, and it comes with interpreters for a few serial protocols (I2C, SPI, RS232) which helped me to track down my ACIA initialization problem in a short timespan.  I'm a very happy customer of this and can recommend Logicport to anyone who can't afford a "real" logic analyzer.

Now that I have Forth running on the FPGA, I am back to debugging the memory controller problems.  I use Forth as a scriptable debug monitor, so in addition to examine and change memory contents, I can define symbolic addresses, write little test programs and thus automate debugging quite a bit.  With Forth and the logic analyzer, I quickly found that my problem lies in how I set up the low and high byte select bits of the RAM chip, which has a 16 bit datapath.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3022969446495862761-2956566132836036088?l=netzhansa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://netzhansa.blogspot.com/feeds/2956566132836036088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://netzhansa.blogspot.com/2007/07/back-to-secd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/2956566132836036088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3022969446495862761/posts/default/2956566132836036088'/><link rel='alternate' type='text/html' href='http://netzhansa.blogspot.com/2007/07/back-to-secd.html' title='Back to SECD'/><author><name>Hans Hübner</name><uri>https://profiles.google.com/101473924494271635476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cNYS1mNWlkU/AAAAAAAAAAI/AAAAAAAAHUo/CAxZZfSO1t8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
