From: Martin M. <ma...@ma...> - 2013-11-09 16:08:03
|
Sorry to trouble you all - I solved that myself. It appears that SBCL does not de facto apply a coercion to the lambda list, by making an explicit coercion my code works. I should have seen that .. Specifically, if I replace the function this like this: (defun afir (coeff &key (dt 1e-9) (from (/ 0.01 dt)) (to (/ 3 dt)) (dec 100)) (let* ((z *(co**erce **`(lambda (z) (+ ,@(loop ** ** for c in coeff** ** for i from 1** ** collect `(* ,c (expt z ,(- i))))))** ** 'function)*) (x (dolog (nil from to :dec dec)))) (values (map 'list #'(lambda (x) (db (funcall (amp-from-z z dt) x))) x) x))) Then all is good. Thank you for reading it anyhow... Martin M ------------------------------------------------------------------------ Dear SBCl team: You need no solve this (but if you could that would be excellent!) --- just point me in the right direction. Here are few forms that make use of LISP's ability to construct a function from data. The task is to find the amplitude response of a finite impulse response filter, which mathematically corresponds to the evaluation of a complex quantity that LISP can handle very well. The issues is that the expression to be evaluated is variable depending on the data (the impulse response) given. As you can see I simple construct the correct lambda expression from the backquote'ed list in the function #'afir. This form works on ACL as you can see, but gets an error on SBCL. I do not think there is anything other than CL here (ie there is no ACL specific code being called). Clearly the difference lies in how SBCL treats the constructed lambda expression in the afir code. ACL seems to accept this as of type function, but SBCL does not. What is the ANSI spec on this distinction? Thank you for any guidance. Martin M *Here on ACL 9.0:* International Allegro CL Enterprise Edition 9.0 [Windows] (May 1, 2013 9:29) Copyright (C) 1985-2012, Franz Inc., Oakland, CA, USA. All Rights Reserved. This development copy of Allegro CL is licensed to: [TC10560] ESS Technology ; Loading C:\Users\Martin\quicklisp\setup.lisp ; Fast loading C:\acl90\code\ASDF.002 ;;; Installing asdf patch, version 2. ;; Optimization settings: safety 1, space 1, speed 1, debug 2. ;; For a complete description of all compiler switches given the ;; current optimization settings evaluate (EXPLAIN-COMPILER-SETTINGS). CL-USER(1): (progn (defconstant +j*2pi+ (* 2 pi (sqrt -1))) (defun db (x) (* 20 (log (max (abs x) 1e-38) 10))) (defun amp-from-z (function-of-z &optional (sample-period 1.0)) #'(lambda (f) (abs (funcall function-of-z (exp (* sample-period +j*2pi+ f)))))) (defmacro dolog ((var &optional (from 1.0) (to (* from 10)) (type :dec) (by 10)) &body body) "Iterate logarithmically: var is bound to a log sequence between from and to. If var is NIL the dolog form returns the log values" (if var `(do ((,var ,from (* ,var (expt ,(ecase type (:dec 10) (:oct 2)) (/ ,by)))) (%var% 0 ,var)) ((> %var% ,to)) ,@body) `(let ((%vals% nil)) (do ((%var% ,from (* %var% (expt ,(ecase type (:dec 10) (:oct 2)) (/ ,by)))) (%var1% 0 %var%)) ((> %var1% ,to)) (push %var% %vals%)) (reverse %vals%)))) (defun afir (coeff &key (dt 1e-9) (from (/ 0.01 dt)) (to (/ 3 dt)) (dec 100)) (let* ((z `(lambda (z) (+ ,@(loop for c in coeff for i from 1 collect `(* ,c (expt z ,(- i))))))) (x (dolog (nil from to :dec dec)))) (values (map 'list #'(lambda (x) (db (funcall (amp-from-z z dt) x))) x) x))) (afir '(1 -1)) ) (-24.037831696994914d0 -23.83789897195664d0 -23.637969121039593d0 -23.438042621760005d0 -23.23811988520433d0 -23.038200542312467d0 -22.83828509802824d0 -22.638373410872997d0 -22.43846626347723d0 -22.238563196393862d0 ...) (1.0e+7 1.023293e+7 1.0471286e+7 1.0715194e+7 1.0964783e+7 1.1220186e+7 1.1481538e+7 1.1748978e+7 1.2022647e+7 1.2302691e+7 ...) *And here on SBCL: C:\Users\Martin>SBCL This is SBCL 1.0.37, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>. SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. This is experimental prerelease support for the Windows platform: use at your own risk. "Your Kitten of Death awaits!" ; in: LAMBDA NIL ; (ASDF::PARSE-WINDOWS-SHORTCUT ASDF::SHORTCUT) ; ; caught STYLE-WARNING: ; undefined function: PARSE-WINDOWS-SHORTCUT ; ; compilation unit finished ; Undefined function: ; PARSE-WINDOWS-SHORTCUT ; caught 1 STYLE-WARNING condition * (progn (defconstant +j*2pi+ (* 2 pi (sqrt -1))) (defun db (x) (* 20 (log (max (abs x) 1e-38) 10))) (defun amp-from-z (function-of-z &optional (sample-period 1.0)) #'(lambda (f) (abs (funcall function-of-z (exp (* sample-period +j*2pi+ f)))))) (defmacro dolog ((var &optional (from 1.0) (to (* from 10)) (type :dec) (by 10)) &body body) "Iterate logarithmically: var is bound to a log sequence between from and to. If var is NIL the dolog form returns the log values" (if var `(do ((,var ,from (* ,var (expt ,(ecase type (:dec 10) (:oct 2)) (/ ,by)))) (%var% 0 ,var)) ((> %var% ,to)) ,@body) `(let ((%vals% nil)) (do ((%var% ,from (* %var% (expt ,(ecase type (:dec 10) (:oct 2)) (/ ,by)))) (%var1% 0 %var%)) ((> %var1% ,to)) (push %var% %vals%)) (reverse %vals%)))) (defun afir (coeff &key (dt 1e-9) (from (/ 0.01 dt)) (to (/ 3 dt)) (dec 100)) (let* ((z `(lambda (z) (+ ,@(loop for c in coeff for i from 1 collect `(* ,c (expt z ,(- i))))))) (x (dolog (nil from to :dec dec)))) (values (map 'list #'(lambda (x) (db (funcall (amp-from-z z dt) x))) x) x))) (afir '(1 -1)) ) debugger invoked on a TYPE-ERROR: The value (LAMBDA (Z) (+ (* 1 (EXPT Z -1)) (* -1 (EXPT Z -2)))) is not of type (OR FUNCTION SYMBOL). Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Exit debugger, returning to top level. (SB-KERNEL:%COERCE-CALLABLE-TO-FUN (LAMBDA (Z) (+ (* 1 (EXPT Z -1)) (* -1 (EXPT Z -2)))))[:EXTERNAL] 0] * |