<?xml version="1.0"?>
<rss version="2.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">
   <channel>
      <title>Lisp/Scheme/Emacs Pipe</title>
      <description>Pipes Output</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=3PHwctj52xGg02vB6kjTQA</link>
      <pubDate>Sun, 22 Nov 2009 03:30:41 -0800</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <item>
         <title>The Zipper [PDF]</title>
         <link>http://www.reddit.com/r/programming/comments/a6r47/the_zipper_pdf/</link>
         <description>submitted by &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.reddit.com/user/lispnik&quot;&gt; lispnik &lt;/a&gt; &lt;br/&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf&quot;&gt;[link]&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.reddit.com/r/programming/comments/a6r47/the_zipper_pdf/&quot;&gt;[14 comments]&lt;/a&gt;</description>
         <guid isPermaLink="false">http://www.reddit.com/r/programming/comments/a6r47/the_zipper_pdf/</guid>
         <pubDate>Sat, 21 Nov 2009 06:51:45 -0800</pubDate>
      </item>
      <item>
         <title>Zach Beane: Go try XONG</title>
         <link>http://xach.livejournal.com/234968.html</link>
         <description>&lt;p&gt;David O'Toole put out version 1.0 of his roguelike puzzle game &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dto.github.com/notebook/xong.html&quot;&gt;XONG&lt;/a&gt; yesterday. &lt;p&gt;When he asked me to try it out, I expected some headache when downloading it, compiling it, grabbing libraries, etc. Nope! I'm using Snow Leopard on an Intel MacBook. I grabbed the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://cloud.github.com/downloads/dto/rlx/xong-1.0.dmg&quot;&gt;.dmg&lt;/a&gt;, double-clicked the xong icon, and it ran perfectly. It bundles an executable SBCL image together with the graphics, sounds, and libraries it needs, so it's completely self-contained and looks like any other Mac .app bundle. It's nice to see this kind of application delivery.</description>
         <guid isPermaLink="false">http://xach.livejournal.com/234968.html</guid>
         <pubDate>Sat, 21 Nov 2009 12:09:34 -0800</pubDate>
      </item>
      <item>
         <title>Lispjobs: Software/firmware developer (Lisp), San Diego, CA</title>
         <link>http://lispjobs.wordpress.com/2009/11/21/softwarefirmware-developer-lisp-san-diego-ca/</link>
         <description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;For biomedical devices, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://search9.smartsearchonline.com/sdrr/jobs/jobdetails.asp?current_page=3&amp;city=&amp;location=&amp;job_type=&amp;emp_status=&amp;direct_jo_num=&amp;country=&amp;k1=&amp;k2=&amp;k3=&amp;k4=&amp;k5=&amp;k6=&amp;k7=&amp;k8=&amp;salary_min=&amp;co_num=&amp;apply=yes&amp;job_number=1336&quot;&gt;Software/Firmware Developer &amp;#8211; Lisp &lt;/a&gt;(Contract to Hire).&lt;/p&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/lispjobs.wordpress.com/403/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/lispjobs.wordpress.com/403/&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/lispjobs.wordpress.com/403/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/lispjobs.wordpress.com/403/&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/lispjobs.wordpress.com/403/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/lispjobs.wordpress.com/403/&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/lispjobs.wordpress.com/403/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/lispjobs.wordpress.com/403/&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/lispjobs.wordpress.com/403/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/lispjobs.wordpress.com/403/&quot;/&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=lispjobs.wordpress.com&amp;blog=504450&amp;post=403&amp;subd=lispjobs&amp;ref=&amp;feed=1&quot;/&gt;&lt;/div&gt;</description>
         <guid isPermaLink="false">http://lispjobs.wordpress.com/2009/11/21/softwarefirmware-developer-lisp-san-diego-ca/</guid>
         <pubDate>Sat, 21 Nov 2009 08:18:09 -0800</pubDate>
      </item>
      <item>
         <title>Zach Beane: LISP is difficult to learn</title>
         <link>http://xach.livejournal.com/234685.html</link>
         <description>&lt;p&gt;The local grocery store has a big bin of used books for $1. After seeing a 1983 computer dictionary's description of LISP, I knew I had to buy it: &lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.flickr.com/photos/xach/4120160953/&quot; title=&quot;Dictionary of Computer Terms - 1983 by Zach Beane, on Flickr&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2672/4120160953_9461064d21_t.jpg&quot; width=&quot;70&quot; height=&quot;100&quot; alt=&quot;Dictionary of Computer Terms - 1983&quot;/&gt;&lt;/a&gt; &lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.flickr.com/photos/xach/4120161253/&quot; title=&quot;LISP, defined, circa 1983 by Zach Beane, on Flickr&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2785/4120161253_bb65f06314.jpg&quot; width=&quot;319&quot; height=&quot;500&quot; alt=&quot;LISP, defined, circa 1983&quot;/&gt;&lt;/a&gt; &lt;p&gt;It says: &lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;LISP&lt;/b&gt; acronym for &lt;b&gt;LIS&lt;/b&gt;T &lt;b&gt;P&lt;/b&gt;ROCESSING a high-level
programming language use primarily for list processing, symbol manipulation, and recursive operations: it can handle many different data types, treat programs as data, and provide for the self-modification of the program as it is executing: &lt;i&gt;generally considered a difficult language to learn&lt;/i&gt;
&lt;/blockquote&gt; &lt;p&gt;(Emphasis mine.)</description>
         <guid isPermaLink="false">http://xach.livejournal.com/234685.html</guid>
         <pubDate>Fri, 20 Nov 2009 15:05:35 -0800</pubDate>
      </item>
      <item>
         <title>François-René Rideau: Software Irresponsibility</title>
         <link>http://fare.livejournal.com/149264.html</link>
         <description>&lt;p&gt;
In the way of achieving a healthy software development environment,
a lot of projects fall in one of these two DON'Ts:
irresponsibility and territoriality.
Irresponsibility is when there is no one in charge
of making things right (with respect to a whole category of problems).
Territoriality is when there is someone in charge,
and he won't let anyone else touch the code without him.
They may sound opposite to one another, but often
irresponsibility is a result of territoriality, where
the person in charge just isn't interested in the kind of problem
you're experiencing, and so any consideration for such problems
gets disregarded in favor of whatever fits the interests of the maintainer.
&lt;/p&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;cutid1&quot;&gt;&lt;/a&gt;
&lt;p&gt;
As a notorious example of irresponsible software design,
I will cite PHP, whose maintainer has repeatedly claimed
he was never interested in designing a good programming language.
It shows.
But I'm sure you'll find plenty of familiar examples
in your own experience,
from the irresponsive provider of some proprietary software
you've been locked into using,
to maybe someone from some other department of your company
that you've had to deal with,
and perhaps even to yourself with respect to your own users.
&lt;/p&gt;&lt;p&gt;
Of course, it is always possible to start a new project
to replace the software you're dissatisfied with.
But the costs associated to such endeavour are often huge.
You will have to reimplement not just the parts
that the replaced software did wrong,
but also the parts it did right.
While by assumption you can clearly see parts of the design that are wrong
and do better with respect to those parts, you may be lacking
the proficiency, time and interest to do as well on these other parts.
Last but not least, the community around the original software,
that made it valuable, will not switch to the new one for merely small gains,
and the transition from the old system to the new system
may impose demanding constraints of backwards compatibility.
&lt;/p&gt;&lt;p&gt;
Free Software can drastically reduce the cost of starting a new project,
by allowing you to fork the existing code base, copy large chunks of it,
or at the very least read the code of what you may have to be compatible with.
It does make the cost go down to zero, however.
There again, cruft that made the original software bad enough
that you felt like changing it
will be a heavy burden upon you if you keep it,
and a huge setback to reimplement if you decide to throw it away.
And even in the world of free software, some licenses can incur
a higher cost to forking than others: for instance, licenses that
force you to distribute the code as source, that prevent you
from making any adaptation and keep the name, or otherwise put
hurdles in the way of forkers.
&lt;/p&gt;&lt;p&gt;
In the world of Common Lisp, an interesting case
of not-so-responsible software is
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.cliki.net/ASDF&quot;&gt;ASDF&lt;/a&gt;.
Yeah, some of you might be tempted to sneer,
is he going to blame the problem with ASDF on
the original author who is long gone,
and the current maintainer who isn't committing enough energy
and availability to making the project go forward?
No, not at all.
Dan Barlow actually did a great job while he was there,
and if no one is stepping up to offer more than Gary King provides,
it's certainly not Gary who's to blame;
he is getting blatant bugs fixed and accepting consensual patches,
and at this point forking would be trivial to fork the git repo
if anyone were dissatisfied with Gary's performance.
Rather, I'll argue that any problem with ASDF is a symptom of the way
responsibilities are distributed with respect to its update,
and propose a small technical change that can hopefully improve things a lot.
&lt;/p&gt;&lt;p&gt;
When Dan Barlow wrote ASDF in 2001, he only wanted a better CL build system
that he could use on top of SBCL for his own projects,
something that would be more declarative than the previous best alternative,
MK:DEFSYSTEM,
and would only need to support modern ANSI CL implementations,
not old forgotten Lisp variants.
In developing ASDF, he loosely followed the better design principles
once proposed by Kent Pitman for an extensible CL build system.
In all those objectives, ASDF was a tremendous success,
and CL users should all be grateful to Dan was his achievement.
However, as usual the problem lies with issues he didn't try to tackle.
&lt;/p&gt;&lt;p&gt;
Problems with ASDF include
the painful way you have to configure it,
deficient support for
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://bugs.launchpad.net/asdf/+bug/479470&quot;&gt;documentation&lt;/a&gt;
or &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://bugs.launchpad.net/asdf/+bug/479478&quot;&gt;testing&lt;/a&gt;,
broken support for conditional compilation,
missing support for generated files,
its weird TRAVERSE algorithm,
etc.
Unlike the issue of
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://common-lisp.net/project/xcvb/doc/ilc09-xcvb-paper.pdf&quot;&gt;deterministic incremental compilation&lt;/a&gt;
that prompted me to start XCVB,
none of the above issues is unsolvable in itself.
But the constraints within which ASDF is developed make it hard to solve them.
Happily, some of these constraints can be removed with a little bit of hackery.
Unhappily, others are intrinsic to the choice of constraints.
&lt;/p&gt;&lt;p&gt;
Indeed, ASDF has a distribution bootstrap problem:
it specifies how to load other systems, but
nothing specifies how ASDF itself is loaded into your system.
That problem is left to whoever writes the Lisp implementation,
distributes the Lisp package, or maintains a larger project
within which ASDF is used.
And in the world of Common Lisp, there are tens of different implementations,
many of them packaged in various ways.
To make the problem tractable, ASDF follows the constraint that it
comes as a single file that may be loaded independently of its location,
and doesn't depend on any third party library beside what is included
by each supported implementation.
&lt;/p&gt;&lt;p&gt;
This means that the provider of libraries that use ASDF
must rely on the least common denominator of ASDF features,
unless he wants to force his users to make sure they upgrade their ASDF.
Upgrading the current ASDF could conceivably be easy, but is actually hard,
because of the
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://bugs.launchpad.net/asdf/+bug/485687&quot;&gt;inability to hot-upgrade a loaded ASDF&lt;/a&gt;.
It is still possible to remove an old ASDF and replace it,
and XCVB does it in an ugly way
(see how xcvb/no-asdf deletes the ASDF package and anything that uses it);
however, files compiled against the old ASDF may not work with the new one
and vice versa
(I've had &quot;interesting&quot; issues that way
while using xcvb-master in slightly different setups).
&lt;/p&gt;&lt;p&gt;
This inability to upgrade further
makes the pre-packaging of a Lisp implementation
with a given version ASDF a bit of a damned if you do, damned if you don't
proposition to Lisp implementers and distributors.
Happily, implementers have the option of only providing ASDF when REQUIRE'd,
and this is the preferred way for users to specify they want to use ASDF,
when it is available.
Distributors may not have this option inasmuch as
there is no standard mechanism to hook into an implementation's REQUIRE.
An example of a failed attempt at distributing Common Lisp with ASDF is
common-lisp-controller. It tried to provide a way to make sure there is always
a configured ASDF, but their solution only works if everyone uses only
debian or another supported OS distribution,
and only if the debian maintainers keep up with all
the common-lisp software (implementations and libraries)
that one may want to use;
two hypotheses that have been disproved in practice
with respect to the needs of many users.
&lt;/p&gt;&lt;p&gt;
To step back to the problem of responsibility,
the current constraints of ASDF are such that a consistent upgrade of ASDF
requires action on the part of tens of people, each in his own territory:
ASDF contributors, Lisp implementers, package distributors.
If only one hacker alone decides to upgrade ASDF,
he has to incur the cost of the associated work of modifying ASDF
and the risk that this will introduce incompatibilities,
for little overall progress in terms of what users may rely upon
unless he convinces tens of other people also do the same.
Thus, the costs of adoption are high, the benefits of development are low,
development is slow, and a cycle of stagnation continues.
&lt;/p&gt;&lt;p&gt;
If someone cares about the future of ASDF, I recommend they should address
the upgradability bug, which will itself unlock a big hurdle on the way
of further evolution of ASDF. Note that this upgradability includes both
the technical ability to load a new ASDF on top of an old one, but probably
also the proper configuration of ASDF, to load systems from a series of
configured paths declared in user and system preference files.
&lt;/p&gt;&lt;p&gt;
Personally, I'd rather work on XCVB, and invite
people interested in build systems to work on it instead of ASDF.
But if XCVB is to prevail, it may as well prevail
against the best ASDF that ASDF can be.
&lt;/p&gt;&lt;p&gt;
XCVB tries to avoid all the problems of ASDF by stepping back
from the assumption that everything happens
in a one Lisp world that has already been setup.
Instead, XCVB will manage many Lisp worlds that it will help you setup.
It doesn't live inside your Lisp image, and thus doesn't depend
on Lisp implementers or distributors to provide it for you;
it can therefore evolve fast without any issue due to slow distribution.
It is also liberated from the constraint ASDF has
of itself having no dependencies,
because these dependencies would both make bootstrap more difficult
and interfere with other versions of same software
as part of the software being built.
XCVB thus reuses plenty of libraries and is richer in features,
and will use even more libraries in the future.
All this in addition to its original essential distinguishing feature
of providing deterministic incremental compilation.
&lt;/p&gt;&lt;p&gt;
XCVB isn't complete yet, but I believe that on supported implementations
(currently only SBCL, CCL, CLISP, but I could add more on demand,
or you could do it yourself), it is already better than ASDF.
If you care for CL build systems, please fix ASDF;
but please give XCVB a try, too.
&lt;/p&gt;&lt;p&gt;
Even if you don't care for CL build systems,
organize your software developments so that
every upgrade step can be done by the single maintainer of a single project,
without requiring the coordination
between many people in many different projects.
&lt;/p&gt;&lt;p&gt;
This lesson should be particularly dear to those who dream of
making a Standard for Lisp, Scheme, Javascript, Java
or any other language or piece of software:
if you need to agree on something that will require
future coordination between plenty of people,
it is almost sure to fail to evolve fast enough to remain relevant,
even though one or two iterations might make it live
(see e.g. R6RS and its current attempted successor).
Instead, you should offer software that already runs
with a free software reference implementation that
others can trivially adapt to their systems if needed
(also in Scheme, compare the SRFI process).
After your code has become de facto standard, you might not even care
for it being any kind of de jure standard anymore.
Whereas if there's going to be a de jure standard,
it will be blood and conflict as long as there's anything to disagree about,
and still resentment at the unsatisfying compromise that results.
&lt;/p&gt;&lt;p&gt;
The same idea also accounts for
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Conway%27s_Law&quot;&gt;Conway's Law&lt;/a&gt;:
if you divide your software project between many teams,
each team will build its own code base,
and the structure of the software will end up following
the structure of the teams that build it.
Parts of the software where the ownership is not clearly assigned
but where authority is divided will be the scene for
conflict, slow evolution, bad design (if design at all), etc.
Vertical disintegration, where independent teams
manage layers of the software and its life-cycle,
will in particular lead to a multiplication of such dysfunctional interfaces
between entrenched overlapping code bases
the global architecture of which cannot be refactored.
&lt;/p&gt;&lt;p&gt;
Happily, solving the problem of irresponsible software
is much easier than solving the problem of
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://unqualified-reservations.blogspot.com/2009/01/gentle-introduction-to-unqualified_29.html&quot;&gt;irresponsible government&lt;/a&gt;.
&lt;/p&gt;</description>
         <guid isPermaLink="false">http://fare.livejournal.com/149264.html</guid>
         <pubDate>Fri, 20 Nov 2009 06:05:02 -0800</pubDate>
      </item>
      <item>
         <title>Vladimir Sedach: November Montreal Scheme/Lisp User Group presentation</title>
         <link>http://carcaddar.blogspot.com/2009/11/november-montreal-schemelisp-user-group.html</link>
         <description>On November 17, I gave a presentation to the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://schemeway.dyndns.org/mslug/mslug-home&quot;&gt;Montreal Scheme/Lisp User Group&lt;/a&gt; about &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://vsedach.googlepages.com/lisp_high_perf_servers.pdf&quot;&gt;developing high-performance network servers in Lisp&lt;/a&gt;. I looked at the lessons to be learned from existing Common Lisp web servers, notably &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://hoytech.com/antiweb/&quot;&gt;Antiweb&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://common-lisp.net/project/teepeedee2/&quot;&gt;TPD2&lt;/a&gt;, tried out some of the ideas in my own new under-development web server &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/vsedach/HTTP-DOHC&quot;&gt;HTTP DOHC&lt;/a&gt; along with some new ideas about threading and concurrency, and put the results of my findings into the presentation.&lt;br /&gt;&lt;br /&gt;If you're interested in the topic, you should also watch &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.youtube.com/watch?v=uUymzUdWBuo&quot;&gt;John Fremlin's TPD2 presentation to the Shibuya Lisp user's group&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I plan on making &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/vsedach/HTTP-DOHC&quot;&gt;HTTP DOHC&lt;/a&gt; a full-featured Common Lisp web server with an interface that's somewhat compatible with &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://weitz.de/hunchentoot/&quot;&gt;Hunchentoot&lt;/a&gt; 1.0.&lt;br /&gt;&lt;br /&gt;In other news, I now have time available for contract work. Get in touch at &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;mailto:vsedach@gmail.com&quot;&gt;vsedach@gmail.com&lt;/a&gt;.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/5728814948530385321-1882612070763049940?l=carcaddar.blogspot.com&quot; alt=&quot;&quot;/&gt;&lt;/div&gt;</description>
         <guid isPermaLink="false">http://carcaddar.blogspot.com/2009/11/november-montreal-schemelisp-user-group.html</guid>
         <pubDate>Thu, 19 Nov 2009 13:36:00 -0800</pubDate>
      </item>
      <item>
         <title>Patrick Stein: Playing with Sheeple-based GUI atop CL-OpenGL</title>
         <link>http://nklein.com/2009/11/playing-with-sheeple-based-gui-atop-cl-opengl/</link>
         <description>&lt;p&gt;Inspired by the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://tclispers.org/news/sheeple-presentation&quot;&gt;previous TC Lispers meeting&lt;/a&gt; and spurred on by the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://tclispers.org/should-we-discuss-question-cl-and-uis-november-meeting&quot;&gt;probable topic of the next TC Lispers meeting&lt;/a&gt;, I have spent the little bit of coding time I&amp;#8217;ve had over the past two weeks on making a GUI layer using &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sykosomatic.org/sheeple/&quot;&gt;Sheeple&lt;/a&gt; atop &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://common-lisp.net/project/cl-opengl/&quot;&gt;CL-OpenGL&lt;/a&gt; and employing &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.xach.com/lisp/zpb-ttf/&quot;&gt;ZPB-TTF&lt;/a&gt; for font-loading.&lt;/p&gt;
&lt;p&gt;I have dubbed this project &lt;q&gt;Woolly&lt;/q&gt; (because it&amp;#8217;s made from Sheeple and because &lt;q&gt;Woolly&lt;/q&gt; sounds sorta like &lt;q&gt;GUI&lt;/q&gt;).&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://nklein.com/wp-content/uploads/2009/11/woolly-peek.png&quot;&gt;&lt;img src=&quot;http://nklein.com/wp-content/uploads/2009/11/woolly-peek-300x235.png&quot; alt=&quot;woolly-peek&quot; title=&quot;woolly-peek&quot; width=&quot;300&quot; height=&quot;235&quot; class=&quot;alignright size-medium wp-image-1008&quot;/&gt;&lt;/a&gt;I spent about half of my coding time so far getting the basic framework in place (proven through clickable buttons with labels). I am trying to keep it cleanly separated between generic GUI stuff and the CL-OpenGL specifics in the event that someone would like to port it to some other I/O spec.&lt;/p&gt;
&lt;p&gt;The other half of my coding time was spent getting the font-rendering to be anti-aliased. I promise to write more about how I accomplished the font-rendering in a future post so that if you&amp;#8217;re ever stuck rendering fonts in OpenGL, you won&amp;#8217;t be stuck with pixelated blockiness or resorting to rendering to a texture-map and letting the mipmapper figure it out.&lt;/p&gt;
&lt;p&gt;For this post, however, I&amp;#8217;ll just show you the code that sets up the interface depicted here.&lt;/p&gt;
&lt;div class=&quot;codecolorer-container lisp blackboard&quot;&gt;&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;div&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;18&lt;br /&gt;19&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;23&lt;br /&gt;24&lt;br /&gt;25&lt;br /&gt;26&lt;br /&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;lisp codecolorer&quot;&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;require &lt;span&gt;:&lt;/span&gt;&lt;span&gt;asdf&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;span&gt;&amp;#40;&lt;/span&gt;asdf&lt;span&gt;:&lt;/span&gt;&lt;span&gt;operate&lt;/span&gt; 'asdf&lt;span&gt;:&lt;/span&gt;&lt;span&gt;load-op&lt;/span&gt; 'woolly-gl &lt;span&gt;:&lt;/span&gt;&lt;span&gt;verbose&lt;/span&gt; &lt;span&gt;nil&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;;; make it easier to change renderer/controller later&lt;/span&gt;&lt;br /&gt;
&lt;span&gt;&amp;#40;&lt;/span&gt;rename-package 'woolly-gl 'toolkit&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;defun&lt;/span&gt; test &lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;let&lt;/span&gt; &lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;font &lt;span&gt;&amp;#40;&lt;/span&gt;sheeple&lt;span&gt;:&lt;/span&gt;&lt;span&gt;object&lt;/span&gt; &lt;span&gt;:&lt;/span&gt;&lt;span&gt;parents&lt;/span&gt; toolkit&lt;span&gt;:=&lt;/span&gt;font&lt;span&gt;=&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;:&lt;/span&gt;&lt;span&gt;em-size&lt;/span&gt; &lt;span&gt;48&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;:&lt;/span&gt;&lt;span&gt;pathname&lt;/span&gt; &lt;span&gt;&quot;okolaks/okolaksRegular.ttf&quot;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;let&lt;/span&gt; &lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;app &lt;span&gt;&amp;#40;&lt;/span&gt;sheeple&lt;span&gt;:&lt;/span&gt;&lt;span&gt;object&lt;/span&gt; &lt;span&gt;:&lt;/span&gt;&lt;span&gt;parents&lt;/span&gt; toolkit&lt;span&gt;:=&lt;/span&gt;app&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#40;&lt;/span&gt;win &lt;span&gt;&amp;#40;&lt;/span&gt;sheeple&lt;span&gt;:&lt;/span&gt;&lt;span&gt;object&lt;/span&gt; &lt;span&gt;:&lt;/span&gt;&lt;span&gt;parents&lt;/span&gt; toolkit&lt;span&gt;:=&lt;/span&gt;window&lt;span&gt;=&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;title&lt;/span&gt; &lt;span&gt;&quot;Woolly Window 1&quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;width&lt;/span&gt; &lt;span&gt;640&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;height&lt;/span&gt; &lt;span&gt;480&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#40;&lt;/span&gt;but &lt;span&gt;&amp;#40;&lt;/span&gt;sheeple&lt;span&gt;:&lt;/span&gt;&lt;span&gt;object&lt;/span&gt; &lt;span&gt;:&lt;/span&gt;&lt;span&gt;parents&lt;/span&gt; toolkit&lt;span&gt;:=&lt;/span&gt;button&lt;span&gt;=&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;offset-x&lt;/span&gt; &lt;span&gt;40&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;offset-y&lt;/span&gt; &lt;span&gt;40&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;width&lt;/span&gt; &lt;span&gt;300&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;height&lt;/span&gt; &lt;span&gt;100&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;font&lt;/span&gt; font&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;label&lt;/span&gt; &lt;span&gt;&quot;Button&quot;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#40;&lt;/span&gt;woolly&lt;span&gt;:&lt;/span&gt;&lt;span&gt;display-window&lt;/span&gt; win&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#40;&lt;/span&gt;woolly&lt;span&gt;:&lt;/span&gt;&lt;span&gt;add&lt;/span&gt; win but&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#40;&lt;/span&gt;woolly&lt;span&gt;:&lt;/span&gt;&lt;span&gt;main-loop&lt;/span&gt; app&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#40;&lt;/span&gt;woolly&lt;span&gt;:&lt;/span&gt;&lt;span&gt;destroy-window&lt;/span&gt; win&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Next up on my agenda is to make the background and button prettier. It should be easy enough to do with &lt;b&gt;GL_LIGHTING&lt;/b&gt; and some vertex-coloring for gradations. After that, it&amp;#8217;s on to more controls like labels, panels, checkboxes, drop-downs, borders, and (my dread) text input boxes. Then, it&amp;#8217;s on to a layout manager.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://nklein.com/wp-content/uploads/2009/11/woolly-peek1.png&quot;&gt;&lt;img src=&quot;http://nklein.com/wp-content/uploads/2009/11/woolly-peek1-150x117.png&quot; alt=&quot;woolly-peek&quot; title=&quot;woolly-peek&quot; width=&quot;150&quot; height=&quot;117&quot; class=&quot;alignright size-thumbnail wp-image-1013&quot;/&gt;&lt;/a&gt;Edit: Here&amp;#8217;s the same GUI a day later. I&amp;#8217;m using a simple lighting scheme and rendering the button in 3D. I haven&amp;#8217;t yet hooked in the bit to render it depressed when the button is pressed. I&amp;#8217;ve tested the code that draws it the other way, but I haven&amp;#8217;t hooked it into the mouse handlers yet.&lt;/p&gt;
&lt;p&gt;Edit #2: Actually, it only took a few minutes for me to hook in the rendering it pressed vs. unpressed. When I did it though, it looked like the label was sliding around because the effect of the contrast between the light and dark edges of the button was so great that you perceive the whole button sliding when it&amp;#8217;s pressed. So, I added a little bit in there to actually slide the text by an amount close to what is perceived. So, now&amp;#8230; it looks pretty spiffy.&lt;/p&gt;</description>
         <guid isPermaLink="false">http://nklein.com/2009/11/playing-with-sheeple-based-gui-atop-cl-opengl/</guid>
         <pubDate>Thu, 19 Nov 2009 08:59:55 -0800</pubDate>
      </item>
      <item>
         <title>Christophe Rhodes: 19 Nov 2009</title>
         <link>http://www.advogato.org/person/crhodes/diary.html?start=136</link>
         <description>A while ago now, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://random-state.net/&quot;&gt;Nikodemus Siivola&lt;/a&gt; moved
bug information for &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.sbcl.org/&quot;&gt;SBCL&lt;/a&gt;
from a flat text file to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://bugs.launchpad.net/sbcl&quot;&gt;Launchpad&lt;/a&gt;. Historically I have had almost nothing but displeasure
working with the &quot;standard&quot; or &quot;industrial&quot; bug trackers; I
have found &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.bugzilla.org&quot;&gt;Bugzilla&lt;/a&gt;
horrible to work with, both as a bug reporter and as an
administrator; lighter-weight solutions such as &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://trac.edgewall.org/&quot;&gt;Trac&lt;/a&gt; are just about
tolerable, but basically anything that &lt;em&gt;requires&lt;/em&gt; me
to have a Web Browser seems to end up confusing and
distracting me. An honourable mention at this point goes to
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://packages.qa.debian.org/d/debbugs.html&quot;&gt;debbugs&lt;/a&gt;:
being able to report, manipulate, update and close bugs by
e-mail is close to my idea of Nirvana. &lt;p&gt; So, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://launchpad.net/&quot;&gt;Launchpad&lt;/a&gt;. Initially, I was dismayed, because there doesn't seem to be
a way of getting notifications of bug updates over RSS,
which would be a second-best to getting updates by e-mail. I managed to ignore all SBCL bug reports for a while, but eventually I bit the bullet and signed up (having
refused to do so a good long while ago, when shortly after I
used &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.ubuntu.com/&quot;&gt;Ubuntu&lt;/a&gt;'s bugzilla
to report a bug they closed the bugzilla in favour of
launchpad without managing to transfer accounts across.) &lt;p&gt; A large motivation for signing up was the discovery that
launchpad does, in fact, have an &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://help.launchpad.net/Bugs/EmailInterface&quot;&gt;email
interface&lt;/a&gt; to the bug tracker; as long as you can emit
GPG-signed mail (which I can), it seems to have all the
required functionality for doing things without needing to
go near a web browser; I can now receive bug reports and
reply to them, and in at least some cases the
&lt;tt&gt;References:&lt;/tt&gt; headers in the mail I receive allows &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gnus.org/&quot;&gt;my client&lt;/a&gt; to thread the
discussion properly (I haven't really stress-tested this
yet, but it works at least well enough for now.) &lt;p&gt; If that were all, this would not be news (and not even
worthy of a blog post). But now I get to demonstrate my
Emacs lisp &amp;ldquo;scripting&amp;rdquo; ability, in much the same
way as &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.coruskate.net/&quot;&gt;Dan Barlow&lt;/a&gt;
did for me &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://web.archive.org/web/20030608101412/http://ww.telent.net/diary/2003/1/#14.28515&quot;&gt;many
years ago&lt;/a&gt;: SBCL has a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://lists.sourceforge.net/lists/listinfo/sbcl-bugs&quot;&gt;mailing
list for reporting bugs&lt;/a&gt;, for people who are unsure as to
whether their problem is a bug or not, or for people who
don't want to go to the trouble to get a launchpad account
just to report a bug. When such a report does describe a
new bug that we should be tracking, that report needs to
make its way to launchpad. &lt;p&gt; Without too much further ado, I present
&lt;tt&gt;sbcl-bugs-mail-forward&lt;/tt&gt;, which constructs a message
(almost) ready to be sent: &lt;p&gt; &lt;pre&gt;
(defun sbcl-bugs-mail-forward () (interactive) (let ((message-forward-ignored-headers &quot;&quot;) from subject) (gnus-summary-mail-forward 4) (message-goto-to) (insert &quot;new@bugs.launchpad.net&quot;) (message-goto-subject) (message-beginning-of-line) (re-search-forward &quot;&amp;#92;&amp;#92;[&amp;#92;&amp;#92;(.*&amp;#92;&amp;#92;)&amp;#92;&amp;#92;].*&amp;#92;&amp;#92;[&amp;#92;&amp;#92;(.*&amp;#92;&amp;#92;)&amp;#92;&amp;#92;] &amp;#92;&amp;#92;(.*&amp;#92;&amp;#92;)$&quot;) (setq from (match-string 1) subject (match-string 3)) (message-beginning-of-line) (let ((kill-whole-line nil)) (kill-line)) (insert subject) (message-goto-body) (insert &quot;Report from &quot; from &quot;&amp;#92;n&amp;#92;n&quot;) (insert &quot; affects sbcl&amp;#92;n status confirmed&amp;#92;n importance &quot;) (save-excursion (insert &quot;&amp;#92;n tag &amp;#92;n done&amp;#92;n&amp;#92;n&quot;) (message-goto-body) (re-search-forward &quot;^&amp;#92;&amp;#92;(-&amp;#92;&amp;#92;)+ Start of forwarded message &amp;#92;&amp;#92;(-&amp;#92;&amp;#92;)+$&quot;) (beginning-of-line) (let ((kill-whole-line t)) (kill-line)) (re-search-forward &quot;^&amp;#92;&amp;#92;(-&amp;#92;&amp;#92;)+$&quot;) (beginning-of-line) (end-of-buffer) (kill-region (mark) (point))) (mml-secure-message-sign-pgpmime)))
&lt;/pre&gt; &lt;p&gt; You can tell it's scripting, really: it's an odd mixture of
plausible and dubious ways of getting things done: regular
expressions to extract the original sender of the report,
and to remove the forwarded message information (and the
dull advert inserted in the footer by &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sourceforge.net/&quot;&gt;SourceForge&lt;/a&gt;'s mailing
list system). On the other hand, that function, coupled
with something along the lines of &lt;p&gt; &lt;pre&gt;
(setq gnus-parameters '((&quot;nnml&amp;#92;&amp;#92;+private:list.sbcl-bugs&quot; (gnus-summary-prepared-hook '(lambda () (local-set-key (kbd &quot;C-c C-f&quot;) 'sbcl-bugs-mail-forward) (local-set-key (kbd &quot;S o m&quot;) 'sbcl-bugs-mail-forward))))))
&lt;/pre&gt; &lt;p&gt; gives me exactly what I think I want: a simple way of
creating, tagging and classifying an entry in the bug
tracker from a mail report. &lt;p&gt; I couldn't find any convenient emacs/launchpad interfaces
(or any at all, in fact); I'm not sure this counts as one
either, but by all means use, adapt and improve on the above
for your purposes &amp;ndash; I'll happily take criticism of and
improvements to this hack.</description>
         <guid isPermaLink="false">http://www.advogato.org/person/crhodes/diary.html?start=136</guid>
         <pubDate>Thu, 19 Nov 2009 05:24:17 -0800</pubDate>
      </item>
      <item>
         <title>Vladimir Sedach: Templates and code generation</title>
         <link>http://carcaddar.blogspot.com/2009/11/templates-and-code-generation.html</link>
         <description>Earlier this month Google released &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://code.google.com/closure/templates/&quot;&gt;Closure Templates&lt;/a&gt;, a new templating library intended for generating HTML. Who cares? I personally dislike HTML templating, and avoid it whenever possible in lieu of s-expression based generation tools like &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://weitz.de/cl-who/&quot;&gt;CL-WHO&lt;/a&gt;. At first look, Closure Templates didn't seem to be anything new or useful.&lt;br /&gt;&lt;br /&gt;The one thing that makes Closure Templates somewhat interesting is that the library works in both Java and JavaScript, so you get client and server-side templates in one place. I did a similar thing with &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://common-lisp.net/project/uri-template/&quot;&gt;uri-template&lt;/a&gt; by having the URI template expand into code that executed in both Common Lisp and JavaScript via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://common-lisp.net/project/parenscript/&quot;&gt;Parenscript&lt;/a&gt; (here I have to state that despite being an author of a templating library, I still dislike templating libraries and even find my own creation annoying at times).&lt;br /&gt;&lt;br /&gt;About a week after Closure Templates was released, Andrey Moskvitin (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://archimag-dev.blogspot.com/&quot;&gt;archimag&lt;/a&gt;) wrote an implementation in Common Lisp (interesting note: it took him &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://translate.google.com/translate?js=n&amp;prev=_t&amp;hl=en&amp;ie=UTF-8&amp;u=http%3A%2F%2Farchimag-dev.blogspot.com%2F2009%2F11%2Fclosure-template-5.html&amp;sl=ru&amp;tl=en&amp;swap=1&amp;swap=1&quot;&gt;only five days and 1/15 the number of lines of code&lt;/a&gt; as the original). The resulting system, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://code.google.com/p/cl-closure-template/&quot;&gt;cl-closure-template&lt;/a&gt;, similarly generates JavaScript via Parenscript.&lt;br /&gt;&lt;br /&gt;I still didn't understand the motivation. Yesterday, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://translate.google.com/translate?js=y&amp;prev=_t&amp;hl=en&amp;ie=UTF-8&amp;u=http%3A%2F%2Farchimag-dev.blogspot.com%2F2009%2F11%2Fclosure-templates.html&amp;sl=ru&amp;tl=en&quot;&gt;Andrey was kind enough to explain it&lt;/a&gt;. Those pampered by web development in Common Lisp using s-expression HTML generation tools simply don't encounter the problem of trying to fit HTML templating onto the paradigm of incremental page updating via AJAX. So if you want to build an AJAX web application and use HTML templating, give &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://code.google.com/p/cl-closure-template/&quot;&gt;cl-closure-template&lt;/a&gt; a try.&lt;br /&gt;&lt;br /&gt;[Blog metanote: if you're reading this blog through its feed, you will shortly see this post show up in Russian. &lt;i&gt;a CONS is an object which cares&lt;/i&gt; is now syndicated on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://lisper.ru/planet/&quot;&gt;Russian Lisp Planet&lt;/a&gt;, and I'm going to be writing Lisp-related posts in Russian as well as English. All such posts will be tagged 'lisp-ru'. Filter out that tag if you don't want the Russian version of the posts to show up in your feed reader.]&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/5728814948530385321-1287513206168526102?l=carcaddar.blogspot.com&quot; alt=&quot;&quot;/&gt;&lt;/div&gt;</description>
         <guid isPermaLink="false">http://carcaddar.blogspot.com/2009/11/templates-and-code-generation.html</guid>
         <pubDate>Wed, 18 Nov 2009 14:12:00 -0800</pubDate>
      </item>
      <item>
         <title>Christophe Rhodes: 18 Nov 2009</title>
         <link>http://www.advogato.org/person/crhodes/diary.html?start=135</link>
         <description>As mentioned earlier: the 2010 European Lisp Symposium
invites your contributions. Unfortunately, the website for
the 2010 event is not set up yet; you can get an impression
of what the event is like by looking at &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.european-lisp-symposium.org/&quot;&gt;last year's
website&lt;/a&gt;, which in the fullness of time (soon, I hope)
will be updated with ELS2010 information. In the meantime,
here's the Call for Contributions: we would welcome both
papers describing original work, not published elsewhere,
and submissions for tutorial sessions. Submission will be
through &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.easychair.org/conferences/?conf=els2010&quot;&gt;EasyChair's
conference management system&lt;/a&gt;. &lt;p&gt; &lt;div&gt;
&lt;big&gt;&lt;b&gt;3rd European Lisp Symposium&lt;/b&gt;&lt;/big&gt; &lt;p&gt; &lt;p&gt;May 6-7, 2010, Funda&amp;ccedil;&amp;atilde;o Calouste Gulbenkian, Lisbon, Portugal &lt;div&gt;
&lt;b&gt;Important Dates&lt;/b&gt;
&lt;div&gt; &lt;p&gt; &lt;ul&gt;
&lt;li&gt;
Submission Deadline: &lt;b&gt;January 29, 2010&lt;/b&gt; &lt;li&gt;
Author Notification: March 1, 2010 &lt;li&gt;
Final Paper Due: March 26, 2010 &lt;li&gt;
Symposium: &lt;b&gt;May 6-7, 2010&lt;/b&gt; &lt;p&gt; &lt;/ul&gt; &lt;p&gt; &lt;p&gt;Authors of accepted research contributions will be
invited to submit
an extended version of their papers to a special issue of the
Journal of Universal Computer Science (J.UCS).
&lt;/div&gt; &lt;p&gt; &lt;/div&gt; &lt;p&gt; &lt;div&gt;
&lt;b&gt;Scope&lt;/b&gt;
&lt;div&gt; &lt;p&gt; &lt;p&gt;The purpose of the European Lisp Symposium is to provide
a forum
for the discussion and dissemination of all aspects of design,
implementation and application of any of the Lisp dialects. We
encourage everyone interested in Lisp to participate. &lt;p&gt;
The European Lisp Symposium 2010 invites high quality papers
about
novel research results, insights and lessons learned from
practical
applications, and educational perspectives, all involving Lisp
dialects, including Common Lisp, Scheme, Emacs Lisp, AutoLisp,
ISLISP, Dylan, Clojure, and so on. &lt;p&gt;
Topics include, but are not limited to:
&lt;ul&gt;
&lt;li&gt;
Language design and implementation &lt;li&gt;
Language integration, interoperation and deployment &lt;li&gt;
Development methodologies, support and environments &lt;li&gt;
Reflection, protocols and meta-level architectures &lt;li&gt;
Lisp in Education &lt;li&gt;
Parallel, distributed and scientific computing &lt;li&gt;
Large and ultra-large-scale systems &lt;li&gt;
Hardware, virtual machine and embedded applications &lt;li&gt;
Domain-oriented programming &lt;li&gt;
Lisp pearls &lt;li&gt;
Experience reports and case studies &lt;p&gt; &lt;/ul&gt; &lt;p&gt; &lt;p&gt;We invite submissions in two categories: original
contributions and
tutorials. &lt;ul&gt;
&lt;li&gt;
Original contributions should neither have been published
previously nor be under review in any other refereed events or
publication. Research papers should describe work that advances
the current state of the art, or presents old results from a new
perspective. Experience papers should be of broad interest and
should describe insights gained from substantive practical
applications. The programme committee will evaluate each
contributed paper based on its relevance, significance, clarity,
and originality. &lt;p&gt; &lt;li&gt;
Tutorial submissions should be extended abstracts of up to four
pages for in-depth presentations about topics of special
interest
for at least 90 minutes and up to 180 minutes. The programme
committee will evaluate tutorial proposals based on the likely
interest in the topic matter, the clarity of the presentation in
the extended abstract, and the scope for interactive
participation. &lt;p&gt; &lt;/ul&gt; &lt;p&gt; &lt;p&gt;The tutorials will run during the symposium on May 6, 2010.
&lt;/div&gt; &lt;p&gt; &lt;/div&gt; &lt;p&gt; &lt;div&gt;
&lt;b&gt;Programme Chair&lt;/b&gt;
&lt;div&gt; &lt;p&gt; &lt;p&gt;Christophe Rhodes, Goldsmiths, University of London, UK
&lt;/div&gt; &lt;p&gt; &lt;/div&gt; &lt;p&gt; &lt;div&gt;
&lt;b&gt;Local Chair&lt;/b&gt;
&lt;div&gt; &lt;p&gt; &lt;p&gt;Ant&amp;oacute;nio Leit&amp;atilde;o, Technical University of Lisbon, Portugal
&lt;/div&gt; &lt;p&gt; &lt;/div&gt; &lt;p&gt; &lt;div&gt;
&lt;b&gt;Programme Committee&lt;/b&gt;
&lt;div&gt; &lt;p&gt; &lt;ul&gt;
&lt;li&gt;
Marco Antoniotti, Universit&amp;agrave; Milano Bicocca, Italy &lt;li&gt;
Giuseppe Attardi, Universit&amp;agrave; di Pisa, Italy &lt;li&gt;
Pascal Costanza, Vrije Universiteit Brussel, Belgium &lt;li&gt;
Ir&amp;egrave;ne Anne Durand, Universit&amp;eacute; Bordeaux I, France &lt;li&gt;
Marc Feeley, Universit&amp;eacute; de Montr&amp;eacute;al, Canada &lt;li&gt;
Ron Garret, Amalgamated Widgets Unlimited, USA &lt;li&gt;
Gregor Kiczales, University of British Columbia, Canada &lt;li&gt;
Nick Levine, Ravenbrook Ltd, UK &lt;li&gt;
Scott McKay, ITA Software, Inc., USA &lt;li&gt;
Peter Norvig, Google Inc., USA &lt;li&gt;
Kent Pitman, PTC, USA &lt;li&gt;
Christian Queinnec, Universit&amp;eacute; Pierre et Marie Curie, France &lt;li&gt;
Robert Strandh, Universit&amp;eacute; Bordeaux I, France &lt;li&gt;
Didier Verna, EPITA Research and Development Laboratory, France &lt;li&gt;
Barry Wilkes, Citi, UK &lt;li&gt;
Taiichi Yuasa, Kyoto University, Japan &lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
         <guid isPermaLink="false">http://www.advogato.org/person/crhodes/diary.html?start=135</guid>
         <pubDate>Wed, 18 Nov 2009 04:02:50 -0800</pubDate>
      </item>
      <item>
         <title>Andreas Fuchs: Hunchentoot gets a debugging-acceptor</title>
         <link>http://boinkor.net/archives/2009/11/hunchentoot-gets-a-debugging-a.html</link>
         <description>&lt;p&gt;Today, I submitted a patch (the first free software lisp one in months for me!) to the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://weitz.de/hunchentoot/&quot;&gt;Hunchentoot&lt;/a&gt; project, and it got accepted. Yay!&lt;/p&gt; &lt;p&gt;Some backstory: Hunchentoot&amp;#8217;s 1.0.0 release dropped a lot of implementation-dependent features, among them functionality to invoke the debugger if an error happens while handling a request. While &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://paste.lisp.org/display/81046&quot;&gt;workarounds&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.lispworks.com/documentation/HyperSpec/Body/v_break_.htm&quot;&gt;exist&lt;/a&gt;, none of them were obvious to new users or users who recently upgraded.&lt;/p&gt; &lt;p&gt;The patch I sent should fix this, hopefully. It adds a rudimentary error handling protocol to Hunchentoot, and provides two generic functions whose behavior can be adapted to your error handling needs. You can see for yourself in Hunchentoot&amp;#8217;s &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://bknr.net/trac/browser/trunk/thirdparty/hunchentoot&quot;&gt;svn repository&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;If you&amp;#8217;re a Hunchentoot user, I urge you to test this (in both development mode using debuggable-acceptor and running with the default settings). The sooner you find bugs, the sooner they can be fixed, the sooner a release can be pushed out. And if you don&amp;#8217;t find bugs at all, that&amp;#8217;s cool, too (-:&lt;/p&gt;</description>
         <guid isPermaLink="false">http://boinkor.net/archives/2009/11/hunchentoot-gets-a-debugging-a.html</guid>
         <pubDate>Sun, 15 Nov 2009 13:11:36 -0800</pubDate>
      </item>
      <item>
         <title>Grant Rettke: Carl Sagan’s Apple Pie</title>
         <link>http://feedproxy.google.com/~r/WisdomAndWonder/~3/dSAFDifsyYk/carl-sagans-apple-pie</link>
         <description>&lt;p&gt;I heard this joke a &lt;em&gt;long&lt;/em&gt; time ago and somehow it never gets old, especially when the person telling the joke turns things around a bit.&lt;/p&gt;
&lt;p&gt;His recipe is a classic; his sense of humor is hard to resist:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.wisdomandwonder.com/wordpress/wp-content/uploads/2009/11/Carl-Sagans-Apple-Pie.jpg&quot;&gt;&lt;img src=&quot;http://www.wisdomandwonder.com/wordpress/wp-content/uploads/2009/11/Carl-Sagans-Apple-Pie-300x200.jpg&quot; title=&quot;Carl-Sagan's-Apple-Pie&quot; height=&quot;200&quot; width=&quot;300&quot; alt=&quot;Carl-Sagan's-Apple-Pie&quot; class=&quot;aligncenter size-medium wp-image-4166&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(image found via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://nevenmrgan.blogspot.com/2006/03/carl-sagans-apple-pie-recipe.html&quot;&gt;Neven&lt;/a&gt;)&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/WisdomAndWonder/~4/dSAFDifsyYk&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <author>Grant</author>
         <guid isPermaLink="false">http://www.wisdomandwonder.com/?p=4165</guid>
         <pubDate>Sat, 21 Nov 2009 08:38:08 -0800</pubDate>
      </item>
      <item>
         <title>Grant Rettke: Conway’s Law</title>
         <link>http://feedproxy.google.com/~r/WisdomAndWonder/~3/B2211LRz1II/conways-law</link>
         <description>&lt;p&gt;Conway’s Law is not intended to be a joke or nasty witticism:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;…organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;– Melvin Conway&lt;/p&gt;
&lt;p&gt;(via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fare.livejournal.com/149264.html&quot;&gt;Fare&lt;/a&gt; via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Conway's_Law&quot;&gt;Wikipedia&lt;/a&gt;)&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/WisdomAndWonder/~4/B2211LRz1II&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <author>Grant</author>
         <guid isPermaLink="false">http://www.wisdomandwonder.com/?p=4161</guid>
         <pubDate>Sat, 21 Nov 2009 06:55:03 -0800</pubDate>
      </item>
      <item>
         <title>Programming Praxis: Master Mind, Part 2</title>
         <link>http://programmingpraxis.com/2009/11/20/master-mind-part-2/</link>
         <description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;In the previous &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.com/2009/11/17/master-mind-part-1/&quot;&gt;exercise&lt;/a&gt; we wrote a Master Mind setter. In today’s exercise we will write a solver, using an algorithm given by Donald E. Knuth in his &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.dcc.fc.up.pt/~sssousa/RM09101.pdf&quot;&gt;article&lt;/a&gt; “The Computer As Master Mind” in Volume 9, Number 1, the 1976-1977 edition, of &lt;em&gt;The Journal of Recreational Mathematics&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The central concept of Knuth’s algorithm is the &lt;em&gt;pool&lt;/em&gt; of potential solutions. His algorithm chooses at each step a probe that minimizes the maximum number of remaining possibilities over all possible response of the codebreaker; in the event of a tie, any pattern that achieves the minimum may be used, subject to the condition that a probe that is a member of the current pool is preferred to one that is not.&lt;/p&gt;
&lt;p&gt;For instance, consider the pool of 1296 possible code words at the start of a puzzle. There are essentially five possible starting probes: 1 1 1 1, 1 1 1 2, 1 1 2 2, 1 1 2 3, and 1 2 3 4 (rotations are excluded, as are variants that substitute one symbol consistently for another). The remaining pool sizes after each of the five probes is applied to all of the 1296 possible code words are given in the table below:&lt;/p&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;2&quot;&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt; &lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;1111&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;1112&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;1122&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;1123&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;1234&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;....&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;625&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;256&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;256&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;81&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;W...&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;308&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;256&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;276&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;152&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;B...&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;500&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;317&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;256&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;182&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;108&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WW..&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;61&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;96&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;222&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;312&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BW..&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;156&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;208&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;230&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;252&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BB..&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;150&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;123&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;114&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;105&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;96&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WWW.&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;16&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;44&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;136&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BWW.&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;27&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;36&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;84&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;132&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BBW.&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;24&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;32&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;40&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;48&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BBB.&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WWWW&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;2&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BWWW&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt; 0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BBWW&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;4&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;5&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BBBB&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;625&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;317&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;256&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;276&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;312 &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The minimax solution is 256, achieved when the probe is 1 1 2 2, so that should always be the first probe. Then the solution is determined by making the minimax probe, reducing the pool by applying the result of the probe, and repeating on the reduced pool until the puzzle is solved.&lt;/p&gt;
&lt;p&gt;Your task is to write a Master Mind solver based on the rules set out in the previous &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.com/2009/11/17/master-mind-part-1/&quot;&gt;exercise&lt;/a&gt; and Knuth’s algorithm given above. When you are finished, you are welcome to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.com/2009/11/20/master-mind-part-2/2/&quot;&gt;read&lt;/a&gt; or &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.codepad.org/tHXIIIfF&quot;&gt;run&lt;/a&gt; a suggested solution, or to post your solution or discuss the exercise in the comments below.&lt;/p&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/programmingpraxis.wordpress.com/1614/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/comments/programmingpraxis.wordpress.com/1614/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/programmingpraxis.wordpress.com/1614/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/delicious/programmingpraxis.wordpress.com/1614/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/programmingpraxis.wordpress.com/1614/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/stumble/programmingpraxis.wordpress.com/1614/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/programmingpraxis.wordpress.com/1614/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/digg/programmingpraxis.wordpress.com/1614/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/programmingpraxis.wordpress.com/1614/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/reddit/programmingpraxis.wordpress.com/1614/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;img src=&quot;http://stats.wordpress.com/b.gif?host=programmingpraxis.com&amp;amp;blog=6649073&amp;amp;post=1614&amp;amp;subd=programmingpraxis&amp;amp;ref=&amp;amp;feed=1&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/div&gt;</description>
         <author>programmingpraxis</author>
         <guid isPermaLink="false">http://programmingpraxis.com/?p=1614</guid>
         <pubDate>Fri, 20 Nov 2009 01:00:49 -0800</pubDate>
      </item>
      <item>
         <title>Ben Simon: NuGram - an architecture worth pondering</title>
         <link>http://benjisimon.blogspot.com/2009/11/nugram-architecture-worth-pondering.html</link>
         <description>&lt;p&gt;Dominique Boucher was kind enough to document the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://theschemeway.blogspot.com/2009/11/architecture-of-nugram-hosted-server.html&quot;&gt;architecture of the NuGram web service&lt;/a&gt;. It's an interesting mixture of &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.gnu.org/software/kawa/&quot;&gt;Scheme&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.erlang.org/index.html&quot;&gt;Erlang&lt;/a&gt;, and serves as an excellent reminder that there's more approaches to developing scalable software than just Apache + MVC (aka: PHP, Ruby, Java, etc.).&lt;/p&gt; &lt;p&gt;
The part that really got my attention, though was:&lt;/p&gt; &lt;blockquote&gt;
Most requests to the RESTful API are done in the context of a session. Each session is associated with an Erlang process and the application keeps a mapping between the session ID and the process for the session in the Mnesia database (it is rather cool to store things like process IDs in a database!). So when the application receives a request, it extracts the session ID from the request URI, finds the corresponding process in the database, and simply forwards the request to that process.
&lt;/blockquote&gt; &lt;p&gt;
Think about that: a request comes in, and you find the running process that is sitting around, ready to serve it. No process yet? Then create a fresh one. And when a session expires, you kill the process.&lt;/p&gt; &lt;p&gt;What a remarkable architecture (and so perfect for Erlang)! It provides an usual level of modularity, as you can effectively program a single process for a single interaction, and then let Erlang scale it all up.&lt;/p&gt; &lt;p&gt;
From a scalability perspective, this is huge, as the system is designed from the ground up to work with individual processes - whether those processes are running on a single machine, or spread out among machines, I assume could be transparent.&lt;/p&gt; &lt;p&gt;As an experiment, it would be interesting to compare traditional session programming, versus 1-session-per-process (like above), versus web continuations. I wonder if one of those models is easier to program with than the other. And I wonder if one scales better than the other.&lt;/p&gt; &lt;p&gt;
If nothing else, it makes for an excellent thought experiment.&lt;/p&gt; &lt;p&gt;
Thanks &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://theschemeway.blogspot.com/&quot;&gt;Dominique&lt;/a&gt;!&lt;/p&gt; &lt;p&gt;
&lt;font color=&quot;red&quot;&gt;Update:&lt;/font&gt; Dominique was kind enough to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://theschemeway.blogspot.com/2009/11/1-session-per-process-some-comments-on.html&quot;&gt;address the thoughts above on his blog&lt;/a&gt;. So check it out, he's got some excellent points.&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/12753102-1243004210472510917?l=benjisimon.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>Ben Simon (noreply@blogger.com)</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-12753102.post-1243004210472510917</guid>
         <pubDate>Thu, 19 Nov 2009 07:26:43 -0800</pubDate>
      </item>
      <item>
         <title>Dominique Boucher: 1-session-per-process - some further comments on the NuGram architecture</title>
         <link>http://theschemeway.blogspot.com/2009/11/1-session-per-process-some-comments-on.html</link>
         <description>In response to my &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://theschemeway.blogspot.com/2009/11/architecture-of-nugram-hosted-server.html&quot;&gt;previous post&lt;/a&gt; on the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.grammarserver.com&quot;&gt;NuGram&lt;/a&gt; architecture, Ben Simon wrote a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://benjisimon.blogspot.com/2009/11/nugram-architecture-worth-pondering.html&quot;&gt;post&lt;/a&gt; in which he focused most exclusively on the idea of using a single process for handling all the requests for a given session. I wanted to add a few comments about this approach.&lt;br /&gt;&lt;br /&gt;First, the idea is not new at all. In fact, I'd say that this is a pretty standard approach in Erlang and the language facilitates its implementation. For instance, the open-source &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.process-one.net/en/ejabberd/&quot;&gt;ejabberd&lt;/a&gt; XMPP server uses this approach. &lt;br /&gt;&lt;br /&gt;Also, it is true that it is completely transparent to the system whether the session's process runs in the same Erlang VM or on a remote machine. The syntax is exactly the same: &lt;code&gt;Process ! Message&lt;/code&gt;. That's it. In the case of NuGram Server, the database (which replicates the session table on all nodes) holds references to Erlang processes. Once it has obtained the reference to the session's process, it simply sends a message encapsulating the request to that process (using the &lt;code&gt;!&lt;/code&gt; notation). &lt;br /&gt;&lt;br /&gt;Of course, there are some complications if the node on which the process runs suddenly crashes or becomes unavailable. Session replication is less trivial to implement. In our case, the system maintains, together with the session table, a table holding all the relevant data to recreate a session if needed. This was fairly easy to do in our server given our requirements and the nature of the API. For more complex APIs, this could be much more challenging.&lt;br /&gt;&lt;br /&gt;Although I'm a big fan of the &lt;i&gt;1-session-per-process&lt;/i&gt; approach (it is a very effective one for the implementation of comet-like servers), it has some limitations that the continuation-based approach do not suffer. The back-button/bookmarking problem immediately comes to mind. Serializable continuations can be put in a database for later retrieval. But the question remains whether this is a practical approach. For instance, for how long do you retain continuations in the database? What happens when the code changes? &lt;br /&gt;&lt;br /&gt;Another benefit of using the continuation-based approach is the fact that the code handling the request is written in a more direct style. By this, I mean that the application flow is coded in a more sequential way: do this, then do that, etc. You don't have to code using state machines or callbacks. &lt;br /&gt;&lt;br /&gt;But this can be achieved in Erlang as well using two processes per session. (Processes are so cheap in Erlang!) This approach can be used to implement dialog-based applications and providing the illusion of a synchronous API, à la &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.tropo.com&quot;&gt;Tropo&lt;/a&gt;). I'll talk more about this in another post very soon.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/7061944-4423545105187958435?l=theschemeway.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>Dominique Boucher (noreply@blogger.com)</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-7061944.post-4423545105187958435</guid>
         <pubDate>Wed, 18 Nov 2009 18:08:57 -0800</pubDate>
      </item>
      <item>
         <title>Grant Rettke: The Grass is Always Greener</title>
         <link>http://feedproxy.google.com/~r/WisdomAndWonder/~3/-de2MZNbCZI/the-grass-is-always-greener</link>
         <description>&lt;p&gt;Here is a little tongue in cheek developer career philosophy/humor:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.wisdomandwonder.com/wordpress/wp-content/uploads/2009/11/academia_vs_business.png&quot;&gt;&lt;img src=&quot;http://www.wisdomandwonder.com/wordpress/wp-content/uploads/2009/11/academia_vs_business-300x154.png&quot; title=&quot;academia_vs_business&quot; height=&quot;154&quot; width=&quot;300&quot; alt=&quot;academia_vs_business&quot; class=&quot;aligncenter size-medium wp-image-4154&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(via xkcd via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://pyre.third-bit.com/blog/archives/3191.html&quot;&gt;Greg Wilson&lt;/a&gt;)&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/WisdomAndWonder/~4/-de2MZNbCZI&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <author>Grant</author>
         <guid isPermaLink="false">http://www.wisdomandwonder.com/?p=4151</guid>
         <pubDate>Wed, 18 Nov 2009 13:33:32 -0800</pubDate>
      </item>
      <item>
         <title>Programming Praxis: Master Mind, Part 1</title>
         <link>http://programmingpraxis.com/2009/11/17/master-mind-part-1/</link>
         <description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;Master Mind is a two-player game of deductive logic. One player, the &lt;em&gt;setter&lt;/em&gt;, selects a four-symbol code, and the other player, the &lt;em&gt;solver&lt;/em&gt;, tries to identify the code by trying test patterns, probes, to which the setter responds with the number of &lt;em&gt;black hits&lt;/em&gt;, indicating the number of positions where the code symbol and probe symbol are identical, and the number of &lt;em&gt;white hits&lt;/em&gt;, where a probe has the right symbol in the wrong position. Setter and solver change roles after each puzzle is solved, for a pre-defined number of rounds, and the winner is the player who has solved the puzzles with the least number of probes. With six symbols and four pegs there are 6&lt;sup&gt;4&lt;/sup&gt; = 1296 possible codes. The physical game uses colored pegs for the symbols; we will use digits instead. Variants of the game increase the number of symbols and/or the length of the code; a variant with five pegs using eight colors is marketed under the name Super Master Mind. Here is a sample game:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;1 1 2 2 B&lt;br /&gt;
1 3 4 4 W&lt;br /&gt;
3 5 2 6 BWW&lt;br /&gt;
1 4 6 2 BW&lt;br /&gt;
3 6 3 2 BBBB&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The solver first probes with the pattern 1 1 2 2, which has a single black hit. The second probe, 1 3 4 4, receives a single white hit. The third probe, 3 5 2 6, earns a single black hit and two white hits. The fourth probe, 1 4 6 2, receives one black hit and one white hit. The fifth probe, 3 6 3 2, solves the puzzle with four black hits.&lt;/p&gt;
&lt;p&gt;Your task is to write a program that performs the role of the setter, selecting a random code, prompting for probes, and scoring each probe until the human solver who is playing the game solves the puzzle. In the next exercise you will be asked to write a solver. When you are finished, you are welcome to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.com/2009/11/17/master-mind-part-1/2/&quot;&gt;read&lt;/a&gt; or &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.codepad.org/59rVyG1X&quot;&gt;run&lt;/a&gt; a suggested solution, or to post your own solution or discuss the exercise in the comments below.&lt;/p&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/programmingpraxis.wordpress.com/1606/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/comments/programmingpraxis.wordpress.com/1606/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/programmingpraxis.wordpress.com/1606/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/delicious/programmingpraxis.wordpress.com/1606/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/programmingpraxis.wordpress.com/1606/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/stumble/programmingpraxis.wordpress.com/1606/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/programmingpraxis.wordpress.com/1606/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/digg/programmingpraxis.wordpress.com/1606/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/programmingpraxis.wordpress.com/1606/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/reddit/programmingpraxis.wordpress.com/1606/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;img src=&quot;http://stats.wordpress.com/b.gif?host=programmingpraxis.com&amp;amp;blog=6649073&amp;amp;post=1606&amp;amp;subd=programmingpraxis&amp;amp;ref=&amp;amp;feed=1&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/div&gt;</description>
         <author>programmingpraxis</author>
         <guid isPermaLink="false">http://programmingpraxis.com/?p=1606</guid>
         <pubDate>Tue, 17 Nov 2009 01:00:10 -0800</pubDate>
      </item>
      <item>
         <title>Llewellyn Pritchard: Experimental monolitic IronScheme executable</title>
         <link>http://xacc.wordpress.com/2009/11/16/experimental-monolitic-ironscheme-executable/</link>
         <description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;A common request is to have some form of compiled libraries to run a Scheme program, and not relying on source files for the program to run.&lt;/p&gt;
&lt;p&gt;This is already provided in IronScheme via precompiled/serialized libraries, but still results in a ‘binary’ format for every library file, which in turn can end up being quite a few with a fixed directory structure.&lt;/p&gt;
&lt;p&gt;So yesterday I worked around a serialization bug that hindered my progress on improving this.&lt;/p&gt;
&lt;p&gt;I have added the following:&lt;br /&gt;
1. Created a container package to shove all precompiled libraries in.&lt;br /&gt;
2. Added the ability to use ILMerge to merge all the assemblies into 1 executable.&lt;br /&gt;
3. And for bonus points, I added the ability to include the container package into such a merged executable, resulting in 1 fat executable with all the libraries included.&lt;/p&gt;
&lt;p&gt;For now, you can go to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ironscheme.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35937&quot;&gt;this IronScheme page&lt;/a&gt; and download the result of step 3. A 21MB executable with everything to run IronScheme, including all IronScheme and SRFI and miscellaneous libraries.&lt;/p&gt;
&lt;p&gt;Of course your own program may not need all the libraries, so you could chose to only merge the ‘base’ 2.1mb executable with say 1mb of libraries.&lt;/p&gt;
&lt;p&gt;I will add some documentation later to explain how to craft these.&lt;/p&gt;
&lt;p&gt;Cheers&lt;/p&gt;
&lt;p&gt;leppie&lt;/p&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/xacc.wordpress.com/314/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/comments/xacc.wordpress.com/314/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/xacc.wordpress.com/314/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/delicious/xacc.wordpress.com/314/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/xacc.wordpress.com/314/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/stumble/xacc.wordpress.com/314/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/xacc.wordpress.com/314/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/digg/xacc.wordpress.com/314/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/xacc.wordpress.com/314/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/reddit/xacc.wordpress.com/314/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;img src=&quot;http://stats.wordpress.com/b.gif?host=xacc.wordpress.com&amp;amp;blog=1242361&amp;amp;post=314&amp;amp;subd=xacc&amp;amp;ref=&amp;amp;feed=1&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/div&gt;</description>
         <author>leppie</author>
         <guid isPermaLink="false">http://xacc.wordpress.com/?p=314</guid>
         <pubDate>Mon, 16 Nov 2009 07:35:52 -0800</pubDate>
      </item>
      <item>
         <title>Yinso Chen: BZLIB/SESSION.plt - a Session Store via BZLIB/DBI.plt</title>
         <link>http://feedproxy.google.com/~r/WebDevelopmentFunctionalProgrammingAndScheme/~3/gRaFo-C873E/bzlibsessionplt-session-store-via.html</link>
         <description>I originally planned to write a series on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://weblambda.blogspot.com/2009/11/building-web-session-store-1.html&quot;&gt;the development of a session store&lt;/a&gt;, but it turned out that there aren't that many things to write about, so I am just going to release the code via planet. As usual, this is released under LGPL.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Installation&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
To download the planet package:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(require (planet bzlib/session)) &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
The package comes with three separate database installation scripts (one each for sqlite, mysql, and postgresql). You can call them via the following:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
;; installing to a sqlite database
(require (planet bzlib/session/setup/jsqlite)) (setup-session-store/jsqlite! &amp;lt;path-to-sqlite-db&amp;gt;) ;; installing to a mysql database (require (planet bzlib/session/setup/jazmysql)) (setup-session-store/jazmysql! &amp;lt;host&amp;gt; &amp;lt;port&amp;gt; &amp;lt;user&amp;gt; &amp;lt;password&amp;gt; &amp;lt;schema&amp;gt;) ;; installing to a postgresql database (require (planet bzlib/session/setup/spgsql)) (setup-session-store/spgsql! &amp;lt;host&amp;gt; &amp;lt;port&amp;gt; &amp;lt;user&amp;gt; &amp;lt;password&amp;gt; &amp;lt;database&amp;gt;) &lt;/code&gt;&lt;/pre&gt;&lt;b&gt;Known Issue&lt;/b&gt;: the script currently can only be run once and it assumes the table &lt;code&gt;session_t&lt;/code&gt; does not exist in the target database. This will be rectified in the future.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Session ID&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The session store uses uuid for session IDs. &lt;code&gt;bzlib/base&lt;/code&gt; provides API for manipulation of uuids.&lt;br /&gt;
&lt;br /&gt;
To create an uuid, just run &lt;code&gt;(make-uuid)&lt;/code&gt;. It can optionally takes in a parameter that are either an uuid in string, and then create the corresponding uuid structure (it can also takes in another uuid structure and make an equivalent uuid structure). &lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
&amp;gt; (require (planet bzlib/base))
&amp;gt; (make-uuid)
#&amp;lt;uuid:4ba52eac-a0b4-415a-88f5-57d1fadd1aba&amp;gt;
&amp;gt; (make-uuid &quot;4ba52eac-a0b4-415a-88f5-57d1fadd1aba&quot;)
#&amp;lt;uuid:4ba52eac-a0b4-415a-88f5-57d1fadd1aba&amp;gt;
&amp;gt; (make-uuid (make-uuid &quot;4ba52eac-a0b4-415a-88f5-57d1fadd1aba&quot;))
#&amp;lt;uuid:4ba52eac-a0b4-415a-88f5-57d1fadd1aba&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;more&quot;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;code&gt;bzlib/session.plt&lt;/code&gt; does not handle parsing cookies into uuids.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creating a Session Object&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In order to create a session object, you first need to make a &lt;code&gt;dbi&lt;/code&gt; handle with either &lt;code&gt;dbd-spgsql&lt;/code&gt;, &lt;code&gt;dbd-jazmysql&lt;/code&gt;, or &lt;code&gt;dbd-jsqlite&lt;/code&gt; driver to where you have setup the &lt;code&gt;session_t&lt;/code&gt; table, and you need to pass in the corresponding query script so the prepared statements (&lt;code&gt;'make-session!&lt;/code&gt;, &lt;code&gt;'load-session&lt;/code&gt;, &lt;code&gt;'save-session!&lt;/code&gt;, and &lt;code&gt;destroy-session!&lt;/code&gt;) can be loaded:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(require (planet bzlib/session) (planet bzlib/dbi)) ;; loading 'jsqlite (require (planet bzlib/dbd-jsqlite)) (define h (connect 'jsqlite &amp;lt;path-to-db&amp;gt; &lt;b&gt;'#:load (session-query-path/sqlite)&lt;/b&gt;)) ;; loading 'spgsql (require (planet bzlib/dbd-spgsql)) (define h (connect 'spgsql &amp;lt;spgsql-parameters&amp;gt; ... &lt;b&gt;'#:load (session-query-path/postgres)&lt;/b&gt;))
;; loading 'jazmysql
(require (planet bzlib/dbd-jazmysql)) (define h (connect 'jazmysql &amp;lt;jazmysql-parameters&amp;gt; ... &lt;b&gt;'#:load (session-query-path/mysql)&lt;/b&gt;)) &lt;/code&gt;&lt;/pre&gt;Then you can pass the handle to &lt;code&gt;build-session&lt;/code&gt; to create the session object.&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
;; create a new session with a new uuid (define s (build-session h)) ;; create a new session with a known uuid (define s (build-session h &amp;lt;uuid&amp;gt;)) &lt;/code&gt;&lt;/pre&gt;As soon as &lt;code&gt;build-session&lt;/code&gt; is called, you'll find a corresponding session record in &lt;code&gt;session_t&lt;/code&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Accessing Session Key/Value Pairs&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;session-ref&lt;/code&gt;, &lt;code&gt;session-set!&lt;/code&gt;, &lt;code&gt;session-del!&lt;/code&gt; modifies the values of session key/value pairs:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(session-ref &amp;lt;session&amp;gt; &amp;lt;key&amp;gt; &amp;lt;optional-default-value&amp;gt;) (session-set! &amp;lt;session&amp;gt; &amp;lt;key&amp;gt; &amp;lt;value&amp;gt;) (session-del! &amp;lt;session&amp;gt; &amp;lt;key&amp;gt;) &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Writing Out Sessions&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;save-session!&lt;/code&gt; saves the sessions out to the database:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(save-session! &amp;lt;session&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;code&gt;refresh-session!&lt;/code&gt; will reload the session from the database:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(refresh-session! &amp;lt;session&amp;gt;) &lt;/code&gt;&lt;/pre&gt;And &lt;code&gt;destroy-session!&lt;/code&gt; will delete the session record from &lt;code&gt;session_t&lt;/code&gt;:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(destroy-session! &amp;lt;session&amp;gt;) &lt;/code&gt;&lt;/pre&gt;&lt;code&gt;call-with-session&lt;/code&gt; and &lt;code&gt;with-session&lt;/code&gt; will help you manage the call to &lt;code&gt;save-session!&lt;/code&gt; so you do not have to write it with every request:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(call-with-session (build-session h) (lambda (session) &amp;lt;... do something with session ...&amp;gt;)) (with-session (build-session h) (lambda () &amp;lt;... do something with session via (current-session) ...&amp;gt;)) &lt;/code&gt;&lt;/pre&gt;&lt;code&gt;with-session&lt;/code&gt; works via &lt;code&gt;(current-session)&lt;/code&gt;, which is a parameter that holds either &lt;code&gt;#f&lt;/code&gt; or a session structure. By passing the session object via &lt;code&gt;with-session&lt;/code&gt; it will automatically parameterize &lt;code&gt;current-session&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Session Expirations&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can use &lt;code&gt;session-expired?&lt;/code&gt; to test whether the session object has expired:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(session-expired? &amp;lt;session&amp;gt;) &lt;/code&gt;&lt;/pre&gt;The expiration value is stored as a number (in Julian days) in &lt;code&gt;session_t&lt;/code&gt;, which by default will be 14 days in the future from the time when &lt;code&gt;save-session!&lt;/code&gt; is called. &lt;br /&gt;
&lt;br /&gt;
The default session expiration value of 14 days can be controlled via the &lt;code&gt;session-expiration-interval&lt;/code&gt; parameter.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Web Server Continuation&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
To simplify the usage of &lt;code&gt;bzlib/session&lt;/code&gt; with &lt;code&gt;web-server&lt;/code&gt; continuation calls, the following wrappers are exported to replace the &lt;code&gt;send/suspend&lt;/code&gt; family:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(require (planet bzlib/session/web-server)) ;; you then have access to... &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.plt-scheme.org/web-server/servlet.html#(def._((lib._web-server/servlet/web..ss)._send/back))&quot;&gt;send/back&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.plt-scheme.org/web-server/servlet.html#(def._((lib._web-server/servlet/web..ss)._send/finish))&quot;&gt;send/finish&lt;/a&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.plt-scheme.org/web-server/servlet.html#(def._((lib._web-server/servlet/web..ss)._send/suspend))&quot;&gt;send/suspend&lt;/a&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.plt-scheme.org/web-server/servlet.html#(def._((lib._web-server/servlet/web..ss)._send/suspend/url))&quot;&gt;send/suspend/url&lt;/a&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.plt-scheme.org/web-server/servlet.html#(def._((lib._web-server/servlet/web..ss)._send/forward))&quot;&gt;send/forward&lt;/a&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.plt-scheme.org/web-server/servlet.html#(def._((lib._web-server/servlet/web..ss)._send/suspend/dispatch))&quot;&gt;send/suspend/dispatch&lt;/a&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.plt-scheme.org/web-server/servlet.html#(def._((lib._web-server/servlet/web..ss)._redirect/get))&quot;&gt;redirect/get&lt;/a&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.plt-scheme.org/web-server/servlet.html#(def._((lib._web-server/servlet/web..ss)._redirect/get/forget))&quot;&gt;redirect/get/forget&lt;/a&gt;
&lt;/code&gt;&lt;/pre&gt;These wrappers have the same corresponding APIs from &lt;code&gt;web-server&lt;/code&gt; itself, and they'll call &lt;code&gt;save-session!&lt;/code&gt; before making the continuation, and call &lt;code&gt;refresh-session!&lt;/code&gt; before returning from the continuation.&lt;br /&gt;
&lt;br /&gt;
That's it for now, enjoy.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/7570364353928786565-5910891301501022338?l=weblambda.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=gRaFo-C873E:A2VwqCuqQvA:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?d=yIl2AUoC8zA&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=gRaFo-C873E:A2VwqCuqQvA:qj6IDK7rITs&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?d=qj6IDK7rITs&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=gRaFo-C873E:A2VwqCuqQvA:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?i=gRaFo-C873E:A2VwqCuqQvA:V_sGLiPBpWU&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=gRaFo-C873E:A2VwqCuqQvA:F7zBnMyn0Lo&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?i=gRaFo-C873E:A2VwqCuqQvA:F7zBnMyn0Lo&quot; border=&quot;0&quot;/&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/WebDevelopmentFunctionalProgrammingAndScheme/~4/gRaFo-C873E&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <author>yc (noreply@blogger.com)</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-7570364353928786565.post-5910891301501022338</guid>
         <pubDate>Sun, 15 Nov 2009 22:32:24 -0800</pubDate>
      </item>
      <item>
         <title>Yinso Chen: Web Sessions vs. Continuations</title>
         <link>http://feedproxy.google.com/~r/WebDevelopmentFunctionalProgrammingAndScheme/~3/54KTwuVtPiM/web-sessions-vs-continuations.html</link>
         <description>The &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://list.cs.brown.edu/pipermail/plt-scheme/2009-November/036500.html&quot;&gt;&quot;session info in web server applications&quot; thread&lt;/a&gt; recently in plt-scheme list has an undertone that continuations are equivalent of web sessions as understood in other languages and frameworks. This undertone is highlighted by the lack of a session-like capability within the web-server collection that exists in other web frameworks. &lt;br /&gt;
&lt;br /&gt;
This got me to think: &lt;b&gt;are continuations equivalent of sessions?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.cs.brown.edu/~sk/Publications/Papers/Published/khmgpf-impl-use-plt-web-server-journal/&quot;&gt;original intent (indicated in Shriram's research paper) of web-server's continuation&lt;/a&gt; is to correctly and succinctly model interactive web application's application flow. The paper sites examples of incorrectly implemented web apps that would do something like the following:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;user browse a list of goods&lt;/li&gt;
&lt;li&gt;user opens new window to get the details of goods A&lt;/li&gt;
&lt;li&gt;user goes back to original window&lt;/li&gt;
&lt;li&gt;user then opens another new window to get the details of goods B&lt;/li&gt;
&lt;li&gt;user then goes to goods A and click &quot;Buy Now&quot;&lt;/li&gt;
&lt;li&gt;incorrectly implemented app will cause the user to buy goods B instead of goods A&lt;/li&gt;
&lt;/ol&gt;The traditional solution to the above interaction would be to use sessions, and since continuation models such interactions as well, there is no question that in this case continuations supplant the needs of sessions. &lt;br /&gt;
&lt;br /&gt;
But for other scenarios involving sessions it might be more natural to model the computations by using the traditional session concepts. &lt;br /&gt;
&lt;br /&gt;
For example - identifying the user across visits after significant time lapse (this is generally toggled by a &quot;remember me&quot; checkbox during login). Normally web sites accomplish this by persisting the user's authenticators via cookies or sessions.&lt;br /&gt;
&lt;br /&gt;
This process is awkward to model with continuations, since the user likely come back to the site via a top level link that has no captured continuations, instead of digging up the last continuation url for the site, and the continuations might have expired between the visits if you use stateful servlets. &lt;br /&gt;
&lt;br /&gt;
If you use web-server's stateless servlet language, an approach is probably to serialize the continuation into a cookie so it can model the above scenario, but you'll have to write your code in the stateless language or convert your code over, and it feels like a more complex solution compared to simply having a regular session capability. This is similar to using continuations to model non-interactive web links - it can work, but it does not follow Occam's razor. &lt;br /&gt;
&lt;br /&gt;
Furthermore - if your site uses extensive ajax, your use of continuations will decrease, since Ajax models the interactions as well and supplants the needs for continuations. and in such case you might regain the needs for sessions that was reduced by continuations. &lt;br /&gt;
&lt;br /&gt;
So, as far as I can tell, continuations is not equivalent to web sessions and do not eliminate the needs for session capabilities.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/7570364353928786565-436184400823140423?l=weblambda.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=54KTwuVtPiM:FXo2D28Q_Ps:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?d=yIl2AUoC8zA&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=54KTwuVtPiM:FXo2D28Q_Ps:qj6IDK7rITs&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?d=qj6IDK7rITs&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=54KTwuVtPiM:FXo2D28Q_Ps:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?i=54KTwuVtPiM:FXo2D28Q_Ps:V_sGLiPBpWU&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=54KTwuVtPiM:FXo2D28Q_Ps:F7zBnMyn0Lo&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?i=54KTwuVtPiM:FXo2D28Q_Ps:F7zBnMyn0Lo&quot; border=&quot;0&quot;/&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/WebDevelopmentFunctionalProgrammingAndScheme/~4/54KTwuVtPiM&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <author>yc (noreply@blogger.com)</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-7570364353928786565.post-436184400823140423</guid>
         <pubDate>Sun, 15 Nov 2009 22:29:41 -0800</pubDate>
      </item>
      <item>
         <title>Programming Praxis: Two Linear Sorts</title>
         <link>http://programmingpraxis.com/2009/11/13/two-linear-sorts/</link>
         <description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;It is well known that any comparison-based sort, as we have been studying, has a lower time bound of &lt;em&gt;O&lt;/em&gt;(&lt;em&gt;n&lt;/em&gt; log &lt;em&gt;n&lt;/em&gt;). But if all the keys are positive integers less than or equal to &lt;em&gt;n&lt;/em&gt;, it is possible to sort in &lt;em&gt;O&lt;/em&gt;(&lt;em&gt;n&lt;/em&gt;) linear time by taking advantage of the structure of the keys themselves.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Count sort&lt;/em&gt; determines, for each input element &lt;em&gt;x&lt;/em&gt;, the number of elements less than &lt;em&gt;x&lt;/em&gt;, then places &lt;em&gt;x&lt;/em&gt; directly in its position in the output; if there are &lt;em&gt;k&lt;/em&gt; elements less than &lt;em&gt;x&lt;/em&gt;, then &lt;em&gt;x&lt;/em&gt; belongs in the &lt;em&gt;k&lt;/em&gt;&lt;sup&gt;th&lt;/sup&gt; + 1 position (being careful to properly consider the case of equal elements). Count sort requires two temporary arrays, one to hold the counts of the various elements, which act as indexes into the array, and one to build up the output.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Radix sort&lt;/em&gt; extends count sort by making multiple passes based on the positional digits of the integers being sorted: first do a count sort on the digits in the ones column of the integers, then a count sort on the digits in the tens column, then the hundreds column, the thousands column, and so on until the input is sorted, taking advantage of the fact that count sort is stable. Radix sort works on other kinds of keys besides integers; for instance, dates can be sorted by doing count sort on day, month and year in succession.&lt;/p&gt;
&lt;p&gt;Your task is to write functions that sort arrays using count sort and radix sort. When you are finished, you are welcome to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.com/2009/11/13/two-linear-sorts/2/&quot;&gt;read&lt;/a&gt; or &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.codepad.org/YMEdwxX5&quot;&gt;run&lt;/a&gt; a suggested solution, or to post your own solution or discuss the exercise in the comments below.&lt;/p&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/programmingpraxis.wordpress.com/1604/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/comments/programmingpraxis.wordpress.com/1604/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/programmingpraxis.wordpress.com/1604/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/delicious/programmingpraxis.wordpress.com/1604/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/programmingpraxis.wordpress.com/1604/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/stumble/programmingpraxis.wordpress.com/1604/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/programmingpraxis.wordpress.com/1604/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/digg/programmingpraxis.wordpress.com/1604/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/programmingpraxis.wordpress.com/1604/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/reddit/programmingpraxis.wordpress.com/1604/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;img src=&quot;http://stats.wordpress.com/b.gif?host=programmingpraxis.com&amp;amp;blog=6649073&amp;amp;post=1604&amp;amp;subd=programmingpraxis&amp;amp;ref=&amp;amp;feed=1&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/div&gt;</description>
         <author>programmingpraxis</author>
         <guid isPermaLink="false">http://programmingpraxis.com/?p=1604</guid>
         <pubDate>Fri, 13 Nov 2009 01:00:47 -0800</pubDate>
      </item>
      <item>
         <title>Dominique Boucher: The architecture of NuGram Hosted Server</title>
         <link>http://theschemeway.blogspot.com/2009/11/architecture-of-nugram-hosted-server.html</link>
         <description>In the comments section of one of my &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://theschemeway.blogspot.com/2009/10/dynamically-setting-yaws-log-level.html&quot;&gt;previous post&lt;/a&gt;, I mentioned that NuGram Hosted Server (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.grammarserver.com/&quot;&gt;www.grammarserver.com&lt;/a&gt;) is implemented in a mix of Erlang/Yaws, Java and Kawa Scheme. Alexandre Abreu then asked a few questions about some architectural aspects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;how do erlang and kawa scheme interop? http / json ? ffi ?&lt;/li&gt; &lt;li&gt;to follow up on that, why erlang / yaws and not scala / lift to have a better integration with the jvm ? &lt;/li&gt; &lt;li&gt;the server part if hosted on 1 machine ? how do you handle the load (both the connection load and the computation load since grammar and the services provided by NuGram seem pretty heavy computation-wise)? Maybe you don't need to do much given the amount of people that uses your service and I know you don't offer any guarantees with people using this service in a commercial setup but I am just wondering&lt;/li&gt;&lt;/ul&gt;These questions prompted for a long answer. So in the following sections I describe some aspects of the NuGram Hosted Server architecture at 10,000 feet high.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. Context&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;NuGram Hosted Server is a grammar hosting server for use by communication applications (VoiceXML applications, IM bots, etc.). It provides various grammar-related services through a RESTful API, like dynamic grammar generation and semantic interpretation of text-based sentences (and it will soon provide robust parsing capabilities). It also provides a community-based HTML application to management and share grammars, consult application logs, etc., using standard AJAX techniques.&lt;br /&gt;&lt;br /&gt;When we started the project, we had some ambitious requirements in mind: &lt;ul&gt; &lt;li&gt;High-performance HTTP server.&lt;/li&gt; &lt;li&gt;Scalability. (We needed the possibility of dynamically adding nodes to our cluster without interruption of service.)&lt;/li&gt; &lt;li&gt;Fault-tolerance.&lt;/li&gt; &lt;li&gt;Hot code swapping.&lt;/li&gt; &lt;li&gt;Distributed database.&lt;/li&gt;&lt;/ul&gt;Since I already had some experience with Erlang, I pushed the idea to the management team, after getting the buy-in from my development team. We decided to use this project to evaluate Erlang in the context of a real project.&lt;br /&gt;&lt;br /&gt;To answer Alexandre's question more specifically, we did not consider Scala/lift mainly for the same reason we did not choose Java itself. Essentially, we could not use the usual session tracking mechanisms found in J2EE environments (jsessionid, cookies) for our RESTful API. Implementing a clustered solution would have required too much work. And using Erlang was a far better (and more elegant) approach.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. The architecture&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;At a very high level, grammarserver.com is composed of two subsystems:&lt;ul&gt; &lt;li&gt;&lt;i&gt;An Erlang/Yaws front-end.&lt;/i&gt;&lt;br /&gt;This is the part handling the HTTP requests. &lt;/li&gt;&lt;li&gt;&lt;i&gt;A number of Java/Kawa workers.&lt;/i&gt;&lt;/li&gt; These workers implement the grammar-related services. There can be many workers running on a single machine. These workers implement the more computation-intensive stuff (parsing of text sentences, grammar template instantation, etc.)&lt;/ul&gt; Let me describe each subsystem separately.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Erlang/Yaws front-end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This subsystem handles all the HTTP requests. It currently consists of a single Erlang node, but it has been designed to support the clustering of many Erlang nodes. In this case, we would need a load-balancer in front of the Erlang cluster.&lt;br /&gt;&lt;br /&gt;The Erlang system follows most OTP principles. It is a real Erlang application and provides a supervisor and a number of gen_servers. The application also starts an embedded yaws serving requests for several virtual hosts (the HTML websites at www.grammarserver.com, nugram.nuecho.com, with and without SSL support, and the RESTful API at www.grammarserver.com:8082).&lt;br /&gt;&lt;br /&gt;Most requests to the RESTful API are done in the context of a session. Each session is associated with an Erlang process and the application keeps a mapping between the session ID and the process for the session in the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.erlang.org/doc/apps/mnesia/index.html&quot;&gt;Mnesia&lt;/a&gt; database (it is rather cool to store things like process IDs in a database!). So when the application receives a request, it extracts the session ID from the request URI, finds the corresponding process in the database, and simply forwards the request to that process.&lt;br /&gt;&lt;br /&gt;When multiple Erlang nodes are running in a cluster, forwarding a request can involve sending the request to a different Erlang node. This is done completely transparently in Erlang.&lt;br /&gt;&lt;br /&gt;Another interesting consequence of using processes to represent sessions is the fact that implementing session timeout becomes trivial. Each session process makes an explicit &lt;code&gt;receive&lt;/code&gt; ... &lt;code&gt;after&lt;/code&gt;. When the timeout is reached, the session is automatically terminated and removed from the database.&lt;br /&gt;&lt;br /&gt;The application also uses Mnesia for other purposes:&lt;ul&gt; &lt;li&gt;It holds the user accounts, of course. &lt;/li&gt; &lt;li&gt;All the instantiated grammars are held in the database.&lt;/li&gt; &lt;li&gt;It holds the node IDs of the available Java/Kawa workers. Keeping that information in a persistent (disk-based) table of Mnesia makes it possible to shut down the Erlang application and reconnect it automatically to the Java nodes when we restart it. More on this below.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Java/Kawa workers&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The Java/Kawa workers implement the basic NuGram services. They are written in a mix of Java and Kawa Scheme because most of the code is also shared with NuGram IDE, an Eclipse plugin.&lt;br /&gt;&lt;br /&gt;The workers use &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.erlang.org/doc/apps/jinterface/index.html&quot;&gt;jinterface&lt;/a&gt; to interface with Erlang. This has the advantage of exposing the workers as standard nodes to the Erlang application. In other words, the Erlang application does not even know that the workers are implemented in Java. This is completely transparent.&lt;br /&gt;&lt;br /&gt;Many workers can be started, independently of the number of Erlang nodes. The first thing they do is try to find an Erlang node and register with it. If they cannot find an Erlang node, they wait for a specified amount of time, then try again. After a number of retries, they simply stop with an error.&lt;br /&gt;&lt;br /&gt;Each grammar is assigned to a single worker. To distribute the load as evenly as possible across the workers, the Erlang system uses a round-robin strategy to assign workers to new grammars (if a session uses a grammar already loaded in a worker, requests are sent directly to that worker, of course).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;3. Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Overall, our experience with Erlang has been excessively positive. (I have to confess that my team members already had some prior exposure to functional programming and Prolog, which helped a lot). Of course, we had to learn some things the hard way, we found some bugs in Yaws. But in the end the platform delivered on its promises. We have an architecture that can scale, we can hot swap code, dynamically change the database schema, add nodes dynamically, etc.&lt;br /&gt;&lt;br /&gt;Since NuGram Hosted Server is a free service, we do not guarantee any quality of service, but the platform is really robust and fast and that is very important for communication applications (especially telephony applications where latency translates to &lt;span style=&quot;font-style:italic;&quot;&gt;dead-air&lt;/span&gt; during a conversation).&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/7061944-8167865147024234653?l=theschemeway.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>Dominique Boucher (noreply@blogger.com)</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-7061944.post-8167865147024234653</guid>
         <pubDate>Thu, 12 Nov 2009 07:12:35 -0800</pubDate>
      </item>
      <item>
         <title>Programming Praxis: Merge Sort</title>
         <link>http://programmingpraxis.com/2009/11/10/merge-sort/</link>
         <description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;The last &lt;em&gt;O&lt;/em&gt;(&lt;em&gt;n&lt;/em&gt; log &lt;em&gt;n&lt;/em&gt;) sorting algorithm that we shall consider in our current series of exercises is merge sort. If you have two sorted sequences, they can be merged into a single sorted sequence in time linear to their combined length by running through them in order, at each step taking the smaller of the heads of the two sequences. Then mergesort works by recursively merging smaller sequences into larger ones, starting with trivially-sorted sequences of one element that are merged into two-element sequences, then merging pairs of two-element sequences into four-element sequences, and so on, until the entire sequence is sorted.&lt;/p&gt;
&lt;p&gt;Your task is to write a function that sorts an array by the merge sort algorithm described above, according to the conventions of the prior exercise. When you are finished, you are welcome to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.com/2009/11/10/merge-sort/2/&quot;&gt;read&lt;/a&gt; or &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://programmingpraxis.codepad.org/Wk6rsu1Z&quot;&gt;run&lt;/a&gt; a suggested solution, or to post your own solution or discuss the exercise in the comments below.&lt;/p&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/programmingpraxis.wordpress.com/1602/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/comments/programmingpraxis.wordpress.com/1602/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/programmingpraxis.wordpress.com/1602/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/delicious/programmingpraxis.wordpress.com/1602/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/programmingpraxis.wordpress.com/1602/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/stumble/programmingpraxis.wordpress.com/1602/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/programmingpraxis.wordpress.com/1602/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/digg/programmingpraxis.wordpress.com/1602/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/programmingpraxis.wordpress.com/1602/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/reddit/programmingpraxis.wordpress.com/1602/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;img src=&quot;http://stats.wordpress.com/b.gif?host=programmingpraxis.com&amp;amp;blog=6649073&amp;amp;post=1602&amp;amp;subd=programmingpraxis&amp;amp;ref=&amp;amp;feed=1&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/div&gt;</description>
         <author>programmingpraxis</author>
         <guid isPermaLink="false">http://programmingpraxis.com/?p=1602</guid>
         <pubDate>Tue, 10 Nov 2009 01:00:56 -0800</pubDate>
      </item>
      <item>
         <title>Yinso Chen: Building a Web Session Store (1)</title>
         <link>http://feedproxy.google.com/~r/WebDevelopmentFunctionalProgrammingAndScheme/~3/w61NatwaZeY/building-web-session-store-1.html</link>
         <description>Given that we have previously &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://weblambda.blogspot.com/2009/11/web-sessions-vs-continuations.html&quot;&gt;determined the need for a web session store even if we are using continuations&lt;/a&gt;, we'll go ahead and build it on top of our DBI stack, so the session data can be persisted as long as necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Quick Word About Session Store Performance&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
One thing to note about session data is that its data usage is both read and write intensive, and such data can put strain on the database. It's write-intensive because with each request we'll extend the expiration time on the session itself, and it's read-intensive because the data is needed for every request, but it changes with every request. &lt;br /&gt;
&lt;br /&gt;
For now we'll assume that our database is capable of handling such needs (and it will until you have a sufficiently large amount of traffic), but it's something to keep in mind. The nice thing of building the session logic on top of DBI is that when we need to deal with the performance issue, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://weblambda.blogspot.com/2009/09/create-driver-for-bzlibdbi-1-dbi.html&quot;&gt;we can add logics into the DBI tier easily with developing a customer driver&lt;/a&gt;, for example, by &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://weblambda.blogspot.com/2009/09/create-driver-for-bzlibdbi-1-dbi.html&quot;&gt;integrating memcached as a intermediate store&lt;/a&gt; that'll flush out the changes to the database once a while instead of with every request. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Active Record&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Active_record_pattern&quot;&gt;active record pattern&lt;/a&gt; are not just for OOP fanatics - we schemers know that you can craft your own OOP with FP easily. In DBI today there is a base structure for active record definition:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(define active-record (handle id)) &lt;/code&gt;&lt;/pre&gt;Such definition is a lot simpler than the usual OOP representations, which usually try to construct the data model in memory, along with dynamically constructed SQL statements. Although such OOP records provide simplicity for the simple cases, it has proven to be a leaky abstraction due to the object vs relational paradigm mismatch, as well as a significant performance overhead. Our simple definition will do us just fine right now. &lt;br /&gt;
&lt;br /&gt;
What would our session API look like then? &lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
;; expiration a julian-day ;; store is a hash table (define-struct (session active-record) (expiration store) #:mutable) ;; the session key/value manipulation calls... (define (session-ref session key (default #f)) ...) (define (session-set! session key val) ...) (define (session-del! session key) ...) ;; the persistence calls (define (build-session handle ...) ...) (define (save-session! session) ...) (define (refresh-session! session) ...) (define (destroy-session! session) ...) &lt;/code&gt;&lt;/pre&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;more&quot;&gt;&lt;/a&gt;&lt;br /&gt;
We'll go through and flesh out the definitions in details.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Store in Memory&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Hashtable is a good internal representation of the key/value pairs that session will hold (for now we'll assume the held data are serializable... we'll deal with this problem later), and this immediately tell us what &lt;code&gt;session-ref&lt;/code&gt;, &lt;code&gt;session-set!&lt;/code&gt;, and &lt;code&gt;session-del!&lt;/code&gt; will look like: &lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(define (session-ref session key (default #f)) (hash-ref (session-store session) key default)) (define (session-set! session key val) (set-session-store! session (hash-set (session-store session) key val))) (define (session-del! session key) (set-session-store! session (hash-remove session key)))
&lt;/code&gt;&lt;/pre&gt;And yes - we are using immutable hash rather than mutable hash. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;When to Persist&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You probably have noticed that &lt;code&gt;session-set!&lt;/code&gt; and &lt;code&gt;session-del!&lt;/code&gt; do not persist out to the database. So if you have multiple concurrent connections for the same session, it might be possible for the session object to get out of the sync.&lt;br /&gt;
&lt;br /&gt;
While this is possible, the chance of it happening isn't great, since for the majority of the time users are going to make one main request at a time, with many auxiliary requests for accompanying images and css files that should not modify session values. &lt;br /&gt;
&lt;br /&gt;
On the other hand, saving every changes with each single &lt;code&gt;session-set!&lt;/code&gt; call could drastically increase the read &amp;amp; write access for the session object (what's the point of saving with each write if you are not doing the same for read?) and could have detrimental impact on performance unless we are ready to implement an intermediate cache. &lt;br /&gt;
&lt;br /&gt;
And finally such decoupling actually simplify the code (I have written the code with the other approach for comparison) and makes it look more refactored. So for now we'll go with this approach.&lt;br /&gt;
&lt;br /&gt;
Hence we'll persist at the end of the request with a call to &lt;code&gt;save-session!&lt;/code&gt;. A simple wrapper so you do not have to explicitly write the separate call would be:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(define (call-with-session session proc) (dynamic-wind void (lambda () (proc session)) (lambda () (save-session! session))))
&lt;/code&gt;&lt;/pre&gt;And with a &lt;code&gt;current-session&lt;/code&gt; parameter we can simplify it as:&lt;br /&gt;
&lt;pre class=&quot;scheme&quot;&gt;&lt;code&gt;
(define current-session (make-parameter #f)) (define (with-session session proc) (call-with-session session (lambda (session) (parameterize ((current-session session)) (proc)))))
&lt;/code&gt;&lt;/pre&gt;Except for one bug, the above will work as you expected in web-server environment. If you have an idea of what the bug will be - please feel free to make a comment. I'll discuss the bug and how to fix it in the next post for the series.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/7570364353928786565-2250839939443586700?l=weblambda.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=w61NatwaZeY:-LLtJJw22iY:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?d=yIl2AUoC8zA&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=w61NatwaZeY:-LLtJJw22iY:qj6IDK7rITs&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?d=qj6IDK7rITs&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=w61NatwaZeY:-LLtJJw22iY:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?i=w61NatwaZeY:-LLtJJw22iY:V_sGLiPBpWU&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?a=w61NatwaZeY:-LLtJJw22iY:F7zBnMyn0Lo&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/WebDevelopmentFunctionalProgrammingAndScheme?i=w61NatwaZeY:-LLtJJw22iY:F7zBnMyn0Lo&quot; border=&quot;0&quot;/&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/WebDevelopmentFunctionalProgrammingAndScheme/~4/w61NatwaZeY&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <author>yc (noreply@blogger.com)</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-7570364353928786565.post-2250839939443586700</guid>
         <pubDate>Mon, 09 Nov 2009 20:54:36 -0800</pubDate>
      </item>
      <item>
         <title>Grant Rettke: Where to Find Jobs in Statistics</title>
         <link>http://feedproxy.google.com/~r/WisdomAndWonder/~3/Hq4u6E0zqvc/where-to-find-jobs-in-statistics</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amstat.org/jobweb/index.cfm&quot;&gt;http://www.amstat.org/jobweb/index.cfm &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.stat.ufl.edu/vlib/jobs.html&quot;&gt;http://www.stat.ufl.edu/vlib/jobs.html &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.stat.purdue.edu/resources/jobs/jobs.cgi?type=1&quot;&gt;http://www.stat.purdue.edu/resources/jobs/jobs.cgi?type=1 &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://jobs.imstat.org/c/search_results.cfm?site_id=1847&quot;&gt;http://jobs.imstat.org/c/search_results.cfm?site_id=1847 &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://eims.ams.org/search/&quot;&gt;http://eims.ams.org/search/ &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.mathjobs.org/jobs&quot;&gt;http://www.mathjobs.org/jobs &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(via Dr. Rowe)&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/WisdomAndWonder/~4/Hq4u6E0zqvc&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <author>Grant</author>
         <guid isPermaLink="false">http://www.wisdomandwonder.com/?p=4136</guid>
         <pubDate>Mon, 09 Nov 2009 07:17:59 -0800</pubDate>
      </item>
      <item>
         <title>Yoni Rabkin Katzenell: CamelHumpSupportForEmacsMovement</title>
         <link>http://yrk.livejournal.com/268635.html</link>
         <description>I'mVeryHappy&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://lists.gnu.org/archive/html/emacs-devel/2009-11/msg00695.html&quot;&gt;ToSeeThis&lt;/a&gt;IncludedInEmacsForThoseTimesINeedToEditStuffLikeJavaScript.</description>
         <author>yrk</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:yrk:268635</guid>
         <pubDate>Fri, 20 Nov 2009 23:59:35 -0800</pubDate>
      </item>
      <item>
         <title>Emacs-fu: showing pop-ups</title>
         <link>http://emacs-fu.blogspot.com/2009/11/showing-pop-ups.html</link>
         <description>&lt;p&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://4.bp.blogspot.com/_kGFGcbwevHE/SwWKlLoseMI/AAAAAAAAAd4/IcakPnbhnRQ/s1600/popup.png&quot;&gt;&lt;img src=&quot;http://4.bp.blogspot.com/_kGFGcbwevHE/SwWKlLoseMI/AAAAAAAAAd4/IcakPnbhnRQ/s400/popup.png&quot; alt=&quot;&quot; style=&quot;float:right;margin:0 0 10px 10px;cursor:pointer;cursor:hand;width:283px;height:128px;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5405879299111418050&quot;/&gt;&lt;/a&gt;
&lt;/p&gt;&lt;div id=&quot;outline-container-1&quot; class=&quot;outline-2&quot;&gt;
&lt;div id=&quot;text-1&quot; class=&quot;outline-text-2&quot;&gt; &lt;strong&gt;Updated: yes, it's %s, not %d&lt;/strong&gt; Sometimes, it's nice when &lt;code&gt;emacs&lt;/code&gt; can warn you when something is happening or
should happen. For example, when a new e-mail has arrived, or when there's a
meeting in 15 minutes you should attend. &lt;p&gt;&lt;/p&gt;
&lt;p&gt;
As always, there are different way to do this, but here's what I've been using
for while. Various versions of this have been circulating around mailing
lists, so I don't know whom to credit with the original idea – anyway, this
is the (modified) version that I'm using.
&lt;/p&gt; &lt;pre class=&quot;src src-emacs-lisp&quot;&gt;(&lt;span class=&quot;org-keyword&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;org-function-name&quot;&gt;djcb-popup&lt;/span&gt; (title msg &lt;span class=&quot;org-type&quot;&gt;&amp;amp;optional&lt;/span&gt; icon sound) &lt;span class=&quot;org-doc&quot;&gt;&quot;Show a popup if we're on X, or echo it otherwise; TITLE is the title
of the message, MSG is the context. Optionally, you can provide an ICON and
a sound to be played&quot;&lt;/span&gt; (interactive) (&lt;span class=&quot;org-keyword&quot;&gt;when&lt;/span&gt; sound (shell-command (concat &lt;span class=&quot;org-string&quot;&gt;&quot;mplayer -really-quiet &quot;&lt;/span&gt; sound &lt;span class=&quot;org-string&quot;&gt;&quot; 2&amp;gt; /dev/null&quot;&lt;/span&gt;))) (&lt;span class=&quot;org-keyword&quot;&gt;if&lt;/span&gt; (eq window-system 'x) (shell-command (concat &lt;span class=&quot;org-string&quot;&gt;&quot;notify-send &quot;&lt;/span&gt; (&lt;span class=&quot;org-keyword&quot;&gt;if&lt;/span&gt; icon (concat &lt;span class=&quot;org-string&quot;&gt;&quot;-i &quot;&lt;/span&gt; icon) &lt;span class=&quot;org-string&quot;&gt;&quot;&quot;&lt;/span&gt;) &lt;span class=&quot;org-string&quot;&gt;&quot; '&quot;&lt;/span&gt; title &lt;span class=&quot;org-string&quot;&gt;&quot;' '&quot;&lt;/span&gt; msg &lt;span class=&quot;org-string&quot;&gt;&quot;'&quot;&lt;/span&gt;)) &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;text only version &lt;/span&gt; (message (concat title &lt;span class=&quot;org-string&quot;&gt;&quot;: &quot;&lt;/span&gt; msg))))
&lt;/pre&gt; &lt;p&gt;
A couple of notes:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
I'm using &lt;code&gt;notify-send&lt;/code&gt; for sending notifications; this assumes you are
using that system (it's part of the &lt;code&gt;libnotify-bin&lt;/code&gt; package in
Debian/Ubuntu). You can of course replace it with whatever is available on
your system. Alternatives are &lt;code&gt;zenity&lt;/code&gt; or &lt;code&gt;kdialog&lt;/code&gt; or &lt;code&gt;xmessage&lt;/code&gt; (for
old-timers) and their equivalents (?) on Windows, MacOS. &lt;/li&gt;
&lt;li&gt;
I'm now using &lt;code&gt;mplayer&lt;/code&gt; for playing sounds. This is a bit heavy, but at
least plays all kinds of audio files. If you only care about &lt;code&gt;.wav&lt;/code&gt;-files,
you could replace it with e.g. &lt;code&gt;aplay&lt;/code&gt;;
&lt;/li&gt;
&lt;li&gt;
as always, please ignore my ego-centric function names :-) &lt;/li&gt;
&lt;/ul&gt; &lt;p&gt;Now, we can use this function by evaluation e.g. &lt;/p&gt; &lt;pre class=&quot;src src-emacs-lisp&quot;&gt;(djcb-popup &lt;span class=&quot;org-string&quot;&gt;&quot;Warning&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;The end is near&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;/usr/share/icons/test.png&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;/usr/share/sounds/beep.ogg&quot;&lt;/span&gt;)
&lt;/pre&gt; &lt;/div&gt; &lt;div id=&quot;outline-container-1.1&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;sec-1.1&quot;&gt;showing pop-ups from &lt;code&gt;org-mode&lt;/code&gt; appointments &lt;/h3&gt;
&lt;div id=&quot;text-1.1&quot; class=&quot;outline-text-3&quot;&gt; &lt;p&gt;
The above popup function is most useful when it's does its work based on some
event. To be notified of appointments and the like, there is the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.gnu.org/software/emacs/manual/html_node/emacs/Appointments.html&quot;&gt;emacs appt facility&lt;/a&gt;. Here, we set up this &lt;code&gt;appt&lt;/code&gt;, and then hook it up with &lt;code&gt;org-mode&lt;/code&gt;, so &lt;code&gt;appt&lt;/code&gt; can warn us when there's something happening soon…
&lt;/p&gt; &lt;pre class=&quot;src src-emacs-lisp&quot;&gt;&lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;the appointment notification facility
&lt;/span&gt;(&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; appt-message-warning-time 15 &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;warn 15 min in advance &lt;/span&gt; appt-display-mode-line t &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;show in the modeline
&lt;/span&gt; appt-display-format 'window) &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;use our func
&lt;/span&gt;(appt-activate 1) &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;active appt (appointment notification)
&lt;/span&gt;(display-time) &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;time display is required for this...
&lt;/span&gt; &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;update appt each time agenda opened &lt;/span&gt;(&lt;span class=&quot;org-keyword&quot;&gt;add-hook&lt;/span&gt; 'org-finalize-agenda-hook 'org-agenda-to-appt) &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;our little façade-function for djcb-popup
&lt;/span&gt; (&lt;span class=&quot;org-keyword&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;org-function-name&quot;&gt;djcb-appt-display&lt;/span&gt; (min-to-app new-time msg) (djcb-popup (format &lt;span class=&quot;org-string&quot;&gt;&quot;Appointment in %s minute(s)&quot;&lt;/span&gt; min-to-app) msg &lt;span class=&quot;org-string&quot;&gt;&quot;/usr/share/icons/gnome/32x32/status/appointment-soon.png&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;/usr/share/sounds/ubuntu/stereo/phone-incoming-call.ogg&quot;&lt;/span&gt;)) (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; appt-disp-window-function (function djcb-appt-display))
&lt;/pre&gt; &lt;p&gt;
Of course, you can freely choose a icon / sound to your liking.
&lt;/p&gt;
&lt;/div&gt; &lt;/div&gt; &lt;div id=&quot;outline-container-1.2&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;sec-1.2&quot;&gt;showing pop-ups for new mail &lt;/h3&gt;
&lt;div id=&quot;text-1.2&quot; class=&quot;outline-text-3&quot;&gt; &lt;p&gt;
Another event you might want to be warned about is new mail. There is
something to be set for &lt;i&gt;not&lt;/i&gt; letting yourself be disturbed for new mail, but
if you sufficiently filter your mails before they enter your inbox, it can be
a good way to periodically bring you back from your deep sl &lt;code&gt;^H^H&lt;/code&gt; thinking. For
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://emacs-fu.blogspot.com/2009/06/e-mail-with-wanderlust.html&quot;&gt;Wanderlust&lt;/a&gt;, I use something like this: &lt;/p&gt; &lt;pre class=&quot;src src-emacs-lisp&quot;&gt;(&lt;span class=&quot;org-keyword&quot;&gt;add-hook&lt;/span&gt; 'wl-biff-notify-hook (&lt;span class=&quot;org-keyword&quot;&gt;lambda&lt;/span&gt;() (djcb-popup &lt;span class=&quot;org-string&quot;&gt;&quot;Wanderlust&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;You have new mail!&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;/usr/share/icons/gnome/32x32/status/mail-unread.png&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;/usr/share/sounds/ubuntu/stereo/phone-incoming-call.ogg&quot;&lt;/span&gt;)))
&lt;/pre&gt; &lt;p&gt;
Exercise for the reader: adapt this for your chosen mail client.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/3992530807750384868-8184896567058918882?l=emacs-fu.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>djcb</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3992530807750384868.post-8184896567058918882</guid>
         <pubDate>Fri, 20 Nov 2009 09:08:28 -0800</pubDate>
      </item>
      <item>
         <title>Got Emacs?: Churn baby, Churn</title>
         <link>http://emacsworld.blogspot.com/2009/11/churn-baby-churn.html</link>
         <description>&lt;div&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://economictimes.indiatimes.com/news/news-by-industry/telecom/TRAI-fixes-Rs-19-as-portability-fee-to-change-mobile-operators/articleshow/5251866.cms&quot;&gt;Rs 19&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;That's the fee for number portability. Less than a half pack of ciggies cost. With a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.google.com/hostednews/afp/article/ALeqM5jlzgSBw-vq2TBxsq46nn-CdflypA&quot;&gt;purported 400 million user base&lt;/a&gt;, it's going to be one massive headache for the operator. Much of the problem is one of their own making. Increasing the subscribers without attendant increase in cell phone towers. Dropped calls and no connectivity, with people on prepaid watching their precious talk time go down without a word being spoken, they're going to get socked like crazy by the prepaid crowd.&lt;br /&gt;&lt;br /&gt;Everyone of my friends and colleagues are just waiting for this to get rolled out and then, they'd hit the phones and switch. I believe the salesmen who work on commission to close out on subscribers for each operator will make a killing in the first few months.&lt;br /&gt;&lt;br /&gt;Though, I'm pretty sure, the operators will find a way to make it a disincentive to switch. One rumour I heard was that it might take as long as 4 or 6 weeks for the switch to be complete. If the US experience is considered when portability was introduced, I'd wait a good 6-8 months before switching.&lt;br /&gt;&lt;br /&gt;If it comes to that. I'll take a lower bill and other extra minutes thrown in, anytime rather than switch. Since I have my broadband and mobile from the same operator, hopefully I have some leverage.&lt;br /&gt;&lt;br /&gt;Hopefully.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img src=&quot;http://img.zemanta.com/pixy.gif?x-id=9c45930d-37a0-8ddf-982e-e37735d406f8&quot; alt=&quot;&quot; class=&quot;zemanta-pixie-img&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/3165518189103293420-9204798562776521570?l=emacsworld.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>sivaram</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3165518189103293420.post-9204798562776521570</guid>
         <pubDate>Fri, 20 Nov 2009 07:52:40 -0800</pubDate>
      </item>
      <item>
         <title>Random Sample: Posting org buffers with weblogger.el to your blog</title>
         <link>http://www.randomsample.de/dru5/node/77</link>
         <description>&lt;p&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.randomsample.de/dru5/node/76&quot;&gt;In my last post&lt;/a&gt;, I described how to setup weblogger.el with
Drupal. Since I love to write posts like this with org (see &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://emacs-fu.blogspot.com/2009/05/writing-and-blogging-with-org-mode.html&quot;&gt;this posting&lt;/a&gt; for details on how you can do this), I wrote myself a little
helper function to directly export an org file to a weblogger entry:
&lt;/p&gt; &lt;pre class=&quot;codepre src src-emacs-lisp&quot;&gt;(&lt;span style=&quot;color:#6495ed;font-weight:bold;&quot;&gt;defun&lt;/span&gt; &lt;span style=&quot;color:#87ceeb;&quot;&gt;DE-org-export-weblogger&lt;/span&gt; () (interactive) (&lt;span style=&quot;color:#6495ed;font-weight:bold;&quot;&gt;let&lt;/span&gt; ((tmpbuffer (get-buffer-create &lt;span style=&quot;color:#32cd32;&quot;&gt;&quot; *org html export*&quot;&lt;/span&gt;)) title text) &lt;span style=&quot;color:#66cdaa;&quot;&gt;;; &lt;/span&gt;&lt;span style=&quot;color:#66cdaa;&quot;&gt;export posting to HTML, but without headers
&lt;/span&gt; (org-export-as-html 1 nil nil tmpbuffer t) (set-buffer tmpbuffer) (goto-char (point-min)) &lt;span style=&quot;color:#66cdaa;&quot;&gt;;; &lt;/span&gt;&lt;span style=&quot;color:#66cdaa;&quot;&gt;get the title
&lt;/span&gt; (&lt;span style=&quot;color:#6495ed;font-weight:bold;&quot;&gt;when&lt;/span&gt; (re-search-forward &lt;span style=&quot;color:#32cd32;&quot;&gt;&quot;&amp;lt;div id=&amp;#92;&quot;outline-container-1&amp;#92;&quot; class=&amp;#92;&quot;outline-2&amp;#92;&quot;&amp;gt;[&lt;/span&gt;&lt;span style=&quot;color:#32cd32;&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#32cd32;&quot;&gt;&amp;#92;0]*&amp;#92;
&amp;lt;h2 id=&amp;#92;&quot;sec-1&amp;#92;&quot;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#ff0000;font-weight:bold;&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;&lt;span style=&quot;color:#ff0000;font-weight:bold;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#32cd32;&quot;&gt;.*?&lt;/span&gt;&lt;span style=&quot;color:#ff0000;font-weight:bold;&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;&lt;span style=&quot;color:#ff0000;font-weight:bold;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#32cd32;&quot;&gt;&amp;lt;/h2&amp;gt;[&lt;/span&gt;&lt;span style=&quot;color:#32cd32;&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#32cd32;&quot;&gt;&amp;#92;0]*&amp;#92;
&amp;lt;div class=&amp;#92;&quot;outline-text-2&amp;#92;&quot; id=&amp;#92;&quot;text-1&amp;#92;&quot;&amp;gt;&quot;&lt;/span&gt; nil t) (setq title (match-string 1)) (replace-match &lt;span style=&quot;color:#32cd32;&quot;&gt;&quot;&quot;&lt;/span&gt;)) &lt;span style=&quot;color:#66cdaa;&quot;&gt;;; &lt;/span&gt;&lt;span style=&quot;color:#66cdaa;&quot;&gt;get the posting
&lt;/span&gt; (setq text (buffer-substring-no-properties (point) (point-max))) (weblogger-start-entry) (insert title) (goto-char (point-max)) (insert text) (kill-buffer tmpbuffer)))
&lt;/pre&gt; &lt;p&gt;
You can now simply call &lt;i&gt;DE-org-export-weblogger&lt;/i&gt; interactively on
your org file, and it will create a new weblogger entry
buffer. Determining the title of the posting is a bit hacky; it
assumes that your org file looks something like this:
&lt;/p&gt; &lt;pre class=&quot;example&quot;&gt;* Title of your blog post text of your blog post
&lt;/pre&gt; &lt;p&gt;
It will then extract the title from the HTML exported output. You can
still edit the produced HTML, maybe inserting your taxonomy tags, and
then post it by pressing C-x C-s.
&lt;/p&gt;
&lt;p&gt;
This of course assumes that your default input format for blogs is
&quot;Full HTML&quot;, otherwise most of the HTML tags will get stripped and
everything will just look plain ugly. You can set the default input
format in Drupal under &lt;i&gt;site configuration -&amp;gt; Input formats&lt;/i&gt;.
&lt;/p&gt;
&lt;p&gt;
BTW, I totally forgot to mention in my last post that you can also
edit &lt;b&gt;existing&lt;/b&gt; Drupal blog entries with weblogger. Simply press C-c
C-p or C-c C-n for the previous/next entry!
&lt;/p&gt;</description>
         <author>randomsample</author>
         <guid isPermaLink="false">http://www.randomsample.de/77 at http://www.randomsample.de/dru5</guid>
         <pubDate>Fri, 20 Nov 2009 07:08:04 -0800</pubDate>
      </item>
      <item>
         <title>Chris Ball: Btrfs snapshots proposal</title>
         <link>http://blog.printf.net/articles/2009/11/19/btrfs-snapshots-proposal</link>
         <description>&lt;p&gt;I've written up a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://fedoraproject.org/wiki/Features/SystemRollbackWithBtrfs&quot;&gt;feature proposal&lt;/a&gt; on how we can use &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Btrfs&quot;&gt;Btrfs&lt;/a&gt; snapshots to enable system rollbacks in Fedora 13, by gluing together the existing kernel code to do Btrfs snapshots, a UI for performing rollbacks, and a yum plugin to make snapshots automatically before each yum transaction. Lots of good comments so far, and LWN has &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://lwn.net/Articles/361695/&quot;&gt;written an article&lt;/a&gt; about it (subscribers only, for the moment).&lt;/p&gt;</description>
         <author>Chris Ball</author>
         <guid isPermaLink="false">urn:uuid:32ca346e-a5dd-4365-a2e5-42ff18dee576</guid>
         <pubDate>Thu, 19 Nov 2009 10:40:00 -0800</pubDate>
      </item>
      <item>
         <title>Random Sample: Posting Drupal blog entries from within Emacs</title>
         <link>http://www.randomsample.de/dru5/node/76</link>
         <description>I just found out you can easily post Drupal blog entries from within
Emacs by using the wonderful 'weblogger.el'. Here's what you have to do: &lt;ul&gt;&lt;li&gt;Enable the 'Blog API' module in your Drupal installation and
configure permissions and the blog types which should be accessible via
XML-RPC. &lt;/li&gt;&lt;li&gt;Go to the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.emacswiki.org/emacs/WebloggerMode&quot;&gt;Weblogger EmacsWiki
page&lt;/a&gt; and get yourself weblogger.el and xml-rpc.el.&lt;/li&gt;&lt;li&gt;Install
both in your load-path and require weblogger in your .emacs.&lt;/li&gt;&lt;li&gt;Now
call weblogger-setup-weblog and use
https://your-drupal-site/xmlrpc.php as URL for accessing
the Drupal XML-RPC API, then provide username and password.&lt;/li&gt;&lt;li&gt;Now
call weblogger-start-entry and start writing.&lt;/li&gt;&lt;li&gt;Use C-x C-s
to post.&lt;/li&gt;&lt;/ul&gt; That's it! Now you can for instance create blog entries with the
fantastic markup from Orgmode, and directly post it via
weblogger-mode. There's just one problem: how can you set the taxonomy
tags for the posting? Simply putting it into the 'keywords' section
didn't work. It seems like you cannot do that via XML-RPC in Drupal, but
luckily there's a little Drupal module called &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://drupal.org/project/inlinetags&quot;&gt;'inline tags'&lt;/a&gt;, which
lets you flag the posting through a special tag &lt;pre class=&quot;codepre&quot;&gt;[tags]Emacs[/tags]
&lt;/pre&gt; Note that the module requires Drupal 6, but it wasn't very hard to make
it work under Drupal 5 (which I'm still using) - let me know if you need
it.</description>
         <author>randomsample</author>
         <guid isPermaLink="false">http://www.randomsample.de/76 at http://www.randomsample.de/dru5</guid>
         <pubDate>Thu, 19 Nov 2009 07:07:38 -0800</pubDate>
      </item>
      <item>
         <title>Matt Harrison: New insight on 100% coverage</title>
         <link>http://panela.blog-city.com/new_insight_on_100_coverage.htm</link>
         <description>&lt;p&gt;Code coverage gets a bad rap. People say it's meaningless. In my &quot;Managing Complexity&quot; talk at &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://panela.blog-city.com/pycon_2008_managing_complexity_slides.htm&quot;&gt;PyCon 2008&lt;/a&gt;, I made the analogy that code coverage was like a shield. One is exposed where the shield doesn't cover. But just because you have shield doesn't mean that your shield is any good. You could be battling against a fire breathing dragon with a WOODEN shield (smart one Wiglaf). Your exposed areas could be dead code (which the literature says is more likely to cause bugs) or code that is hard to test.&lt;/p&gt;
&lt;p&gt;This last point, code that is hard to test was hit home to me over the weekend when I spent some time going over &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://misko.hevery.com/&quot;&gt;Miško Hevery's blog about testability&lt;/a&gt;. While perusing the site and some of his presos, it hit me that 100% code coverage (and I'm talking about the line/statement variety here) indicates something else. That your code is testable. If you can't get 100% coverage, then you are probably violating some of the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://misko.hevery.com/2008/07/30/top-10-things-which-make-your-code-hard-to-test/&quot;&gt;10 things that make code hard to test&lt;/a&gt;. I especially appreciate the Law of Demeter analogy he uses, (paraphrasing) &quot;You don't give the cashier your wallet when they tell your lunch costs $5.98. You give them the money (or the credit card)&quot;. So if you are struggling getting the coverage numbers you want, you probably need to use dependency injection to get rid of that Law of Demeter violation....&lt;/p&gt;
&lt;p&gt;Of course, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://nedbatchelder.com/blog/200911/coverage_v32b1_branch_coverage.html&quot;&gt;now that Python has branch coverage&lt;/a&gt;. we can get to work on some of the interesting things that you get from path coverage. Oh yeah, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mattharrison/pycoverage.el&quot;&gt;editor support&lt;/a&gt; would be nice too.&lt;/p&gt;</description>
         <author>Matt</author>
         <guid isPermaLink="false">http://panela.blog-city.com/new_insight_on_100_coverage.htm</guid>
         <pubDate>Wed, 18 Nov 2009 08:56:00 -0800</pubDate>
      </item>
      <item>
         <title>Bryan Murdock: Initial Thoughts on Google Go</title>
         <link>http://bryan-murdock.blogspot.com/2009/11/initial-thoughts-on-google-go.html</link>
         <description>&lt;p&gt;I read the “tutorial”: and thought, “the syntax is Frankenstein ugly. They have Guido on staff, but this looks like they consulted Larry Wall. Why didn’t they just write an open source &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.digitalmars.com/d/&quot;&gt;D&lt;/a&gt; compiler?”&lt;/p&gt; &lt;p&gt;Then I read the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://golang.org/doc/go_faq.html&quot;&gt;FAQ&lt;/a&gt;. Some very interesting ideas, and personally, ever since using C++ for some large embedded programming projects (large? embedded? not as oxymoronic as you might think), I’ve been thinking these same things for a while now:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;No major systems language has emerged in over a decade, but over that time the computing landscape has changed tremendously. There are several trends:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Computers are enormously quicker but software development is not faster.&lt;/li&gt; &lt;li&gt;Dependency management is a big part of software development today but the “header files” of languages in the C tradition are antithetical to clean dependency analysis—and fast compilation.&lt;/li&gt; &lt;li&gt;There is a growing rebellion against cumbersome type systems like those of Java and C++, pushing people towards dynamically typed languages such as Python and JavaScript.&lt;/li&gt; &lt;li&gt;Some fundamental concepts such as garbage collection and parallel computation are not well supported by popular systems languages.&lt;/li&gt; &lt;li&gt;The emergence of multicore computers has generated worry and confusion. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;We believe it’s worth trying again with a new language, a concurrent, garbage-collected language with fast compilation.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;D has been around a while, but it just doesn’t seem to be catching on; maybe because it just doesn’t have a large corporation behind it. Maybe because it’s not fully open source. Or, maybe because it doesn’t have all the features of Go.&lt;/p&gt; &lt;p&gt;Bryan&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/3669809752172683097-5909530710835661308?l=bryan-murdock.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>Bryan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3669809752172683097.post-5909530710835661308</guid>
         <pubDate>Wed, 18 Nov 2009 08:29:58 -0800</pubDate>
      </item>
      <item>
         <title>Yoni Rabkin Katzenell: There is Very Little Good on the Web; Keep it Alive</title>
         <link>http://yrk.livejournal.com/268539.html</link>
         <description>I don't think that Wikipedia is particularly accurate or run by saints but it is an important part of what makes the Web useful. So &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://wikimediafoundation.org/wiki/Special:ContributionHistory?offset=1258559485#276354&quot;&gt;I donated 10 bucks&lt;/a&gt; as a part of their new fund drive and I think that &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://wikimediafoundation.org/wiki/Support_Wikipedia2&quot;&gt;you should too&lt;/a&gt;.</description>
         <author>yrk</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:yrk:268539</guid>
         <pubDate>Wed, 18 Nov 2009 08:06:06 -0800</pubDate>
      </item>
      <item>
         <title>sachachua: Automating tedious wiki editing tasks with Emacs and w3m</title>
         <link>http://sachachua.com/wp/2009/11/17/automating-tedious-wiki-editing-tasks-with-emacs-and-w3m/</link>
         <description>
&lt;p&gt;I needed to update many of the links in our wiki because a team member left, so I had to reupload all of her files to a shared service and change all the URLs to point to the new files. Unfortunately, the file service didn’t send me the former URLs of the files, so that was going to be a manual process. Our wiki had 149 pages in it. Not fun.&lt;/p&gt;
&lt;p&gt;After a few pages of editing (and correcting the occasional typo that crept in as I changed URLs), I decided to partially automate the process. Using a smidgen of Emacs Lisp, I created a function that pasted text into a temporary buffer, performed whatever automatic fixes it could make, prompted me for any URLs it didn’t recognize, remembered the old URL – new URL mapping I defined, and copied the text back.&lt;/p&gt;
&lt;p&gt;The function looked somewhat like this:&lt;/p&gt;
&amp;lt;style type=&quot;text/css&quot;&amp;gt;
pre.code { background: black; color: white }
.code .comment { background: black; border: 0 } .comment { /* font-lock-comment-face */ color: #ff7f24; } .comment-delimiter { /* font-lock-comment-delimiter-face */ color: #ff7f24; } .doc { /* font-lock-doc-face */ color: #ffa07a; } .function-name { /* font-lock-function-name-face */ color: #87cefa; } .keyword { /* font-lock-keyword-face */ color: #00ffff; } .negation-char { } .regexp-grouping-backslash { /* font-lock-regexp-grouping-backslash */ font-weight: bold; } .regexp-grouping-construct { /* font-lock-regexp-grouping-construct */ font-weight: bold; } .string { /* font-lock-string-face */ color: #ffa07a; } .variable-name { /* font-lock-variable-name-face */ color: #eedd82; }
&amp;lt;/style&amp;gt;
&lt;pre class=&quot;code&quot;&gt;(&lt;span class=&quot;keyword&quot;&gt;defvar&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;sacha/wiki-links&lt;/span&gt; nil &lt;span class=&quot;doc&quot;&gt;&quot;Associative list of (old-url . new-url).&quot;&lt;/span&gt;)
(&lt;span class=&quot;keyword&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;sacha/wiki-fix&lt;/span&gt; () (interactive) (&lt;span class=&quot;keyword&quot;&gt;with-temp-buffer&lt;/span&gt; &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Insert text from clipboard
&lt;/span&gt; (yank) (goto-char (point-min)) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Look for all the links
&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (re-search-forward &lt;span class=&quot;string&quot;&gt;&quot;&amp;#92;&amp;#92;[&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;regexp-grouping-backslash&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;regexp-grouping-construct&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;negation-char&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;|]+&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;regexp-grouping-backslash&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;regexp-grouping-construct&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;regexp-grouping-backslash&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;regexp-grouping-construct&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;negation-char&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;#92;]]+&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;regexp-grouping-backslash&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;regexp-grouping-construct&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;#92;&amp;#92;]&quot;&lt;/span&gt; nil t) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Check if it's one of the links I want to replace
&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (or (string-match-p &lt;span class=&quot;string&quot;&gt;&quot;viewpage&quot;&lt;/span&gt; (match-string 2)) (string-match-p &lt;span class=&quot;string&quot;&gt;&quot;lsoohoo&quot;&lt;/span&gt; (match-string 2))) (replace-match (&lt;span class=&quot;keyword&quot;&gt;save-match-data&lt;/span&gt; &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Prompt and the entry to the map if it does not yet exist
&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;unless&lt;/span&gt; (assoc (match-string 2) sacha/wiki-links) (add-to-list 'sacha/wiki-links (cons (match-string 2) (read-string (concat (match-string 1) &lt;span class=&quot;string&quot;&gt;&quot;? &quot;&lt;/span&gt;))))) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;pick up the corresponding URL
&lt;/span&gt; (cdr (assoc (match-string 2) sacha/wiki-links))) t t nil 2))) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Copy the text into the clipboard
&lt;/span&gt; (kill-new (buffer-string))))
&lt;/pre&gt;
&lt;p&gt;I used &lt;code&gt;M-x global-set-key&lt;/code&gt; to bind a convenient function key to it (F12, I think), and then it was just a matter of clicking on each page, clicking on Edit, typing Ctrl-C to copy the text, switching to Emacs, pressing F12, switching back to my browser, typing Ctrl-V, and saving the wiki page. I also added some lines (not shown here) to convert the previous wiki gardener's full links to intrawiki links, change server URLs, and do other fun things.&lt;/p&gt;
&lt;p&gt;I thought about fully automating it (somehow hooking into w3, perhaps?), but that seemed to be more trouble than needed. Besides, it was good to review all the pages.&lt;/p&gt;
&lt;p&gt;As a result of this Emacs wizardry, processing all 149 wiki pages took me a few hours instead of a few days. Yay!&lt;/p&gt;
&lt;p&gt;Of course, I finished the last wiki page, I found out that I needed to change the servers in the URL. I decided to go ahead and fully automate the darn thing.&lt;/p&gt;
&lt;p&gt;I extracted a list of URLs for the wiki by viewing the tree version of the wiki index. It used Javascript, so I couldn't just pull the URLs out of the source code. Fortunately, the Firebug plugin for Firefox lets me copy the rendered HTML, so I used that instead. Some judicious text-editing later (&lt;code&gt;replace-regexp&lt;/code&gt; rocks), I had a list of URLs to the different pages. I knew I needed to put in some kind of delay when loading web pages. &lt;code&gt;sleep-for&lt;/code&gt; let me spread out my requests so I didn't hammer the server too badly. Reading the w3m.el source code turned up &lt;code&gt;w3m-async-exec&lt;/code&gt;. Once I set that to nil, requesting web pages and running code on the results turned out to be straightforward. Selecting the right widgets was a bit of a hack (&lt;code&gt;re-search-forward&lt;/code&gt; here, &lt;code&gt;w3m-previous-anchor&lt;/code&gt; there), but hey, it worked. After confirming it by manually running it on a few pages, I left it merrily running in the background.&lt;/p&gt;
&lt;p&gt;Here it is (some tweaking required):
&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;(&lt;span class=&quot;keyword&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;sacha/edit-wiki-page&lt;/span&gt; () (interactive) (&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; ((buffer (current-buffer)) (w3m-async-exec nil) (delay 5)) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;number of seconds
&lt;/span&gt; &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;While not at the end of the buffer
&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (not (eobp)) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Load the URL on the current line
&lt;/span&gt; (w3m-browse-url (buffer-substring (line-beginning-position) (line-end-position))) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Look for the edit button
&lt;/span&gt; (goto-char (point-min)) (&lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; (search-forward &lt;span class=&quot;string&quot;&gt;&quot;Edit&quot;&lt;/span&gt; nil t) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Click it
&lt;/span&gt; (w3m-view-this-url) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Look for the Minor change checkbox
&lt;/span&gt; (goto-char (point-min)) (&lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; (search-forward &lt;span class=&quot;string&quot;&gt;&quot;Minor change&quot;&lt;/span&gt; nil t) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;The text area is the second widget back
&lt;/span&gt; (w3m-previous-anchor 2) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Open the text area in a temporary buffer for editing
&lt;/span&gt; (w3m-view-this-url) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Do the changes
&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (re-search-forward &lt;span class=&quot;string&quot;&gt;&quot;https?://example.com/path&quot;&lt;/span&gt; nil t) (replace-match &lt;span class=&quot;string&quot;&gt;&quot;http://path.example.com&quot;&lt;/span&gt; t t nil 0)) &lt;span class=&quot;comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Save the value
&lt;/span&gt; (w3m-form-input-textarea-set) (&lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; (search-backward &lt;span class=&quot;string&quot;&gt;&quot;Save&quot;&lt;/span&gt; nil t) (w3m-view-this-url)))) (switch-to-buffer buffer) (forward-line) (sleep-for delay))))&lt;/pre&gt;
&lt;p&gt;I’m sure this kind of automation might be possible with lots of hacking in Mozilla Firefox, and I’ve seen great scripts for the Mac, too. But I know Emacs, I’m comfortable digging into source code, and I can make things work.&lt;/p&gt;
&lt;p&gt;Awesome. =D&lt;/p&gt;
&lt;p&gt;Post from: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sachachua.com/wp&quot;&gt;sacha chua :: enterprise 2.0 consultant, storyteller, geek&lt;/a&gt;.
Check out my blog for tips on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sachachua.com/wp/category/va&quot;&gt;managing virtual assistants&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sachachua.com/wp/category/drupal&quot;&gt;Drupal&lt;/a&gt;, and other topics!&lt;br /&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sachachua.com/wp/2009/11/17/automating-tedious-wiki-editing-tasks-with-emacs-and-w3m/&quot;&gt;Automating tedious wiki editing tasks with Emacs and w3m&lt;/a&gt;&lt;/p&gt;</description>
         <author>Sacha Chua</author>
         <guid isPermaLink="false">http://sachachua.com/wp/2009/11/17/automating-tedious-wiki-editing-tasks-with-emacs-and-w3m/</guid>
         <pubDate>Tue, 17 Nov 2009 11:24:31 -0800</pubDate>
      </item>
      <item>
         <title>Alex Bennée: Thinking about email</title>
         <link>http://www.bennee.com/~alex/blog/2009/11/17/thinking-about-email/</link>
         <description>&lt;p&gt;I saw a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://keithp.com/blogs/notmuch/&quot;&gt;post on my feeds&lt;/a&gt; today discussing a new email client called &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://notmuchmail.org/&quot;&gt;notmuch&lt;/a&gt; which set me thinking about my own use of email.&lt;/p&gt;
&lt;p&gt;
I have three primary ways of accessing email at the moment. On my domain I run &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.mutt.org/&quot;&gt;Mutt&lt;/a&gt; in a screen session. At work I have the GUI behemoth that is &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Evolution_%28software%29&quot;&gt;Evolution&lt;/a&gt; and most of my mailing list subscriptions run through a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Gmail&quot;&gt;Gmail&lt;/a&gt; account I have set aside for the very purpose.&lt;/p&gt;
&lt;p&gt;
I’m quite happy with Mutt for my main personal email. As I don’t use my personal email to subscribe to mailing lists the volume is low, it’s fairly quick and snappy to write email (in an emacsclient naturally) and searching is only a “/” away. However it is intrinsically a folder based email client which works fine as I only have two folders: Inbox and Oldmail. I periodically (~annually) move email into Oldmail when Mutt starts to slow down on start-up.&lt;/p&gt;
&lt;p&gt;
The main bugbear is my work email. I mainly run evolution through inertia and 2 features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It connects to the work Exchange server, although calendering doesn’t really work properly as I can’t Accept/Decline meeting invites.&lt;/li&gt;
&lt;li&gt;The vFolder concept allows me to easily separate company emails from the bug tracker and CVS commits and the odd work related mailing list while still offering a quick eyeball indication of what pending emails there are.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other than those features Evolution sucks balls in every other way. It takes an age to compose a new email, I have to shut it down every night to avoid swap death and it’s certainly not keyboard operable.&lt;/p&gt;
&lt;p&gt;
The GMail account I have to live with as there isn’t really anywhere else I can easily index and search the 4gb (and growing) of mailing lists I subscribe to. Of course it is accessible via IMAP so it would be nice if I could access it from the same client, especially as the web interface tends to munge in-line patches.&lt;/p&gt;
&lt;p&gt;
The obvious choice would be to look into one of the many many modes for handling email in emacs. However the plethora of choices is one that makes selecting one to try even harder. Some people at work have fetchmail tasks setup to mirror the email on the server which sounds a little clunky but I guess must work well enough. I don’t think it would be practical for Gmail though, I usually just browse through various tags for mailing lists, including the very handy ‘mythreads’ which marks any email list thread I’m involved in.&lt;/p&gt;
&lt;p&gt;
I think the key feature I need will be something like Evolutions vFolders for the quick eyeball along with a decent way to interact with Gmail. Any suggestions?&lt;/p&gt;</description>
         <author>Alex</author>
         <guid isPermaLink="false">http://www.bennee.com/~alex/blog/?p=1361</guid>
         <pubDate>Tue, 17 Nov 2009 04:49:55 -0800</pubDate>
      </item>
      <item>
         <title>Joseph Miklojcik: Lexical Analysis</title>
         <link>http://jfm3-repl.blogspot.com/2009/11/lexical-analysis.html</link>
         <description>Lexical analysis turns a stream of input characters into identifiable chunks; &quot;lexemes&quot;. For example the stream of input &quot;3&quot; should turn into the lexeme for the number three. Decisions about the syntax of a language must be made at the lexical level to disambiguate stream of input such as &lt;tt&gt;10E-6&lt;/tt&gt;. One language may intend for such a stream to mean a single number, namely ten times 10 to the power of negative six. Another may instead intend two numbers and a symbol; ten, E and negative six.&lt;br /&gt;&lt;br /&gt;The main decision in designing a lexical system is usually about how to divide lexemes into names, numeric literals, special punctuation, and comments. If the characters that can go in each of these categories do not overlap, separation between lexical elements can be more free in programs. If there are few restrictions on what goes in a name or numeric literal, then disambiguating them from their surroundings requires more care.&lt;br /&gt;&lt;br /&gt;For example, imagine language A has the lexical rules; &quot;names may consist only of letters&quot; and &quot;numbers may contain only decimal digits&quot;. More complicated numeric literals presumably are constructed using other language features. With these two lexical rules, we can give special lexical significance to single characters that can represent common arithmetic operations. &lt;tt&gt;a3&lt;/tt&gt; generates two lexemes, &lt;tt&gt;a&lt;/tt&gt; and &lt;tt&gt;3&lt;/tt&gt;. The program fragment &lt;tt&gt;a+3&lt;/tt&gt; is read as three lexemes. Programmers are free to use white space as they choose. Transitions between lexemes are accounted for entirely by the contents of the lexemes themselves, unless two numbers or two names occur in sequence.&lt;br /&gt;&lt;br /&gt;Now imagine a different language B, which has the lexical rules; &quot;names may consist of any characters other than white space&quot; and &quot;numbers are names which contain only decimal digits&quot;. Again, this glosses over more complex numeric literals. Under language B's lexical rules, the program fragment &lt;tt&gt;a+3&lt;/tt&gt; is a single lexeme (as is &lt;tt&gt;a3&lt;/tt&gt;). To generate three lexemes, the programmer must explicitly separate the lexical elements using white space; &lt;tt&gt;a + 3&lt;/tt&gt;. However, in this case &lt;tt&gt;+&lt;/tt&gt; need have no special significance. It can be a name like any other.&lt;br /&gt;&lt;br /&gt;A third general approach to lexical analysis could be characterized by a language C, which has more complicated lexical rules that describe when lexemes begin and when they end. Language C's rules are: a name begins with something that is not a digit, and ends when a space or special character is encountered. A number begins with something that is not a letter, and ends when a space or a special character is encountered. Such a lexical system interprets &lt;tt&gt;a+3&lt;/tt&gt; as three lexemes, but &lt;tt&gt;a3&lt;/tt&gt; as one.&lt;br /&gt;&lt;br /&gt;Languages A, B, and C as presented above are greatly simplified and gloss over a large number of important issues. But judging these rudimentary forms, it would seem that languages A and C have the preferable quality of doing the right thing if a programmer omits spaces, language C more so than language A. However, the more important question is, which of language A or B conforms more to how the human mind processes language? In my opinion, language B comes closer.&lt;br /&gt;&lt;br /&gt;In terms of orthography, we know that words are things human readers take in as units separated by spaces. The well known trick of changing the order of letters in words save for the first and last letter, and observing that such words are still somehow comprehensible, demonstrates this;&lt;br /&gt;&lt;br /&gt; &quot;Tihs is an eaxpmle of scuh a senetcne.&quot;&lt;br /&gt;&lt;br /&gt;Compare your ability to comprehend the above sentence to the one in which letters are all in the correct order, but spaces are omitted;&lt;br /&gt;&lt;br /&gt; &quot;Thisisanexampleofsuchasentence.&quot;&lt;br /&gt;&lt;br /&gt;The eye of a reader can go faster (and correct more errors) if lexemes that produce a sound when read aloud are separated by space. Demanding such separation in a programming language therefore makes it conform to the human eye. Most programming languages which allow a great deal of freedom in the omission of spaces between lexemes also have earnest style guides which encourage programmers to use spaces to separate the lexemes anyway.&lt;br /&gt;&lt;br /&gt;In terms of natural language, we chunk lexical elements from either language A or B into several utterable chunks, as in &quot;ey plus three&quot;, or &quot;ten times ten to the power of negative six&quot;. The amount of compression into the shorthand &lt;tt&gt;10E6&lt;/tt&gt; is similar in A, B, and C, whether we demand that it be written &lt;tt&gt;10 E 6&lt;/tt&gt; or not. Lexical issues in programming languages must focus more on making an unambiguous orthography than on, say, morphological rules in natural languages.&lt;br /&gt;&lt;br /&gt;The exception to the natural use of spaces to separate lexemes comes when we want to form compound names. Many natural languages allow putting multiple nouns together into a single word both in spoken and written form. Sometimes the programmer wants to name something with a single programming language lexeme that contains multiple names, for example, the fifth element of an array named &lt;tt&gt;R&lt;/tt&gt; might be &lt;tt&gt;R[5]&lt;/tt&gt;. It seems unnatural to write &lt;tt&gt;R [5]&lt;/tt&gt;, since we are naming one thing, just with compound terms.&lt;br /&gt;&lt;br /&gt;Rosebud defines several characters which can not go in names, including white space characters. Lexemes are separated by these characters. These include characters that are used to form compound names, and characters that indicate program structure. Except for white space, these single characters are all themselves lexemes. By convention, as in written English, a hyphen is used to construct names that are compound in meaning to the programmer, but singular in meaning to the author.&lt;br /&gt;&lt;br /&gt;Whether UTF-8 or UTF-16 would be a more compact encoding for Rosebud programs is impossible to say. UTF-8 eliminates byte ordering issues. So, Rosebud interprets its input as a stream of bytes in UTF-8. Rosebud has enough syntactic extension facilities so that if large amounts of data that would require three bytes in UTF-8 but only two in UTF-16 needed to live in program files, a UTF-16 encoding could be used for it.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/29447904-6986413027416672632?l=jfm3-repl.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>jfm3</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-29447904.post-6986413027416672632</guid>
         <pubDate>Sun, 15 Nov 2009 07:41:39 -0800</pubDate>
      </item>
      <item>
         <title>Joseph Miklojcik: jJava: a possible Phosphoros competitor?</title>
         <link>http://jfm3-repl.blogspot.com/2009/08/jjava-possible-phosphoros-competitor.html</link>
         <description>The Phosphoros team is uncertain as to whether or not &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://codetojoy.blogspot.com/2008/04/open-source-group-announces-jjava.html&quot;&gt;jJava&lt;/a&gt; is a serious competitor to our own offering. A well known member of the Lisp community and the Java specification team is sometime quoted as writing about Java:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;we were not out to win over the Lisp programmers; we were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;we fear that developments in the area of jJava will drag a lot of innocent programmers halfway back to C++. &lt;br /&gt;&lt;br /&gt;We are also curious to see how they will solve the Gosling Tarpit problem.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/29447904-8750570771010583593?l=jfm3-repl.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>jfm3</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-29447904.post-8750570771010583593</guid>
         <pubDate>Sun, 15 Nov 2009 07:32:42 -0800</pubDate>
      </item>
      <item>
         <title>Yann Hodique: https traffic logger</title>
         <link>http://www.hodique.info/blog/2009/11/15/https_traffic_logger</link>
         <description>&lt;div class=&quot;level1&quot;&gt;&lt;div class=&quot;styler styler-float-left&quot;&gt;
&lt;p&gt;
&lt;span class=&quot;vcard&quot;&gt;&lt;img src=&quot;http://www.hodique.info/lib/exe/fetch.php?cache=recache&amp;amp;media=http%3A%2F%2Fwww.gravatar.com%2Favatar.php%3Fgravatar_id%3Dd9b955e7af49b0cbfd68c15947b25012%26default%3Dhttp%253A%252F%252Fwww.hodique.info%252Flib%252Fexe%252Ffetch.php%253Fcache%253Drecache%2526media%253Dhttp%25253A%25252F%25252Fwww.hodique.info%25252F%25252Flib%25252Fplugins%25252Favatar%25252Fmonsterid.php%25253Fseed%25253Dd9b955e7af49b0cbfd68c15947b25012%252526size%25253D40%252526.png%26size%3D40%26rating%3DR%26.jpg&quot; title=&quot;yann.hodique@gmail.com&quot; height=&quot;40&quot; width=&quot;40&quot; alt=&quot;yann.hodique@gmail.com&quot; class=&quot;media photo fn&quot;/&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt; &lt;p&gt;
I'm currently writing a Simulator (really a mock) for some server, and more precisely for the SOAP interface it provides.
All traffic is done only in https, and for debug purpose I needed to dump traces of the communication between a client and the real WebService, to compare them with the communication I have between the same client and the fake WebService.
So here is a tiny script that acts as a proxy to unwrap/log/re-wrap SSL stuff.
&lt;/p&gt; &lt;p&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gist.github.com/224171&quot; class=&quot;urlextern&quot; title=&quot;http://gist.github.com/224171&quot;&gt;http://gist.github.com/224171&lt;/a&gt;
&lt;/p&gt; &lt;p&gt;
I have the feeling all this should be doable by using ncat only, but did not find how yet.
&lt;/p&gt; &lt;/div&gt;
&lt;span class=&quot;plugin_feedmod_comments&quot;&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.hodique.info/blog/2009/11/15/https_traffic_logger#discussion__section&quot; title=&quot;Read or add comments to this article&quot;&gt;Read or add comments to this article&lt;/a&gt;
&lt;/span&gt;</description>
         <author>Yann Hodique</author>
         <guid isPermaLink="false">http://www.hodique.info/blog/2009/11/15/https_traffic_logger</guid>
         <pubDate>Sun, 15 Nov 2009 03:21:51 -0800</pubDate>
      </item>
      <item>
         <title>Yann Hodique: s5 presentation from org-mode</title>
         <link>http://www.hodique.info/blog/2009/11/14/s5_presentation_from_org-mode</link>
         <description>&lt;div class=&quot;level1&quot;&gt;&lt;div class=&quot;styler styler-float-left&quot;&gt;
&lt;p&gt;
&lt;span class=&quot;vcard&quot;&gt;&lt;img src=&quot;http://www.hodique.info/lib/exe/fetch.php?cache=recache&amp;amp;media=http%3A%2F%2Fwww.gravatar.com%2Favatar.php%3Fgravatar_id%3Dd9b955e7af49b0cbfd68c15947b25012%26default%3Dhttp%253A%252F%252Fwww.hodique.info%252Flib%252Fexe%252Ffetch.php%253Fcache%253Drecache%2526media%253Dhttp%25253A%25252F%25252Fwww.hodique.info%25252F%25252Flib%25252Fplugins%25252Favatar%25252Fmonsterid.php%25253Fseed%25253Dd9b955e7af49b0cbfd68c15947b25012%252526size%25253D40%252526.png%26size%3D40%26rating%3DR%26.jpg&quot; title=&quot;yann.hodique@gmail.com&quot; height=&quot;40&quot; width=&quot;40&quot; alt=&quot;yann.hodique@gmail.com&quot; class=&quot;media photo fn&quot;/&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
Generating &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://meyerweb.com/eric/tools/s5/&quot; class=&quot;urlextern&quot; title=&quot;http://meyerweb.com/eric/tools/s5/&quot;&gt;S5&lt;/a&gt; based presentations from an &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://orgmode.org&quot; class=&quot;urlextern&quot; title=&quot;http://orgmode.org&quot;&gt;Org Mode&lt;/a&gt; file is something I've considered for a while.
I've just published some working code to do so: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/sigma/org-s5&quot; class=&quot;urlextern&quot; title=&quot;http://github.com/sigma/org-s5&quot;&gt;http://github.com/sigma/org-s5&lt;/a&gt;
The README file should give the basic steps to make it work.
&lt;/p&gt; &lt;p&gt;
Constraints I wanted to respect:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; no modification needed on Org-mode or S5&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; easy to reuse the glue across multiple presentations&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; adaptable enough to survive multiple S5 themes&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt; &lt;p&gt; This is probably far from being complete, but at least it's usable enough for me to do presentations at work.
&lt;/p&gt; &lt;p&gt;
Hope it can be useful for someone else.
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.hodique.info/tags/emacs&quot; class=&quot;wikilink1&quot; title=&quot;tags:emacs&quot;&gt;emacs&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt; &lt;/div&gt;
&lt;span class=&quot;plugin_feedmod_comments&quot;&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.hodique.info/blog/2009/11/14/s5_presentation_from_org-mode#discussion__section&quot; title=&quot;Read or add comments to this article&quot;&gt;Read or add comments to this article&lt;/a&gt;
&lt;/span&gt;</description>
         <author>Yann Hodique</author>
         <guid isPermaLink="false">http://www.hodique.info/blog/2009/11/14/s5_presentation_from_org-mode</guid>
         <pubDate>Sat, 14 Nov 2009 12:21:33 -0800</pubDate>
      </item>
      <item>
         <title>Thomas Kappler: Announcing md-readme</title>
         <link>http://jugglingbits.wordpress.com/2009/11/14/announcing-md-readme/</link>
         <description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;You can find quite a few &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/languages/Emacs%20Lisp&quot;&gt;Emacs libraries on github&lt;/a&gt; these days. I only have one very small project there, wpmail, which I haven’t written about yet because I want to finish the Markdown support first… anyway: something I find really neat on github is the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/guides/readme-formatting&quot;&gt;automatic display of the README file&lt;/a&gt; in the repository’s root directory, if it exists. Only, as we all know, writing READMEs is tedious and we’d rather spend our time programming. But wait: in the Emacs world, we’re actually writing a README for each project: the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.gnu.org/software/emacs/manual/html_node/elisp/Library-Headers.html#Library-Headers&quot;&gt;library headers&lt;/a&gt;. Their content and structure are rather clearly defined, and it’s expected for all Emacs libraries. So I had the idea of generating a nice, Markdown-formatted README.md for github from these headers.&lt;/p&gt;
&lt;p&gt;I just pushed the first version of &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/thomas11/md-readme&quot;&gt;md-readme&lt;/a&gt; that does just that. The README that you see on the github page is auto-generated from md-readme.el, with lists, code-block and everything.&lt;/p&gt;
&lt;p&gt;The conversion to Markdown is of course pretty simple, but even so it’s pretty cool to see how little code I had to write. Emacs provides everything out of the box. &lt;code&gt;(with-temp-file &quot;README.md&quot; (do-it))&lt;/code&gt; is just elegant.&lt;/p&gt;
&lt;p&gt;Now, seeing that we have code that generates a nice README from our Lisp file, it’s natural to have it run automatically so we always have an up-to-date README. Here I was struggling for a while. I had lots of ideas, but none seemed to work out. My current solution is setting a per-directory local variable for each of your ELisp projects that triggers the conversion via an after-save-hook. Code is in the README. The problem with adding the after-save-hook to all modes is that it’s evaluated all the time, for each save. Kinda annoying, even if it’s just a single condition.&lt;/p&gt;
&lt;p&gt;Does anyone have a better idea? Do it outside Emacs in a git pre-commit hook?&lt;/p&gt;
&lt;p&gt;But even with the current solution it works, and that’s the important part. Please try it, and enjoy your new READMEs.&lt;/p&gt;
Posted in Own Code Tagged: elisp, emacs, github, markdown, Own Code, readme &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/jugglingbits.wordpress.com/248/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/comments/jugglingbits.wordpress.com/248/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/jugglingbits.wordpress.com/248/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/delicious/jugglingbits.wordpress.com/248/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/jugglingbits.wordpress.com/248/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/stumble/jugglingbits.wordpress.com/248/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/jugglingbits.wordpress.com/248/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/digg/jugglingbits.wordpress.com/248/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/jugglingbits.wordpress.com/248/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/reddit/jugglingbits.wordpress.com/248/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;img src=&quot;http://stats.wordpress.com/b.gif?host=jugglingbits.wordpress.com&amp;amp;blog=6812373&amp;amp;post=248&amp;amp;subd=jugglingbits&amp;amp;ref=&amp;amp;feed=1&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/div&gt;</description>
         <author>thomas11</author>
         <guid isPermaLink="false">http://jugglingbits.wordpress.com/?p=248</guid>
         <pubDate>Sat, 14 Nov 2009 08:56:22 -0800</pubDate>
      </item>
      <item>
         <title>Justin Heyes-Jones: Transparent emacs on windows</title>
         <link>http://justinsboringpage.blogspot.com/2009/10/transparent-emacs-on-windows.html</link>
         <description>&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/_nkGbjVeC3i4/StQIyYwON5I/AAAAAAAADMc/lvO2Qo2ZidE/s1600-h/transparentemacs.png&quot;&gt;&lt;img src=&quot;http://2.bp.blogspot.com/_nkGbjVeC3i4/StQIyYwON5I/AAAAAAAADMc/lvO2Qo2ZidE/s320/transparentemacs.png&quot; alt=&quot;&quot; style=&quot;cursor:pointer;cursor:hand;width:320px;height:186px;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5391944315600517010&quot;/&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's a handy function which lets you choose a transparent level (0 is fully transparent and 100 is opaque), for the main emacs frame in both focused and unfocused state.&lt;/div&gt;&lt;pre style=&quot;font-family:Andale Mono, Lucida Console, Monaco, fixed, monospace;color:#000000;background-color:#eee;font-size:12px;border:1px dashed #999999;line-height:14px;padding:5px;overflow:auto;width:100%;&quot;&gt;&lt;code&gt;(defun transparent(alpha-level no-focus-alpha-level)&lt;br /&gt; &quot;Let's you make the window transparent&quot;&lt;br /&gt; (interactive &quot;nAlpha level (0-100): &amp;#92;nnNo focus alpha level (0-100): &quot;)&lt;br /&gt; (set-frame-parameter (selected-frame) 'alpha (list alpha-level no-focus-alpha-level))&lt;br /&gt; (add-to-list 'default-frame-alist `(alpha ,alpha-level)))&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;font-family:arial;&quot; class=&quot;Apple-style-span&quot;&gt;To run M-x transparent. &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot; class=&quot;Apple-style-span&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:arial;&quot; class=&quot;Apple-style-span&quot;&gt;Enter the values you want for when the window has focus and when it does not. &lt;/span&gt;In the background you can see system status information on the desktop, which is another excellent utility from sysinternals called &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://technet.microsoft.com/en-us/sysinternals/bb897557.aspx&quot;&gt;BgInfo&lt;/a&gt;. It let's you display useful info about your system right on your desktop, similar to tools you may find on linux. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/4777243148323391813-8882538686469456338?l=justinsboringpage.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>Justin</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4777243148323391813.post-8882538686469456338</guid>
         <pubDate>Fri, 13 Nov 2009 22:30:24 -0800</pubDate>
      </item>
      <item>
         <title>Phil Hagelberg: in which things are mapped, but also reduced</title>
         <link>http://technomancy.us/130</link>
         <description>&lt;p&gt;A while ago Tim Bray had a project called the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.tbray.org/ongoing/When/200x/2007/09/20/Wide-Finder&quot;&gt;Wide Finder&lt;/a&gt; to collect implementations of a log parsing problem in different languages to see which ones made it easy to take advantage of massively-parallel hardware. The idea is to accept a web server log file and return statistics for which pages have been requested the most. &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.tbray.org/ongoing/When/200x/2009/11/11/Clojure-References&quot;&gt;Yesterday&lt;/a&gt; he posted a follow-up in Clojure using refs.&lt;/p&gt; &lt;p&gt;While his version is interesting for someone just getting into the language because it uses refs (probably the sexiest piece of the language), I think a map/reduce approach is a little more idiomatic since it can be done with no explicit state change.&lt;/p&gt; &lt;p&gt;I'll step through &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://p.hagelb.org/wide_finder.clj.html&quot;&gt;my implementation&lt;/a&gt; piece-by-piece. Note that it is naïve and could be optimized for speed at the expense of straightfowardness, especially with regard to reading from disk; my intent here is simply to explain the functional approach.&lt;/p&gt; &lt;p&gt;&lt;b&gt;Update&lt;/b&gt;: Commenters have posted a version that totally smokes my agent-based implementation in terms of performance and simplicity. I'm leaving it up because I think it's a fun romp in the land of higher-order functions; if you think having higher-order functions means &quot;I can pass a block to &lt;code&gt;Array#map&lt;/code&gt; in Ruby&quot; then you're in for a treat.&lt;/p&gt; &lt;pre class=&quot;code&quot;&gt;&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;ns&lt;/span&gt; wide-finder &lt;span class=&quot;string&quot;&gt;&quot;A basic map/reduce approach to the wide finder using agents. Optimized for being idiomatic and readable rather than speed.&quot;&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;:use&lt;/span&gt; [clojure.contrib.duck-streams &lt;span class=&quot;builtin&quot;&gt;:only&lt;/span&gt; [reader]]&lt;span class=&quot;esk-paren&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt; &lt;p&gt;Every Clojure file opens with a call to the &lt;code&gt;ns&lt;/code&gt; macro. This defines a namespace (&lt;code&gt;wide-finder&lt;/code&gt;) and states any dependencies it may have on other namespaces, in this case the &lt;code&gt;reader&lt;/code&gt; function from the &lt;code&gt;duck-streams&lt;/code&gt; contrib library. Omitting the &lt;code&gt;:only&lt;/code&gt; clause would cause it to make all the &lt;code&gt;duck-streams&lt;/code&gt; vars available in this namespace, but it's usually better to be explicit about what you need.&lt;/p&gt; &lt;p&gt;We'll start with the entry point. The &lt;code&gt;find-widely&lt;/code&gt; function below takes a filename and a number of agents to work with. Agents can be thought of as independent asynchronous workers that share a thread pool and keep a single state value. They are initialized with the &lt;code&gt;agent&lt;/code&gt; function that takes a starting state. We'll be using each agent to keep a map of pages to hit counts, so we map this function over a list of &lt;code&gt;n&lt;/code&gt; empty maps generated by &lt;code&gt;repeat&lt;/code&gt; to get our list of initialized agents.&lt;/p&gt; &lt;pre class=&quot;code&quot;&gt;&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;find-widely&lt;/span&gt; [filename n] &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; [agents &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;map&lt;/span&gt; agent &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;repeat&lt;/span&gt; n {}&lt;span class=&quot;esk-paren&quot;&gt;))&lt;/span&gt;] &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;dorun&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;map&lt;/span&gt; #&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;send&lt;/span&gt; %1 count-line %2&lt;span class=&quot;esk-paren&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;cycle&lt;/span&gt; agents&lt;span class=&quot;esk-paren&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;line-seq&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;reader filename&lt;span class=&quot;esk-paren&quot;&gt;))))&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;doseq&lt;/span&gt; [a agents] &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;await a&lt;span class=&quot;esk-paren&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;apply&lt;/span&gt; merge-with + &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;map&lt;/span&gt; deref agents&lt;span class=&quot;esk-paren&quot;&gt;))))&lt;/span&gt;
&lt;/pre&gt; &lt;p&gt;Once the agents are initialized, we send them work. Our &lt;code&gt;line-seq&lt;/code&gt; sets up a lazy sequence of lines from the file. We map over this sequence together with an infinite loop of the &lt;code&gt;agents&lt;/code&gt; we construct using &lt;code&gt;cycle&lt;/code&gt;. The &lt;code&gt;map&lt;/code&gt; function can loop over multiple sequences in parallel and will stop when the shorter one runs out, so this is just a way of pairing each line in the file with an agent in a round-robin fashion.&lt;/p&gt; &lt;pre class=&quot;code&quot;&gt;&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;dorun&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;map&lt;/span&gt; #&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;send&lt;/span&gt; %1 count-line %2&lt;span class=&quot;esk-paren&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;cycle&lt;/span&gt; agents&lt;span class=&quot;esk-paren&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;line-seq&lt;/span&gt; &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;reader filename&lt;span class=&quot;esk-paren&quot;&gt;))))&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;The code that does the mapping is the anonymous function &lt;code&gt;#(send %1 count-line %2)&lt;/code&gt;, which adds a call to the &lt;code&gt;count-line&lt;/code&gt; function to the agent's internal queue. This could be written in more traditional lambda form as &lt;code&gt;(fn [a line] (send a count-line line)&lt;/code&gt;; the &lt;code&gt;#()&lt;/code&gt; form is simply shorthand. The &lt;code&gt;count-line&lt;/code&gt; function will be called with two arguments: the agent's current value and the next line in the seq. That function will return a new value for the agent.&lt;/p&gt; &lt;pre class=&quot;code&quot;&gt;&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;doseq&lt;/span&gt; [a agents] &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;await a&lt;span class=&quot;esk-paren&quot;&gt;))&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;Once all the work has been queued up, it's necessary to call &lt;code&gt;await&lt;/code&gt; on each agent to make sure it has a chance to finish its queue. If we used &lt;code&gt;map&lt;/code&gt; here, it would be a no-op, since &lt;code&gt;map&lt;/code&gt; merely creates a lazy sequence; it does not actually perform the function calls until the value is needed. Since it's not in the tail-call position, the value would simply be discarded. Note that the same problem would occur in the previous call to map, but wrapping it in a &lt;code&gt;dorun&lt;/code&gt; call forces the lazy seq to be evaluated.&lt;/p&gt; &lt;pre class=&quot;code&quot;&gt;&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;apply&lt;/span&gt; merge-with + &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;map&lt;/span&gt; deref agents&lt;span class=&quot;esk-paren&quot;&gt;))&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;Once that's done we can call &lt;code&gt;deref&lt;/code&gt; on each agent to get its value. But this gives us &lt;code&gt;n&lt;/code&gt; maps rather than a list of totals, so we need to merge the values. &lt;code&gt;merge-with&lt;/code&gt; is a special case of &lt;code&gt;reduce&lt;/code&gt; that assumes it works on a sequence of maps and merges key collisions using the provided function, in this case &lt;code&gt;+&lt;/code&gt;. This gives us a map of page names to hit counts.&lt;/p&gt; &lt;pre class=&quot;code&quot;&gt;&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;count-line&lt;/span&gt; [counts line] &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;if-let&lt;/span&gt; [[_ hit] &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;re-find&lt;/span&gt; #&lt;span class=&quot;string&quot;&gt;&quot;GET /(&amp;#92;d+) &quot;&lt;/span&gt; line&lt;span class=&quot;esk-paren&quot;&gt;)&lt;/span&gt;] &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;update-in counts [hit] inc-or-init&lt;span class=&quot;esk-paren&quot;&gt;)&lt;/span&gt; counts&lt;span class=&quot;esk-paren&quot;&gt;))&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;Finally we have the function that actually performs the counting. As mentioned, it takes an agent's state (which is the current map of pages to hits) and a line from the log file. If the line matches the regex &lt;code&gt;#&quot;GET /(&amp;#92;d+) &quot;&lt;/code&gt;, then we return an updated version of the &lt;code&gt;counts&lt;/code&gt; map that increments the entry corresponding to the hit. The other interesting thing here is that &lt;code&gt;if-let&lt;/code&gt; uses &lt;em&gt;destructuring&lt;/em&gt;: by binding the return value of &lt;code&gt;re-find&lt;/code&gt; to a vector form, it splits the value in two. The first element (the full matched string) is bound to the unused &lt;code&gt;_&lt;/code&gt; local, and the second element (the match group corresponding to the actual page path) is bound to &lt;code&gt;hit&lt;/code&gt;.&lt;/p&gt; &lt;pre class=&quot;code&quot;&gt;&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;inc-or-init&lt;/span&gt; [i] &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; i &lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;inc&lt;/span&gt; i&lt;span class=&quot;esk-paren&quot;&gt;)&lt;/span&gt; 1&lt;span class=&quot;esk-paren&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt; &lt;p&gt;The only piece left is the tiny &lt;code&gt;inc-or-init&lt;/code&gt; function that increments the counter given it but treats nil as zero. This would be unnecessary if we could construct hash-maps with custom default values, which a perusal of the implementation of PersistentHashMap.java seems to indicate is supported, though it's not exposed anywhere through a Clojure function. This is the piece of the puzzle that I'm the least happy with, but it may be possible to eliminate it.&lt;/p&gt; &lt;p&gt;In any case, this is a simple example of how to break up a commonplace problem using a classic map/reduce strategy and immutable data structures. I have no idea how it compares in terms of performance to the other Wide Finder implementations since the logs I have for this site are not exactly the hundred-megabyte blockbuster kind of logs that &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://tbray.org/ongoing&quot;&gt;ongoing&lt;/a&gt; enjoys, but the fact that it can be parallelized in twelve lines is a testament to the expressiveness of the language.&lt;/p&gt;</description>
         <author>Phil Hagelberg</author>
         <guid isPermaLink="false">tag:technomancy.us,2007:in%20which%20things%20are%20mapped,%20but%20also%20reduced</guid>
         <pubDate>Fri, 13 Nov 2009 12:29:30 -0800</pubDate>
      </item>
      <item>
         <title>Emacs-fu: copying lines without selecting them</title>
         <link>http://emacs-fu.blogspot.com/2009/11/copying-lines-without-selecting-them.html</link>
         <description>&lt;div id=&quot;outline-container-1&quot; class=&quot;outline-2&quot;&gt;
&lt;div id=&quot;text-1&quot; class=&quot;outline-text-2&quot;&gt; &lt;p&gt;
When I'm programming, I often need to copy a line. Normally, this requires me
to first select ('mark') the line I want to copy. That does not seem like a
big deal, but when I'm in the 'flow' I want to avoid any little obstacle that
can slow me down.
&lt;/p&gt;
&lt;p&gt;
So, how can I copy the current line without selection? I found a nice trick by
&lt;i&gt;MacChan&lt;/i&gt; on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.emacswiki.org/emacs/SlickCopy&quot;&gt;EmacsWiki&lt;/a&gt; to accomplish this. It also adds ta function to kill
(cut) the current line (similar to &lt;code&gt;kill-line&lt;/code&gt; (&lt;code&gt;C-k&lt;/code&gt;), but kills the whole
line, not just from point (cursor) to the end.
&lt;/p&gt;
&lt;p&gt;
The code below simply embellishes the normal functions with the functionality
'if nothing is selected, assume we mean the current line'. The key bindings
stay the same (&lt;code&gt;M-w&lt;/code&gt;, &lt;code&gt;C-w&lt;/code&gt;).
&lt;/p&gt;
&lt;p&gt;
To enable this, put the following in your &lt;code&gt;.emacs&lt;/code&gt;:
&lt;/p&gt; &lt;pre class=&quot;src src-emacs-lisp&quot;&gt;(&lt;span class=&quot;org-keyword&quot;&gt;defadvice&lt;/span&gt; &lt;span class=&quot;org-function-name&quot;&gt;kill-ring-save&lt;/span&gt; (before slick-copy activate compile) &lt;span class=&quot;org-doc&quot;&gt;&quot;When called interactively with no active region, copy a single line instead.&quot;&lt;/span&gt; (interactive (&lt;span class=&quot;org-keyword&quot;&gt;if&lt;/span&gt; mark-active (list (region-beginning) (region-end)) (message &lt;span class=&quot;org-string&quot;&gt;&quot;Copied line&quot;&lt;/span&gt;) (list (line-beginning-position) (line-beginning-position 2))))) (&lt;span class=&quot;org-keyword&quot;&gt;defadvice&lt;/span&gt; &lt;span class=&quot;org-function-name&quot;&gt;kill-region&lt;/span&gt; (before slick-cut activate compile) &lt;span class=&quot;org-doc&quot;&gt;&quot;When called interactively with no active region, kill a single line instead.&quot;&lt;/span&gt; (interactive (&lt;span class=&quot;org-keyword&quot;&gt;if&lt;/span&gt; mark-active (list (region-beginning) (region-end)) (list (line-beginning-position) (line-beginning-position 2)))))
&lt;/pre&gt; &lt;p&gt;
It also shows the power of Emacs-Lisp with the &lt;code&gt;defadvice&lt;/code&gt;-macro – see the
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.gnu.org/software/emacs/elisp/html_node/Advising-Functions.html&quot;&gt;fine documentation&lt;/a&gt;. Using &lt;code&gt;defadvice&lt;/code&gt;, you can 'decorate' any function with
your own modifications. This great power should be used with caution, of
course, as to not break other usage that assumes the undecorated versions. In
this case, that seem unlikely. And note that the 'advise' only applies when
the functions are called interactively.
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/3992530807750384868-7902853816255222152?l=emacs-fu.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>djcb</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3992530807750384868.post-7902853816255222152</guid>
         <pubDate>Thu, 12 Nov 2009 11:27:32 -0800</pubDate>
      </item>
      <item>
         <title>Flickr tag 'emacs': Tidy up clojure code in TextMate</title>
         <link>http://www.flickr.com/photos/manjilab/4097992719/</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.flickr.com/people/manjilab/&quot;&gt;manjilab&lt;/a&gt; posted a photo:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.flickr.com/photos/manjilab/4097992719/&quot; title=&quot;Tidy up clojure code in TextMate&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2773/4097992719_044a7e2e8a_m.jpg&quot; alt=&quot;Tidy up clojure code in TextMate&quot; height=&quot;166&quot; width=&quot;240&quot;/&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Indentation of Textmate (for Lisp/Clojure) is poor.&lt;br /&gt;
&lt;br /&gt;
This is how to tidy up your code with emacs-style indentation.&lt;/p&gt;</description>
         <author>manjilab</author>
         <guid isPermaLink="false">tag:flickr.com,2004:/photo/4097992719</guid>
         <pubDate>Thu, 12 Nov 2009 09:31:27 -0800</pubDate>
      </item>
      <item>
         <title>Flickr tag 'emacs': Tidy up clojure code in TextMate</title>
         <link>http://www.flickr.com/photos/manjilab/4098724850/</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.flickr.com/people/manjilab/&quot;&gt;manjilab&lt;/a&gt; posted a photo:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.flickr.com/photos/manjilab/4098724850/&quot; title=&quot;Tidy up clojure code in TextMate&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2562/4098724850_6a1fc3f9bd_m.jpg&quot; alt=&quot;Tidy up clojure code in TextMate&quot; height=&quot;172&quot; width=&quot;240&quot;/&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Indentation of Textmate (for Lisp/Clojure) is poor.&lt;br /&gt;
&lt;br /&gt;
This is how to tidy up your code with emacs-style indentation.&lt;/p&gt;</description>
         <author>manjilab</author>
         <guid isPermaLink="false">tag:flickr.com,2004:/photo/4098724850</guid>
         <pubDate>Thu, 12 Nov 2009 09:19:14 -0800</pubDate>
      </item>
      <item>
         <title>Bryan Murdock: I Got a Mac</title>
         <link>http://bryan-murdock.blogspot.com/2009/11/i-got-mac.html</link>
         <description>&lt;p&gt;My employer just supplied me with a MacBook Pro running OS X Version 10.6.1 (is that a little redundant?). For a long time I have eyed macs with wary suspicion, but with a lot of curiosity too. If Microsoft is evil, as some like to say, because it locks customers in to its proprietary software, Apple must be at least twice as evil. They lock customers in to their software *and* hardware! I kind of like the new laptop, though. Mechanically, it's awesome. The aluminum body feels nice and solid. The lid doesn't latch when it closes, it just kind of (magnetically?) holds to the body. The buttons and USB slots and everything are also very nicely done. The display is one of those glossy ones for &quot;brighter colors&quot; and I hate the glare. The user interface has me all confused with buttons and menus in places I'm not used to. It has this fancy new mouse trackpad that is huge and it lest you do multi-finger stuff kind of like an iPhone (which I don't have). That's all going to take some getting used to also.&lt;/p&gt; &lt;p&gt;The biggest thing that surprised was the childhood memories that it evoked. The first computer I ever used was a Mac. Grandpa is a chemical engineer, and he recognized right away how useful personal computers would be. He had a Mac Classic in his den and he would let me play with it all I wanted when I came to visit. MacPaint was about all I could do with it when I was 5 years old, but I moved the mouse and clicked on things, pushed a floppy disk into its drive and then drug the icon to the trash to eject it, and poked around at whatever I could. On this new laptop when I first saw the little mouse pointer turn to the text entry icon, the same icon that the Mac classic used, all the memories of that Mac Classic in Grandpa's den came back. There are a few other subtle little things, like the apple menu, that give me a little bit of nostalgic joy every time I encounter them as well. It's very cool that Apple has kept some things the same over all those years. Apple can't be totally evil, right?&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/3669809752172683097-8747735772236867509?l=bryan-murdock.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>Bryan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3669809752172683097.post-8747735772236867509</guid>
         <pubDate>Wed, 11 Nov 2009 11:58:11 -0800</pubDate>
      </item>
      <item>
         <title>Got Emacs?: Another Day, Another Language: Go: From Google</title>
         <link>http://emacsworld.blogspot.com/2009/11/another-day-another-language-go-from.html</link>
         <description>&lt;div&gt;From &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://lwn.net/Articles/361390/&quot;&gt;LWN&lt;/a&gt;, I learnt that Google has released a new systems language because....nothing had been done in that area for some time.&lt;br /&gt;&lt;br /&gt;So, we have &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://golang.org/&quot;&gt;Go&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After you've gone through the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://golang.org/doc/go_faq.html&quot;&gt;FAQs&lt;/a&gt;, which I strongly suggest you do, as it contains interesting pointers on the whys and whats of this language, one has this nagging feeling ....&lt;br /&gt;&lt;br /&gt;Exactly what issue are they addressing and for whom? It's there in the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://golang.org/doc/go_faq.html&quot;&gt;FAQ &lt;/a&gt;but are YOU convinced?&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img src=&quot;http://img.zemanta.com/pixy.gif?x-id=e6d87889-c1ab-88b3-b97a-270c5c3c51d6&quot; alt=&quot;&quot; class=&quot;zemanta-pixie-img&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/tracker/3165518189103293420-6802411821482653422?l=emacsworld.blogspot.com&quot; alt=&quot;&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;&lt;/div&gt;</description>
         <author>sivaram</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3165518189103293420.post-6802411821482653422</guid>
         <pubDate>Wed, 11 Nov 2009 09:19:24 -0800</pubDate>
      </item>
      <item>
         <title>Phil Jackson: A Magit clone</title>
         <link>http://www.shellarchive.co.uk/2009-11-08-a-magit-clone.html</link>
         <description>&lt;p&gt;I’ve got a clone of Magit which I’ve been hacking away at. It’s
mostly a bunch of git-svn fixes/features as that’s what I use for
work but there’s some other stuff that might be of interest. It
includes the following branches (all merged into their master at
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gitorious.org/~philjackson/magit/philjacksons-reclone&quot;&gt;gitorious&lt;/a&gt;):&lt;/p&gt;
&lt;dl&gt; &lt;dt&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gitorious.org/~philjackson/magit/philjacksons-reclone/commits/fancier-diffs&quot;&gt;fancier-diffs&lt;/a&gt;&lt;/dt&gt; &lt;dd&gt;Some basic
highlighting of the commit sha and of the diff markers (just the
diff markers, not the whole line).&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl&gt; &lt;dt&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gitorious.org/~philjackson/magit/philjacksons-reclone/commits/fancy-log-pt1&quot;&gt;fancy-log-pt1&lt;/a&gt;&lt;/dt&gt; &lt;dd&gt;Some new
faces for the log buffer: magit-log-graph, magit-log-sha1,
magit-log-message, magit-log-head-label-remote,
magit-log-head-label-tags and magit-log-head-label-local. They should
give a clue as to what this branch is for…&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl&gt; &lt;dt&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gitorious.org/~philjackson/magit/philjacksons-reclone/commits/git-svn-fixes-and-features&quot;&gt;fancy-log-pt1&lt;/a&gt;&lt;/dt&gt; &lt;dd&gt;Basically
makes git-svn work again.&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl&gt; &lt;dt&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gitorious.org/~philjackson/magit/philjacksons-reclone/commits/squashable-merges&quot;&gt;squashable-merges&lt;/a&gt;&lt;/dt&gt; &lt;dd&gt;Giving
a prefix arg to magit-merge will allow you to squash it
(handy for git-svn if your colleagues aren’t used to seeing lots of
commits in trunk).&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl&gt; &lt;dt&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gitorious.org/~philjackson/magit/philjacksons-reclone/commits/magit-completing-read&quot;&gt;magit-completing-read&lt;/a&gt;&lt;/dt&gt; &lt;dd&gt;Lets
you use anything-completing-read or ido-completing-read for…
completion.&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl&gt; &lt;dt&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gitorious.org/~philjackson/magit/philjacksons-reclone/commits/svn-find-rev&quot;&gt;svn-find-rev&lt;/a&gt;&lt;/dt&gt; &lt;dd&gt;Hitting N f
with prompt for an &lt;span class=&quot;caps&quot;&gt;SVN&lt;/span&gt; revision and give you the commit if it’s in
the current branch. With a prefix arg you will be prompted for a
branch in which to look.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Like I said, all of the above is in master so you can just &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gitorious.org/~philjackson/magit/philjacksons-reclone/blobs/raw/master/magit.el&quot;&gt;download
magit.el from there&lt;/a&gt; and
you’ll get it all.&lt;/p&gt;</description>
         <author>Phil Jackson</author>
         <guid isPermaLink="false">http://www.shellarchive.co.uk/2009-11-08-a-magit-clone.html</guid>
         <pubDate>Sun, 08 Nov 2009 10:55:46 -0800</pubDate>
      </item>
      <item>
         <title>Matt Keller: Switching to Atom from RSS</title>
         <link>http://www.littleredbat.net/mk/blog/story/80/</link>
         <description>&lt;p&gt;I've added an &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.littleredbat.net/mk/blog/atom.xml&quot;&gt;Atom feed&lt;/a&gt; for this
blog that carries complete xHTML content. The &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.littleredbat.net/mk/blog/feed.xml&quot;&gt;old RSS feed&lt;/a&gt; carries just simple
text. I'll leave the RSS feed in place for the time being, but I
will likely pull the plug on it in the future.&lt;/p&gt; &lt;p&gt;I've also created an Atom feed that carries just my &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.littleredbat.net/mk/blog/atom-emacs.xml&quot;&gt;Emacs-related content&lt;/a&gt;. This
might be useful for anyone following &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.littleredbat.net/mk/code/mk-project.html&quot;&gt;mk-project&lt;/a&gt; happenings.&lt;/p&gt; &lt;p&gt;Both feeds should be auto-discoverable by your browser.&lt;/p&gt; &lt;p&gt;--Matt&lt;/p&gt;</description>
         <author>Matt Keller</author>
         <guid isPermaLink="false">urn:uuid:6186BE8F-A4AF-3520-BFC0-42491CE1EA95</guid>
         <pubDate>Sun, 08 Nov 2009 03:43:19 -0800</pubDate>
      </item>
      <item>
         <title>Thomas Kappler: Now focus!</title>
         <link>http://jugglingbits.wordpress.com/2009/11/06/now-focus/</link>
         <description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;I’m having fun with this bit of Emacs Lisp that turns your current buffer in a fullscreen, minimal, no-frills frame a la &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.hogbaysoftware.com/products/writeroom&quot;&gt;Writeroom&lt;/a&gt;. I got it from the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.emacswiki.org/emacs/WriteRoom&quot;&gt;EmacsWiki&lt;/a&gt; and made a few small modifications.&lt;/p&gt;
&lt;p&gt;Now, whenever you feel distracted, tell your Emacs (and thus yourself, as Emacs is a direct extension of your brain): &lt;code&gt;now-focus!&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
(defun now-focus! () &quot;Open the current buffer in a frame without any bling.&quot; (interactive) ;; to restore: ;; (setq mode-line-format (default-value 'mode-line-format)) (let ((frame (nowfocus-make-minimal-frame))) (select-frame frame) (setq mode-line-format nil) ;; for Windows, untested (when (fboundp 'w32-send-sys-command) (w32-send-sys-command 61488 frame)))) (defun nowfocus-make-minimal-frame () (make-frame '((minibuffer . nil) (vertical-scroll-bars . nil) (left-fringe . 0) (right-fringe . 0) (border-width . 0) (internal-border-width . 64) ; whitespace! (cursor-type . box) (menu-bar-lines . 0) (tool-bar-lines . 0) (fullscreen . fullboth) (unsplittable . t))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you’d like some more options, turn to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://bitbucket.org/phromo/darkroom-mode/overview/&quot;&gt;darkroom-mode&lt;/a&gt;.&lt;/p&gt;
Posted in Stuff Tagged: elisp, emacs, programming, Stuff &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/jugglingbits.wordpress.com/238/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/comments/jugglingbits.wordpress.com/238/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/jugglingbits.wordpress.com/238/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/delicious/jugglingbits.wordpress.com/238/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/jugglingbits.wordpress.com/238/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/stumble/jugglingbits.wordpress.com/238/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/jugglingbits.wordpress.com/238/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/digg/jugglingbits.wordpress.com/238/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/jugglingbits.wordpress.com/238/&quot;&gt;&lt;img src=&quot;http://feeds.wordpress.com/1.0/reddit/jugglingbits.wordpress.com/238/&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/a&gt; &lt;img src=&quot;http://stats.wordpress.com/b.gif?host=jugglingbits.wordpress.com&amp;amp;blog=6812373&amp;amp;post=238&amp;amp;subd=jugglingbits&amp;amp;ref=&amp;amp;feed=1&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/div&gt;</description>
         <author>thomas11</author>
         <guid isPermaLink="false">http://jugglingbits.wordpress.com/?p=238</guid>
         <pubDate>Fri, 06 Nov 2009 13:45:06 -0800</pubDate>
      </item>
      <item>
         <title>@emacs: emacs: Happy 3 years of Planet Emacsen! http://planet.emacsen.org/</title>
         <link>http://twitter.com/emacs/statuses/5430846002</link>
         <description>emacs: Happy 3 years of Planet Emacsen! http://planet.emacsen.org/</description>
         <author>@emacs</author>
         <guid isPermaLink="false">http://twitter.com/emacs/statuses/5430846002</guid>
         <pubDate>Wed, 04 Nov 2009 13:27:58 -0800</pubDate>
      </item>
      <item>
         <title>Edward O'Connor: &lt;img src=&quot;http://planet.emacsen.org/E-flag01.png&quot; alt=&quot;Planet Emacsen&quot;/&gt;</title>
         <link>http://edward.oconnor.cx/2009/11/planet-emacsen-turns-3</link>
         <description>&lt;p&gt;I &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://edward.oconnor.cx/2006/10/planet-emacsen&quot;&gt;launched&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://planet.emacsen.org/&quot;&gt;Planet Emacsen&lt;/a&gt; three years (and five days) ago. Since then I’ve enjoyed reading all sorts of interesting things about how other people live in Emacs, and I hope you have too! &lt;/p&gt; &lt;p&gt; If you’d like me to add your Emacs feed to Planet Emacsen, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;mailto:hober0@gmail.com&quot;&gt;send me an email&lt;/a&gt; and I’ll get right on it. &lt;/p&gt;</description>
         <author>Edward O’Connor</author>
         <guid isPermaLink="false">tag:edward.oconnor.cx,2009-11-04:planet-emacsen-turns-3</guid>
         <pubDate>Wed, 04 Nov 2009 08:50:27 -0800</pubDate>
      </item>
      <item>
         <title>Nathaniel Flath: Java and C++ Utilities</title>
         <link>http://nflath.com/2009/11/java-and-c-utilities/</link>
         <description>&lt;p&gt;I’ve been working on some utilities for coding in Java. JDE and CEDET ground my emacs to a halt the last time I tried them, so I wanted something lightweight. So far, I mostly have some functions for looking up documentation - including c++ documentation - that I store locally on my computer and keep in a repository, but I also have a few utilities for auto-importing Java classes.&lt;/p&gt;
&lt;p&gt;The utilities to follow need these macros defined. I talked about them previously at:&lt;br /&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://nflath.com/2009/08/emacs-timing-and-upgrades/&quot;&gt;http://nflath.com/2009/08/emacs-timing-and-upgrades/&lt;/a&gt;. They are utilities for generating functions that take arguments defaulting to word at point.&lt;/p&gt; &lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre style=&quot;font-family:monospace;&quot; class=&quot;lisp&quot;&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;defun&lt;/span&gt; my-fn &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;fn prompt&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;When given a function taking one argument and applying a function to it, will use that function and default to the word at point, with a prompt including that word.&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;default &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;current-word&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;needle &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;read-string &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;concat prompt &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot; &amp;lt;&quot;&lt;/span&gt; default &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;&amp;gt;: &quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;equal&lt;/span&gt; needle &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;funcall&lt;/span&gt; fn default&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;funcall&lt;/span&gt; fn needle&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;defmacro&lt;/span&gt; defun-my &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;name&lt;/span&gt; prompt &lt;span style=&quot;color:#66cc66;&quot;&gt;&amp;amp;&lt;/span&gt;rest body&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Will define both a function and a my- version of the function,
which defaults to the word at point.&quot;&lt;/span&gt; `&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;progn&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;defun&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;name&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;arg&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;,&lt;/span&gt;@body&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;defun&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;intern&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;concat &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;my-&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;symbol-&lt;span style=&quot;color:#b1b100;&quot;&gt;name&lt;/span&gt; &lt;span style=&quot;color:#b1b100;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;interactive&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;my-fn &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;quote&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;,&lt;/span&gt;prompt&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;p&gt;These functions will be used in some of the later functions I wrote. These are used for caching large directory structures in a buffer to search for files instead of parsing the output of ‘find’ each time. Specifically, I use these to quickly look up which file I should be referencing to view documentation on Java and C++ classes. create-file-list will just create a list of files in the given buffer, and find-location-for-doc-from-buffer will return the full path of the matching html file you are searching for. Java-find-html-for-class is just a helper function that fills in the arguments for find-location-for-doc-from-buffer for Java buffers.&lt;/p&gt; &lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre style=&quot;font-family:monospace;&quot; class=&quot;lisp&quot;&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;defun&lt;/span&gt; create-file-&lt;span style=&quot;color:#b1b100;&quot;&gt;list&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;directory buffer&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Creates the list of files in a directory&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;save-window-excursion &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;default-directory directory&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;shell-command &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;find . &quot;&lt;/span&gt; buffer&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;switch-to-buffer buffer&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;flush-lines &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;.&lt;/span&gt;svn&quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;flush-lines &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;class-use&quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;defun&lt;/span&gt; find-location-for-doc-from-buffer &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;arg buffer-&lt;span style=&quot;color:#b1b100;&quot;&gt;name&lt;/span&gt; buffer-creation-fn begin&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Finds the file for a given documentation name in the buffer
that may be created with buffer-creation&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;save-excursion &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;save-window-excursion &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;doc-buffer &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;or&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;get-buffer buffer-&lt;span style=&quot;color:#b1b100;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;funcall&lt;/span&gt; buffer-creation-fn&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;switch-to-buffer doc-buffer&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;goto-char &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;point-&lt;span style=&quot;color:#b1b100;&quot;&gt;min&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;while &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;not&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;line-matches &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;concat &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;/&quot;&lt;/span&gt; arg &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;.&lt;/span&gt;html&quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;search-forward arg&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;concat begin &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;buffer-substring &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#cc66cc;&quot;&gt;1&lt;/span&gt;+ &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;line-beginning-position&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;line-end-position&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;p&gt;These next functions are used to look up documentation. my-java-describe-class will open up documentation for the input class file, whereas java-describe-variable will take a variable name and look backwards to it’s declaration and find documentation for that class. c-search-docs does something similar; it will prompt you for a keyword and see if anything in my c++ documentation matches it.&lt;/p&gt; &lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre style=&quot;font-family:monospace;&quot; class=&quot;lisp&quot;&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;defun-my java-describe-class &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Open Javadoc for Class&quot;&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Loads javadoc for specified class in your browser.&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;interactive &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;MClass Name: &quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;browse-url &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;java-find-html-for-class arg&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;defun-my java-describe-variable &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Open Javadoc for Variable&quot;&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Opens the javadoc for the variable at point, if possible.&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;interactive&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;save-excursion &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;re-search-backward &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;concat &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;[ &lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;t&lt;/span&gt;&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;n&lt;/span&gt;]&quot;&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;[A-Za-z]+&quot;&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;&amp;lt;[][A-Za-z0-9&amp;lt;&amp;gt;]*&amp;gt;&quot;&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;[ &lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;t&lt;/span&gt;&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;n&lt;/span&gt;]&quot;&lt;/span&gt; arg&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;forward-char&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;java-describe-class &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;current-word&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;defun-my c-search-docs &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Documentation For&quot;&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Searches C++ Documentation for the requested term&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;browse-url &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;find-location-for-doc-from-buffer arg &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;*C Documentation*&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;lambda&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;create-file-&lt;span style=&quot;color:#b1b100;&quot;&gt;list&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;~/.emacs.d/documentation/c++/&quot;&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;*C Documentation*&quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;~/.emacs.d/documentation/c++/&quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;p&gt;Another task that I frequently have to do is fix imports in Java classes. Doing this manually is a huge pain, so I wrote a few functions to help. my-java-import-class will prompt for a class, look up it’s full package name, and add the import to the top of your file. Java-get-undefined-classes will run compile-command and parse the output to add all unimported classes. This needs java-undefined-symbol-regexp to be defined correctly, as well as compile-command to be set to something like ‘javac filename’.&lt;/p&gt; &lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre style=&quot;font-family:monospace;&quot; class=&quot;lisp&quot;&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;defun-my java-import-class &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Import Class&quot;&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;Adds an import statement for the class at point.&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;save-excursion &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;my-retn-&lt;span style=&quot;color:#b1b100;&quot;&gt;value&lt;/span&gt; &lt;span style=&quot;color:#b1b100;&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;my-string &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;java-find-html-for-class arg&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;find-file my-string&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;end-of-buffer&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;re-search-backward &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;&quot;&lt;/span&gt;&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;([A-Za-z0-9]+&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;.&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;)+[A-Za-z0-9]+ [ci][ln][at][se][sr]&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;start &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;point&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;re-search-forward &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;setq&lt;/span&gt; my-retn-&lt;span style=&quot;color:#b1b100;&quot;&gt;value&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;substring &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;buffer-string&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; start &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;- &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;point&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#cc66cc;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;kill-buffer &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;current-buffer&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;beginning-of-buffer&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;re-search-forward &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;import &quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;point-&lt;span style=&quot;color:#b1b100;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; t&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;beginning-of-line&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;when&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;looking-at &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;import&quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;end-of-line&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;newline&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;insert &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;import &quot;&lt;/span&gt; my-retn-&lt;span style=&quot;color:#b1b100;&quot;&gt;value&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;;&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;n&lt;/span&gt;&quot;&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;defvar java-undefined-symbol-regexp &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;symbol : class &lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;([A-Za-z0-9]*&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;&amp;#92;&lt;/span&gt;)&quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;defun&lt;/span&gt; java-get-undefined-class-names &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;interactive&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;save-window-excursion &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;remove-&lt;span style=&quot;color:#b1b100;&quot;&gt;if&lt;/span&gt; #'&lt;span style=&quot;color:#b1b100;&quot;&gt;not&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;remove-duplicates &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;mapcar&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;lambda&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;x&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;string-match java-undefined-symbol-regexp x&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;match-string &lt;span style=&quot;color:#cc66cc;&quot;&gt;1&lt;/span&gt; x&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;split-string &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;shell-command-to-string compile-command&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;&quot;&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;n&lt;/span&gt; *^&lt;span style=&quot;color:#000099;font-weight:bold;&quot;&gt;&amp;#92;n&lt;/span&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#555;&quot;&gt;test&lt;/span&gt; #'string-&lt;span style=&quot;color:#b1b100;&quot;&gt;equal&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;defun&lt;/span&gt; java-import-undefined-classes &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;interactive&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;save-window-excursion &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#b1b100;&quot;&gt;mapc&lt;/span&gt; #'java-import-class &lt;span style=&quot;color:#66cc66;&quot;&gt;(&lt;/span&gt;java-get-undefined-class-names&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#66cc66;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</description>
         <author>nflath</author>
         <guid isPermaLink="false">http://nflath.com/?p=467</guid>
         <pubDate>Wed, 04 Nov 2009 07:42:42 -0800</pubDate>
      </item>
      <item>
         <title>Alex Bennée: Avoiding RSI one keypress at a time</title>
         <link>http://www.bennee.com/~alex/blog/2009/11/04/avoiding-rsi-one-keypress-at-a-time/</link>
         <description>&lt;p&gt;Much as I love emacs some of the key combinations it expects of you to a) remember b) use are don’t help when your trying to ameliorate the effects of RSI. As I spend an lot of time in compilation mode the following quick win helps:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre style=&quot;color:#f5deb3;background-color:#2f4f4f;font-size:8pt;&quot;&gt;(define-key compilation-mode-map (kbd &lt;span style=&quot;color:#ffa07a;&quot;&gt;&quot;n&quot;&lt;/span&gt;) 'compilation-next-error)
(define-key compilation-mode-map (kbd &lt;span style=&quot;color:#ffa07a;&quot;&gt;&quot;p&quot;&lt;/span&gt;) 'compilation-previous-error)
&lt;/pre&gt;
&lt;p&gt;
If you try executing (self-insert-command) the buffer would complain it’s read-only anyway. I took this single keypress approach to the next level when I was doing a lot of patch merging and &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/stsquad/my-emacs-stuff/blob/master/my-diff-mode.el&quot;&gt;tweaked diff-mode&lt;/a&gt; to be a little less multi-finger.&lt;/p&gt;</description>
         <author>Alex</author>
         <guid isPermaLink="false">http://www.bennee.com/~alex/blog/?p=1320</guid>
         <pubDate>Wed, 04 Nov 2009 03:04:38 -0800</pubDate>
      </item>
      <item>
         <title>Back from vacation</title>
         <link>http://bc.tech.coop/blog/090925.html</link>
         <description>I just got back from a 2-week vacation, so I've been busy catching up on things.</description>
         <guid isPermaLink="false"></guid>
         <pubDate>Sun, 27 Sep 2009 22:28:02 -0700</pubDate>
      </item>
      <item>
         <title>Xcode Requirement for iPhone OS 3.0.1</title>
         <link>http://bc.tech.coop/blog/090731.html</link>
         <description>I've just updated my iPhone OS to 3.0.1 (it's a security upgrade to fix the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.forbes.com/2009/07/28/hackers-iphone-apple-technology-security-hackers.html&quot;&gt; iPhone SMS vulnerability that was recently announced&lt;/a&gt;) and found that I could no longer build/install development apps on my iPhone. A bit of searching uncovered this Apple advisory:&lt;br /&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://adcdownload.apple.com/iphone/iphone_sdk_3.0__final/iphone_os_3.0.1_advisory.pdf&quot;&gt; http://adcdownload.apple.com/iphone/iphone_sdk_3.0__final/iphone_os_3.0.1_advisory.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt; So, if you plan to install iPhone OS 3.0.1 on an iPhone that you use for iPhone app development, you'll need to follow the instructions in the advisory. Note that the terminal command that is described in the advisory is one long line, not 2 lines.</description>
         <guid isPermaLink="false"></guid>
         <pubDate>Fri, 31 Jul 2009 14:20:15 -0700</pubDate>
      </item>
      <item>
         <title>HebrewBible App Store Rankings</title>
         <link>http://bc.tech.coop/blog/090721.html</link>
         <description>I use a variety of different tools to measure how my &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sites.google.com/site/hebrewsoftware/&quot;&gt; HebrewBible iPhone App&lt;/a&gt; is doing. With the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://bc.tech.coop/blog/090717.html&quot;&gt; latest 2.0 version&lt;/a&gt; of the app, it has now moved into the top 100 of the &quot;Reference&quot; app category in both the USA and France (the top markets for the app). The following &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://majicjungle.com/majicrank.html&quot;&gt; MajicRank&lt;/a&gt; graph illustrates the current rankings:&lt;br /&gt;&lt;br /&gt; &lt;img src=&quot;http://bc.tech.coop/blog/images/majicrank.jpg&quot; alt=&quot;MajicRank rating&quot;/&gt;&lt;br /&gt;&lt;br /&gt; Woohoo!&lt;br /&gt;&lt;br /&gt; &lt;b&gt;Update-2009-07-28:&lt;/b&gt; After 1 week, the app's performance in both the USA and France has improved even more and I've broken into the top 100 for another &quot;Big Eight&quot; country - Canada!:&lt;br /&gt;&lt;br /&gt; &lt;img src=&quot;http://bc.tech.coop/blog/images/majicrank1.jpg&quot; alt=&quot;MajicRank rating&quot;/&gt;&lt;br /&gt;&lt;br /&gt; Woohoo, Woohoo!</description>
         <guid isPermaLink="false"></guid>
         <pubDate>Tue, 28 Jul 2009 12:39:03 -0700</pubDate>
      </item>
      <item>
         <title>New Version of Hebrew Bible iPhone App Available</title>
         <link>http://bc.tech.coop/blog/090717.html</link>
         <description>Today, Apple approved Version 2.0 of my &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sites.google.com/site/hebrewsoftware/&quot;&gt; Hebrew Bible iPhone application&lt;/a&gt;. In addition to providing 8 different versions of the Hebrew Bible (which can either be read online with no content stored on the iPhone or cached locally for off-network reading) and Hebrew word lookup/lexicon, this version includes links to over 200 Wikipedia articles and provides Google Maps of over 1,000 locations.&lt;br /&gt;&lt;br /&gt; &lt;img src=&quot;http://sites.google.com/site/hebrewsoftware/_/rsrc/1247861497558/images/bible1.png&quot; alt=&quot;Hebrew/English version&quot;/&gt;&amp;nbsp;&amp;nbsp;&lt;img src=&quot;http://sites.google.com/site/hebrewsoftware/_/rsrc/1247861497558/images/topic1.png&quot; alt=&quot;Hebrew/English version&quot;/&gt;&amp;nbsp;&amp;nbsp;&lt;img src=&quot;http://sites.google.com/site/hebrewsoftware/_/rsrc/1247861497558/images/map2.png&quot; alt=&quot;Hebrew/English version&quot;/&gt;&lt;br /&gt;&lt;br /&gt; Apple made me change the rating of the app to &quot;17+&quot; to indicate that there are &quot;Frequent/Intense&quot; types of &quot;Mature/Suggestive Themes&quot;. Their reasoning for this was:&lt;blockquote&gt; &quot;Our review indicates that the application content is not consistent with the current rating. HebrewBible allows unfiltered access to wikipedia.org, where content with mature or suggestive themes can be accessed.&quot;&lt;/blockquote&gt; Come on guys, you've got to be kidding - give me a break! Hmm, a rating of &quot;17+&quot; seems to boost sales of certain movies - maybe I can expect a sudden spike in downloads now! ;-)</description>
         <guid isPermaLink="false"></guid>
         <pubDate>Sat, 18 Jul 2009 18:47:07 -0700</pubDate>
      </item>
      <item>
         <title>Good thing I got my iPhone 3GS last week</title>
         <link>http://bc.tech.coop/blog/090629.html</link>
         <description>It looks like Rogers is all sold out of all models of the iPhone 3GS throughout Canada. Good thing I got mine last week - I've been really pleased by how much better the user experience is with the 3GS over my old iPhone 3G. The features I find most compelling are:&lt;ul&gt; &lt;li&gt;Speed: The increase in processor speed (600MHz CPU as opposed to the 412MHz iPhone 3G) and RAM (256 MB vs 128MB on the iPhone 3G) make a HUGE difference. &lt;/li&gt; &lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gizmodo.com/5302097/giz-bill-nye-explains-the-iphone-3gss-oleophobic-screen&quot;&gt; Oleophobic Screen&lt;/a&gt;: The yucky fingerprint-covered screen of the iPhone 3G is now a thing of the past. The new iPhone's screen coating is the secret and it makes a big difference in the visual appeal of the display.&lt;/li&gt; &lt;li&gt;Video and Camera: The video camera was a nice additon; however, the camera has improved significantly as well. The camera is now 3 megapixels (vs 2 megapixels in the 3G) and both video and camera have geotagging, autofocus, and tap-to-focus functionality. I rarely used the camera on the 3G because of the poor picture quality but I can see myself using the 3GS camera a lot. &lt;/li&gt; &lt;li&gt;Magnetometer: This is most visible in the new Compass app that comes with the 3GS. However, the more useful application of the direction-awareness provided by the magnetometer is in the Maps app. If you press the &quot;location&quot; icon in the bottom-left of the Maps app, it displays your current location (as it did with the iPhone 3G). However, if you press it a second time, the map reorients itself to the direction you're facing and the blue location dot displays a &quot;flashlight&quot; to illustrate the direction you're heading. Very useful when you're in an unfamiliar neighborhood!&lt;/li&gt; &lt;/ul&gt; &lt;img src=&quot;http://bc.tech.coop/blog/images/rogers3gs.jpg&quot; alt=&quot;Rogers iPhone 3GS&quot;/&gt;</description>
         <guid isPermaLink="false"></guid>
         <pubDate>Mon, 29 Jun 2009 16:00:25 -0700</pubDate>
      </item>
      <item>
         <title>New iPhone + New Apple Developer Provisioning Profile</title>
         <link>http://bc.tech.coop/blog/090621.html</link>
         <description>Yesterday, I took some time off from the nice weather and gardening tasks to go out and get a new iPhone 3GS. First off, let me say that the speed difference is really great! I've only played around with a few of the new features (such as the video camera and compass), but the speed increase is a huge plus. Today, I got around to creating a new developer profile for my new iPhone 3GS. My old iPhone was having some problems a few months ago and Apple replaced it, so I remembered the hassles I had then setting up a new provisioning profile for the replacement device (this seems to be a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.google.com/search?client=safari&amp;rls=en-us&amp;q=apple+provisioning+profile&amp;ie=UTF-8&amp;oe=UTF-8&quot;&gt; common iPhone developer complaint&lt;/a&gt;). I had similar problems this time with the 3GS, so I've decided to note down all the things that I did to get it setup properly. Hopefully, this will help someone else (or, at least, it might remind me of the necessary steps the next time I have to do it!). Not all these steps may be necessary (and it's probably a lot easier if you're just adding a device to an existing profile rather than replacing a provisioning profile); however, I wanted to make sure I knew all the steps this time and it's what worked for me!&lt;br /&gt;&lt;br /&gt; When you upgrade to a new device, you need to do the following:&lt;br /&gt;&lt;br /&gt; In Apple's iPhone Developer Program Program Portal:&lt;ol&gt; &lt;li&gt;Create a new provisioning profile for the device&lt;/li&gt; &lt;li&gt;Set up a new device profile&lt;/li&gt; &lt;li&gt;Download the new provisioning profile to the Desktop&lt;/li&gt; &lt;/ol&gt; On the Mac:&lt;ol&gt; &lt;li&gt;Delete the old provisioning profile from ~/Library/MobileDevice/Provisioning Profiles/&lt;/li&gt; &lt;li&gt;Drag the new provisioning profile from the Desktop into ~/Library/MobileDevice/Provisioning Profiles/&lt;/li&gt; &lt;/ol&gt; In the Organizer window in Xcode:&lt;ol&gt; &lt;li&gt;Click on the device (in the left-hand pane)&lt;/li&gt; &lt;li&gt;Drag the new provisioning profile into the &quot;Provisioning&quot; box&lt;/li&gt; &lt;li&gt;Click on the &quot;Provisioning Profiles&quot; (in the left-hand pane)&lt;/li&gt; &lt;li&gt;Double-click on the new profile name (in the top pane) - it should appear in the &quot;Included Devices&quot; bottom pane with an &quot;Installed&quot; status&lt;/li&gt; &lt;li&gt;Close the Organizer window&lt;/li&gt; &lt;li&gt;Press the Xcode/Empty Caches... menu option&lt;/li&gt; &lt;li&gt;Close Xcode&lt;/li&gt; &lt;/ol&gt; On the Mac and iPhone:&lt;ol&gt; &lt;li&gt;Power off both the Mac and the iPhone &lt;/li&gt; &lt;li&gt;Power on both the Mac and the iPhone&lt;/li&gt; &lt;li&gt;Attach the iPhone to the Mac&lt;/li&gt; &lt;/ol&gt; For each project you previously built with the old provisioning profile:&lt;ol&gt; &lt;li&gt;Right-click on the [projectname].xcodeproj file and select &quot;Show Package Contents&quot;&lt;/li&gt; &lt;li&gt;Make a backup copy of the project.pbxproj file&lt;/li&gt; &lt;li&gt;Use a text editor (I used Emacs) to edit the project.pbxproj file:&lt;ol&gt; &lt;li&gt;Delete any lines that have the key CODE_SIGN_IDENTITY&lt;/li&gt; &lt;li&gt;Delete any lines that have the key PROVISIONING_PROFILE&lt;/li&gt; &lt;li&gt;Delete any lines that have the key &quot;CODE_SIGN_IDENTITY[sdk=iphoneos*]&quot;&lt;/li&gt; &lt;li&gt;Delete any lines that have the key &quot;PROVISIONING_PROFILE[sdk=iphoneos*]&quot;&lt;/li&gt; &lt;/ol&gt;&lt;/li&gt; &lt;/ol&gt; In Xcode, for each project you previously built with the old provisioning profile:&lt;ol&gt; &lt;li&gt;Open the project&lt;/li&gt; &lt;li&gt;Press the Build/Clean All Targets menu option&lt;/li&gt; &lt;li&gt;Press the Project/Edit Project Settings menu option&lt;/li&gt; &lt;li&gt;On the Build tab under &quot;All Configurations&quot;, chage the &quot;Code Signing Identity&quot; value to iPhone Developer&lt;/li&gt; &lt;li&gt;On the Xcode dropdown menu, select to build on the Device &lt;/li&gt; &lt;li&gt;Press the Build/Build and Run menu option (the application should build and load on the device)&lt;/li&gt; &lt;/ol&gt; That's what worked for me. If anyone has an easier/alternative approach, let me know and I'll publish relevant comments in updates to this post.</description>
         <guid isPermaLink="false"></guid>
         <pubDate>Sun, 21 Jun 2009 21:54:27 -0700</pubDate>
      </item>
      <item>
         <title>Twin Cities Lisp Group Inaugural Meeting</title>
         <link>http://bc.tech.coop/blog/090508.html</link>
         <description>Two years ago, Robert Goldman &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://bc.tech.coop/blog/070712.html&quot;&gt; gave a presentation&lt;/a&gt; to our Vancouver lispvan group. I'm pleased to note that he's decided to start up his own Lisp User Group in Minneapolis. Here are the details of their upcoming inaugural meeting:&lt;blockquote&gt;&lt;em&gt; &lt;center&gt;TWIN CITIES LISP GROUP INAUGURAL MEETING&lt;/center&gt; &lt;center&gt;9 June 2009, 6:00 PM - 8:00 PM CDT&lt;/center&gt; &lt;center&gt;Common Roots Cafe&lt;/center&gt; &lt;center&gt;Corner of 26th and Lyndale, Minneapolis, MN&lt;/center&gt; &lt;center&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://preview.tinyurl.com/tclisp-crc&quot;&gt; http://preview.tinyurl.com/tclisp-crc&lt;/a&gt;&lt;/center&gt; &lt;center&gt;Temporary web page: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://rpgoldman.real-time.com/tc-lisp.html&quot;&gt; http://rpgoldman.real-time.com/tc-lisp.html&lt;/a&gt;&lt;/center&gt; &lt;br /&gt; There's a lisp renaissance out there, spurred by the availability of several high-quality open source Common Lisp implementations (SBCL, CMUCL, Clozure CL, and CLISP, at least). After attending the 2009 International Lisp Conference in Cambridge (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.international-lisp-conference.org/2009/index&quot;&gt; http://www.international-lisp-conference.org/2009/index&lt;/a&gt;) I was fired up to see if we could share in some of this renaissance here in the Twin Cities.&lt;br /&gt; &lt;br /&gt; I was also inspired by visiting with the Vancouver Lisp group, Lispvan. They meet roughly monthly at some location offering coffee, beer, and wine, where they have a talk and some mingling. &lt;br /&gt; &lt;br /&gt; In the interests of setting up something like this here, I've (well, Josh Hamell did all the real work) set up a mailman mailing list, tc-lispers (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sift.info/mailman/listinfo/tc-lispers_sift.info&quot;&gt; http://sift.info/mailman/listinfo/tc-lispers_sift.info&lt;/a&gt;), and I've reserved the meeting room at Common Roots Cafe (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.commonrootscafe.com/ourcommunity.htm&quot;&gt; http://www.commonrootscafe.com/ourcommunity.htm&lt;/a&gt;), which offers the aforementioned coffee, beer, and wine (and tasty food --- vegetarian is available and there seem to be at least some vegan options).&lt;br /&gt; &lt;br /&gt; At the first meeting John Maraist will talk about the NST unit testing framework for Common Lisp, which he has been developing at SIFT (abstract follows). Then we can plan a next meeting, chat, mingle, and swap stories. Share and learn the latest Lisp applications, techniques, packages, and implementations. Show off your lambda tattoos, evil hacks, and wigflip graphics.&lt;br /&gt; &lt;br /&gt; Please come if you can and, whether you can or not, please sign up for the tc-lispers mailing list.&lt;br /&gt; &lt;br /&gt; Best,&lt;br /&gt; &lt;br /&gt; Robert Goldman&lt;br /&gt; &lt;center&gt;NST: A Unit Test Framework for Common Lisp&lt;/center&gt; &lt;br /&gt; In this talk we will introduce the Lisp unit test framework NST. SIFT developed NST for internal use on a number of ongoing Lisp projects, and we believe that the system is now mature enough to release more broadly. In this talk we will review the notion of a unit test, and introduce the use of NST in Lisp project development. NST's implementation makes interesting use of a number of Lisp features --- macro expansion, compile-time execution, metaobject protocols --- and we will discuss its current implementation as well as the lessons we learned along the way.&lt;/em&gt;&lt;/blockquote&gt; If you will be in the Twin Cities area on June 9, be sure to attend this new user group meeting. Best wishes to Robert and all the other Twin Cities lispers! By the way, if anyone else is inspired to start a new Lisp User Group, you might want to read my &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://bc.tech.coop/blog/071030.html&quot;&gt; &quot;How to start a Lisp User Group&quot;&lt;/a&gt; blog post. I've tried to summarize my experiences in that post.</description>
         <guid isPermaLink="false"></guid>
         <pubDate>Fri, 08 May 2009 11:53:01 -0700</pubDate>
      </item>
   </channel>
</rss>
<!-- fe7.pipes.sp1.yahoo.com uncompressed/chunked Sun Nov 22 03:30:41 PST 2009 -->
