Dear List,
I have the following procedure that takes a list of vectors or a list of
lists and flattens the list to create a structure called `f64matrix'.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;;this can be a list of lists, list of vectors, or a flat list
;; it would be better to only write out this error once, instead of three times
(define (list->f64matrix lst #!optional rows cols)
(letrec ((rows->f64matrix
;; this procedure delegates in the uncertain case of
;; (list->f64matrix lst #f #f)
(lambda (lst)
;; is the list a list of lists?
(cond ((list? (car lst))
(lol->f64matrix lst))
;; or is it a list of vectors?
((f64vector? (car lst))
(lov->f64matrix lst))
;; otherwise it is one row
(else (lst->f64matrix lst 1 (length lst))))))
(lst->f64matrix
;; this procedure actually makes the matrix given n rows
;; and m columns and a list
(lambda (lst rows cols)
(if (= (* rows cols) (length lst))
(make-f64matrix rows cols (list->f64vector lst))
(error "Not enough elements for given dimensions"))))
(lol->f64matrix
;; this procedure takes a list of n lists of length m and
;; passes a flattened version of lol to (lst->f64matrix
;; lol n m)
(lambda (lol)
(let ((rows (length lol))
(cols (length (list-ref lol 0)))
(flatlol (flatten lol)))
(if (= (* rows cols) (length flatlol))
;; flatten the list
(lst->f64matrix flatlol rows cols)
(error "Not enough elements for given dimensions")))))
(lov->f64matrix
;; This procedure transforms a list of n f64vectors of
;; length m into a list and passes it to lst->f64matrix
;; with n rows and m columns
(lambda (lov)
(let ((rows (length lov))
(cols (f64vector-length (list-ref lov 0)))
(flatlov (f64lov-flatten lov)))
(if (= (* rows cols) (f64vector-length flatlov))
;; flatten the vectors into one vector or list
(lst->f64matrix flatlov rows cols)
(error "Not enough elements for given dimensions"))))))
;; execution starts here:
;;
;; gatekeeper: if rows and columns is #f
;; then send to the delegating procedure rows->f64matrix, whose
;; default function is to set a flat list to the data element of a
;; matrix with one row
(cond ((and rows cols)
;; lst->f64matrix only takes lists because if you need to
;; specify rows and columns and your input is a vector, you
;; should just use make-f64matrix
(lst->f64matrix lst rows cols))
(else (rows->f64matrix lst)))))
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
This requires `flatten', defined by
;;;;;;;;;;;;;;;;;;;;list.ss;;;;;;;;;;;;;;;;;;;;
;; -*-mode:scheme-*-
;; list operations
;; flatten
;; this macro works on lists, however I encounter some funny behavior
;; since macros don't evaluate their arguments
;;(define-syntax flatten
;; (syntax-rules ()
;; ;; base case to stop recursion
;; ((flatten (l1 l2 ...)) (list l1 l2 ...))
;; ((flatten (l1 l2 ...) l3 ...)
;; (append (list l1 l2 ...) (flatten l3 ...)))))
(define (flatten lol)
(cond ((null? lol) '())
((not (pair? lol)) lol)
(else (append (car lol)
(flatten (cdr lol))))))
;; vector-list-flatten
(define (f64lov-flatten lov)
(cond ((null? lov) '())
((not (pair? lov)) (f64vector->list lov))
((not (f64vector? (car lov))) (error "f64vector expected"))
(else (append (f64vector->list (car lov))
(f64lov-flatten (cdr lov))))))
;;end list.ss
Here's the problem: this (list->f64matrix) compiles just fine when I
define `flatten' as a function (flatten works just fine as a function,
but I need to work on macros, so I decided to try it as a macro).
However, if I copy ~~/syntax-case.scm to gambcext.scm and then compile,
I get an "invalid syntax" error during compilation.
What changes when I load "~~/syntax-case"? Does the definition of
letrec change?
I appreciate any comments on the code, as well.
Thanks!
Joel
--
Joel J. Adamson
Biostatistician
Pediatric Psychopharmacology Research Unit
Massachusetts General Hospital
Boston, MA 02114
(617) 643-1432
(303) 880-3109
The information transmitted in this electronic communication is intended only
for the person or entity to whom it is addressed and may contain confidential
and/or privileged material. Any review, retransmission, dissemination or other
use of or taking of any action in reliance upon this information by persons or
entities other than the intended recipient is prohibited. If you received this
information in error, please contact the Compliance HelpLine at 800-856-1983 and
properly dispose of this information.