Tuesday, October 31, 2006

Ruby falls short

An intesting post which mirrors my feelings about Ruby exactly: the syntax is too complex, and a lot of stuff that should be library is hard-wired into the language. And Ruby blocks are inconsistent and limited. I still think Ruby is decent, but if it had better performance by an order of magnitude, and cleaner syntax and semantics, it would be killer.

cl-darcs

If you want to try the latest Factor development code, but are using a platform supported by Factor but without a ported Haskell environment (for example, Solaris/x86 -- this may be the only such platform) then you can try cl-darcs, implemented in Commmon Lisp.

Saturday, October 28, 2006

Friday, October 27, 2006

Cat programming language 0.9

Christopher Diggins has released Cat 0.9. This version adds a new unit test suite intended to shake out bugs from the static type inferencer, and also now works on Mono.

Monday, October 23, 2006

Factor talk at MSLUG, November 22nd

I will be presenting about Factor at MSLUG, the Montreal Scheme/Lisp Users Group, on Wednesday November 22nd.

Saturday, October 21, 2006

Module documentation

I have changed the syntax for module definitions; here is the one for concurrency to demonstrate the new syntax. Note that you can now specify a main help article for your module, and I encourage everybody to document their modules now:
! Copyright (C) 2005 Chris Double. All Rights Reserved.
! See http://factorcode.org/license.txt for BSD license.
!
REQUIRES: contrib/dlists contrib/serialize contrib/match ;

PROVIDE: contrib/concurrency
{ +files+ {
"concurrency.factor"
"concurrency.facts"
} }
{ +tests+ {
"concurrency-tests.factor"
} }
{ +help+ { "concurrency" "concurrency" } } ;

What Factor is missing now is a nice graphical tool to browse modules, load them, run their main entry points, jump to module documentation, and jump to source files making up the module. This will come in 0.86.

Double-click support in UI

Me and Doug Coleman implemented double click recognition in the UI. While Windows and Cocoa have native APIs to get multiple click counts from events, Windows only reports double clicks, not triple clicks, and X11 doesn't have this at all. So this is done in a purely cross-platform manner, except the system default double click timeout is used on Windows.

Basically before a button-down gesture is sent, the global hand-click# variable is incremented if necessary. Here is an example from the editor gadget:
: editor-mouse-down ( editor -- )
hand-click# get {
[ ]
[ dup position-caret ]
[ dup T{ word-elt } select-elt ]
[ dup T{ one-line-elt } select-elt ]
} ?nth call drop ;

The click count is used to index an array of quotations. Nice and neat. Then we add this command to the "caret" command table:
editor "caret" {
{ "Position caret" T{ button-down } [ editor-mouse-down ] }
{ "Previous character" T{ key-down f f "LEFT" } [ T{ char-elt } editor-prev ] }
{ "Next character" T{ key-down f f "RIGHT" } [ T{ char-elt } editor-next ] }
... more commands ...
} define-commands

Thursday, October 19, 2006

Module main entry points

Modules can now define an entry point. Here is the updated contrib/tetris/load.factor:
! Copyright (C) 2006 Alex Chapman
! See http://factorcode.org/license.txt for BSD license.

REQUIRES: contrib/lazy-lists ;

PROVIDE: contrib/tetris {
"tetris-colours.factor" "tetromino.factor" "tetris-piece.factor"
"tetris-board.factor" "tetris.factor" "tetris-gl.factor"
"tetris-gadget.factor"
} {
"test/tetris-piece.factor" "test/tetris-board.factor" "test/tetris.factor"
} ;

USE: tetris-gadget

MAIN: contrib/tetris tetris-window ;

This means with the latest darcs code (not 0.85) you can now run Tetris simply by starting Factor and entering the following:
"contrib/tetris" run-module
The module is loaded first (unless it has already been loaded).

Factor 0.85 released

Factor 0.85 is now available. Check out the change log. Thanks to Doug Coleman for the Windows package and Alex Chapman for the Mac OS X Intel package.

Chris Double found a silly regression: the contrib/furnace module does not load. Now this module is not very useful yet, but nevertheless, I did ensure that all modules load before releasing 0.85, then went ahead and made some changes to Furnace without testing if they load in a fresh image. How foolish. Anyway if you feel like taking a look at the new incomplete web framework, you should use the latest code from the Darcs repository instead.

Embedding a stack language in Haskell with static type checking

Kevin Reid has been playing around with this.

Factor tetris

Alex Chapman (author of the OpenGL binding and gap buffer data structure) has submitted a tetris game written in Factor to contrib. To run it, you probably need Factor from darcs, and then:
"contrib/tetris" require
USE: tetris
tetris-window

It looks like this:

The implementation uses an infinite lazy list to draw the next piece from. That is just so cool.

Tuesday, October 17, 2006

You know you're a Forth (or Factor) geek when...

...you type .s in bash to get a file listing. I do this all the time, and a few other people on IRC mentioned the same thing. It's funny.

Parser combinators example

Chris Double has put together a lovely example of parsing s-expressions using his parser combinators library.

Parser combinators are one of the Haskell community's nicest contributions to computer science at large.

Monday, October 16, 2006

Working on a Factor web framework

Factor has some components of a web framework already:
  • contrib/httpd - basic request processing
  • contrib/embedded - reads a file, evaluates Factor code between <% and %>, and dumps the result
  • contrib/xml

I'm working on a web framework named Furnace which builds on these components and adds features to help construct typical CRUD web applications. It is located in contrib/furnace and is almost non-existent at this point, but my goals are to have it do the following:
  • Action processing, forwarding
  • Form validation
  • HTML component management
  • Templating

I still haven't decided how templating will work in the end:
  • Right now I'm using contrib/embedded because it is simple and the code is there
  • Pure-HTML templates marked up with 'id' attributes (like Wicket)
  • XML templates, mixing HTML with custom Factor tags but no Factor code

The last two approaches have potential to be cleaner, because right now the contrib/embedded templates feel boilerplate-ish:
<tr><th>Paste by:</th><td><% "author" get write %></td></tr>
<tr><th>Channel:</th><td><% "channel" get write %></td></tr>
<tr><th>Created:</th><td><% "date" get write %></td></tr>

I think some custom tag, or "id" attributes on the <td> tags would be prettier.

So far the example web app I've been building in parallel with the framework is a pastebin. Once the framework has enough features to make the pastebin support all the necessary features (navigation, validation, etc) with pleasing and simple code, I want to build a wiki and blog, and then eat my own dog food, using Factor to host this web log. I expect these CRUD-style web apps to be trivial to build once the framework is done.

Note that I haven't said anything about persistence yet. For a pastebin, a global variable holding a list of tuples is enough, but obviously for a wiki or weblog this is horribly insufficient. We have code in contrib for interfacing with PostgreSQL and SQLite, Chris Double has a simple O/R mapper that maps Factor tuples to SQLite table rows, and Doug Coleman has expressed interest in extending this to a more general O/R mapper. Pending some kind of miracle whereby an object database written in Factor suddenly appears, the preferred method of persistence in Furnace will be an SQL database together with an O/R mapper.

I plan on integrating Chris Double's work on continuation-based control flow, however the standard "REST" style will be preferred in most cases. Chris Double has also been working on a Factor library for writing web applications using the Comet style. I know very little about JavaScript, but integrating this with Furnace, along with other client-side features such as validation and completion would be nice.

Crash while running unit tests caused by unit tests

I spent an hour last night on a weird crashing bug that manifested itself on Windows: if you ran test-modules from the UI a few times, it would eventually crash Factor in unpredictable ways. I narrowed this down to the test for I/O buffers, which are low-level character queues, allocated in malloc() space, for when the Factor implementation needs to call native I/O functions with a pointer which will not be moved by the GC.

Now one of the unit tests created two buffers from a pair of strings, appended one to the other, then converted the result to a string, and compared the result against the expected string. Unfortunately, the word to append them was written rather carelessly. It used memcpy to copy the contents of one buffer to another, without checking bounds and growing the buffer first. The result? Random crashes, yet amazingly they never appeared on Linux or Mac OS X.

Lessons learned? Well, I knew all of these already, but this incident underscores them:
  • Pointer arithmetic is dangerous. Fortunately I don't believe in "hair shirt" programming, so Factor makes minimal use of unsafe constructs, only resorting to direct memory manipulation when calling C code which wants us to deal with C data. User programs never have to step outside the memory safe sandbox.
  • When unit tests fail, it doesn't necessarily imply the code being tested is buggy. The unit tests could be broken too! The reason it took me a long time to track down the bug is simply that I did not think to check the unit tests themselves, since after all, the buffers test passed most of the time.
  • Testing on multiple platforms helps weed out bugs.

Saturday, October 14, 2006

Common Lisp IDE built on Eclipse

I know some people don't like the dated user interface of Emacs, so Cusp might be interesting. This is a plugin for Eclipse which uses the same backend (Swank) as SLIME for Emacs and provides similar features, however at this point it looks a lot less mature than SLIME.

Using the X11 UI on Mac OS X

One of the mailing list participants noted that the Cocoa UI does not run on Mac OS X 10.3. Getting this working is not a high priority, since after all 10.4 has been out for quite some time and I'd rather focus on new features and bug fixes than backwards compatibility.

However I did make it easy to build Factor so that the X11 UI may be used. First you compile with an extra flag passed to make:
make macosx-ppc X11=1
Then you bootstrap with two special switches:
./f boot.image.ppc -no-cocoa -x11
That is all. You do not need to build a Factor.app as with the Cocoa UI, you can just set $DISPLAY and run ./f.

Friday, October 13, 2006

Interface builder, Cocoa, and interactive development

I went ahead and scrapped the Factor code which defines Factor's menu bar on Mac OS X in favor of using Interface Builder to set the menu bar up. I discovered that Cocoa is fully capable of reloading nib files at runtime.

Factor can subclass Objective C classes. Until now however, the definition would only be entered if the class did not already exist, so if you changed some method definitions and reloaded the source file which contains them, the methods would not be visible to the Objective C runtime until you restarted Factor. I fixed this so that method definitions are replaced on the fly when a new Objective C class is defined in Factor, even if the class already exists in the runtime.

Together with the nib reloading, I can add a menu item together with the corresponding action, and observe the result instantly.

Factor is now a better Objective C (and XCode) than Objective C (and XCode).

Monday, October 09, 2006

Three cheers for C syntax

I found this lovely snippet in a C application which shall remain nameless:
void interpreter( void ) { for(;;) (*(prim *)(intptr_t)*(cell *)(intptr_t)(*++lc))(); }

So, which pairs of brackets correspond to casts, grouped expressions, and function invocations? What is the operator precedence between casts, dereferencing, and pre-increment? I really don't know.

Here is the PowerPC disassembly:
0x00002488 :     mflr    r0
0x0000248c : bcl- 20,4*cr7+so,0x2490 interpreter+8
0x00002490 : stmw r30,-8(r1)
0x00002494 : mflr r31
0x00002498 : stw r0,8(r1)
0x0000249c : stwu r1,-80(r1)
0x000024a0 : addis r2,r31,0
0x000024a4 : lwz r30,23748(r2)
0x000024a8 : lwz r2,0(r30)
0x000024ac : addi r2,r2,8
0x000024b0 : stw r2,0(r30)
0x000024b4 : lwz r9,4(r2)
0x000024b8 : lwz r0,4(r9)
0x000024bc : mr r12,r0
0x000024c0 : mtctr r0
0x000024c4 : bctrl
0x000024c8 : b 0x24a8 interpreter+32

Now if I wanted to figure things out, I could spend 5 minutes going through every instruction and keep track of registers with a paper and pen, but at least its possible. Not so with the C code.

Like watching a puss-filled boil explode in slow motion

Reading this (which is only the latest in a long saga of closure debates on Java sites) makes me glad I don't program in Java anymore. I personally think it is too late to add closures to Java, simply because the existing libraries are not designed for it, but the responses posted in discussions such as these are so comical that I want to see closures added just so that these guys get pissed off.

Come on now enterprise monkeys, make up your mind: are closures simply for newbie "script kiddies" who are not man enough to use a 400$ keyboard macro IDE? Or are they so complex that newbies cannot learn them (nevermind the extremely convoluted anon inner class syntax). Or are they easy to learn but simply unsuitable for serious Enterprise(tm) team development?

This is sort of like watching assembly freaks debate if parameters should be passed in registers or on the stack... or if subroutine calls are any good at all. Those of us in the know have moved on long ago.

Enchilada programming language

The Enchilada language now has a home page.

Saturday, October 07, 2006

Swapping two variable values

I thought this was kind of nifty when I first thought of it:
: swap-vars [ [ get ] 2apply ] 2keep [ set ] 2apply ;
For example:
5 "x" set
7 "y" set
"x" "y" swap-vars
"x" get "y" get 2array .
==> { 7 5 }

Completion and right-click popups in the UI

I've been pretty busy with my mathematics research lately as I've managed to prove some pretty nice results. However things have not all been quiet on the Factor front.

Documentation for the below features is forthcoming, but for now the below is as good as it gets. You can press TAB to get a keyboard-navigatable, automatically updating, buzzword compliant completion popup:

If you press Up/Down to select a word followed by Enter, the word name is inserted in the input area. Instead you can right-click on the word to see a menu of other commands.
Now if you press C+e, you get the same popup, but instead it completes loaded source file names; again pressing Enter opens the file in your editor (if you've previously loaded a module such as contrib/jedit or contrib/emacs) and a right-click offers another option, running the file -- note that this works for loaded contrib modules too, not just core library files, and in the future there will be a more extensive integrated module browsing tool than this:

Finally, you can press C+u to get a vocabulary completer, where the default operation is to USE: the vocabulary and from the popup menu you can also browse it or IN: it -- this screenshot shows the popup menu (yes its ugly):

Some of you will remember that the Factor UI used to have popup menus, then they disappeared, then in the recent darcs release I started using the three mouse buttons to invoke different object operations, and now menus are back again. I have a hard time making my mind up on certain issues, but my code does tend to slowly converge on a preferred approach. In either case, I think its better than picking an approach and religiously sticking with it, despite observations that it may be better to do things differently.

Tuesday, October 03, 2006

bigForth

I didn't realise bigForth had a good compiler until I saw this. It does a lot better in this benchmark that gForth did.

Sunday, October 01, 2006

Single stepping

With a stack language, single stepping has a certain intuitive appeal, and there is no ambiguity when it comes to what will happen next. Single stepping through C, on the other hand, is an exercise in frustration. Suppose you have a piece of code like:
foo(bar(),baz())
If I want to step over the calls to bar() and baz(), but step into foo(), it appears that I'm out of luck, at least in gdb. You can set a breakpoint on foo(), or just step into the nested function calls and then step out, but it wastes time and breaks concentration.
I like having a programmer-visible stack. It seems to shorten the 'round trip time' between my brain and the computer.