Michael Weber: Random Bits and Pieces

Lisp Logo (by Conrad Barsky)

Mikel Evins has released Apis, a sample Common Lisp Cocoa application using CCL's Cocoa bridge. Obligatory screenshot:

Apis screenshot

For what it's worth, Mikel also provides Atta, which is a similar project but based on Gambit Scheme.

Lisp Logo (by Conrad Barsky)

Today I stumbled upon the discussion forum for ILC2009. Why did Planet Lisp not tell me before? Slackers.

Lisp Logo (by Conrad Barsky)

Some time ago, I translated Gregor Kiczales' Tiny-CLOS to Common Lisp and Java: MW-TINY-CLOS and jCLOS.

The Common Lisp port is probably not very interesting, this was mostly a warm-up exercise. Only when I was mostly finished, I found Kiczales' original CL (back?)port.

For jCLOS, package jclos contains all functionality. The main method contains some straight-forward example code, which creates an object with two slots x and y, an instance, and a method on the print generic function.


public static void main(String[] args) {
    System.out.println("JCLOS booted.");

    CLOSInstance POS = defineClass(null, null, 
            Arrays.asList(new DirectSlotDefn[]{
                    new DirectSlotDefn(Symbol.intern("x")),
                    new DirectSlotDefn(Symbol.intern("y"))
                }),
            Symbol.intern("<pos>"));
    
    System.out.println(POS);

    CLOSInstance pos = make(POS);
    pos.setSlot(Symbol.intern("x"), 42);
    System.out.println(pos.slot(Symbol.intern("x")));

    CLOSInstance print = makeGeneric();
    addMethod(print,
            makeMethod(Collections.singletonList(OBJECT),
              new StdCallable() {
                  @Override
                  public Object apply(Object[] args) {
                      System.out.println("'" + args[1] + "' is an OBJECT!");
                      return null;
                  }
              }));
    /* ... */
    print.call(POS);
    print.call(pos);
}

I find it quite self-evident that Java is sorely missing some kind of facility for syntactic abstraction. The Java camp appears to disagree, and as Dan Weinreb reports from ILC2009, there are even Lispers thinking that macros are a net drawback!

Regarding jCLOS, I have some ideas what to do with it. However, this might take a while. Short-term, the next step should be to simplify the current implementation as much as possible, for example by getting rid of symbols and keyword arguments. Also, the poor-man's closure objects could probably benefit from some clean-up. (Incidentally, perhaps I should switch to Javascript, just for its support for anonymous functions.)

Some more interesting changes involve the implementation of jCLOS slots (taken over from Tiny-CLOS) in terms of fields. Other/better approaches are known for quite a while:

Shigeru Chiba, Gregor Kiczales, John Lamping: Avoiding Confusion in Metacircularity: The Meta-Helix. ISOTAS 1996: 157–172.

Generally, a cleaner way to avoid meta-stability and circularity issues is also on my list of things to look into.

I also remember a posting by Scott McKay about class slots versus accessors, which is probably also worth following up on (in particular in combination with CHANGE-CLASS like functionality).

A from-scratch version of the Bottle Song in Lisp: bottle-song.lisp. We can see some nice features of FORMAT in action (conditionals, relative & absolute go-to, user extensions, pluralization, radix control, case conversion, etc.), but by far not everything that is offered.


;; * clisp bottle-song.lisp

(in-package :cl-user)

(defun bottle-song (&optional (in-stock 99) (stream *standard-output*))
  ;; Original idea by Geoff Summerhayes <sumrnot@hotmail.com>
  ;; Formatting idea by Fred Gilham <gilham@snapdragon.csl.sri.com>
  ;; Actual formatting & minor recoding by Kent M Pitman
  ;;   <pitman@world.std.com>
  ;; Redone for conformance to <http://www.99-bottles-of-beer.net/>
  ;;   by Michael Weber <michaelw@foldr.org>.
  (format

              stream
            "~v{~1&~0%~
             ~000000%~
             ~000000%~
             ~000000%~
            ~00000000%~
           ~:/bottles/ ~
         of beer on ~000%~
         the wall, ~001:*~
         ~99/bottles/ of ~
         beer.~1:*~%~[Go ~
         to the store and~
         ~000@* buy some ~
         more, ~/bottles/~
         ~00% of beer on ~
         the wall.~01%~:;~
         Take one down an~
         d pass it around~
         , ~999/bottles/ ~
         ~:*of beer on th~
         e wall.~002%~]~}"
           (1+ in-stock)

   (loop for bottle from in-stock downto 0 collect bottle)))

(defun bottles (stream arg &optional colonp atp &rest args)
  (declare (ignore atp args))
  (format stream "~[~:[n~;N~]o more bottles~:;~:*~A bottle~:*~P~]"
          arg colonp))

(bottle-song)

Alternatively, numbers can be printed as (properly capitalized) words with:


(defun bottles (stream arg &optional colonp atp &rest args)
  (declare (ignore atp args))
  (format stream "~[~:[n~;N~]o more bottles~:;~
                  ~:[~2:*~R~;~2:*~@(~R~)~] bottle~:*~P~]"
          arg colonp))

Ninety-nine bottles of beer on the wall, ninety-nine bottles of beer.
Take one down and pass it around, ninety-eight bottles of beer on the wall.

Ninety-eight bottles of beer on the wall, ninety-eight bottles of beer.
Take one down and pass it around, ninety-seven bottles of beer on the wall.

[…]

UPDATE 2009-04-08: Fame, at last!

Zach Beane showed the bottle song sources (in form of a Format Automotivator) during his ILC2009 lightning talk about the Wigflig imperium!

Format Automotivator Poster (by Zach Beane)
Lisp Logo (by Conrad Barsky)

Rainer Joswig has an awesome library of Lisp books!

Page 1/10: 1 2 3 4 5 6 7 8 9 »