From: Karl Pflästerer
Subject: Beginner's Clos question regarding :initform
Date: 
Message-ID: <m3d65hmozw.fsf@hamster.pflaesterer.de>
Hi,
I wanted to implement a simple pop3 client with CL and thought about
trying it with Clos.

But then I stumbled across a problem I couldn't solve: can (and if how)
an initform in a class refer to the slot values of that classes instance
when instantiated?

To make clearer what I mean here the code:

(defclass tcp-connection ()
  ((port       :accessor port
               :initarg :port
               :initform 0
               :type integer
               :documentation "The TCP port number (an integer)")
   (host       :accessor host
               :initarg :host
               :initform "127.0.0.1"
               :type string
               :documentation "The address (a string); default is \"127.0.0.1\"")
   (connect    :reader con
               :documentation "The actual socket connection")))

(defclass pop3 (tcp-connection)
  ((port       :initform 110)
   (user       :accessor user
               :initarg :user
               :type string
               :documentation "The account specifier")
   (pass       :accessor pass
               :initarg :pass
               :type string
               :documentation "The account password")))

(defmethod connect ((inst tcp-connection) &key user pass)
  (setf (slot-value inst 'connect) (socket-connect (port inst) (host inst)))
  (read-all (con inst))
  inst)

(defmethod connect ((inst pop3) &key user pass)
  (call-next-method)
  (let ((user (or user (and (slot-boundp inst 'user) (user inst))))
        (pass (or pass (and (slot-boundp inst 'pass) (pass inst)))))
    (when user
      (login inst :user user :pass pass))
    inst))

(defmethod login ((inst pop3) &key user pass)
  (write+read (string-concat "user " (or user (user inst))) inst)
  (when (or pass (and (slot-boundp inst 'pass) (pass inst)))
    (write+read (string-concat "pass " (or pass (pass inst))) inst)))

(defmethod write+read ((str string) (inst tcp-connection))
  (write-line str (con inst))
  (finish-output)
  (read-all (con inst)))

(defun read-all (stream)
  (loop while (listen stream)
        do (format t "~A~%" (read-line stream)))
  stream)


If I need an instance I write e.g.:

(connect (make-instance 'pop3 :user "me") :pass "secret")

So far so good.  But how can I write an initform for the connect slot
which establishes a connection and logs in if user and pass are given so
I don't have to call the connect method explicitly?



   KP

-- 
"But it has nothing to do with what a _value_ is.  This has to do with
whether you pass whatever-a-value-is or wherever-whatever-is-a-value-is
whenever you pass an argument to a function.  (Call it the Shakira
theory. :)"    [Erik Naggum in cllisp �ber call-by-value und call-by-reference]

From: Pascal Costanza
Subject: Re: Beginner's Clos question regarding :initform
Date: 
Message-ID: <c7dv1v$uc$2@newsreader2.netcologne.de>
Karl Pfl�sterer wrote:

> Hi,
> I wanted to implement a simple pop3 client with CL and thought about
> trying it with Clos.
> 
> But then I stumbled across a problem I couldn't solve: can (and if how)
> an initform in a class refer to the slot values of that classes instance
> when instantiated?

No. Define an :after method on initialize-instance or shared-initialize 
instead.


Pascal

-- 
1st European Lisp and Scheme Workshop
June 13 - Oslo, Norway - co-located with ECOOP 2004
http://www.cs.uni-bonn.de/~costanza/lisp-ecoop/
From: Karl Pflästerer
Subject: Re: Beginner's Clos question regarding :initform
Date: 
Message-ID: <m38yg5mizh.fsf@hamster.pflaesterer.de>
On  6 May 2004, Pascal Costanza <- ········@web.de wrote:


> Karl Pfl�sterer wrote:

>> Hi,
>> I wanted to implement a simple pop3 client with CL and thought about
>> trying it with Clos.
>> But then I stumbled across a problem I couldn't solve: can (and if
>> how)
>> an initform in a class refer to the slot values of that classes instance
>> when instantiated?

> No. Define an :after method on initialize-instance or
> shared-initialize instead.

Thanks.  Works like a charm.  I start to like Clos; it's OO without too
much emphasizing that you use OOP.  You are not forced as programmer to
use an object where you think a e.g closure would be better.

   KP

-- 
If you have nothing to say on a subject, replying with a line such as,
"I agree with this." puts you in the TO:'s for all future messages, and
establishes you as "one who really cares", if not an actual expert, on
the topic at hand.         -- from the Symbolics Guidelines for Sending Mail
From: Kenny Tilton
Subject: Re: Beginner's Clos question regarding :initform
Date: 
Message-ID: <v7zmc.96197$WA4.64693@twister.nyc.rr.com>
Karl Pfl�sterer wrote:

> On  6 May 2004, Pascal Costanza <- ········@web.de wrote:
> 
> 
> 
>>Karl Pfl�sterer wrote:
> 
> 
>>>Hi,
>>>I wanted to implement a simple pop3 client with CL and thought about
>>>trying it with Clos.
>>>But then I stumbled across a problem I couldn't solve: can (and if
>>>how)
>>>an initform in a class refer to the slot values of that classes instance
>>>when instantiated?
> 
> 
>>No. Define an :after method on initialize-instance or
>>shared-initialize instead.
> 
> 
> Thanks.  Works like a charm.  I start to like Clos; 

I was not going to mention this, but Rainer wants me to advertise my 
projects more often here on cll, so...wait till you see Cells. One 
incidental charm of that OO extension of mine is that one can indeed 
specify the value for a slot (via either initform or via initarg at 
make-instance time) with a form which is a function of the instance 
itself (hence can get to the other slots of the instance). The mechanism 
is one which has grander capabilities overall, but I find myself taking 
guilty pleasure all the time in just this little bit of fun (where 
'self' is a smalltalk ripoff for the instance):

     (defclass button
       ((id :initarg :id :accessor id :initform (c? (class-of self)))
        (title$ :initarg :title$ :accessor title$
                :initform (c? (string (id self))))))

Those would be easy enough to shift into initialize-instance, since they 
are being authored for the class. But one can also:

     (make-instance 'button
        :id (c? (intern
                   (concatenate 'string
                       "close-" (type-of (parent self)))))
        :title$ (c? (subsitute #\space #\- (string (id self))))
        :control-action (lambda (self) (close (parent self))))

In this case initialize-instance would need help (a new slot with some 
sort of parameter) knowing which kind of initialization was desired. But 
with Cells one just codes it up without breaking one's stride.

I think overall this makes classes more flexible aka reusable, simply 
because some of the semantics can be moved out of the class definition 
and into the code where the special cases arise which usually force new 
subclasses or at best new parameterizing slots to be invented.

kenny



-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: ·········@random-state.net
Subject: Re: Beginner's Clos question regarding :initform
Date: 
Message-ID: <c7efu7$9ff75$2@midnight.cs.hut.fi>
Kenny Tilton <·······@nyc.rr.com> wrote:

>      (defclass button
>        ((id :initarg :id :accessor id :initform (c? (class-of self)))
>         (title$ :initarg :title$ :accessor title$
>                 :initform (c? (string (id self))))))

This is quite off-topic for the thread, but I for one always cringe when I
see Cells code due to C? and friends. 

If the syntax were:

 RULE-LAMBDA (binding) form*

  or

 RULE-LAMBDA binding form*

things would be soooo much better, whatever sensible name you
wanted to use in place of RULE-LAMBDA -- then people would not cry out for
standardized sockets, and everyone would have a moon on a stick for
free. ;-)

Cheers,

 -- Nikodemus
From: Kenny Tilton
Subject: Re: Beginner's Clos question regarding :initform
Date: 
Message-ID: <QvCmc.97403$WA4.47460@twister.nyc.rr.com>
·········@random-state.net wrote:

> Kenny Tilton <·······@nyc.rr.com> wrote:
> 
> 
>>     (defclass button
>>       ((id :initarg :id :accessor id :initform (c? (class-of self)))
>>        (title$ :initarg :title$ :accessor title$
>>                :initform (c? (string (id self))))))
> 
> 
> This is quite off-topic for the thread, but I for one always cringe when I
> see Cells code due to C? and friends. 
> 
> If the syntax were:
> 
>  RULE-LAMBDA (binding) form*
> 
>   or
> 
>  RULE-LAMBDA binding form*

Garnet's KR had (I forget)-formula. But when one is /really/ using 
Cells, one is spraying CVs and C?s around all the time, and this is more 
a candidate for something like collapsing QUOTE into ' or FUNCTION into 
#' then it is expansion into big-huge-name useful at the application 
level where, as we all know, excessive abbreviation saves so very little 
and detracts so much from readability.

That said, if some contributor wanted to create c-formula and c-variable 
macros and add them to Cells I would not mind.

kenny (taking a break from global destudlification of his projects)

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Karl Pflästerer
Subject: Re: Beginner's Clos question regarding :initform
Date: 
Message-ID: <m34qqsb9gc.fsf@hamster.pflaesterer.de>
On  7 May 2004, Kenny Tilton <- ·······@nyc.rr.com wrote:

> projects more often here on cll, so...wait till you see Cells. One
> incidental charm of that OO extension of mine is that one can indeed
> specify the value for a slot (via either initform or via initarg at
> make-instance time) with a form which is a function of the instance
> itself (hence can get to the other slots of the instance). The

That's exactly what I wanted.  I think that is sometimes clearer (as you
can, when you read the code of the class, instantly see what's happening
at the time you create an instance without having to look for some
:around or :after methods).

> mechanism is one which has grander capabilities overall, but I find
> myself taking guilty pleasure all the time in just this little bit of
> fun (where 'self' is a smalltalk ripoff for the instance):

>      (defclass button
>        ((id :initarg :id :accessor id :initform (c? (class-of self)))
>         (title$ :initarg :title$ :accessor title$
>                 :initform (c? (string (id self))))))

> Those would be easy enough to shift into initialize-instance, since
> they are being authored for the class. But one can also:

>      (make-instance 'button
>         :id (c? (intern
>                    (concatenate 'string
>                        "close-" (type-of (parent self)))))
>         :title$ (c? (subsitute #\space #\- (string (id self))))
>         :control-action (lambda (self) (close (parent self))))

> In this case initialize-instance would need help (a new slot with some
> sort of parameter) knowing which kind of initialization was desired. 
> But with Cells one just codes it up without breaking one's stride.

That's really great.  I think that way you can code in a very natural
way so you don't have to force the way you think to the way the language
behaves (for me Lisp code is written most of the time in a way I think
about a problem respectively its solution).  That part of Clos didn't
behave that way but you show a solution how it can be writtten.


   KP

-- 
'Twas brillig, and the slithy toves
    Did gyre and gimble in the wabe;
  All mimsy were the borogoves,
   And the mome raths outgrabe.   "Lewis Carroll" "Jabberwocky"
From: Kenny Tilton
Subject: Re: Beginner's Clos question regarding :initform
Date: 
Message-ID: <NzNmc.98072$WA4.19660@twister.nyc.rr.com>
Karl Pfl�sterer wrote:
> On  7 May 2004, Kenny Tilton <- ·······@nyc.rr.com wrote:
> 
> 
>>projects more often here on cll, so...wait till you see Cells. One
>>incidental charm of that OO extension of mine is that one can indeed
>>specify the value for a slot (via either initform or via initarg at
>>make-instance time) with a form which is a function of the instance
>>itself (hence can get to the other slots of the instance). The
> 
> 
> That's exactly what I wanted.  I think that is sometimes clearer (as you
> can, when you read the code of the class, instantly see what's happening
> at the time you create an instance without having to look for some
> :around or :after methods).
> 
> 
>>mechanism is one which has grander capabilities overall, but I find
>>myself taking guilty pleasure all the time in just this little bit of
>>fun (where 'self' is a smalltalk ripoff for the instance):

...

> 
>>     (make-instance 'button
>>        :id (c? (intern
>>                   (concatenate 'string
>>                       "close-" (type-of (parent self)))))
>>        :title$ (c? (subsitute #\space #\- (string (id self))))
>>        :control-action (lambda (self) (close (parent self))))
> 
> 
>>In this case initialize-instance would need help (a new slot with some
>>sort of parameter) knowing which kind of initialization was desired. 
>>But with Cells one just codes it up without breaking one's stride.
> 
> 
> That's really great.  I think that way you can code in a very natural
> way so you don't have to force the way you think to the way the language
> behaves (for me Lisp code is written most of the time in a way I think
> about a problem respectively its solution).  That part of Clos didn't
> behave that way but you show a solution how it can be writtten.

But as I said, it is a part of a larger system with lots of other 
implications and requirements, so you cannot just drop this into a 
conventional CLOS app. otoh, if you like OO, you really should check out 
my Cells project, because it adds a lot of power in return for the 
"implications and requirements".

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application