tag:blogger.com,1999:blog-51355172024-03-14T00:09:29.709-07:00Making it stick."I have a mind like a steel... uh... thingy." Patrick Logan's weblog.Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.comBlogger2267125tag:blogger.com,1999:blog-5135517.post-43627438290191950152011-12-07T15:06:00.001-08:002011-12-07T16:05:11.010-08:00Calling Prolog from Java with Prolog Cafe<p>A couple two, three more details from yesterday's post. The first is how to establish the package name for a Prolog source file being compiled to Java:<br />
<p>Simply put the following at the top of the Prolog source:<br />
<p><code><br />
:- package 'com.example.foo'.<br />
</code><br />
<p>Now, calling predicates from Java: each predicate and arity is compiled from Prolog to its own Java class. For example the following Prolog source:<br />
<p><code><br />
<pre>main :-
queens(8, Qs), write(Qs), nl, fail.
queens(N,Qs) :-
range(1,N,Ns),
queens(Ns,[],Qs).
queens([],Qs,Qs).
queens(UnplacedQs,SafeQs,Qs) :-
select(UnplacedQs,UnplacedQs1,Q),
not_attack(SafeQs,Q),
queens(UnplacedQs1,[Q|SafeQs],Qs).
%% ...and so on.
</pre></code><br />
<p>If you omit the package name then the package defaults to "user" and the compiler creates a "user" directory for the Java source. Otherwise the Java files will be placed in a nested source tree corresponding to the package name you've defined.<br />
<p>The section of code above defines three predicates: <br />
<ul><li><code>main/0</code> is compiled to a class named PRED_main_0 (i.e. a class for a predicate with no arguments, "arity zero")</li>
<li><code>queens/2</code> is compiled to a class named PRED_queens_2 (i.e. a class for the two-argument predicate, "arity two")</li>
<li><code>queens/3</code> is compiled to a class named PRED_queens_3 (i.e. a class for the three-argument predicate, "arity three")</li>
</ul><p>These predicates can be called from Java using the Prolog Cafe API. The predicate <code>main/0</code> will display the results to standard output using the <code>write/1</code> and <code>nl/0</code> predicates which write a given term and write a newline, respectively. Running that predicate was illustrated in yesterday's post.<br />
<p>If you want to find the values of the logic variables given in a goal, then the Java would look something like:<br />
<p><code><br />
<pre>IntegerTerm eight = new IntegerTerm(8);
VariableTerm solution = new VariableTerm();
PRED_queens_2 queens = new PRED_queens_2(eight, solution, Failure.FAILURE);
BlockingPrologControl prolog = new BlockingPrologControl();
prolog.setPredicate(queens);
StringBuffer buf = new StringBuffer();
for (boolean r = prolog.call(); r; r = prolog.redo()) {
buf.append("A solution: " + solution + "\n");
}
queens_solutions = buf.toString();
</pre></code><br />
<p>This Java code creates an instance of the <code>queens/2</code> predicate corresponding to the following Prolog: <code>queens(8, Qs), fail.</code><br />
<p>Constructors for a predicate instance require a "continuation" argument. Lacking no other interesting continuation, the default choice is <code>Failure.FAILURE</code>, a built-in predicate telling the search to backtrack for further solutions.<br />
<p>The <code>IntegerTerm eight</code> is a constant, telling the application to try to place eight queens. And the <code>VariableTerm</code> is a logic variable telling the application to unify found solutions with this variable.<br />
<p><code>BlockingPrologControl</code> is going to conduct the search to satisfy its given predicate. The <code>call</code> method tries to find a solution, and returns <code>true</code> if it does. Subsequent calls to <code>redo</code> try to find further solutions, finally returning <code>false</code> when no more solutions exist.<br />
<p>The loop iterates once per solution. With each iteration the value of the logic variable, <code>solution</code>, is unified with the current solution. This code simply builds a string of all of the solutions, and I happened to use just one logic variable in the goal.<br />
<p>If you're not (yet) a Prolog programmer, note that a clause can have any number of variables, and the search will attempt to satisfy each of them so that the whole solution is true. Given the following definition of <code>append/3</code>, in which the third term is logically equated to the first term appended to the second term:<br />
<p><code><br />
<pre>append([X|Y],Z,[X|W]) :- append(Y,Z,W).
append([],X,X).
</pre></code><br />
<p>The following goal will attempt to find values for each of the variables such that the two appends are satisfied:<br />
<p><code><br />
append([N], [Y, Z], [X, 2, 3]), append([3], [2, 1], [3, 2, N]).<br />
</code><br />
<p>There is one solution:<br />
<p><code><br />
<pre>N = 1,
Y = 2,
Z = 3,
X = 1
</pre></code><br />
See that the variables <code>N</code> and <code>X</code> are unified to each other, and unified to the number 1 as well.<br />
<p>Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-19784627130570378992011-12-06T12:09:00.001-08:002011-12-06T12:26:47.670-08:00Prolog in Java<p>There are a number of implementations of Prolog in Java. Most of them are interpreters, and a number of those implement a complete Prolog system. Most implementations are a bit dated.<br />
<p>Wanting to get a bit more speed but remain in the JVM, I took a <a href="http://kaminari.istc.kobe-u.ac.jp/PrologCafe/">look at Prolog Cafe</a>, which compiles Prolog to Java source. Even better, the source is as recent as 2009.<br />
<p>Then I looked around to see who might be using Prolog Cafe, and how recently. Even better news: <a href="http://code.google.com/p/gerrit/">The Gerrit code review system</a> uses Prolog Cafe for rule checking. The team has been <a href="http://code.google.com/p/prolog-cafe/">actively supporting a fork</a> off the last original release of 1.2.5.<br />
<p>I just began trying Prolog Cafe (the new fork) this morning. The most significant difference so far is the Java package namespace. Below are a few notes illustrating the system, based off <a href="http://kaminari.istc.kobe-u.ac.jp/PrologCafe/manual_en.html">the original documentation</a>, using the new namespace, etc.<br />
<p><ol><li>Install SWI Prolog for bootstrapping.</li>
<li>cd to the prolog-cafe source directory.</li>
<li>make</li>
</ol><p>The package namespace has changed from<br />
<code>jp.ac.kobe_u.cs.prolog.*</code><br />
to: <code>com.googlecode.prolog_cafe.*</code>.<br />
<p>Prolog Cafe has an interpreter. Try it:<br />
<p><code><br />
<pre>java -cp $PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.lang.PrologMain com.googlecode.prolog_cafe.builtin:cafeteria
Prolog Cafe 1.2.5 (mantis)
Copyright(C) 1997-2009 M.Banbara and N.Tamura
| ?- [queens].
{consulting /home/patrick/dev/prolog-cafe-ex/queens.pl ...}
{/home/patrick/dev/prolog-cafe-ex/queens.pl consulted 350 msec}
| ?- main.
[4,2,7,3,6,8,5,1]
[5,2,4,7,3,8,6,1]
[3,5,2,8,6,4,7,1]
[3,6,4,2,8,5,7,1]
...
</pre></code><br />
<p>Compile Prolog to Java:<br />
<p><code><br />
java -cp $PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.compiler.Compiler ../queens.pl<br />
</code><br />
<p>Compile the resulting Java:<br />
<p><code><br />
javac -d . -cp $PLCAFEDIR/plcafe.jar user/*.java<br />
</code><br />
<p>Run the compiled code:<br />
<p><code><br />
<pre>java -cp .:$PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.lang.PrologMain com.googlecode.prolog_cafe.builtin:cafeteria
Prolog Cafe 1.2.5 (mantis)
Copyright(C) 1997-2009 M.Banbara and N.Tamura
| ?- main.
[4,2,7,3,6,8,5,1]
[5,2,4,7,3,8,6,1]
[3,5,2,8,6,4,7,1]
[3,6,4,2,8,5,7,1]
[5,7,1,3,8,6,4,2]
[4,6,8,3,1,7,5,2]
[3,6,8,1,4,7,5,2]
[5,3,8,4,7,1,6,2]
[5,7,4,1,3,8,6,2]
[4,1,5,8,6,3,7,2]
...
</pre></code><br />Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com5tag:blogger.com,1999:blog-5135517.post-30269773597652129192011-08-27T13:47:00.000-07:002011-08-27T13:59:20.583-07:00The Relative Coordinate Systems of Cappuccino's CPView<p>
Cappuccino's Objective-J API is based on the Objective-C source for NeXTStep. NextStep was developed at NeXT in the 1980's. At that time it was considered the premier GUI programming API. As it happens the corresponding Cappuccino API should be considered the premier browser-based, "rich", "single-page app", whathaveyou, programming API.
<p>
I added <a href="https://github.com/patrickdlogan/cappex">a simple example to github</a> which illustrates how easy it is to create multiple subdivided views that resize appropriately as the browser window resizes. Or you could use HTML5/CSS3 and write "puns" to trick the web page layout model into behaving like a window system. I find the straightforward approach significantly more productive.
<p>
The best way to solve a complex programming problem is to address simpler problems that add up. The nested views with relative coordinate systems goes back to something like the beginning of computer graphics. Complex layouts become simple combinations of much simpler layouts.
<p>
I'm putting most of my exposition in the README.org and jotting about updates on <a href="http://subjot.com/jot/22272">subjot, e.g. this one</a>, or watch the github repository itself.
Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-71197891087652912782011-08-23T10:31:00.000-07:002011-08-23T10:35:16.152-07:00Objective-J Exuberant Ctags Regex<p>
The following does a decent job of indexing Objective-J source using <a href="http://ctags.sourceforge.net/">Exuberant Ctags</a> (a ctags/etags replacement with a lot of features). Based on <a href="http://www.gregsexton.org/2011/04/objective-c-exuberant-ctags-regex/">Greg Sexton's regexps for Objective-C</a>.
<p>
<code>
<pre>
--langdef=objj
--langmap=objj:.j
--regex-objj=/^[[:space:]]*[-+][[:space:]]*\([[:alpha:]]+[[:space:]]*\*?\)[[:space:]]*([[:alnum:]]+):[[:space:]]*\(/\1/m,method/
--regex-objj=/^[[:space:]]*[-+][[:space:]]*\([[:alpha:]]+[[:space:]]*\*?\)[[:space:]]*([[:alnum:]]+)[[:space:]]*\{/\1/m,method/
--regex-objj=/^[[:space:]]*[-+][[:space:]]*\([[:alpha:]]+[[:space:]]*\*?\)[[:space:]]*([[:alnum:]]+)[[:space:]]*\;/\1/m,method/
--regex-objj=/^[[:space:]]*\@implementation[[:space:]]+(.*)$/\1/c,class/
</pre>
</code>
Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-33208885922484762092011-08-21T16:26:00.000-07:002011-08-21T18:32:40.916-07:00Double Dispatch In Objective-J<p>
My previous post describes a controller for separating an
application's model from Cappuccino's <code>CPOutlineView</code>. But
there's actually one place where the model and view kind of meet up:
<p>
<code>
<pre>
- (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item
{
return (nil == item) ? @"" : [item objectValueForOutlineColumn: tableColumn];
}
</pre>
</code>
<p>
I decided to have the controller give a model class access to a
column, which is part of the view. Why?
<p>
This example has four kinds of columns and three kinds of model
classes. Each column wants to display each kind of model element
differently. One obvious solution is to use a conditional expression:
<p>
<q>if the column is a ... and the model element is a ... then ...</q>
<p>
But even simple object-oriented languages like Objective-J have easy
mechanisms and patterns for reducing the need to test objects for
their class or whether they implement some specific message. Going way
back in Smalltalk lore, <a href="http://en.wikipedia.org/wiki/Double_dispatch">there's Double Dispatch</a>.
<p>
The goal is to reveal to a column the presentation object to use in
each of its rows. To do so, the column
view, <code>CPTableColumn</code>, is subclassed for each kind of
column in the example's outline:
<ul>
<li><code>SDNavigationColumn</code></li>
<li><code>SDTopicColumn</code></li>
<li><code>SDNotesColumn</code></li>
<li><code>SDDateColumn</code></li>
</ul>
<p>
Each of these subclasses implements the following methods:
<ul>
<li><code>objectValueForTopLevel:</code></li>
<li><code>objectValueForPriority:</code></li>
<li><code>objectValueForStuff:</code></li>
</ul>
<p>
Each of the model classes
implements <code>objectValueForOutlineColumn:</code> by sending one of
the above messages to the given column. For
example, <code>SDStuff</code> is implemented as follows:
<p>
<code>
<pre>
- (id)objectValueForOutlineColumn:(id)anOutlineColumn
{
return [anOutlineColumn objectValueForStuff: self];
}
</pre>
</code>
<p>
This dispatches right back ("double dispatch") to have the column respond with the awareness that it is on a row for detailed stuff. Each
column will be interested in different aspects of the stuff. The
navigation column is only interested in hierarchy and not
details. Here is its implementation, which just returns the empty
string to indicate its disinterest:
<p>
<code>
<pre>
- (id)objectValueForStuff:(SDStuff)aStuff
{
return "";
}
</pre>
</code>
<p>
On the other hand the date column is interested in a presentation of
the given date:
<p>
<code>
<pre>
- (id)objectValueForStuff:(SDStuff)aStuff
{
return [[[aStuff date] description] substringToIndex: 10];
}
</pre>
</code>
<p>
Although this kind of brings the model and the view together, the
names could be refactored because there is nothing really
"column-specific" about this mini-protocol. Also Objective-J has
"categories" for grouping methods. The intent of this protocol could
be explained by placing the methods in a "presenting" category.
<p>
There are certainly more elaborate mechanisms available for keeping
views and models separated, yet in-sync. <a href="http://en.wikipedia.org/wiki/Double_dispatch">Double Dispatch is just a simple one</a> for
reducing the need to test for classes and messages before sending
them.
Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-26514530675534329362011-08-21T13:45:00.000-07:002011-08-21T15:31:07.181-07:00Programming with Cappuccino's CPOutlineView<p>
I wrote in <a href="http://patricklogan.blogspot.com/2011/08/on-cappuccino-and-avoiding-modern.html">my recent post on Cappuccino</a> about the OK but not great
state of documentation. My learning process has been smooth though. I
have always had a sense of moving forward with little frustration. But
I should attempt to fill some of the documentation gaps myself.
<p>
I recently wanted to understand how to program outline views, but ran
into some of those gaps. And so my second blog post of the day begins
like so.
<p>
<code>CPOutlineView</code> is a subclass of <code>CPTableView</code>
however from the code using an outline, the requirements are
different. Rather than providing a two-dimensional array of data, an
application has to provide more of a hierarchy of two-dimensional
data. The way I achieve this in my first example is through defining a
new class, an <code>SDOutlineController</code>.
<p>
(Don't worry about "SD" - that's just the class prefix I am
using. Class prefixes are a convention going way back with NeXTStep
and before that Smalltalk. Presumably Javascript itself will adopt a
conventional if not standard namespace mechanism, and Objective-J can
piggyback on that. But I digress...)
<p>
This example outline has two groups at the top level: "my stuff" and
"other's stuff". Each top-level group has three second-level groups of
priorities: "high", "medium", and "low". The third level of the
outline are the lists of stuff, themselves. These are arrays of
instances of <code>SDStuff</code>.
<p>
Here's the class definition for stuff with instance variables for a
date, a topic, and notes:
<code>
<pre>
@implementation SDStuff : CPObject
{
CPDate date @accessors(readonly);
CPString topic @accessors(readonly);
CPString notes @accessors(readonly);
}
</pre>
</code>
<p>
This is Objective-J, a superset of Javascript. I'm assuming that's
fairly readable even if you've not programmed in Objective-C and
Cocoa. Objective-J can be compiled to Javascript up-front on the
server, or in the browser.
<p>
The SDOutlineController is the C in MVC for this outline. The V is
Cappuccino's CPOutlineView class (and some others). The controller's
job is to work with an application's model (the M) in order to present
it in the view for user interaction. The model in this case is a
little controved, but boils down the essence of a hierarchical model.
<p>
I have defined the top-level of the model hierarchy to be a simple
class with a label and references to it's children, which group stuff
into high, medium, and low priorities:
<p>
<code>
<pre>
@implementation SDStuffTopLevel : CPObject
{
CPString label @accessors(readonly);
SDStuffParent highPriorityStuffParent @accessors(readonly);
SDStuffParent mediumPriorityStuffParent @accessors(readonly);
SDStuffParent lowPriorityStuffParent @accessors(readonly);
}
</pre>
</code>
<p>
The middle of the hierarchy is similarly defined, but the children are
maintained as an array of stuff:
<p>
<code>
<pre>
@implementation SDStuffParent : CPObject
{
CPString label @accessors(readonly);
CPArray stuff @accessors(readonly);
}
</pre>
</code>
<p>
The model classes above organize data into a fairly simple
hierarchical structure. However this structure does not suit all
imaginable hierarchies. And so <code>SDOutlineController</code> is
designed to avoid having the view depend on any given structure, and
vice-versa. The controller has a reference to the top-level for my
stuff and the top-level for other's stuff:
<p>
<code>
<pre>
@implementation SDOutlineController : CPObject
{
SDStuffTopLevel myStuffTopLevel;
SDStuffTopLevel othersStuffTopLevel;
}
</pre>
</code>
<p>
The controller has methods expected by <code>CPOutlineView</code> for
mediating between the model and the view. The messages are:
<ul>
<li><code>outlineView:numberOfChildrenOfItem:</code> is kind of obvious.</li>
<li><code>outlineView:isItemExpandable:</code> should be YES (true) if the item has children.</li>
<li><code>outlineView:child:ofItem:</code> should access a hierarchical node's children given an index.</li>
<li><code>outlineView:objectValueForTableColumn:byItem:</code> should provide an object for representing the given model element in the view.</li>
</ul>
<p>
In this example, the top-level of the model always has two
elements. The protocol for <code>CPOutlineView</code> uses the
convention of passing <code>nil</code> (i.e. the Objective-J
equivalent of Javascript's <code>null</code>.) to indicate the root of
the model. And so I have not implemented the root as a class.
<p>
The following method provides the number of children for any given
model element because I have implemented methods for
the <code>count</code> message for each model class.
<p>
<code>
<pre>
- (int)outlineView:(CPOutlineView)outlineView numberOfChildrenOfItem:(id)item
{
return (item == nil) ? 2 : [item count];
}
</pre>
</code>
<p>
Expandability of a hierarchical element is based on the number of
children being greater than zero:
<p>
<code>
<pre>
- (BOOL)outlineView:(CPOutlineView)outlineView isItemExpandable:(id)item
{
return 0 < [self outlineView: outlineView numberOfChildrenOfItem: item];
}
</pre>
</code>
<p>
Indexing the child of a hierarchical element is a little more
complicated, again just because the root is represented
as <code>nil</code>. Otherwise I have
implemented <code>objectAtIndex:</code> for the model classes:
<p>
<code>
<pre>
- (id)outlineView:(CPOutlineView)outlineView child:(int)index ofItem:(id)item
{
var result = nil;
if (nil == item) {
switch (index) {
case 0:
result = myStuffTopLevel;
break;
case 1:
result = othersStuffTopLevel;
break;
}
} else {
result = [item objectAtIndex: index];
}
return result;
}
</pre>
</code>
<p>
The remaining method determines the the presentation object for a
given model element. The root is never displayed, but to be compelete,
this method returns the empty string. Every model class
implements <code>objectValueForOutlineColumn:</code> in order to convert itself to its
presentation object (which is always a string in this example).
<p>
<code>
<pre>
- (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item
{
return (nil == item) ? @"" : [item objectValueForOutlineColumn: tableColumn];
}
</pre>
</code>
<p>
I will use a follow-up blog post to discuss the implementation
of <code>objectValueForOutlineColumn:</code>. Perhaps this post
provides a little more clarity than other information I've found on
the web for programming with <code>CPOutlineView</code>. Let me know
if you have a correction or something to add.
Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-52245858488295255372011-08-21T11:37:00.000-07:002011-08-21T13:15:39.855-07:00On Cappuccino and Avoiding The Modern "Impedance" Mismatch<p>
Wow. My head is just not geared toward writing a blog any longer. But
I will model through it.
<p>
<a href="http://cappuccino.org/">Cappuccino</a> is a great system for
writing rich web applications in the browser, without plugins. There's
finally a growing emphasis on Model/View/Controller among modern
javascript libraries. Most of them rely on HTML and CSS for the View
mechanisms. Which is as you would expect. The problem is the
"impedance mismatch" (if you will) between these mechanisms and the
desired views for traditional rich applications.
<p>
Cappuccino does not suffer such a mismatch, being based on a good
portion of the API
of <a href="http://en.wikipedia.org/wiki/NeXTSTEP">NeXTStep</a>, <a href="http://en.wikipedia.org/wiki/OpenStep">OpenStep</a>, <a href="http://en.wikipedia.org/wiki/GNUstep">GNUStep</a>,
and Apple's <a href="http://en.wikipedia.org/wiki/Cocoa_(API)">Cocoa</a>. And
so the Cappuccino API is essentially 25 years old or so.
<p>
This choice is not without its pro's and con's. The pro's win for me
for applications with these characteristics:
<ul>
<li>At least one display screen greater than 10 inches, i.e. typically used on more than a tablet or phone
</li>
<li>A good bit more data than would easily fit on a single page, and complex relationships throughout
</li>
<li>More than a few operations on that data, with a good bit of keyboard input
</li>
</ul>
<p>
Because Cappuccino provides an HTML view, this is not a total
loss. I've not done much with this yet, but the "con" seems to become
a "pro" by allowing for applying HTML and CSS when those mechanisms
are the best fit.
<p>
Another initial "con" for me the first time I poked at Cappuccino
turned "pro" eventually. I'd done a fairly extensive search several
months ago on the state of the art of MVC for javascript. Cappuccino
was low on my list because I wanted to use javascript per se. Just as
Cocoa, et al. are written in Objective-C, Cappuccino is in
Objective-J.
<p>
I actually like the syntax and class mechanisms, and their similarity
to Objective-C and Smalltalk. (Also emacs' Objective-C mode works
pretty well as-is with Objective-J.) As the javascript runtimes and
tools are adapted to support multiple languages, the tool support for
Objective-J should increase.
<p>
I came back to Cappuccino after frustration with manipulating HTML and
CSS to do my bidding. I don't have any great need for the kind of
styling afforded by HTML and CSS. (And with the fallback to an HTML
view as per above, even less so.) Most of what I need can be provided
satisfactorily using the traditional GUI views going back to
Smalltalk-80's MVC.
<p>
As it happens, I've done a lot of GUI programming in Smalltalk and
several other languages and libraries over the years, so my claim of
the pragmatism of this approach also coincides with my
experience. Some <a href="http://patricklogan.blogspot.com/2007/05/even-more-on-web-again.html">readers
may recall a few years ago</a> that I was in favor of programming web
clients using Adobe Flex with ReSTful web services rather than
immature javascript/HTML/CSS libraries.
<p>
The programmability of views from javascript/HTML/CSS is significantly
better now than in 2007. But the majority of libraries are still
immature and incomplete. Cappuccino is the best exception to the rule
I know of. Fortunately one no longer requires a plugin to achieve
Flex's level of productivity.
<p>
<a href="http://cappuccino.org/learn/documentation/">Cappuccino's class documentation</a> is good, because the API and
documentation is already 25 years mature. Tutorials and examples are
good, growing, and fortunately supplemented by Cocoa material when the
Capp material iteself is lacking.
Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-27809360740067008572011-07-22T15:59:00.000-07:002011-07-22T16:19:09.533-07:00Kotlin == Harry Potter, Scala == LoTR?<p>
<a href="http://confluence.jetbrains.net/display/Kotlin/Welcome">kotlin is a new JVM language, from JetBrains</a>. To understand my title, you may want to read <a href="http://confluence.jetbrains.net/display/Kotlin/Comparison+to+Scala">a comparison with Scala</a> from the Kotlin perspective, and <a href="https://groups.google.com/d/topic/scala-debate/k47zvdiOnRY/discussion">some of the discussion</a> taking place in the Scala community.
<p>
Perhaps since I recently saw the final Harry Potter movie, the title of this post came immediately to mind. Harry Potter appears to me to be a fun story, whose details exist mainly to support that story. For example, characters seem to have the abilities they require to meet a specific challenge.
<p>
On the other hand, the characters in Middle Earth seem be situated in a world that has its own physics. The stories are based on that world, those characters, and the given physics. My understanding is that this is the intention and the process taken to write the books.
<p>
Arguably, Harry Potter is far simpler than LoTR. But, arguably, Harry Potter has less to offer than LoTR.
<p>
Ten years ago this analogy could have been (and was, essentially) made between Java and Smalltalk. Ten years before *that* the argument had been made between C++ and Smalltalk.
<p>
Java is not "pure". Java is in essence Smalltalk but with the "magic" its authors deemed necessary to make Java more successful.
<p>
Harry's world is not pure. Middle Earth is (minus some of the complications that can also be found in Smalltalk and Scala.)
<p>
Kotlin is a big improvement over Java, but it is merely Java minus some cruft, plus enough magic to be useful in 2011. Scala on the other hand has its own physics that makes sense, and provides for a more rich future than Kotlin.
<p>
Hmmm. Just thinking...Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com3tag:blogger.com,1999:blog-5135517.post-62423788120233036452011-04-09T15:42:00.000-07:002011-04-09T21:11:15.948-07:00Implementing McCarthy's AMB Operator in Javascript Using a Trampoline<p>
John McCarthy in 1963 wrote about his "AMB" operator for making nondeterministic choices. ("A Basis for a Mathematical Theory of Computation", <a href="http://www-formal.stanford.edu/jmc/basis1.pdf">PDF</a>) AMB is also explained in detail in <a href="http://mitpress.mit.edu/sicp/full-text/sicp/book/node89.html">the (free, online) book Structure and Interpretation of Computer Programs</a>.
<p>
AMB provides nondeterministic choices with backtracking in the case of failure. This is one of the major components of logic programming, with unification being the other major component. But AMB is useful even without unification. For example AMB makes it easy to collect all permutations of mutliple choices and to generate <a href="http://patrickdlogan.github.com/ambjs/docs/amb-test.html#section-4">selective</a> <a href="http://patrickdlogan.github.com/ambjs/docs/amb-test.html#section-6">permutations</a>. (Remember writing permutations as a beginning programmer? Yeah - you probably wish you had been taught AMB ahead of that.)
<p>
The SICP book uses Scheme for AMB. Scheme makes this easy, using <code>call/cc</code> and macros. And Common Lisp makes this manageable and pretty using macros. Javascript should not be too bad either - no continuations, no macros, but first-class functions help.
<p>
Mihai Bazon recently provided <a href="http://mihai.bazon.net/blog/amb-in-javascript">an implementations of AMB in Javascript</a>. (Along with some great examples of using AMB, for example to implement N-Queens and Map Coloring).
<p>
Implementing AMB benefits from first-class functions, but they are not necessary. Some mechanism for a dynamic escape is needed. In C this is setjump/longjump. In Javascript (and many other languages) this is throw/catch. C does not have first-class functions, so that part gets ugly. Javascript though is a semi-functional language with first-class functions.
<p>
Rather than throw/catch, another versatile way to implement control structures with dynamic extent is to use a trampoline. A few weeks ago <a href="http://patricklogan.blogspot.com/2011/03/bouncing-back.html">I wrote here about NCONC, the core of a Scheme interpreter</a> written in Javascript using a "trampoline" for tail-recursion efficiency as well as for first class continuations.
<p>
The <a href="https://github.com/patrickdlogan/ambjs">project ambjs is an implementation of AMB</a> I wrote in Javascript using a trampoline. The source and the tests <a href="http://patrickdlogan.github.com/ambjs/">are explained using docco</a>.
<p>
Using trampolines for dynamic-extent control structures can be cleaner, and they can provide more control options. In the case of AMB this implementation exposes fewer mechanisms than Mihai's, the nesting of AMBs is more apparent (to me), and there are fewer rules to be obeyed (and so fewer opportunities for bugs).Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-85455975601011983202011-04-05T06:32:00.001-07:002011-04-05T06:39:07.841-07:00Moby Grape on the Mike Douglas Show<p>
The video is not perfect, and the sound is not a lot better, but Moby Grape plays a couple of really good songs on the Mike Douglas Show. And it looks like they're having fun being there.
</p>
<iframe title="YouTube video player" width="480" height="390" src="http://www.youtube.com/embed/-r6eGG6Y-zs" frameborder="0" allowfullscreen></iframe>Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-64648811953498844602011-04-03T06:08:00.000-07:002011-04-03T06:47:01.433-07:00I Have Monkeys In My Clouds<p>
I took advantage of Amazon's offer for a year of 20GB free Cloud Drive storage by purchasing an album stored directly into the cloud. So far I am happy using the Cloud Player from linux, mac, and android. And I am v.happy uploading tons of music that had been spread over several machines and largely unsync'd together in a playable fashion.
<p>
The album I purchased to enable the additional storage <a href="http://www.amazon.com/Head/dp/B00123NXS0/ref=ntt_mus_ep_dpi_2">is The Monkeys, "Head"</a>.
<p>
The Monkeys started as a TV show, and most of their work was produced and marketed as such. But they did have some talent, and fought, and broke through occasionally as a group that could sing and perform. On "Head" they reflect on their origins.
<blockquote>
<pre>
Hey, hey, we're The Monkeys
...
The money's in, we're made of tin
We're here to give you more!
</pre>
</blockquote>
"Head" is <a href="http://en.wikipedia.org/wiki/Head_%28film%29">a movie starring The Monkeys and produced by Jack Nicholson.</a> The music is a soundtrack and a really good album in its own right. It's no more dated than the best music from the late 60s, and it's more fresh because it hasn't been overplayed. Or even played.Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-1109294138992229192011-04-02T16:20:00.000-07:002011-04-02T20:44:03.144-07:00Practical Common Lisp<p>
<em>I am reposting this from February 24, 2005 - given my renewed interest in Common Lisp. It has been 22 years since programming in CL professionally. I have brought up a CL implementation several times in between, but never to do much of anything real. Most of my Lisping over these years has been in various Scheme dialects.
<p>
I love Scheme and some great Scheme implementations like Gambit. I may not have given up on Scheme forever, but... After all these years the Scheme standard is a kernel and there's not much in the way of a portable registry of libraries.
<p>
There are several commercial and free Common Lisp implementations of very good quality. And an apparently long list of portable libraries. I've only recently tried <a href="http://www.sbcl.org/">Steel Bank Common Lisp</a> (derived from CMU CL, which was first <a href="http://en.wikipedia.org/wiki/CMU_Common_Lisp">implemented in the early 1980s</a>), but my impression is that any of these high-quality CL implementations is as good a choice as ever. Nothing like Java's base of software, but rich enough to keep exploring nevertheless.
<p>
What about Clojure? I've used Clojure a bit over the last couple of years. Clojure is great, and has access to Java's libraries. However I recently gave up the JVM for Lent. Really I'm just stepping away from the Java platform to see what other things can do. For exploring and fun I felt the need to step away at least temporarily from all the Java-based bits and pieces. I am not really missing anything so far.
<p>
I am happy to move around. There are a lot of good options in the wide web world. One dream not quite yet fulfilled is a world where all these languages can get along with extreme ease. (And by that I do *not* mean "running in the same virtual machine".) They can each get along fairly well with Javascript, running on a server and talking over HTTP. They can get along with each other modestly using JSON or XML, one as the HTTP client, another as the HTTP server. Better than ever, but the difficulties mount rapidly beyond this simple case.
<p>
Oh yeah, I digress. Here's that repost from 2005:
</em>
<p>
As <a href="http://lemonodor.com/archives/001077.html">seen on Lemonodor</a>...
<blockquote>
<em>
The book <a href="http://www.amazon.com/exec/obidos/ASIN/1590592395/qid=1109294066/sr=2-1/ref=pd_ka_b_2_1/103-3914066-2665435">Practical Common Lisp</a> shows the power of Lisp not only in the areas that it has traditionally been noted for—such as developing a complete unit test framework in only 26 lines of code but also in new areas such as parsing binary MP3 files, building a Web application for browsing a collection of songs, and streaming audio over the Web. Many readers will be surprised that Lisp allows you to do all this with conciseness similar to scripting languages such as Python, efficiency similar to C++, and unparalleled flexibility in designing your own language extensions.
</em>
</blockquote>Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-12215576012923593162011-04-02T14:03:00.000-07:002011-04-02T17:55:00.823-07:00Using SPARQL endpoints and 4store RDF databases from Common Lisp<p>
Jeni Tennison <a href="http://www.jenitennison.com/blog/node/152">posted an interesting article</a> using the 4store for RDF databases from Ruby. This was an experiment to see how close one can get to meeting <a href="http://memespring.co.uk/2011/01/linked-data-rdfsparql-documentation-challenge/">a challenge from Richard Pope</a>. The challenge puts forth criteria for a set of easy-to-use "linked data" programming tools.
</p><p>
I have duplicated the essence of the ruby/4store demonstration, using common lisp. Mainly because I like programming in various lisp dialects, I want to explore using 4store, and I recently decided to pick up common lisp again after, for all intents and purposes, a 20 year hiatus from that particular dialect.
</p><p>
The source and sample data is on github at <a href="https://github.com/patrickdlogan/sbcl-4store">https://github.com/patrickdlogan/sbcl-4store</a>
</p><p>
These are just some examples that a reusable package could be based on. The code in <tt><a href="https://github.com/patrickdlogan/sbcl-4store/blob/master/workspace.lisp">workspace.lisp</a></tt> includes instructions for installing <a href="http://4store.org/">4store</a> on ubuntu, installing <a href="http://www.sbcl.org/">Steel Bank Common Lisp</a>, and using the <a href="http://www.quicklisp.org/">quicklisp</a> system (think ruby gems) for finding and installing useful libraries.
</p><p>
Several functions are defined showing quickly how to load, query, and process RDF data. Two primary functions and their results are listed here:
</p><p>
The function <code>extract-rdfs-classes</code> performs a SPARQL "select" query to select all of the RDFS classes from the sample data. Note: these are not 'object-oriented classes', rather <a href="http://en.wikipedia.org/wiki/RDF_Schema#Classes">an RDFS class</a> is more like the identifier of a logical "set" of members which are themselves identifiers.
<p>
The SPARQL query is:
<blockquote>
<pre>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select distinct ?type
where {
?x a ?type .
}
order by ?type
</pre>
</blockquote>
And running it from the lisp REPL:
<blockquote>
<pre>* (extract-rdfs-classes)
("http://purl.org/linked-data/cube#DataSet"
"http://purl.org/linked-data/cube#DataStructureDefinition"
"http://purl.org/linked-data/cube#Observation"
"http://purl.org/net/opmv/ns#Artifact" "http://purl.org/net/opmv/ns#Process"
"http://purl.org/net/opmv/types/google-refine#OperationDescription"
"http://purl.org/net/opmv/types/google-refine#Process"
"http://purl.org/net/opmv/types/google-refine#Project"
"http://rdfs.org/ns/void#Dataset"
"http://reference.data.gov.uk/def/central-government/AssistantParliamentaryCounsel"
"http://reference.data.gov.uk/def/central-government/CivilServicePost"
"http://reference.data.gov.uk/def/central-government/Department"
"http://reference.data.gov.uk/def/central-government/DeputyDirector"
...
</pre>
</blockquote>
The function <code>extract-persons</code> performs a SPARQL "construct" query to construct a graph of FOAF Person instances along with their FOAF names and other triples having the instance as the subject.
<p>
The SPARQL query is:
<blockquote>
<pre>
prefix foaf: <http://xmlns.com/foaf/0.1/>
construct {
?person
a foaf:Person ;
foaf:name ?name ;
?prop ?value .
} where {
?person a foaf:Person ;
foaf:name ?name ;
?prop ?value .
}
</pre>
</blockquote>
And running it from the lisp REPL:
<blockquote>
<pre>
* (extract-persons)
(("http://source.data.gov.uk/data/reference/organogram-co/2010-10-31#person189"
"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
"http://xmlns.com/foaf/0.1/Person")
("http://source.data.gov.uk/data/reference/organogram-co/2010-10-31#person189"
"http://xmlns.com/foaf/0.1/name" #<"Philip Davies"@en>)
("http://source.data.gov.uk/data/reference/organogram-co/2010-10-31#person189"
"http://reference.data.gov.uk/def/central-government/holdsPost"
"http://reference.data.gov.uk/id/department/co/post/190")
("http://source.data.gov.uk/data/reference/organogram-co/2010-10-31#person189"
"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
"http://xmlns.com/foaf/0.1/Person")
("http://source.data.gov.uk/data/reference/organogram-co/2010-10-31#person189"
"http://xmlns.com/foaf/0.1/name" #<"Philip Davies"@en>)
("http://source.data.gov.uk/data/reference/organogram-co/2010-10-31#person189"
"http://xmlns.com/foaf/0.1/mbox"
"mailto:philip.j.davies@cabinet-office.x.gsi.gov.uk")
("http://source.data.gov.uk/data/reference/organogram-co/2010-10-31#person189"
"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
"http://xmlns.com/foaf/0.1/Person")
...
</pre>
</blockquote>Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-28955939250310020292011-04-02T10:07:00.000-07:002011-04-02T11:50:38.399-07:00Bill Hicks<p>
Netflix now has <a href="http://www.netflix.com/RoleDisplay/Bill_Hicks/20017145">four "watch instantly" shows regarding Bill Hicks</a>. Three standups and one posthumous documentary.
<p>
Youtube <a href="http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=youtube+bill+hicks">has a number of videos too</a>, including a good portion of the posthumous documentary, and the 2009 Late Show With David Letterman with Bill Hicks' mother. The Late Show decided to <a href="http://en.wikipedia.org/wiki/Bill_Hicks#Censorship_and_aftermath">censor Hicks' October 1993 appearance</a>.
<p>
The following February, Hicks died of pancreatic cancer in his early 30's. Letterman had his mother on in 2009, regretted the censorship and the additional pain it caused in Hicks' last months, then aired the censored performance. Letterman had had Hicks on a dozen times, on his previous 12:30am NBC show.
<p>
(Aside: I also recall Letterman had an episode at 12:30am in the 1980s where, during the course of the hour, the broadcast rotated once around the center of the screen. i.e. at 1:00am the show was upside down. An ongoing theme originally was the absurdity of television. There were many ways the show was "toned down" for the 11:30pm slot.)
<p>
There are a handful of social critics/satirists/comedians I continue to rate high my the list:
<ul>
<li><a href="http://en.wikipedia.org/wiki/Mort_Sahl">Mort Sahl</a></li>
<li><a href="http://en.wikipedia.org/wiki/George_carlin">George Carlin</a></li>
<li><a href="http://www.harryshearer.com/">Harry Shearer</a></li>
<li><a href="http://en.wikipedia.org/wiki/Bill_Hicks">Bill Hicks</a></li>
</ul>
I'd have to put <a href="http://en.wikipedia.org/wiki/Monty_python">the Pythons</a> on the list too, from my early teens and their series showing up on PBS, waiting each week for the next one, trying to memorize as much as possible in the half-hour. I didn't really recognize the Pythons or Carlin as social critics at the time. And <a href="http://en.wikipedia.org/wiki/Andy_kaufman">Andy Kaufman</a>, in his own way. More recently, <a href="http://www.billmaher.com/">Bill Maher</a> and probably <a href="http://en.wikipedia.org/wiki/Eddie_Izzard">Eddie Izzard</a>.
<p>
Hicks and I were born the same year. I wonder where he'd have gone over the last 17 years. He was pretty far out on the edge back then, and he didn't seem to hold anything back.
<p>
<quote>
"It's just a ride... a choice right now, between fear and love." -Bill Hicks
</quote>Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-80200789250305756892011-04-02T04:04:00.000-07:002011-04-02T16:13:13.803-07:00Common Lisp libraries and QuicklispI made a modest donation to <a href="http://www.quicklisp.org/donations.html">quicklisp</a>, a very handy hosted-library system for common lisp. (Think of ruby gems and clojure's clojars) Quicklisp is fairly new, but already worth using at very low effort.
<p>
One thing that strikes me about common lisp libraries, beyond quicklisp per se, is the number of libraries available. I've been away from common lisp for all intents and purposes since 1989. The total number of libraries, and the number of library alternatives in any one feature area, are nowhere near those for the currently popular languages like java, ruby, or python. However I am impressed at the ease I've had finding what I am looking for, and then installing and using these libraries with ease.
<p>
I can simply say my recently renewed engagement with common lisp has been more than satisfactory on this front, and others I'll write about later.Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-91153220883583226232011-03-31T21:25:00.000-07:002011-04-02T16:08:23.164-07:00Richard Stallman at Portland State - April 7Richard Stallman will be speaking at Portland State University next
Thursday (April 7th) at 7:30.
<p>
Details are now on caligator:
<p>
<a href="http://calagator.org/events/1250460423">http://calagator.org/events/1250460423</a>Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-28008524301292151492011-03-25T09:40:00.000-07:002011-03-25T10:53:45.800-07:00Building and Running 4store on Ubuntu 10.10<p>
Note to self, if no one else: it's not immediately obvious, but time-saving to know, that <a href="http://4store.org/">4store 1.1.2</a> will build with <a href="http://librdf.org/raptor/">raptor 2.0.2</a> and <a href="http://librdf.org/rasqal/">rasqal 0.9.25</a>.
<p>
<a href="http://4store.org/trac/wiki/Dependencies">All the other dependencies</a> are available as packages on Ubuntu 10.10.
<p>
Upon building and installing raptor and rasqal, it is also not immediately obvious, but you might have to run <tt>sudo ldconfig</tt> for those shared libs to be found by 4store.
<p>
Starting the sparql http server includes one strange message in its output, something like:
<blockquote>4store[31919]: 4s-client.c:129 kb=sample getaddrinfo failed for “fe80::21e:64ff:fe2b:f42%wlan0” with error: Address family for hostname not supported</blockquote>
<p>
This probably is related to 4store using <a href="http://avahi.org/">avahi to perform dynamic discoveries</a>. Running 4store on a single machine, with a single store, this does not seem to be a problem. (Although I don't want to ignore this for long... so if you have any information...)Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com2tag:blogger.com,1999:blog-5135517.post-75643790014127901062011-03-16T16:17:00.000-07:002011-03-16T16:39:00.679-07:00Bouncing Back<p>
Over the years whenever I've wanted to learn a new programming language, the first significant application I've tried is a Scheme interpreter. Many (most?) Scheme interpreters on the web don't implement <code>call-with-current-continuation</code> and often do not handle tail calls well (i.e. they blow the implementation language's stack).
<p>
It's not hard to implement these things using simple mechanisms, but the simple mechanisms are not widely known. And as it happens, implementing these two very mechanisms tell you a <em>lot</em> about the implementation language. (Primarily because most languages have neither, and most languages do not have closures, and so you have to go to widely varying lengths to implement these two things.)
<p>
I've wanted to try out Javascript on a "significant" application. So below is a link to <code>NCONC</code>, which uses "trampoline style" to trampoline a "continuation-passing style" interpreter written in Javascript. I have a reasonable start on docco-style comments which I will put up asap. I presented this at pdxfunc last Monday and will use my memory of that to write more. 8^D
<p>
Note since I have only put in (parts of) a couple of weekends, and my only interest has been illustrating trampolines and <code>call-with-current-continuation</code>, you will not yet find more than a handful of implemented standard procedures. (Enough to run some tests.) And you will not find <code>display</code> so no printing yet. Oh, and no macros yet! But you do have <code>call/cc</code>.
<p>
<a href="https://github.com/patrickdlogan/nconc">https://github.com/patrickdlogan/nconc</a>
<p>
Suggestions for better Javascript style are welcome too. I have a few in mind already, but people wanted to see the code. So.Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-88387320799303950842011-03-12T10:48:00.000-08:002011-03-12T12:44:53.684-08:00Node.js and the Javascript Tools EcosystemI recently have been picking up some javascript tools to test the waters of "serious" programming in that language (browser-side or otherwise). Although I've not used <a href="http://nodejs.org/">node.js</a> yet for application development, it curiously shows up in several javascript-based shell tools.
<p>
And it works fine so far. My initial impression was, "Why use a web server to run shell tools?" But, e.g. <a href="http://jashkenas.github.com/docco/">docco</a> installed perfectly using <a href="http://nodejs.org/">node.js</a> and <a href="http://npmjs.org/">npm</a>.
<p>
Being a skeptic, I first tried <a href="http://fitzgen.github.com/pycco/">pycco</a>, a a similar tool but more traditionally installed pythonically. Something wasn't right and it didn't run. This is just one, unfair, data point. But it was a reassuring experience that javascript tools are showing up and working fine.
<p>
Another javascript tool installed and run using node.js and npm is <a href="http://pegjs.majda.cz/">PEG.js</a>, a parser generator based on, well, PEGs (<a href="http://en.wikipedia.org/wiki/Parsing_expression_grammar">parsing expression grammars</a>).
<p>
These tools run fine, and I'm thinking they startup much more quickly than the java-based <a href="http://www.mozilla.org/rhino/">rhino javascript runtime</a> tools. I've not bothered to investigate though.Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com5tag:blogger.com,1999:blog-5135517.post-2253480046502319942010-11-10T20:48:00.000-08:002010-11-10T20:59:37.705-08:00This is not the one: On Lisp<p>
This is not the post I'm going to write, but it is the one I'm writing.
<p>
I recently saw a tweet that reads something like, "<i>Nice presentation on Clojure, but any language where you write 1 + 2 as (+ 1 2) is not for me.</i>" Fair enough. I won't hold it against you if you share that sentiment.
<p>
What about a language where you write 1 + 2 + 3 + ... + 1000 as:
<p>
<code>
<pre>
(apply + (take 1000 (iterate inc 1)))
</pre>
</code>
Lisp may seem foreign at first. And looking at a small expression in your language compared to the same in lisp may turn you off lisp forever. Fair enough.
<p>
Maybe your language has something equally as expressive. Fair enough.
<p>
But lisp is more than prefixes and parentheses, and you may want to dig deeper into the benefits of all of lisp's characteristics. Fair enough if you don't.Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com5tag:blogger.com,1999:blog-5135517.post-30371740809137404822010-11-09T11:15:00.000-08:002010-11-09T11:16:58.980-08:00Is This Thing On?Hi!
(Insert animated gif of that guy digging. "Under Construction" - I'm working on a new blog post...)Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-72243129428247181172009-06-08T15:49:00.000-07:002009-06-08T15:51:36.970-07:00Jobs of the Not-Steve Kind<p>
An interesting graph of jobs related to some relatively hot programming language...
<p>
<div style="width:540px">
<a href="http://www.indeed.com/jobtrends?q=scala%2C+groovy+and+java%2C+erlang%2C+haskell" title="scala, groovy and java, erlang, haskell Job Trends">
<img width="540" height="300" src="http://www.indeed.com/trendgraph/jobgraph.png?q=scala%2C+groovy+and+java%2C+erlang%2C+haskell" border="0" alt="scala, groovy and java, erlang, haskell Job Trends graph">
</a>
<table width="100%" cellpadding="6" cellspacing="0" border="0" style="font-size:80%"><tr>
<td><a href="http://www.indeed.com/jobtrends?q=scala%2C+groovy+and+java%2C+erlang%2C+haskell">scala, groovy and java, erlang, haskell Job Trends</a></td>
<td align="right"><a href="http://www.indeed.com/q-scala-jobs.html">scala jobs</a> - <a href="http://www.indeed.com/q-groovy-and-java-jobs.html">groovy and java jobs</a> - <a href="http://www.indeed.com/q-erlang-jobs.html">erlang jobs</a> - <a href="http://www.indeed.com/q-haskell-jobs.html">haskell jobs</a></td>
</tr></table>
</div>Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com1tag:blogger.com,1999:blog-5135517.post-73532133029829912792009-06-08T11:46:00.001-07:002009-06-08T11:46:48.029-07:00David Gelernter re: programming for/with clouds, etc."the reason why our approach was considered radical and strange in the<br>1980's was the so-called Tuple Space Model — the idea being that if<br>you had a lot of computing agents who needed to communicate, instead<br>of sending messages to each other, essentially like e-mail, if I had<br>information for someone, I'd just write it on a piece of datum and<br>release it and it would just float up into the cybersphere. If I<br>needed information, I'd look around, grab whatever I want, I would<br>read it or, if it were a task to be done, I'd grab it so nobody else<br>could grab it. "<br>-David Gelernter<p><a href="http://www.edge.org/3rd_culture/gelernter09/gelernter09_index.html">http://www.edge.org/3rd_culture/gelernter09/gelernter09_index.html</a><p>(still beats the pants off all that crap we call integration<br>technology today. -me)Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-58402035634975637542009-06-05T14:45:00.001-07:002009-06-05T14:45:17.542-07:00On Clojure, Testing the Implementation, and Protecting Your InvestmentOver on the Object Mentor blog, Dean Wampler writes about the Clojure<br>programming language and the designer's stand on testing the<br>implementation. Dean writes that...<p>"TDD provides two important benefits<br>* Driving the design.<br>* Building a suite of automated regression tests. "<p>But another important benefit of a good collection of tests is communication.<p>Clojure is a fine Lisp in many ways. I personally would hesitate to<br>use it for anything in which I had a significant investment given the<br>maintainer's stand on testing. At least not without a good deal of<br>evidence that Clojure will continue to be maintainable and understood<br>(at the implementation level in particular) by more than one person.<p>Maybe his approach will work over a long period of time, and for a<br>user community that will rely on Clojure for many heavy-duty, valuable<br>production uses. I cannot say that it won't.<p>I can only say that for _me_ this would be a significant reason to<br>hesitate before taking too significant of a plunge.<p>And that's saying something because I am a veteran of programming in<br>various Lisps for 29 years, and Lisp generally is my favorite<br>language. I love that Clojure has rejuvenated interest in Lisp.<p><a href="http://blog.objectmentor.com/articles/2009/06/05/rich-hickey-on-testing">http://blog.objectmentor.com/articles/2009/06/05/rich-hickey-on-testing</a>Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0tag:blogger.com,1999:blog-5135517.post-42953235584050413382009-05-18T19:12:00.001-07:002009-05-18T19:15:01.574-07:00TriSano: "Best Project for Government"<p>
Click on this badge to vote for <a href="http://www.trisano.org/">TriSano</a> for "Best Project for Government"...
<p>
<a href="http://sourceforge.net/community/cca09/nominate/?project_name=TriSano&project_url=http://www.trisano.org/"><img src="http://sourceforge.net/images/cca/cca_nominate.png" border="0"/></a>Patrick Loganhttp://www.blogger.com/profile/02088461489050417591noreply@blogger.com0