Scripting OS X with Scheme

Scheme-OSA stands for Open Scripting Architecture. It provides an abstract interface for applications to compile, execute, and manipulate scripts without needing to know the details of the particular scripting language. Scheme-OSA bridge furnishes a Scheme user with a means of accessing the OS X multimedia and other resources from Apple and the third parties – introducing graphics, scientific plotting, dialog boxes, music, etc. into the world of Scheme language.

(via comp.lang.scheme)

How to do something to all elements of a list but the last

In this post on the PLT discussion list I sleepily wondered how to do something to all elements of a list but the last.

The reasons I asked is because I had used ‘do’ loops in lieu of something better, and from what I can gather, you basically never write ‘do’ loops in Scheme (maybe once every 30 years you do use ‘do’).

I hastily posted a solution using the ‘match’ library as I had just read the documentation while cutting over from ‘mzlib/match’ to ‘match’. Both Robby and Ethan replied with much, much faster solutions. Have a look:


#lang scheme

(require (prefix-in srfi/1: srfi/1))

; Grant's
(define (foo1 args fun last-fun)
  (match args
    [(list arg args ..1)
     (fun arg)
     (foo1 args fun last-fun)]
    [(list arg)
     (last-fun arg)]))

(provide/contract
 [foo2 (-> (cons/c any/c (listof any/c))
           (-> any/c any)
           (-> any/c void?)
           void?)])

; Robby's
(define (foo2 args fun last-fun)
  (let loop ([fst (car args)]
             [rst (cdr args)])
    (cond
      [(empty? rst) (last-fun fst)]
      [else (fun fst) (loop (car rst) (cdr rst))])))

(define data (srfi/1:make-list 10000 "hi"))

; Ethan's
(define (foo3 lst fun funl)
  (begin
    (for-each fun (srfi/1:drop-right lst 1))
    (funl (srfi/1:take-right lst 1))))

(time
 (foo1 data
       (λ (x) (void))
       (λ (x) (void))))

(time
 (foo2 data
       (λ (x) (void))
       (λ (x) (void))))

(time
 (foo3 data
       (λ (x) (void))
       (λ (x) (void))))

> cpu time: 2593 real time: 2625 gc time: 718
> cpu time: 0 real time: 0 gc time: 0
> cpu time: 0 real time: 0 gc time: 0

In the end, I only needed this functionality in two places, and I probably would not have required it if I had designed things better in the first place.

Joel Bartlett’s Famous Scheme->C System

Joel Bartlett’s original Scheme->C system has been in stealth mode for some years now, but with a recent re-license under F/OSS terms by HP, the allocation of a web site http://scheme2c.alioth.debian.org/, the integration of all known useful patches including LINUX/i386 and LINUX/amd64 ports, and uploading into the Debian incoming queue, this zippy R4RS Scheme is on the move again!

(via comp.lang.scheme)

An alternate syntax for let

In this post I wondered how one might implement an alternate syntax for let (described in this C.L.L. post), which looks like this:

(let (x 0 y 1 z 2) (+ x y z))

As it turns out my solution was actually let*, and therefore wrong.
Nonetheless, here is wonderful macro provided by Jos that both implements the alternate syntax for let and also demonstrates a technique for how to use the equivalent of “temporary variables” inside of a macro:

(define-syntax my-let
  (syntax-rules ( )
    ((_ my-bindings body-expr0 body-expr ...)
     (my-let-aux my-bindings ( ) body-expr0 body-expr ...))))
(define-syntax my-let-aux
  (syntax-rules ( )
    ((_ ( ) (binding ...) body-expr0 body-expr ...)
     (let (binding ...) body-expr0 body-expr ...))
    ((_ (var value-expr . rest) (binding ...) body-expr0 body-expr ...)
     (my-let-aux rest (binding ... (var value-expr)) body-expr0 body-expr ...))))
(my-let (x 1 y 2 z 3)
        (+ x y z))