From: ········@gmail.com
Subject: method-let
Date: 
Message-ID: <1166677536.592129.188610@t46g2000cwa.googlegroups.com>
Has anyone ever seen something implimented like a METHOD-LET operator,
that defines a method for a generic function but only within the scope
of it's form, like FLET for methods?

(defclass wheat ())

(defclass bread (wheat) ())

(defclass toast (bread) ())

(defgeneric eat (x))

(defmethod eat ((x wheat))
  (print "yuck"))

(defmethod eat ((x toast))
  (print "yum"))

(method-let ((foo ((x bread))
	          (print "will you put this in the toaster?")))
   (mapc #'foo (list (make-instance 'wheat)
	               (make-instance 'bread)
	               (make-instance 'toast))))
=>
"yuck"
"will you put this in the toaster?"
"yum"
NIL

I thought I remembered such an operator mentioned in an appendix at the
end of Keene's book, but when I went back and checked it was something
like GENERIC-FLET that I miss-remembered...

I think this would be super usefull for say... making PRINT-OBJECT
behave differently in different situations (like printing to XML or in
a GUI) but not losing the semactics of the type-hierarchy and the
method dispatch...

and on the subject of fantasy, how about a declaration that proclaims a
generic function to be "sealed" and that no more methods can be defined
and it can be inlined?

Nick

From: ·······@gmail.com
Subject: Re: method-let
Date: 
Message-ID: <1166687330.790172.78910@a3g2000cwd.googlegroups.com>
········@gmail.com wrote:
> Has anyone ever seen something implimented like a METHOD-LET operator,
> that defines a method for a generic function but only within the scope
> of it's form, like FLET for methods?

This is at least related:

http://common-lisp.net/project/closer/aspectl-overview.html#functions

Cheers,
Edi.
From: Raffael Cavallaro
Subject: Re: method-let
Date: 
Message-ID: <2006122101252016807-raffaelcavallaro@pasdespamsilvousplaitmaccom>
On 2006-12-21 00:05:36 -0500, ········@gmail.com said:

> how about a declaration that proclaims a
> generic function to be "sealed" and that no more methods can be defined
> and it can be inlined?

dylan has this
From: rydis (Martin Rydstr|m) @CD.Chalmers.SE
Subject: Re: method-let
Date: 
Message-ID: <w4c4primki6.fsf@rackham.cd.chalmers.se>
Raffael Cavallaro <················@pas-d'espam-s'il-vous-plait-mac.com> writes:
> On 2006-12-21 00:05:36 -0500, ········@gmail.com said:
> 
> > how about a declaration that proclaims a
> > generic function to be "sealed" and that no more methods can be defined
> > and it can be inlined?
> 
> dylan has this

And some CL implementations, like, for instance, CMUCL.

',mr
-- 
rydis (Martin Rydstr�m) @CD.Chalmers.SE             http://www.rydis.se

[Emacs] is written in Lisp, which is the only computer language that is
beautiful.  -- Neal Stephenson, _In the Beginning was the Command Line_
From: Pascal Costanza
Subject: Re: method-let
Date: 
Message-ID: <4uuv1lF1a7nt8U1@mid.individual.net>
········@gmail.com wrote:
> Has anyone ever seen something implimented like a METHOD-LET operator,
> that defines a method for a generic function but only within the scope
> of it's form, like FLET for methods?
> 
> (defclass wheat ())
> 
> (defclass bread (wheat) ())
> 
> (defclass toast (bread) ())
> 
> (defgeneric eat (x))
> 
> (defmethod eat ((x wheat))
>   (print "yuck"))
> 
> (defmethod eat ((x toast))
>   (print "yum"))
> 
> (method-let ((foo ((x bread))
> 	          (print "will you put this in the toaster?")))
>    (mapc #'foo (list (make-instance 'wheat)
> 	               (make-instance 'bread)
> 	               (make-instance 'toast))))
> =>
> "yuck"
> "will you put this in the toaster?"
> "yum"
> NIL
> 
> I thought I remembered such an operator mentioned in an appendix at the
> end of Keene's book, but when I went back and checked it was something
> like GENERIC-FLET that I miss-remembered...

CLOS had a WITH-ADDED-METHODS constructs at some stage, but this was 
dropped due to unclear semantics. See 
http://www.lispworks.com/documentation/HyperSpec/Issues/iss359_w.htm for 
details.

> I think this would be super usefull for say... making PRINT-OBJECT
> behave differently in different situations (like printing to XML or in
> a GUI) but not losing the semactics of the type-hierarchy and the
> method dispatch...

Yes, it would be very useful. ;)

I am actually convinced that it should be a dynamically scoped 
construct. ContextL supports this and similar features. See 
http://common-lisp.net/project/closer/contextl.html

> and on the subject of fantasy, how about a declaration that proclaims a
> generic function to be "sealed" and that no more methods can be defined
> and it can be inlined?

"One man's constant is another man's variable." - Alan Perlis

I doubt that function and class sealing would be really useful in 
practice. From a semantics point of view, it would be weird because it 
would then be one of the very few constructs (if any) that prohibits 
doing something in Common Lisp.

 From an efficiency point of view, I also doubt that sealing would buy a 
lot.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal Bourguignon
Subject: Re: method-let
Date: 
Message-ID: <87y7p12pg3.fsf@thalassa.informatimago.com>
········@gmail.com writes:

> Has anyone ever seen something implimented like a METHOD-LET operator,
> that defines a method for a generic function but only within the scope
> of it's form, like FLET for methods?
>
> (defclass wheat ())
>
> (defclass bread (wheat) ())
>
> (defclass toast (bread) ())
>
> (defgeneric eat (x))
>
> (defmethod eat ((x wheat))
>   (print "yuck"))
>
> (defmethod eat ((x toast))
>   (print "yum"))
>
> (method-let ((foo ((x bread))
> 	          (print "will you put this in the toaster?")))
>    (mapc #'foo (list (make-instance 'wheat)
> 	               (make-instance 'bread)
> 	               (make-instance 'toast))))
> =>
> "yuck"
> "will you put this in the toaster?"
> "yum"
> NIL


You can do it with a normal flet:

C/USER[615]> (flet ((eat (x)
                      (if (eq (class-of x) (find-class 'bread))
                          (print "will you put this in the toaster?")
                          (eat x))))
               (mapc (function eat) (list (make-instance 'wheat)
                                          (make-instance 'bread)
                                          (make-instance 'toast)))
               (values))

"yuck" 
"will you put this in the toaster?" 
"yum" 


> I think this would be super usefull for say... making PRINT-OBJECT
> behave differently in different situations (like printing to XML or in
> a GUI) but not losing the semactics of the type-hierarchy and the
> method dispatch...

This is not a good idea. PRINT-OBJECT, being a standard method has
some restrictions that may become unfortunate.  For example, it's not
necessarily called when specialized on a standard type or standard
class.

Note that:

    "The function print-object is called by the Lisp printer; it
     should not be called by the user."

    -- http://www.lispworks.com/documentation/HyperSpec/Body/f_pr_obj.htm


If you want to format differently depending on the "device", you
should use your own generic function:

(defgeneric render (object device))

(defmethod render ((object integer) (device xml-device))
  (format (device-stream device) "<integer>~D</integer>" object))

(defmethod render ((object date) (device text-device))
  (format (device-stream device) "~4,'0D-~2,'0D-~2,'0D" 
     (year date) (month date) (day date)))

...

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/