[Openmcl-devel] Q: Clozure CL and built-in class vs. CLOS class, how to get a CLOS instance from CCL:MAKE-SOCKET?

Gary Byers gb at clozure.com
Sat Jul 6 00:06:31 PDT 2013


The documentation does mention some things that your code is missing, but
the explanation is garbled enough that it's not surprising that things
didn't quite work as expected.

First of all:

  - a BASIC-STREAM is an instance of one of a fixed set of  built-in classes.
You can't easily subclass a BASIC-STREAM class, and methods defined on these
classes may or may not be called by I/O primitives.

  - a FUNDAMENTAL-STREAM is a STANDARD-OBJECT; FUNDAMENTAL-STREAM classes can
    be subclassed and extended like other standard CLOS objects.  It's expected
    that FUNDAMENTAL-STREAMS obey a protocol suggested by David Gray ("the Gray
    Streams protocol") late in the ANSI CL standardization process.  (The
    relevant email is archived at

     <ftp://ftp.clozure.com/pub/stream-definition-by-user.mail>
     or
     <http://www.clozure.com/FTP/pub/stream-definition-by-user.mail>

OPEN and CCL:MAKE-SOCKET accept two keyword arguments that affect the
class of the streams that they create:

   :BASIC (which default to T) is intended to differentiate between the two
     cases described above.

   :CLASS should be a class or class name; a prototype instance of the
     specified class is used to determine the actual class of the created
     stream (see below.)

It's a little anomalous (at least) for :BASIC to default to T and for :CLASS
to denote a FUNDAMENTAL-STREAM class.  I'm a little surprised that it seems to
work at all, wouldn't be shocked if it currently didn't work in some cases,
and wouldn't be shocked if it's considered to be an error in the future.

A prototype instance of the specified class (the class's CLASS-PROTOTYPE) is
used to determine a concrete class by calling the method CCL::SELECT-STREAM-CLASS
with the instance  a boolean indicating whether or not the stream is being opened
for input, another boolean indication whether it's being opened for output, and
a third boolean indicating whether the stream will support character (as opposed
to binary) I/O operations.  This makes more sense in the case of FILE-STREAMs than
it does on sockets:  the hypothetical abstract class CASE-INVERTING-FILE-STREAM
may have concrete subclasses CASE-INVERTING-INPUT-FILE-STREAM and 
CASE-INVERTING-OUTPUT-FILE-STREAM and CASE-INVERTING-IO-FILE-STREAM, and so
one might define:

(defmethod ccl::select-stream-class ((s case-inverting-file-stream) in-p out-p char-p)
   (if char-p
     (if in-p
       (if out-p
         'case-inverting-io-file-stream
         'case-inverting-input-file-stream)
       'case-inverting-output-file-stream
      (call-next-method)))

For TCP streams - which are generally bidirectional and bivalent - the
:CLASS argument is more likely to be concrete; a plausible definition
of the CCL::SELECT-STREAM-CLASS method for FUNDAMENTAL-TCP-STREAM could
be:

(defmethod ccl::select-stream-class ((s fundamental-tcp-stream) in-p out-p char-p)
   (declare (ignorable in-p out-p char-p))
   (class-name (class-of s)))

Unfortunately, the actual method always returns the symbol
FUNDAMENTAL-TCP-STREAM, and your MY-STREAM class inherits this method.
You'd need to override this method:

(defmethod ccl::select-stream-class ((s my-stream) in-p out-p char-p)
   (declare (ignorable in-p out-p char-p))
   (class-name (class-of s)))

? (ccl:make-socket :remote-host "www.apple.com" :remote-port 80 :basic nil :class 'my-stream)
#<MY-STREAM :ISO-8859-1 (SOCKET/22) #x302002A6E17D>
?


On Sat, 6 Jul 2013, Rainer Joswig wrote:

> Hi,
>
> okay, I read the documentation.
>
> Welcome to Clozure Common Lisp Version 1.8-store-r15418  (DarwinX8664)!
> ? (apropos "fundamental-tcp")
> CCL::FUNDAMENTAL-TCP-STREAM
>
> ? (defclass my-stream (CCL::FUNDAMENTAL-TCP-STREAM) ())
> #<STANDARD-CLASS MY-STREAM>
>
> ? (ccl:make-socket :remote-host "www.apple.com" :remote-port 80 :class 'my-stream)
> #<FUNDAMENTAL-TCP-STREAM :ISO-8859-1 (SOCKET/10) #x3020010FE43D>
>
> In above call it returns a CLOS stream of class CCL::FUNDAMENTAL-TCP-STREAM , but I would have expected that it uses the class argument - given the CCL documentation in chapter 10.1.2 .
>
> Is there anything I'm doing wrong?
>
> Regards,
>
> Rainer Joswig
>
>
>
>
>
>
>
>
>
> Am 05.07.2013 um 11:51 schrieb Gary Byers <gb at clozure.com>:
>
>> If there were manual sections that answered these questions, I bet that
>> they'd be called "10.1.2" and "10.1.3". I suppose that those sections
>> could address some aspects of what they discuss more clearly than they
>> do, but it'd probably be more productive to ask any remaining questions
>> after reading those sections than to not do so ...
>>
>> On Fri, 5 Jul 2013, Rainer Joswig wrote:
>>
>>> Hi,
>>>
>>>
>>> I'm currently using Clozure CL on two types of tiny ARM computers under Linux: Raspberry Pi and Odroid-X2. I have to say, it really rocks. Many thanks for the fantastic ARM port!
>>>
>>> While trying to port some code to Clozure CL I was a bit thinking about the following:
>>>
>>> If I create a socket with CCL:MAKE-SOCKET , I then get an instance of built-in class CCL::BASIC-TCP-STREAM .
>>>
>>> Interestingly enough this built-in class also inherits from a CLOS class CCL::TCP-STREAM, plus two built-in streams.
>>>
>>> For the particular functionality I would like to have a CLOS-based TCP-STREAM, so that I can write my own subclass and also can use CHANGE-CLASS.
>>>
>>> Now I have the following questions:
>>>
>>> * why is CCL::BASIC-TCP-STREAM not a CLOS class? Wouldn't it be more useful for the developer?
>>>
>>> * how can I use CCL:MAKE-SOCKET so that it returns a CLOS class?
>>>
>>> * are there other easy ways to get a socket as a CLOS class?
>>>
>>>
>>> Regards,
>>>
>>> Rainer Joswig
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> Openmcl-devel mailing list
>>> Openmcl-devel at clozure.com
>>> http://clozure.com/mailman/listinfo/openmcl-devel
>>>
>>>
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>



More information about the Openmcl-devel mailing list