Hi, thanks for help. On Mon, Sep 26, 2011 at 3:02 PM, Scott McKay <s...@google.com> wrote: > You're pretty much asking for type inference, but with you > being the one doing the inference.
Yes, it's more or less a way to provide more type hints to SBCL. On Mon, Sep 26, 2011 at 4:28 PM, Peter Stirling <pe...@pjstirling.plus.com> wrote: > You are misunderstanding the way that symbols work: > > First your source code is read by the reader, and symbols are looked up > by their package prefix, or interned in the current package if > unqualified. After this point the raw text that from your lisp file is > thrown away and macro-expansion and compilation is performed using only > the symbols and constants identified/produced by the reader. Since your > macro is trying to shadow symbols rather than generate new ones you only > need to worry about package prefixes at the call site of your macro, and > not in the macro itself > Thanks for explanation. I was confused thinking that reader subsequently reads more of the form as it is expanded, which is rubbish. > :use in defpackage will import all external symbols into the defined > package, and since "+" is external in :cl, and it's highly likely that > you are ":use :cl" it wouldn't need a prefix. > > > (defmacro with-typed-arguments ((name) type &body body) > (let ((func (gensym))) > `(let ((,func #',name)) > (declare (sb-ext:disable-package-locks ,name)) > (macrolet ((,name (&rest args) > (list* 'funcall ',func > (mapcar (lambda (arg) > (list 'the ',type arg)) > args)))) > (declare (sb-ext:enable-package-locks ,name)) > ,@body)))) > > > Should do the expansion you want, but it's not the "right" way in > common-lisp. > Works nicely, thank you! Why do you consider it as not "right"? Have a nice day. Karol > On Mon, 2011-09-26 at 09:31 +0200, karol skocik wrote: >> Hi Lispers, >> I need a help with a following macro I am trying to write: >> >> When the call site looks like this: >> >> (with-typed-arguments (distance) single-float >> (+ (distance a b c d) >> (distance x y z w))) >> >> I want it to expand into something like this: >> >> (+ (DISTANCE (THE SINGLE-FLOAT A) (THE SINGLE-FLOAT B) (THE >> SINGLE-FLOAT C) (THE SINGLE-FLOAT D)) >> (DISTANCE (THE SINGLE-FLOAT X) (THE SINGLE-FLOAT Y) (THE >> SINGLE-FLOAT Z) (THE SINGLE-FLOAT W)))) >> >> Now, what I have currently is: >> >> (defmacro with-typed-arguments ((&rest functions) argument-type &body body) >> (flet ((macrolet-body (fun) >> `(,fun (&rest args) >> `(funcall #',',fun ,@(iter (for arg :in args) >> (collect `(the >> ,',argument-type ,arg))))))) >> `(macrolet (,@(mapcar #'macrolet-body functions)) >> ,@body))) >> >> But it some things I don't understand: >> >> 1.) the function called with typed arguments is called using funcall - >> not a show stopper, just a style issue. Without funcall the expansion >> loops forever since the expansion does not emit the code, but expands >> deeper into infinite recursion of macrolets. Can it be fixed somehow? >> >> 2.) in the flet macrolet-body, I have a trouble understanding ,',fun >> construction next to the funcall - why the "fun" next to funcall can't >> be replaced by macrolet-body argument fun with ,,fun ? It is buried in >> `` but ,,fun there just got me (for call (macrolet-body +)) -> `(,+ >> ...). Let me show my trouble in the example: >> >> In this definition: >> (defmacro with-typed-arguments ((&rest functions) argument-type &body body) >> (flet ((macrolet-body (fun) >> `(,fun (&rest args) >> `(funcall #',,fun ,@(iter (for arg :in args) >> (collect `(the >> ,',argument-type ,arg))))))) >> `(macrolet (,@(mapcar #'macrolet-body functions)) >> ,@body))) >> >> this expansion: >> (with-typed-arguments (distance) single-float >> (+ (distance a b c d) >> (distance x y z w))) >> >> results in this: >> (MACROLET ((DISTANCE (&REST ARGS) >> `(FUNCALL #',DISTANCE >> ;; <- why is there ,DISTANCE when there is `(... `(... ,,fun >> ? >> ,@(ITER >> (FOR ARG :IN ARGS) >> (COLLECT `(THE SINGLE-FLOAT ,ARG)))))) >> (+ (DISTANCE A B C D) (DISTANCE X Y Z W))) >> >> 3.) package-locks - I want it to work with arithmetic functions >> (especially!) defined in CL package. That doesn't work, since I can't >> make a macrolet ((+ (&rest args) ...) because of package-locks. I am >> happy with SBCL specific fix, using SBCL's >> sb-ext:disable-package-locks, or sb-ext:without-package-locks, but I >> can't make it work. >> Especially, I have a trouble understanding, how do I create a symbol >> with package prefix needed in declaration like this: >> (declare (sb-ext:disable-package-locks cl::+)) >> >> Is there a way to prepend the symbol-package and '::' to the given >> symbol? How to construct such fully qualified symbol like cl::+? >> >> Thank you, >> Karol >> >> _______________________________________________ >> pro mailing list >> pro@common-lisp.net >> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/pro > > > _______________________________________________ pro mailing list pro@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/pro