Saturday, May 10, 2008

Programming: sometimes simpler is better

I recently chose a development environment for a spare time project: I am re-working some of my old algorithms and miscelanious code (in several different programming languages) for extracting semantic information from plain text after reading through the excellent book The Text Mining Handbook: Advanced Approaches in Analyzing Unstructured Data. I have been working on information extraction for about 20 years (very much part time), and although most of the material in this book was familiar I found the book to be an excellent reference and a good summary for the state of the art in information extraction techniques. I have blogged before about the excellent Reuters/ClearForest system - the authors were principles at ClearForest.

I chose for this project the combination of Gambit-C Scheme, Emacs, and a few customizations of the Gambit-C Emacs code. For "mostly thinking" projects like my information extraction library, I like simplicity: a simple clean programming language and an environment that provides good editing and debugging support but otherwise stays out of my way. Professionally, I do a lot of work with Common Lisp (either Franz + ELI + Emacs, or SBCL + Slime + Emacs) but since I am basically just experimenting with algorithms I felt like using something light weight. I thought about using Ruby (with either the excellent NetBeans support or TextMate) but I like the ease with which Gambit-C Scheme can be used to build native applications or libraries (compiles to intermediate C) and I will probably want to share my information extraction program (perhaps a free and commercial version) but not release the source code. The performance of compiled Gambit-C code is also very good.

Labels: ,


Saturday, April 19, 2008

Using JSON for communicating between Ruby and Lisp or Scheme

JSON is very much lighter weight than XML and is meeting a need for easily calling some Scheme code from a Ruby program. The Scheme code I am using is old, I wrote it years ago to extract entities from plain text. Since the Scheme program starts very quickly, I am able to simply start a Scheme interpreter as a separate process using back quotes to capture any output to stdout in a Ruby string variable:
require 'json'
s = `gsi extraction.scm -e '(get-proper-names "President Bush moved to South America.")'`
# parse JSON text...
Here I am using Gambit-C Scheme interpretively. It is very easy to write any structured data in JSON format in the Scheme (or Lisp) code and parse it on the Ruby side. It is also easy to speed things up and compile my program:
gsc -c extraction.scm
gsc -link extraction.c
gcc -o extraction extraction.c extraction_.c -lgambc -I/Library/Gambit-C/current/include/ -L/Library/Gambit-C/current/lib/
which both makes the program faster and reduces the startup time down to a few milliseconds. Since the extraction program starts very quickly, this solution is good enough. However, I have been looking at an alternative idea in case I ever need to use a Lisp or Scheme program that has a long startup time. I have not done this yet, but here are my ideas for Gambit-C Scheme:This looks easy enough, but getting memory allocation and deallocation correct might be difficult. For now, I am calling my old Scheme code from Ruby the easy way :-)

Labels: , ,


Sunday, March 16, 2008

C++, taking a second look

I earned my living between 1988 and 1997 developing and being a mentor using C++. I usually argue against using C++, a language that offers superb runtime performance (speed and memory utilization) with the penalty of greatly increased development costs.

For most applications, it is less expensive to optimize for developer productivity. In my decade of using C++, with hindsight, the only projects that needed the performance of C++ were a commercial product for Windows 1.03, some VR work for SAIC and Disney, work on two Nintendo video games, a real time expert system for PacBell, and a PC racing game. All other C++ projects could have been done with more economy and effectiveness using other languages.

I used to error on the side of staying current with too many programming languages, although in the last few years I have invested heavy time in only three: Ruby, Java, and Common Lisp. Even though I find C++ development to be less fun, slow, and sometimes even a little painful, I am considering replacing Common Lisp with C++ in my small set of 3 languages that I am willing to invest heavily in. This Benchmark game of C++ vs. SBCL Lisp is one reason for this (possible) decision. The other reason is that I find Ruby to also be very good for quick prototyping and fast agile development, and even though the runtime performance of Ruby is very poor, it seems like the combination of Ruby + Java + C++ covers a wider range of application development than the combination of Ruby + Java + Lisp. In other words: Ruby gives me a lot of what Lisp does and I feel like I need one agile scripting language in my programming language toolbox.

Sure, "the best tool for the job", but I like to also consider the costs of not totally mastering the tools that I use in my work. This is why I have given up (for serious work) some great programming languages like Python, Smalltalk, C#, and Prolog.

Labels: , , ,


Sunday, January 06, 2008

Cool: Common Lisp Elephant object persistence package

One of my customers uses Common Lisp for a lot of development and we go with Franz, largely because of AllegroCache object persistence and great support.

Until today, I had never bothered getting Elephant installed and set up with a back end data store (I chose CL-SQL with native PostgreSQL). Since I own my own licensed copy of Franz Lisp (and my customer provides me with another license for their work), I was always happy to just use AllegroCache.

Anyway, after reading Vetle Roeim's blog post Implementing a blog in Common Lisp I decided to take a little time setting up Elephant and Edi Weitz's Hunchentoot web server and his HTML-TEMPLATE Common Lisp templating system. I used a fairly recent release of SBCL Common Lisp on a MacBook. This is all free open source software. I found the Elephant API to be easy to use.

After having some fun with this, I do have a few comments on Common Lisp vs. Ruby development:

Labels: ,


Saturday, September 22, 2007

Programming languages: advantages of both specialization and being a generalist

In the 1970s, I very much enjoyed working through Jean Sammet's classic book "PROGRAMMING LANGUAGES: History and Fundamentals". For one thing, it was my first real exposure to Lisp, and it was fun learning many new languages at once. At one point I had over a dozen programming languages on my resume (due to needing to use some one-off languages for military hardware, and several different assembler languages).

Generalization is good because the more experience with different languages, libraries, frameworks, and development styles that you have, then the easier it is to choose a good technology to solve new problems. I would argue that broad experience is at least a little better than narrow but deep experience.

Unfortunately there is another side to this issue: whenever I see really great design and code, it almost always seems to be written by someone who deeply specializes in one, or perhaps two, programming languages.

In the last few years, due to customer requirements, I have had to work in Java, Common Lisp, Ruby, and Python (and a little work with Prolog, and even less fortunately in C++). I am now in my mid-50s, and semi-retired (I try to limit myself to working no more than 25 hours per week). I would like to specialize in just one or two languages and not have the overhead of staying current with a half dozen programming languages.

The language that I enjoy the most is Ruby, and with the maturation of JRuby, it is great to be able to use the same language for scripting and general software development (using Matz's C based Ruby) and when I need to use existing Java libraries and frameworks (JRuby). While I really enjoy Lisp and Smalltalk (never professionally), my hope is that as JRuby continues to get faster and integration with the Java platform improves that the combination of (C or J)Ruby and Java will cover everything that I need for my work. BTW, the comment about future work on a "compiler that allows compiling a given Ruby class 1:1 to a Java class, producing a class you can construct, with specific signatures you can call from Java code" posted by Charles Nutter a few days ago to my JRuby blog article was very good news indeed.

Labels: , ,


Saturday, April 21, 2007

How much does web framework choice really matter?

Based on experience with consulting jobs developing web applications using several Java frameworks, Ruby on Rails, and Portable AllegroServe with WebActions (open source Common Lisp frameworks), I believe that choice of framework is less important than:I think that these 3 issues are all more important than choosing a web UI framework.

I have been investing a fair amount of time learning Erlang this year and the ErlyWeb framework (that uses the high performance Yaws Erlang web server) looks very good for both interactive development and distributed deployment. For web applications that map well to Erlang, ErlyWeb allows Erlang to be the development language of choice, but again the important choice is programming language selection rather than web framework.

Labels: , , , ,


Monday, March 12, 2007

Google Guice: probable affects on my development methodology

As a developer, I have spent about equal time the last few years doing paid-for work in three programming languages: Common Lisp, Ruby, and Java. As you would expect, I try to apply the same tools and ideas for all three languages. This helps prevent the small "mental overhead" when switching languages. After reading the Guice User's Guide while having lunch today, I believe that I am going to use Guice for one or two of my "personal time" projects in order to try it out and add it to my toolkit.

The question that interests me is: how to use Guice patterns in dynamic languages like Common Lisp and Ruby? For Common Lisp, I recently started studying the project Closer - a wrapper for smaller projects for AOP and uniform interfaces (and enhancements) for MOP and context oriented programming. Good stuff!

For Ruby, there are a few projects for injection of control (e.g., Needle).

I am not sure how well spreading this pattern over three programming languages will work for me, but it makes sense to put some effort into consistency.

Labels: , ,


Saturday, January 20, 2007

Using the Dojo Javascript library in Ruby Rails

I have been using the fine Dojo Javascript library in a web app written in Common Lisp and this morning added Dojo to the code base for a current Rails project. The easiest way to get started using Dojo and Rails is to simply install the developer's version (non-compacted) of dojo.js and the src directory directly in your Rail project's public/javascripts directory, so it looks like this:
public/
javascripts/
dojo.js
src/
Again, the "src" directory contains the dojo source files (besides the dojo.js loader). Dojo will complain about rendered Rails web pages withot HTML and HEAD tags, so I added the following HTML with Dojo setup to the view for my main application controller:
<html>
 <head>
  <title>KBSportal KnowledgeManagement</title>
  <script type="text/javascript">
  djConfig = {isDebug: true};
 </script>
 <script src="/javascripts/dojo.js" type="text/javascript"></script>
 <script type="text/javascript">
  dojo.require("dojo.io.*");
  dojo.require("dojo.event.*");
  dojo.require("dojo.widget.TabContainer");
  dojo.require("dojo.widget.LinkPane");
  dojo.require("dojo.widget.ContentPane");
  dojo.require("dojo.widget.LayoutContainer");
  dojo.require("dojo.widget.Checkbox");
 </script>
 <style type="text/css">
  body {
   font-family : sans-serif;
  }
  .dojoTabPaneWrapper {
   padding : 10px 10px 10px 10px;
  }
 </style>
</head>
Dojo is definitely "heavier weight" than the prototype.js Javascript library that is provided with Rails so you may not want to use Dojo for very high traffic sites.

Labels: , , ,


Saturday, December 30, 2006

JRuby 0.9.2

JRuby 0.9.2 was released a few weeks ago but I just got around to trying it out this morning. My favorite feature is the "JRuby IRB Console". An easy way to experiment with JRuby is to simply to download the console JAR file that conveniently contains the JRuby run time system, has a "tab auto complete", and has readline support. If you have not given JRuby a try yet, download the IRB Console, and follow through the tutorials. Good stuff!

JRuby performance problems:

I love programming in Ruby but find myself working a lot in Common Lisp instead for vastly better runtime performance. JRuby performance is very poor at this time (much slower than the standard Ruby system, which is itself slow), but with support from Sun and some development time, performance and Java platform integration will improve.

Labels: , ,


Wednesday, November 08, 2006

Some dissatisfaction with Ruby

I use Ruby a lot for small database tasks (love ActiveRecord!) and for using Rails for some web applications (not with scaffolding, mostly generating controllers and writing my own code).

That said, for a lot of what I do, Ruby is much more than an order of magnitude slower that compiled Common Lisp. I find myself still using Ruby and Java when appropriate, but for most tasks, I am going back to using Common Lisp. Better language, and the learning curve is not so bad (I have been using Lisp for over 25 years, and I am already up to a 'moderate' level of competence :-)

Labels: ,


Tuesday, October 24, 2006

VAR agreement with Franz

I do a lot of Common Lisp development for my commercial products. I like to develop in Lisp, start selling products compiled with Lisp, then if it makes sense, do a Java port and sell that also. I now have a VAR agreement with Franz to use Allegro Common Lisp for development and for shipping applications.

Labels: ,


Tuesday, October 10, 2006

Human minds, programming, and the "caching problem"

When writing large software systems, rapid access to data is often important: what can be kept in memory or more slowly: processes on the same local network and on disk. In software development, we see the same effect: maximum speed and efficiently if a single person can understand the architecture and comprehend the entire system. Moving from a single developer to a very small team adds a little overhead: design notes and pencil and paper drawings turn into casual but more explicit short documents and conversation. The optimisation is minimising cost between two people talking and sharing information vs. maintaining documentation and reading time. Talking is almost always better because communication is a two way street, but if you have N developers, O(N^2) "talking overhead" is too expensive with a large N, so back to the one way street of documentation.

I like to view programming languages in terms of how they allow me to deal with complexity, keeping as much stuff in my head at once:

Labels: , ,


Monday, September 18, 2006

Persistence for object oriented languages vs. programmer efficiency

I am about 4 months into a project using a very expensive object persistence mechanism (Franz Lisp AllegroCache) that almost automatically wraps Common Lisp CLOS classes for automatic persistence and B-Tree indexing of as many slots as you want to tag as indexed. As is sometimes is the case, here commercial software tools save time and effort. There is a very interesting open source project for Common Lisp (Elephant) that does something similar by using BerkleyDB or a relational database as the backend - it looks good, but it is not yet an out of the box solution.

For Java work, although I was once a fan of Hibernate, I try to use Prevayler instead: if you add new instance variables to the end of class definitions you can add to your object model without breaking your persistent storage - a neat trick, to be sure.

When it comes to the best programmer productivity using object relational mappers, I personally think that Ruby Rail's ActiveRecord wins hands down - with the slight cost that you design database schema instead of class models.

Labels: , , ,


Sunday, September 03, 2006

Disconnect between thinking about a problem and programming

The Subtext programming system has been getting some buzz, and I think that this is worth while if it makes us think about the disconnect between thinking about problems and writing software to solve these problems.

While state of the art IDEs like IntelliJ for Java and VisualStudio for .Net languages provide a comfortable working environment, I must say that both Java and the .Net languages are poor choices for many programming tasks.

Scripting languages like Ruby and Python help this thinking vs. programming disconnect in one important way: for small programming tasks, very short programs are sufficient and we can keep track of both problem task thinking and programming.

What about large projects? There are two good alternatives in programming languages: Common Lisp and Smalltalk:

Common Lisp lends itself really well to growing your own application specific language (using macros if you like, and functions). Once you build up an application specific language, a lot of the complexity of even complex programs goes away. Even more importantly, domain specific languages should help close the gap between thinking about problem solutions and programming these solutions.

The downside of Common Lisp is that while Emacs based IDEs are effective environments, even with add on code browsers, I find exploring large Common Lisp software projects to be tedious.

Smalltalk implementations generally have great code browsers because the simplicity and regularity of the language make it easier to automatically process the structure and semantics of code. Smalltalk blocks and closures, like in Ruby, allow many concise coding tricks - shorter programs are easier to understand and modify.

Labels: , , ,


Saturday, August 05, 2006

Yes languages affect our thoughts, even in programming

The Sapir-Whorf hypothesis poses that our native language affects how we think. Computer programming languages also strongly affect how we think about, design, implement, and maintain code.

I was working on some tricky code this morning that builds on some Common Lisp CLOS class libraries. The new code is really orthogonal to the existing functionality and it seemed like a poor idea to merge the new in with the old, especially since the old codebase will probably be used as-is for a while. I decided to start a new module (as defined by physical file organization) that added the new functionality to the existing classes as generic methods. The new module stays small, and anyone needing to use the original codebase is not confused with extra code for functionality that they do not need.

In Ruby, I like to do the same sort of thing: have different modules (as defined by physical file organization) where new orthogonal functionality is added by defining new methods to existing classes in new file modules.

In Java (and other languages), you can always use Aspect-oriented programming (AOP) to add new orthogonal behavior to class libraries, but, to be honest, I dislike AOP - this is not the fault of AOP per se, but because I have only used AOP with Java.

Labels: , ,


Friday, July 28, 2006

Criticism of non-dynamic languages

For the last year most of my work has been using dynamic programming languages (Ruby and Common Lisp). I have written about this before but given that programmers are properly trained/educated, dynamic languages simply are more efficient when measured against programmer time. I think that the reason is fairly simple: dynamic programming, meta object protocol, Ruby's missing method, etc. all make it possible to solve some difficult problems with relatively few lines of code.

I have made a good living using the Java platform (starting with Java 1.0 beta) but I think that it is time to move on. Sure, I am still likely to take on interesting work even if it has to be done in Java, but I think that both Java and the .Net platform languages missed the boat on programmer productivity.

I have a few comments on Ruby vs. Common Lisp also: the beauty of Ruby is that it is a simple language to learn and to master. It is difficult to find programmers who are willing to make the effort to master Common Lisp and CLOS. Too bad, but that is the way it is. Personally, I still like Common Lisp a lot because I have already invested decades (part time) learning Lisp and Common Lisp blows Ruby away performance wise. BTW, my positive comments on Ruby and Common Lisp largely also apply to Smalltalk.

Labels: , ,


Thursday, June 29, 2006

New version 350 of PLT Scheme

Here is the download page

New features include an easy option for generating standalone applications that have all dependencies bundled in and a just in time compiler. Cool stuff.

I prefer Common Lisp for application development, but Scheme is a great language and PLT Scheme is one of the best free development kits - includes lots of useful libraries, web application and web services support, etc.

Labels:


Friday, June 23, 2006

More work combining Ruby and Common Lisp

I am doing a lot of coding using both Lisp and Ruby for my current project. I am finding interop between the languages to be especially easy because of the dynamic nature of both languages. When I use REST style calls I can dynamically create classes and instances just from the XML so changing classes in one language does not break code in the other.

Labels: , ,


Saturday, June 17, 2006

Meta object protocol in Lisp and Ruby

One thing that I like about Common Lisp and Ruby is the ability to examine class definitions, etc. at runtime. I have several model classes in a Common Lisp application and I want to implement a web services API for my application that in some cases returns model objects to the requester.

I wrote a very short utility function today that takes any class instance looks up all of the slot names, and then gets the slot values. I output to an XML stream.

I don't have to manually change any code to marshall any of my classes to XML if I change the model class definitions.

Labels: , ,


Sunday, May 14, 2006

The Lisp community needs to do this more often

One of my gripes with Lisp is that there is not an easy to use package installation utility like, for example, Ruby gems. Common Lisp does have ASDF, but I get a lot of "misses" trying to install and experiment with Lisp programs using ASDF.

The continuation based UnCommon Web project looks interesting, but has been a pain to install all of the dependencies until now. Marco Baringer has packaged UCW and all of its dependencies in a single tar file so for me the install was very quick, and I could experiment with UCW painlessly. Thanks Marco!

Labels:


Tuesday, May 09, 2006

Integrating a semantic network with a reasoning system

For a long term AI project, I am using Common Lisp and CLOS to model customer application specific nodes in a semantic network. This morning I worked out the non-obvious (to me!) bits for integrating my stuff with the Loom reasoning system by deriving Loom concepts from my CLOS classes. Cool stuff!

Labels: , ,


Tuesday, May 02, 2006

I sometimes forget how fast compiled Common Lisp is

Java and Ruby are usually my staple languages for my work. I am working on an AI system for a new customer and I started prototyping everything in Ruby - lots of progress in a short time, but for some things that I want to do Ruby is just too slow so I have separated out the most time consuming calculations and I am writing that module in Common Lisp. Compared to Ruby (and even Java), test cases, etc. in compiled Lisp seem infinitely fast - surprising since for a lot of things like hash table lookups, etc. most of the time is spent in library routines anyway.

I used to have a strong preference for writing entire systems in the same language, but really, it is easy enough to break up systems into modules written in different languages.

Labels:


Wednesday, March 29, 2006

Matz on Ruby's Lisp heritage

I like this! From Matz:
Ruby is a language designed in the following steps:

* take a simple lisp language (like one prior to CL).
* remove macros, s-expression.
* add simple object system (much simpler than CLOS).
* add blocks, inspired by higher order functions.
* add methods found in Smalltalk.
* add functionality found in Perl (in OO way).

So, Ruby was a Lisp originally, in theory.
Let's call it MatzLisp from now on. ;-)
Since the late 1970s, I have always been happy writing software in Lisp, but except for the development of three commercial products and quite a bit of R&D, Lisp has been a hard sell. With the mass enthusiasm for Ruby on Rails, Ruby is starting to be an easy sell. My only problem with Ruby is that you don't get the white-hot high performance of compiled Common Lisp - but I can live with that.

Labels: ,


Friday, February 24, 2006

Wonderful mix of functional and logic programming

I received the book The Reasoned Schemer last week. The authors use the same socratic teaching style (ask questions of the reader) that they used in the Little Schemer to introduce the implementation of logic programming using a functional programming style. I can just feel my brain twisting a little from new ways of thinking about old problems.

I mostly use object oriented programming (Java, Ruby, Smalltalk, and Common Lisp's CLOS) so it is healthy to switch to a functional programming style if only for research and learning projects. Anyway, this is an awesome book.

Labels: ,


Monday, December 20, 2004

Lisp world: the old and the new

The new: the "so good I can't believe it is free software" DrScheme Scheme development environment has a new 2.09 version available now.

The old: over on the Lisp blogs recently, I saw a reference to the availability Xerox Parc Medley Lisp for non-commercial use. It is bundled with the LFG grammar toolkit. It is available here.

This is the Lisp that I used in the 1980s on my Xerox 1108 Lisp machine. I downloaded the Medley Lisp and LFG grammar bundle (runtime converted to run on Linux) and took a trip down 'memory lane'. (I am in bed with the flu - not well enough to work, but well enough for messing around with old software).

While I use Common Lisp for my Lisp development now, I am so happy to have a non-commercial version of Medley. Wowza!

Labels:


This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]