Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

specialize method based on array element type

20 views
Skip to first unread message

John DeSoi

unread,
Mar 10, 2002, 10:37:50 AM3/10/02
to
Is is possible to specialize a defmethod parameter based on the
array-element-type? For example, I want to create a
stream-write-sequence method only for '(unsigned-byte 8) arrays. I can't
seem to find the right syntax.

Thanks,

John DeSoi, Ph.D.


Vladimir Zolotykh

unread,
Mar 10, 2002, 11:23:51 AM3/10/02
to
John DeSoi wrote:
>
> Is is possible to specialize a defmethod parameter based on the
> array-element-type?

Specializer can be a list (eql form) or a symbol naming a class.
See DEFMETHOD in HyperSpec.

--
Vladimir Zolotykh

Erik Naggum

unread,
Mar 10, 2002, 1:29:20 PM3/10/02
to
* John DeSoi

| Is is possible to specialize a defmethod parameter based on the
| array-element-type?

That does not appear to be the case, as the specialized arrays are not
subclasses of the array class. You can find whether the implemenentation
has an extension by comparing the value of class-of of your vectors:

(class-of (make-array 4 :element-type '(unsigned-byte 8)))

I am not sure whether the return value would have to be vector or could
be a subclass of vector. Allegro CL 6.1, Lispworks 4.120, CLISP 2.27 all
return vector, while CMUCL 3.0.8/18c+/build 3030/whatever has a
specialized class.

///
--
In a fight against something, the fight has value, victory has none.
In a fight for something, the fight is a loss, victory merely relief.

Michael Parker

unread,
Mar 10, 2002, 5:23:42 PM3/10/02
to
jde...@planetc.com (John DeSoi) wrote in message news:<1f8trud.14ns1b1sjj3r2N%jde...@planetc.com>...

> Is is possible to specialize a defmethod parameter based on the
> array-element-type? For example, I want to create a
> stream-write-sequence method only for '(unsigned-byte 8) arrays. I can't
> seem to find the right syntax.

Not portably.

When I've needed to do this, I create a class to hold the array,
and specialize on that, and use the REFS library's generic accessors
to deal with them. To enforce the type constraints on the individual
elements I put the type assertion in a :before method on (setf ref),
and in an :after method on initialize-instance.

There is a type-constrained scalar type in REFS already, but you
currently have to roll your own type-constrained arrays.

This should be fixed as soon as I get some spare time -- one of my
current projects is a database for time-series type data that uses
lazily-loaded disk arrays, and I need the type guarantees so invalid
data doesn't linger around until the system decides to flush it. I
just need to factor out the specialized vector stuff into a reusable
form.

John DeSoi

unread,
Mar 11, 2002, 11:26:57 PM3/11/02
to
Vladimir Zolotykh <gsm...@eurocom.od.ua> wrote:

> > Is it possible to specialize a defmethod parameter based on the


> > array-element-type?
>
> Specializer can be a list (eql form) or a symbol naming a class.
> See DEFMETHOD in HyperSpec.

Yes, I was wondering if there was a way to write the (eql form) in a
portable way. As Erik pointed out, (class-of (make-array 4 :element-type
'(unsigned-byte 8))) is implementation dependent.

Thanks,

John DeSoi, Ph.D.

John DeSoi

unread,
Mar 11, 2002, 11:26:56 PM3/11/02
to
Erik Naggum <er...@naggum.net> wrote:

> * John DeSoi
> | Is it possible to specialize a defmethod parameter based on the


> | array-element-type?
>
> That does not appear to be the case, as the specialized arrays are not
> subclasses of the array class. You can find whether the implemenentation
> has an extension by comparing the value of class-of of your vectors:
>
> (class-of (make-array 4 :element-type '(unsigned-byte 8)))
>
> I am not sure whether the return value would have to be vector or could
> be a subclass of vector. Allegro CL 6.1, Lispworks 4.120, CLISP 2.27 all
> return vector, while CMUCL 3.0.8/18c+/build 3030/whatever has a
> specialized class.


MCL says

(class-of (make-array 4 :element-type '(unsigned-byte 8)))

#<BUILT-IN-CLASS CCL::SIMPLE-UNSIGNED-BYTE-VECTOR>

I can use this directly, but I'm surprised there is not a portable way
to write it with eql. So would the best portable way be to make an
additional test and then use call-next-method if it does not meet the
criteria?

Thanks,

John DeSoi, Ph.D.

Kent M Pitman

unread,
Mar 11, 2002, 11:41:18 PM3/11/02
to
jde...@planetc.com (John DeSoi) writes:

Why don't you say what you're trying to accomplish? Maybe that will be
more tractable.

John DeSoi

unread,
Mar 13, 2002, 2:12:40 AM3/13/02
to
Kent M Pitman <pit...@world.std.com> wrote:

> Why don't you say what you're trying to accomplish? Maybe that will be
> more tractable.

Primarily, I'm tring to work around what I think is a bug in MCL. I have
a binary (tcp) stream and some code I'm porting calls write-sequence
with an (unsigned-byte 8) array. This generates an error in MCL that the
element type is not of the expected type, character. So I wanted to
create a new method only for this array type.

I have this working now in a non-portable way (which is fine since this
only seems to be a problem with MCL). But I have been away from Lisp for
a while, so I was curious if there was a better way.

Best,

John DeSoi, Ph.D.

Kent M Pitman

unread,
Mar 13, 2002, 3:25:42 AM3/13/02
to
jde...@planetc.com (John DeSoi) writes:

Just IMO, for what that's worth, once you get as deep into pain as you were
getting trying to find a portable solution, I suggest backing out and fixing
the bug locally in the implementation that's giving you grief.

I don't use MCL these days, so can't try your particular exampe, but
generally I'd usually do something of this general form in some 'foothold'
file:

(defconstant +binary-sequence-array-element-type+
;; In FOO-CL, calling WRITE-SEQUENCE with an (UNSIGNED-BYTE 8) array
;; fails, so we have to choose some other element type.
;; --JDoe 1-Jan-1998
#+foo-cl '... what FOO-CL expects..
#-foo-cl '(unsigned-byte 8))

and then later

(make-array ... :element-type +binary-sequence-array-element-type+)

in all the places in my main code that need to reference the type, to avoid
having #+/#- littered about, and to isolate your system dependency to a
documented local region that can easily be fixed if the bug is ever fixed.

Pierre R. Mai

unread,
Mar 13, 2002, 1:40:16 PM3/13/02
to
jde...@planetc.com (John DeSoi) writes:

> Kent M Pitman <pit...@world.std.com> wrote:
>
> > Why don't you say what you're trying to accomplish? Maybe that will be
> > more tractable.
>
> Primarily, I'm tring to work around what I think is a bug in MCL. I have
> a binary (tcp) stream and some code I'm porting calls write-sequence
> with an (unsigned-byte 8) array. This generates an error in MCL that the
> element type is not of the expected type, character. So I wanted to
> create a new method only for this array type.

Well, what is the element-type of the stream? If it is character,
then the MCL behaviour is not a bug, and you should find a way to get
a TCP stream that is in fact "binary", i.e. that has an element-type
of (unsigned-byte 8).

And if the element-type of the stream is (unsigned-byte 8), then this
is a clear implementation bug, and you should get a fix to it from
Digitool, instead of kludging around it.

Regs, Pierre.

--
Pierre R. Mai <pm...@acm.org> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein

John DeSoi

unread,
Mar 14, 2002, 1:35:21 AM3/14/02
to
Pierre R. Mai <pm...@acm.org> wrote:


> Well, what is the element-type of the stream? If it is character,
> then the MCL behaviour is not a bug, and you should find a way to get
> a TCP stream that is in fact "binary", i.e. that has an element-type
> of (unsigned-byte 8).
>


? (setf s (ccl::open-tcp-stream "www.yahoo.com" 80 :element-type
'(unsigned-byte 8)))
#<OPENTRANSPORT-BINARY-TCP-STREAM :DATAXFER ->64.58.76.229:http
#x1FBAD90E>
? (write-sequence (make-array 5 :element-type '(unsigned-byte 8)) s)
> Error: value 0 is not of the expected type CHARACTER.
> While executing: CCL::IO-BUFFER-TYO
> Type Command-. to abort.

I asked about this a while back on the MCL list, but never got a
response. I'll try again.

Best,

John DeSoi, Ph.D.

Pierre R. Mai

unread,
Mar 14, 2002, 8:34:48 AM3/14/02
to
jde...@planetc.com (John DeSoi) writes:

> ? (setf s (ccl::open-tcp-stream "www.yahoo.com" 80 :element-type
> '(unsigned-byte 8)))
> #<OPENTRANSPORT-BINARY-TCP-STREAM :DATAXFER ->64.58.76.229:http
> #x1FBAD90E>
> ? (write-sequence (make-array 5 :element-type '(unsigned-byte 8)) s)
> > Error: value 0 is not of the expected type CHARACTER.
> > While executing: CCL::IO-BUFFER-TYO
> > Type Command-. to abort.
>
> I asked about this a while back on the MCL list, but never got a
> response. I'll try again.

This seems like a bug, but of course, since I don't know the spec
for ccl::open-tcp-stream, _and_ it even seems to be a private symbol
(i.e. you are not supposed to use it), it is hard to tell. Is that
indeed the proper way to open a tcp stream on MCL?

In any case, contacting Digitool support directly would seem to be the
proper course of action.

Janis Dzerins

unread,
Mar 13, 2002, 7:20:32 AM3/13/02
to
jde...@planetc.com (John DeSoi) writes:

> Kent M Pitman <pit...@world.std.com> wrote:
>
> > Why don't you say what you're trying to accomplish? Maybe that will be
> > more tractable.
>
> Primarily, I'm tring to work around what I think is a bug in MCL. I have
> a binary (tcp) stream and some code I'm porting calls write-sequence
> with an (unsigned-byte 8) array. This generates an error in MCL that the
> element type is not of the expected type, character. So I wanted to
> create a new method only for this array type.

Is it a case that the stream is created with :element-type 'character?

--
Janis Dzerins

Takehiko Abe

unread,
Mar 14, 2002, 10:35:28 AM3/14/02
to
In article <1f90fgd.hn4dn71r6f4ieN%jde...@planetc.com>,
jde...@planetc.com (John DeSoi) wrote:

> ? (setf s (ccl::open-tcp-stream "www.yahoo.com" 80 :element-type
> '(unsigned-byte 8)))
> #<OPENTRANSPORT-BINARY-TCP-STREAM :DATAXFER ->64.58.76.229:http
> #x1FBAD90E>
> ? (write-sequence (make-array 5 :element-type '(unsigned-byte 8)) s)
> > Error: value 0 is not of the expected type CHARACTER.
> > While executing: CCL::IO-BUFFER-TYO
> > Type Command-. to abort.
>
> I asked about this a while back on the MCL list, but never got a
> response. I'll try again.

It is a bug. A quick workaround is, I believe, to define
CCL:STREAM-WRITE-SEQUENCE method for
CCL::OPENTRANSPORT-BINARY-TCP-STREAM and vector class.

btw, the above CCL::IO-BUFFER-TYO is a name of local
function defined inside CCL:STREAM-WRITER method for
CCL::BUFFERED-CHARACTER-OUTPUT-STREAM-MIXIN.
[CCL::OPENTRANSPORT-BINARY-TCP-STREAM inherits
from CCL::BUFFERED-CHARACTER-OUTPUT-STREAM-MIXIN. I don't
know how that happened.]

Abe

--
<keke at mac com>
"I wanted to see Mr Gates because he's so rich."

John DeSoi

unread,
Mar 17, 2002, 2:10:05 PM3/17/02
to
Pierre R. Mai <pm...@acm.org> wrote:

> > I asked about this a while back on the MCL list, but never got a
> > response. I'll try again.
>
> This seems like a bug, but of course, since I don't know the spec
> for ccl::open-tcp-stream, _and_ it even seems to be a private symbol
> (i.e. you are not supposed to use it), it is hard to tell. Is that
> indeed the proper way to open a tcp stream on MCL?
>
> In any case, contacting Digitool support directly would seem to be the
> proper course of action.


Digitool confirms this as a bug and sent a patch. I have not had a
chance to test it yet.

And the only TCP interface that I'm aware of for MCL is in
OpenTransport.lisp in the MCL library. Absolutely nothing is exported
hence ccl::open-tcp-stream. I asked about this too before undertaking
porting AllegroServe.

Best,

John DeSoi, Ph.D.


=====
> From: owner-i...@digitool.com [mailto:owner-i...@digitool.com]On
> Behalf Of John DeSoi
> Sent: Wednesday, February 06, 2002 8:27 PM
> To: Macintosh Common Lisp
> Subject: Open Transport
>
>
> Is there any documented way to use Open Transport with MCL? I have
> some basic things working by looking at OpenTransport.lisp but it
> bothers me that there does not seem to be any documentation and none
> of the symbols in that file are exported.

There is no real documentation, but there are some examples around.
(A simple one is at
<http://groups.google.com/groups?q=wiseman+group:cu.cs.macl.info&hl=en&s
elm=
931293057.3924%40news.Colorado.EDU&rnum=6>.)

0 new messages