On Scheme

Thoughts on Scheme and teaching Scheme

Archive for March 7th, 2006

An if extension

Posted by Peter on March 7, 2006

I have noticed that the if statement can be a bit tricky for the new programmer. Not because they don’t understand how it works, but because they wish to put more than one statement for the positive or negative clause, especially when debugging. I am reluctant to direct a new student to the more complicated looking cond, and likewise begin can make their programs too intimidating.

My solution was to create a new if, the lif, which separates the positive clause from the negative with an else, here is an example of what it should look like in actions:

(lif (null? x)
  (display x)
  (display (cdr x))

Initially I thought this would be an easy task, but scheme’s pattern matchers in their macros will only accept one at a given level of nesting, so I was forced to write an intermediate macro called lif-i

  (define-syntax lif-i
    (lambda (x)
      (syntax-case x (else)
          (lif-i condition else (neg ...))
          (syntax (unless condition (begin neg ...)))
          (lif-i condition pos ... else (neg ...))
          (syntax (if condition (begin pos ...) (begin neg ...)))
          (lif-i condition pos ...)
          (syntax (if condition (begin pos ...)))

If we were to use lif-i directly it would look like:

(lif-i (null? x)
  (display x)
  ((display (cdr x))

lif could then be implemented as a macro that collects the statements after an else into a list, and then uses lif-i to do the rest of the work.

  (define-syntax lif
    (lambda (x)
      (let ((lst (cdr (syntax-object->datum x))))
        (letrec ((elser (lambda (l)
                          (cond ((null? l) '())
                                ((eq? (car l) 'else) (list 'else (cdr l)))
                                (else (cons (car l) (elser (cdr l))))))))
          (datum->syntax-object (syntax k) (cons 'lif-i (elser lst)))))))

Posted in Teaching Scheme | 3 Comments »

Teaching Scheme: defun

Posted by Peter on March 7, 2006

Hello, and welcome to my blog-thingy.

In this blog I may occasionally wander to other topics, but I will mainly stick to my experiments with scheme and my experiences in teaching it to a new programmer.

To begin teaching a new programmer the first thing I did was to create a standard include file that they could include in their programs that would give them access to functions and macros that would simplify their programming and learning experience. The first function/macro I wrote for this file was defun, listed straight from common lisp. The motivation behind this was to give the beginning student the ability to create their own functions on the first day of using scheme without any confusion. I rejected the (define (name params) body) syntax for this purpose because it can create a confusion between the name of the function and its parameters. Likewise I rejected the (define name (lambda (params) body)) syntax because it adds an extra level of parenthesis to the function declaration, as well as creating confusion about lambda. Defun however, which for those of you who have never seen it before is used thus: (defun name (params) body), has neither of these problems. The only downside however is that lambda is completely new when it is introduced as a way of making functions at runtime.

The defun maco is as follows:

(define-syntax defun
      (syntax-rules ()
      ((defun a b ...) (define a (lambda b ...)))))

If you have any comments regarding defun, or any suggestions as to how to introduce functions to the new programmer I would be happy to hear them.

p.s. If anyone could give me a tip as to how to write properly indented code in here without jumping though hoops that would be appreciated.

Posted in Teaching Scheme | Leave a Comment »