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
Afficher les réponses par date