Saturday, April 19, 2008
Using JSON for communicating between Ruby and Lisp or Scheme
require 'json'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:
s = `gsi extraction.scm -e '(get-proper-names "President Bush moved to South America.")'`
# parse JSON text...
gsc -c extraction.scmwhich 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:
gsc -link extraction.c
gcc -o extraction extraction.c extraction_.c -lgambc -I/Library/Gambit-C/current/include/ -L/Library/Gambit-C/current/lib/
- Write a C wrapper for the Scheme (a good reference) to create a Ruby callable class whose initialization method performs the long running initialization for the Scheme library
- Wrap the Scheme side library according to this reference
Sunday, March 16, 2008
C++, taking a second look
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.
Friday, March 07, 2008
Ruby becoming a first class language on Mac OS X
Friday, February 15, 2008
My DevX article "Real-Life Rails: Develop with NetBeans, Deploy on Linux"
Labels: NetBeans, Ruby, Ruby Rails
Wednesday, January 30, 2008
I finally tried Ruby 1.9 (developer's release)
With the good work also being done on JRuby and Rubinius, it is great to know that Ruby is under active development.
Labels: Ruby
Sunday, January 06, 2008
Cool: Common Lisp Elephant object persistence package
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:
- Common Lisp compiled code runs much faster than Ruby: typical benchmark results are about 30 times faster - but Ruby's slowness is mitigated if a lot of processing is performed in native libraries like Ferret.
- Development with Common Lisp takes longer than Ruby (for me, at least). It would have taken me 10 minutes to get set up with Ruby for this tutorial while it took a full 90 minutes to get 20 different Common Lisp packages and install them in the project directory for Vetle's tutorial. It is true that I will keep this project around, and if I ever need to use Elephant, HTML-TEMPLATE, Hunchentoot, etc., then I will just clone and modify this project (if I don't care about using the most up to date libraries). Common Lisp ASDF is a good package manager but in my opinion is not as good as Ruby Gems.
- I find that I work a little faster in Ruby than Common Lisp, mostly because the language is terser: simply less code to write and read. That said, Common Lisp is also a great language to work in.
Saturday, September 22, 2007
Programming languages: advantages of both specialization and being a generalist
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.
Saturday, May 19, 2007
Why the ODF is better than Microsoft's document formats
require 'rubygems'I have spent too much of my time over the last 10 years dealing "programatically" with Microsoft document formats. I am tired of wasting my time when open document formats are so much easier and less expensive to use.
require 'rexml/document'
require 'rexml/streamlistener'
require 'zip/zipfilesystem' # install with gem
include REXML
class OOXmlHandler
include StreamListener
attr_reader :plain_text
def initialize; @plain_text = ""; @last_tag_name =""; end
def tag_start name, attrs; @last_tag_name = name; end
def text s
@plain_text << s << "\n" if @last_tag_name.index('text')
end
end
class ReadOpenOffice
attr_reader :text
def initialize file_path
Zip::ZipFile.open(file_path) { |zipFile|
xml_handler = OOXmlHandler.new
Document.parse_stream((zipFile.read('content.xml')), xml_handler)
@text = xml_handler.plain_text
}
end
end
puts ReadOpenOffice.new('KBrecipes.odt').text
Wednesday, May 02, 2007
My article "A Java Developer's Guide to Ruby" was just published
In this article I write about why a Java developer might want to also use Ruby and I cover a few cool Ruby features.
Labels: Ruby
Saturday, April 21, 2007
How much does web framework choice really matter?
- Programming language: choose a language that both fits the application domain and has good library support for your application
- Data modeling: while I believe in interactive bottom up development, spending time up front getting object models 'right' makes development easier
- Object persistence: there are lots of good choices (prevalence, object relational mapping for relational databases, distributed memory only, etc.) but choose a scheme that makes sense both for development and deployment
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: Erlang, Java, Lisp, Ruby, web applications
Saturday, March 31, 2007
Less is more: advantages of compact programming languages
The implementation of Ruby and the standard Ruby libraries is compact, basically divided into the C implementation of Ruby itself and the Ruby code for the standard libraries. If you are going to be working much with Ruby then consider creating at least a project (using Eclipse, IntelliJ, TextMate, etc.) with the library source code. Good for library reference, looking up APIs, and for just reading code.
I would make the same suggestion to developers who use Squeak Smalltalk (or other implementations): you have the source code to the standard libraries: read it!
I also enjoy and am very productive using the Java and Common Lisp frameworks, but these languages with their standard libraries are so huge that I would personally never attempt to dive in and understand their implementations. Not having a mental road map of the implementations of Common Lisp and Java reduces the effectiveness of these platforms.
Wednesday, March 14, 2007
I have released some NLP (natural language processing) tools with a LGPL license
BTW, I consider the LGPL to be "business friendly". You are allowed to mix my LGPL software with your own commercial products without open sourcing your products. You may also mix my LGPL software with open source with projects with Apache, BSD, MIT, or Mozilla style licenses. If you have any questions, ask me. If the LGPL license prevents you from using this material, please let me know about it.
Labels: AI, C#, C++, Java, Ruby
Integrating PHP and Ruby with Java server side deployments
Monday, March 12, 2007
Google Guice: probable affects on my development methodology
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.
Sunday, March 04, 2007
Automating the technical writing process
I have been working fairly hard in my free time on two "free web books" for my main we site. In the past I have simply created PDF files and made them available for my site. Although I write my "free web books" using a Creative Commons license, I decided that I wanted to make at least a small revenue stream so that I can spend more time on these projects. My plan has been to have all of my web books readable for free online with a small Google Adsense advertisement at the beginning of each chapter and offer through lulu.com the ability to buy PDFs with no advertising for a few dollars or get a printed book for about $12.
I would prefer spending my time writing rather than preparing HTML, PDF, and printer ready PDF. I think that I now have this process automated about as fully as I can, using custom Ruby code, shell scripting, and a "do everything" Makefile. I had experimented with using OpenOffice.org and writing some utilities to modify the generated HTML. I also experimented with the very cool SiSU system.
In the end, I went back to automating my writing setup using Latex, htlatex, pdflatex, custom Ruby code and shell scripts, and the OS X Latex editor TexShop. It feels good to get things working "just right".
Labels: Latex, Ruby, technical writing
Monday, February 19, 2007
Ruby 2.0 svn trunk with Yarv
Labels: Ruby
Saturday, December 30, 2006
JRuby 0.9.2
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.
Sunday, December 17, 2006
I updated RubyPlanet.net this weekend
Labels: Ruby
Saturday, November 25, 2006
AJAX tools for multiple development platforms
I have spent many evenings playing around with various release versions of the Google Web Toolkit (GWT) and it is very compelling, especially if you already are used to developing GUI applications in Java - the only new wrinkle worth mentioning is getting used to handling events asynchronously. The problem with GWT is that it really does tie you to the Java platform. I spend most of my time developing AI applications, but that said, who does not want basic knowledge and competence at building web applications?
I use Common Lisp, Java, and Ruby for development, so for the occasional AJAX tasks that I have, I have settled with the well respected dojo Javascript toolkit because it plays very well with both Lisp and Java JSP based web applications. Dojo is also easy to use with Rails, if you want an alternative to Rail's great AJAX support.
By using Dojo, I basically have to deal with just one learning curve no matter what platform I am developing on. Here is a simple example for a JSP page (assuming that this would be more interesting to most people than a Lisp example):
Add this to your <head> section on a top level JSP page:
Then try putting this somewhere on your JSP page (note: this assumes that you have another JSP page ajax.jsp that gets the form values and returns content to be placed into the DIV element with ID=ajxplydiv. Anthing that ajax.jsp writes using out.print() gets inserted asynchronously into the "ajxplaydiv" DIV element):
<script type="text/javascript">
var djConfig = { isDebug: true };
</script>
<script type="text/javascript" src="dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.io.*");
dojo.require("dojo.event.*");
</script>
The call to dojo.io.bind sends a request containing the form data to the ajax.jsp page, and whenever the results are returned then the Javascript functions "load" or "error" defined in the data block in my_onclick_button() is called. This is just one example of processing form data and adding HTML below the form without refreshing the page - but is a common use case for using AJAX. This example assumes that I have both the dojo "src" directory and dojo.js in my top level web resources directory. The great thing about dojo is that it encapsulates all asynchronous event handling, offers a good supply of visual components (that map to HTML elements) and is simple to use no matter what programming language you are using for a web application.
<h3>test AJAX Form:</h3>
<form id="myForm">
<input type="text" name="input_test_form_text" />
<input type="button" name="button1"
value="Try AJAX form" id="ajaxButton" />
</form>
<div id="ajxplaydiv">
initial context for AJAX play div
</div>
<script type="text/javascript">
var buttonObj = document.getElementById("ajaxButton");
dojo.event.connect(buttonObj, "onclick",
this, "my_onclick_button");
function my_onclick_button() {
var ajaxargs = {
url: "ajax.jsp",
load: function(type, data, evt){
dojo.byId('ajxplaydiv').innerHTML = data;
},
error: function(type, data, evt){
alert("Error occurred!");
},
mimetype: "text/plain",
formNode: document.getElementById("myForm")
};
dojo.io.bind(ajaxargs);
}
</script>
Labels: AJAX, Java, Javascript, Ruby, search
Wednesday, November 08, 2006
Some dissatisfaction with Ruby
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 :-)
Tuesday, October 10, 2006
Human minds, programming, and the "caching problem"
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:
- Lisp: great for building up the language from the bottom and extending towards an application domain. The new application "programming language" is higher level and the remaining part of a system is more concise code and easier to keep track of.
- Ruby: concise, so programs are much shorter and easier to understand.
- Java: the language does little for me as far as reducing complexity, but great IDEs like IntelliJ at least allow rapid code browsing, "who calls this" queries, etc.
Monday, September 18, 2006
Persistence for object oriented languages vs. programmer efficiency
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: Java, Lisp, object mapping, Ruby
Friday, September 08, 2006
JRuby
I have been using both Ruby and Rails a lot in the last year, and have not missed Java too much. That said, an efficient Rails platform on top of a Hotspot JVM sounds good. My quick experiments with JRuby have not been totally without problems, but with Sun's obvious motivation to get a first rate Ruby environment running on the JVM, I expect things to get better. The smooth integration of Java classes in an interactive Ruby IRB shell environment is fun.
Labels: Ruby, Ruby Rails
Friday, July 28, 2006
Criticism of non-dynamic languages
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.
Friday, June 30, 2006
Incredible what a few lines of Ruby code will do
This would take a lot of code in Java, Common Lisp, etc. Unless my customers specifically ask me to use another programming language, I just about always use Ruby now.
class CreateIndex
def initialize
@index = Ferret::Index::Index.new(:path => './search_index')
ActiveRecord::Base.establish_connection(
:adapter => 'postgresql',
:host => 'localhost',
:username => 'postgres',
:database => 'test_database')
process_class(Item)
process_class(Plan)
process_class(Procedure)
process_class(Visit)
@index.close
end
def process_class the_class
the_class.find_all.each {|obj|
doc1 = Document.new
doc1 << Field.new("text", obj.attributes.values.join(' '), Field::Store::YES, Field::Index::TOKENIZED)
doc1 << Field.new("class", the_class.to_s, Field::Store::YES, Field::Index::NO)
doc1 << Field.new("id", obj.id.to_s, Field::Store::YES, Field::Index::NO)
@index << doc1
}
end
end
Labels: object mapping, Ruby
Friday, June 23, 2006
More work combining Ruby and Common Lisp
Labels: Lisp, object mapping, Ruby
Saturday, June 17, 2006
Meta object protocol in Lisp and Ruby
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: Lisp, object mapping, Ruby
Friday, June 09, 2006
Saving time with Ruby and ActiveRecord
Ruby on Rails has a deserved reputation for saving time on web application development, but you should really consider ActiveRecord a separate part of Rails that can be used standalone.
Labels: object mapping, Ruby
Wednesday, March 29, 2006
Matz on Ruby's Lisp heritage
Ruby is a language designed in the following steps: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.
* 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. ;-)
Friday, March 03, 2006
Ruby 'duck typing' addiction
Well, since both String and File classes support << (which is what I used in the first version of the code for writing to an open file), I did not have to change any code since I could just pass in an empty string instead of an open file, and return what used to the a file descriptor (instead of closing it) as the value of the accumulated text. Try that in Java or C++ :-)
Anyway, not a big deal, but it did save me refactoring some old code for a new use, saving a few minutes.
Labels: Ruby
Subscribe to Posts [Atom]
