[ANN] R7RS Scheme

Kjetil Svalastog Matheussen <[email protected]> Sun, 1 Apr 2007 23:19:29 +0200 (CEST)
Newsgroups gmane.comp.java.sisc.user
Message-ID <[email protected]>
Sisc was used to implement R7RS scheme. It may contain code someone 
might find useful.





R7RS Scheme Draft V2007-4-1
***************************
***************************


About
=====
R7RS Scheme is a Lisp dialect largely inspired by Scheme.


Summary
=======
R7RS Scheme is a statically scoped and properly tail-recursive dialect of
the Lisp programming language. It was designed to have an exceptionally
clear and simple semantics and few different ways to form expressions. A
wide variety of programming paradigms, including imperative, functional,
and message passing styles, find convenient expression in R7RS Scheme.


Introduction
============
Programming languages should be designed not by piling feature on top of
feature, but by removing the weaknesses and restrictions that make
additional features appear necessary. R7RS Scheme demonstrates that a very
small number of rules for forming expressions, with no restrictions on how
they are composed, suffice to form a practical and efficient programming
language that is flexible enough to support most of the major programming
paradigms in use today.



Implementation
==============
http://www.notam02.no/~kjetism/r7rs.tar.gz


Changes between R7RS Scheme and Scheme[1]
=========================================

* "define" can be used anywhere in an expression, just like on the 
top-level:

  (let ((a 1))
     (set! a 2)
     (define a 3)
     a)
  => 3

  (let ((a 1))
     (set! a 2)
     (define (a) (c))
     (define (c) 3)
     (a))
  => 3

  (let ((a 1))
     (set! a 2)
     (define (a) (c))
     (define (c) 3)
     (define a (+ (a) 1))
     a)
  => 4


* "include" includes code from another file:
  (define (cdr-list-copy list)
    (include "srfi-1.scm")
    (cdr (list-copy list)))


* "define-toplevel":

  (let ((a* 1))
    (define-toplevel (a)
      a*))
  (a)
  => 1

  (let ((a* 1)
        (funcname 'a))
    (define-toplevel (,funcname)
      a*))
  (a)
  => 1



* "unquote" and "unquote-splicing" can appear outside quasiquotes:
  (let ((a 1))
     ,'a)
  => 1

  (let ()
    ,(+ 8 5))
  => 14
  ("(+ 8 6)" was calculated at compile time, and not at run time)

  (let ((a 1)
        (b 2))
    ,@(map (lambda (val)
             `(begin
                (display (string-append (symbol->string ',val) "=" (number->string ,val)))
                (newline)))
           '(a b)))
  => "a=1"
     "b=2"



* Arguments are evaluated in order left to right and top to bottom:

  (let ((a 1))
     (list (begin
             (set! a 2)
             3)
           a))
  => (3 2)

  (let ((a 1))
    `(,(begin
         (set! a 2)
         3)
      ,a))
  => (3 2)

  (let ((a 1))
    (let ((b (begin
               (set! a 2)
               3))
          (c a))
      (list b c)))
  => (3 2)



* "map" works like "map-in-order" as defined in scheme/srfi-1.



* Calling "car" on the empty list returns the empty list:
  (car '())
  => ()



* Calling "cdr" on the empty list returns the empty list:
  (cdr '())
  => ()



* "eval" takes one argument only:
  (let ((a 1))
     (eval '(+ a 2)))
  => 3



* "letrec*":
  (letrec* ((a d)
            (b (lambda () (c)))
            (c (lambda () a))
            (d 1))
    (b))
  => 1




* Symbols, keywords, syntax and function names are case sensitive.




* "define-macro" does not need to be placed at the top-level.
  However, the following expression does not work:

  (let ((a 1))
    (define-macro (gakk val)
      `(+ ,val a)))
  (gakk 2)
  => Error, undefined varible "a" in expression "(gakk 2) => (+ 2 a)"



* "macroexpand" and "macroexpand-1" are guaranteed to return expressions
  where the transformations are defined only by the use of "define-macro".

  For example, "define-macro" is not used to implement core functionality
  such as "cond" or "letrec*". So this will always work in a clean
  environment:

  (macroexpand '(cond (#t 5)(else 6)))
  => (cond (#t 5)(else 6))



* "(gensym)" returns a unique symbol. Handy for macros.



* Macros can be used as functions:

  (define-macro (add . rest)
     `(+ ,@rest))

  (apply add '(1 2))
  => 3

  (let ((list '(1 2)))
    (apply add list)
  => 3

  (map add '(1 2) '(3 4))
  => '(4 6)


  Max 30 arguments, and the macro must be defined before being referenced.



* Keywords:

  (list :this-is-a-keyword 'this-is-a-symbol)
  => (:this-is-a-keyword this-is-a-symbol)

  (keyword->symbol :gakk)
  => gakk

  (symbol->keyword 'gakk)
  => :gakk

  (keyword->string :gakk)
  => "gakk"

  (string->keyword "gakk")
  => :gakk

  (keyword? :gakk)
  => #t

  (keyword? 'gakk)
  => #f



* No hygenic macros. (Programming languages should be designed not by
  piling feature on top of feature, but by removing the weaknesses and
  restrictions that make additional features appear necessary).




Notes
=====

[1] As defined by the r5rs specification.





-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV