From: Gabriel D. R. <gd...@in...> - 2011-08-11 04:45:36
|
Hi, Given these three forms (deftype |%String| () 'string) (format t "~s~%" (map 'string #'(lambda (c) (code-char c)) #(94 89 103))) (format t "~s~%" (map '|%String| #'(lambda (c) (code-char c)) #(94 89 103))) I was expecting to get the same behavior on the last two forms. Alas, SBCL-1.0.50 chocks on the last one with: debugger invoked on a SB-INT:SIMPLE-PROGRAM-ERROR in thread #<THREAD "initial thread" RUNNING {1002900E01}>: STRING is too hairy for sequence functions. Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. Either both should succeed or none should (and I would expect both to succeed.) PS: The testcase is distilled from a testcase against an SBCL-based OpenAxiom. -- Gaby |
From: Christophe R. <cs...@ca...> - 2011-08-11 05:32:21
|
Gabriel Dos Reis <gd...@in...> writes: > Given these three forms > > (deftype |%String| () 'string) > > (format t "~s~%" > (map 'string #'(lambda (c) (code-char c)) #(94 89 103))) > > (format t "~s~%" > (map '|%String| #'(lambda (c) (code-char c)) #(94 89 103))) > > > I was expecting to get the same behavior on the last two forms. Alas, > SBCL-1.0.50 chocks on the last one with: > > debugger invoked on a SB-INT:SIMPLE-PROGRAM-ERROR in thread #<THREAD > "initial > thread" RUNNING > {1002900E01}>: > STRING is too hairy for sequence functions. > > Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. > > > Either both should succeed or none should (and I would expect both to succeed.) Well, there's actually an argument from the language standard for the current behaviour too. That is that the standard for "System Class STRING" says When used as a type specifier for object creation, string means (vector character). STRING in SBCL is actually something like (OR (VECTOR NIL) (VECTOR BASE-CHAR) (VECTOR CHARACTER)) so that special case in the standard is needed for (map 'string ...) to work at all; there's no such exception for user-specified types. Now, I can see that you might want (deftype %string () 'string) to imply that %STRING should mean exactly the same as STRING; it's even possible (though not all that much fun) to implement, but it's not really guaranteed as far as I can tell. Compare with (deftype %%string () '(or (vector nil) (vector base-char) (vector character))) as something which probably /shouldn't/ be special-cased. So, doable, but probably a bit of work. How workaroundable is this issue in Axiom? Cheers, Christophe |
From: Anton K. <an...@sw...> - 2011-08-11 10:21:31
|
Christophe Rhodes <cs...@ca...> writes: > Gabriel Dos Reis <gd...@in...> writes: >> Given these three forms >> >> (deftype |%String| () 'string) >> >> (format t "~s~%" >> (map 'string #'(lambda (c) (code-char c)) #(94 89 103))) >> >> (format t "~s~%" >> (map '|%String| #'(lambda (c) (code-char c)) #(94 89 103))) [...] >> Either both should succeed or none should (and I would expect both to >> succeed.) The [or none should] part is problematic; more on that below. > Well, there's actually an argument from the language standard for the > current behaviour too. I'd second that; however, the OP's interpretation of the standard may be defended as well, so it's still better to make SBCL successful for both cases. After taking a look at the current code, I think that the best solution here is to extend MAP, so if a union type of array types is given, it selects the least-specialized array. I've uploaded a snippet to <http://paste.lisp.org/display/123956>: it is a ready-to-use /workaround for the original problem/, and also an illustration of what behavior I'd expect from MAP for a UNION-TYPE. Now let me comment on the expectation that both statement should fail if one of them fails: I can't recall /any/ area when the Standard requires such "consistence in failures". Basically, if some frobnication is both permitted to fail and allowed to succeed for a given set of quuxes, there are no restrictions on /which/ subset of quuxes is frobbable. Some users may have reasonable objections on SUBTYPEP depending on current temperature and humidity, but it seems that it's conforming too. -- Regards, Anton Kovalenko +7(916)345-34-02 | Elektrostal' MO, Russia |
From: Christophe R. <cs...@ca...> - 2011-08-11 11:07:54
|
Anton Kovalenko <an...@sw...> writes: > After taking a look at the current code, I think that the best solution > here is to extend MAP, so if a union type of array types is given, it > selects the least-specialized array. least-specialized isn't terribly well-defined, though, is it? What about (map '(or bit-vector base-string) ...)? (Also, we'd need to extend MAKE-SEQUENCE, COERCE, MERGE and CONTATENATE in the same way; I think there is some common code to manage the type identification, so that's the place for the normalisation I think). I would not be opposed to a change to handle user-defined types that are type-equivalent to exactly STRING (and SIMPLE-STRING); I think handling other union types is unwise. Cheers, Christophe |
From: Gabriel D. R. <gd...@in...> - 2011-08-11 15:13:16
|
On Thu, Aug 11, 2011 at 6:07 AM, Christophe Rhodes <cs...@ca...> wrote: > Anton Kovalenko <an...@sw...> writes: > >> After taking a look at the current code, I think that the best solution >> here is to extend MAP, so if a union type of array types is given, it >> selects the least-specialized array. > > least-specialized isn't terribly well-defined, though, is it? What > about > (map '(or bit-vector base-string) ...)? > > (Also, we'd need to extend MAKE-SEQUENCE, COERCE, MERGE and CONTATENATE > in the same way; I think there is some common code to manage the type > identification, so that's the place for the normalisation I think). > > I would not be opposed to a change to handle user-defined types that are > type-equivalent to exactly STRING (and SIMPLE-STRING); I think handling > other union types is unwise. Handling types that are equivalent to standard types would be sufficient for OpenAxiom needs. -- Gaby |
From: Anton K. <an...@sw...> - 2011-08-11 12:21:19
|
Christophe Rhodes <cs...@ca...> writes: >> After taking a look at the current code, I think that the best solution >> here is to extend MAP, so if a union type of array types is given, it >> selects the least-specialized array. > > least-specialized isn't terribly well-defined, though, is it? What > about > (map '(or bit-vector base-string) ...)? It's perfectly well defined, it only has a restricted domain: not every set of array types have a least-specialized one. The standard doesn't special-case #1=(map '(or bit-vector base-string)), as opposed to (map 'string). Formally, #1# is allowed to return /either/ bit-vector /or/ base-string, and is certainly allowed (but not required) to fail. Therefore the behavior of my MAP* is conforming, even if the set of element types is unordered with 'subtypep: (FIRST (SORT...)) selects *something* as "the best result type", and that *something*, as a whole, is certainly a subtype of the type given to MAP*. Special requirements for strings would override this reasoning, but the string type /does/ have the least specialized subtype -- that's why I came up with this slight generalization of 'string requirements. (There is also a less generic generalization, lying between mine and the CL standard: we could require a set of element types to be fully ordered with 'subtypep -- it's more strict than requiring just a /single/ "best" type to be there, yet it's not restricted to strings). It's trivial to add an extra test to ensure that my "least specialized" result is sensible, and it's certainly better to have such a test, so the behavior is predictable. I've left it out only because I expected that it would make this discussion more interesting, and it worked :-). -- Regards, Anton Kovalenko +7(916)345-34-02 | Elektrostal' MO, Russia |
From: Gabriel D. R. <gd...@in...> - 2011-08-11 13:40:39
|
On Thu, Aug 11, 2011 at 12:32 AM, Christophe Rhodes <cs...@ca...> wrote: > Gabriel Dos Reis <gd...@in...> writes: > >> Given these three forms >> >> (deftype |%String| () 'string) >> >> (format t "~s~%" >> (map 'string #'(lambda (c) (code-char c)) #(94 89 103))) >> >> (format t "~s~%" >> (map '|%String| #'(lambda (c) (code-char c)) #(94 89 103))) >> >> >> I was expecting to get the same behavior on the last two forms. Alas, >> SBCL-1.0.50 chocks on the last one with: >> >> debugger invoked on a SB-INT:SIMPLE-PROGRAM-ERROR in thread #<THREAD >> "initial >> thread" RUNNING >> {1002900E01}>: >> STRING is too hairy for sequence functions. >> >> Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. >> >> >> Either both should succeed or none should (and I would expect both to succeed.) > > Well, there's actually an argument from the language standard for the > current behaviour too. That is that the standard for "System Class > STRING" says > > When used as a type specifier for object creation, string means > (vector character). My expectation is based on the fact that a deftype is just an abbreviation, and in many (all?) other contexts where I use a deftype as a type specifier, it expands to its body. > > STRING in SBCL is actually something like > (OR (VECTOR NIL) (VECTOR BASE-CHAR) (VECTOR CHARACTER)) > so that special case in the standard is needed for (map 'string ...) to > work at all; there's no such exception for user-specified types. > > Now, I can see that you might want > (deftype %string () 'string) > to imply that %STRING should mean exactly the same as STRING; it's even > possible (though not all that much fun) to implement, but it's not > really guaranteed as far as I can tell. Compare with > (deftype %%string () '(or (vector nil) (vector base-char) (vector character))) > as something which probably /shouldn't/ be special-cased. > > So, doable, but probably a bit of work. How workaroundable is this > issue in Axiom? Thanks for the explanation -- though I am still unclear as to why the deftype is not expanded first, then SBCL special recognition of STRING applied. The purpose of introducing %String as a deftype is to abstract over the choice of general string (unicode enabled) or just basic string (ascii restricted). Having to sprinkle STRING lexically in the OpenAxiom source code makes it unattractive from code engineering point of view. Of the 5 free Lisps that I have tested (SBCL, ECL, CCL, GCL, ABCL), only SBCL surprised me with this. The original bug was a bit hard to trace to the reduced testcase because I did not expect that behaviour -- and all other Lisp-based builds just worked fine. I've put a temporary workaround for the code that generates the MAP with %String, but we use other deftypes in many other object creation contexts and now I am bit nervous about SBCL's interpretation. It would be great if something can be done about this from the SBCL side. Thanks, -- Gaby |
From: Gabriel D. R. <gd...@in...> - 2011-08-11 15:16:31
|
On Thu, Aug 11, 2011 at 7:21 AM, Anton Kovalenko <an...@sw...> wrote: > It's trivial to add an extra test to ensure that my "least specialized" > result is sensible, and it's certainly better to have such a test, so > the behavior is predictable. I've left it out only because I expected > that it would make this discussion more interesting, and it worked :-). :-) Would this be in SBCL-1.0.51? -- Gaby |
From: Anton K. <an...@sw...> - 2011-08-11 18:59:42
|
Gabriel Dos Reis <gd...@in...> writes: >> It's trivial to add an extra test to ensure that my "least specialized" >> result is sensible, and it's certainly better to have such a test, so >> the behavior is predictable. I've left it out only because I expected >> that it would make this discussion more interesting, and it worked :-). > :-) > Would this be in SBCL-1.0.51? I'm not a SBCL developer, I'm more like a guest in sbcl-devel@. And I'd bet that nothing of this kind will be in SBCL-1.0.51 or SBCL-1.0.99: there is a common belief that having few features is good for portability (i.e. that the compiler should be dumb enough to reject anything that won't be accepted by the dumbest of other implementations that is still conforming). I don't expect this idea to go away soon -- after all, I used to believe it myself (when I discovered that SBCL's LOOP is much less pedantic than some other LOOPs, my first reaction was to blame SBCL for not enforcing portability!). No doubts that it could be useful to have an implementation that rejects any thing rejectable, warns on any thing warnable, and does the dumbest thing allowed by the standard in each case there is a choice; I would probably use this "PedantiCL" for portability testing myself. But SBCL is /not/ of this kind, it's already too smart on too many things. Hopefully, this idea of portability-by-failure will eventually lose its wide acceptance. (Like when I started to /understand/ whether I'm writing a main-clause or a variable-clause into my LOOPs, they suddenly became portable, without any help of a sufficiently dumb compiler). -- Regards, Anton Kovalenko +7(916)345-34-02 | Elektrostal' MO, Russia |
From: Christophe R. <cs...@ca...> - 2011-08-11 16:46:51
Attachments:
%string.diff
|
Gabriel Dos Reis <gd...@in...> writes: > I've put a temporary workaround for the code that generates the MAP > with %String, > but we use other deftypes in many other object creation contexts and now I am > bit nervous about SBCL's interpretation. It would be great if > something can be done > about this from the SBCL side. Well. Formally if you want to write portable Lisp code, then your workaround is really necessary: I stand by my reading of the standard, which is that there's no guarantee that implementations do type-expansion before considering whether a given type specifier is exactly STRING (or SIMPLE-STRING). People with long memories say that this is consistent with my position of yesteryear. However, I must be in a good mood, or too sleepy to argue with you (preferring instead to argue with those who want to have ultraliberal interpretations of the specifier argument: I still think that there's merit in being an implementation which attempts to strengthen outward portability, but I concede that it's possible to take that argument too far). In an attempt to head off an unconservative rewrite of this code, I'm attaching a patch which performs the type expansion for all five affected functions. Only lightly tested. |
From: Gabriel D. R. <gd...@in...> - 2011-08-11 16:57:16
|
On Thu, Aug 11, 2011 at 11:46 AM, Christophe Rhodes <cs...@ca...> wrote: > Gabriel Dos Reis <gd...@in...> writes: > >> I've put a temporary workaround for the code that generates the MAP >> with %String, >> but we use other deftypes in many other object creation contexts and now I am >> bit nervous about SBCL's interpretation. It would be great if >> something can be done >> about this from the SBCL side. > > Well. Formally if you want to write portable Lisp code, then your > workaround is really necessary: I stand by my reading of the standard, > which is that there's no guarantee that implementations do > type-expansion before considering whether a given type specifier is > exactly STRING (or SIMPLE-STRING). People with long memories say that > this is consistent with my position of yesteryear. > > However, I must be in a good mood, or too sleepy to argue with you > (preferring instead to argue with those who want to have ultraliberal > interpretations of the specifier argument: I still think that there's > merit in being an implementation which attempts to strengthen outward > portability, but I concede that it's possible to take that argument too > far). In an attempt to head off an unconservative rewrite of this code, > I'm attaching a patch which performs the type expansion for all five > affected functions. Only lightly tested. > > > > I'd prefer this or something like it to any cleverness involving union > types, but I'm aware that I'm only one voice among many these days (and > not a particularly strong voice at that). > Thanks, that definitely is sufficient for OpenAxiom's needs. -- Gaby |
From: Anton K. <an...@sw...> - 2011-08-11 18:16:32
|
Gabriel Dos Reis <gd...@in...> writes: > I've put a temporary workaround for the code that generates the MAP > with %String, but we use other deftypes in many other object creation > contexts and now I am bit nervous about SBCL's interpretation. It > would be great if something can be done about this from the SBCL side. I was suspecting exactly this use case, but I was unsure whether you go beyond object creation -- TYPEP, SUBTYPEP, function type declarations and the like. When the prevailing (or the only) use of deftypes is object creation, there /is/ a perfectly portable solution: let your DEFTYPE expand to (VECTOR CHARACTER), not to a string. Such types are /required/ to work in a conforming implementation (for any vector element type) -- and this requirement is much more clear than the remark about 'STRING specifiers. The problem with 'STRING is that it's /realy/ a hairy type. It's not an unicode-aware sibling of 'BASE-STRING (that would be (VECTOR CHARACTER) -- exactly what you need). 'STRING is about something that has /doubts/ whether it wants to be unicode-aware or ascii-only. Using it for object creation doesn't have any natural, obvious semantics: imagine that you're talking to malloc(), asking it to "please, allocate 4096 bytes of memory -- or 2048, i'm not sure yet". We can't even express it for C and malloc(); but the straightforward meaning of (MAP 'STRING ...) is very much like this! > My expectation is based on the fact that a deftype is just an abbreviation, and > in many (all?) other contexts where I use a deftype as a type specifier, it > expands to its body. It may be useful to read the RECURSIVE-DEFTYPE issue writeup (just follow the link from CLHS page on DEFTYPE). There was a /discussion/ whether non-terminating recursive type definition should be allowed. (it's a useful thing to have, not some remote theoretical construct: (DEFTYPE LIST-WITH-ELTS-OF-TYPE (INSIDE) `(CONS ,INSIDE (LIST-WITH-ELTS-OF-TYPE ,INSIDE)))). If expanding DEFTYPE fully were the only way for Lisp implementors, there would be no such discussion (btw, I seem to recall that recursive deftypes were actually supported by some /pre-Common/ Lisp). (And if it /were/ the only conceivable way, I would expect to find something like DEFTYPE-EXPAND it the standard: if the cost of full expansion were inevitable, why not reap the benefits of it?). -- Regards, Anton Kovalenko +7(916)345-34-02 | Elektrostal' MO, Russia |
From: Gabriel D. R. <gd...@in...> - 2011-08-11 19:42:32
|
On Thu, Aug 11, 2011 at 1:08 PM, Anton Kovalenko <an...@sw...> wrote: > Gabriel Dos Reis <gd...@in...> writes: > >> I've put a temporary workaround for the code that generates the MAP >> with %String, but we use other deftypes in many other object creation >> contexts and now I am bit nervous about SBCL's interpretation. It >> would be great if something can be done about this from the SBCL side. > > I was suspecting exactly this use case, but I was unsure whether you go > beyond object creation -- TYPEP, SUBTYPEP, function type declarations > and the like. We do not use directly TYPEP or SUBTYPEP. But, we do rely heavily on function type proclamations involving those type specifiers. Is such usage also not-recommended? > When the prevailing (or the only) use of deftypes is object creation, > there /is/ a perfectly portable solution: let your DEFTYPE expand to > (VECTOR CHARACTER), not to a string. Such types are /required/ to work > in a conforming implementation (for any vector element type) -- and this > requirement is much more clear than the remark about 'STRING specifiers. OK. So, just to make sure I understand: it is OK to use the type specifiers as long as they expand to (VECTOR something), but not to the type specifier STRING or SIMPLE-STRING. Is that correct? > The problem with 'STRING is that it's /realy/ a hairy type. It's not an > unicode-aware sibling of 'BASE-STRING (that would be (VECTOR CHARACTER) > -- exactly what you need). 'STRING is about something that has /doubts/ > whether it wants to be unicode-aware or ascii-only. Using it for object > creation doesn't have any natural, obvious semantics: imagine that > you're talking to malloc(), asking it to "please, allocate 4096 bytes of > memory -- or 2048, i'm not sure yet". We can't even express it for C and > malloc(); but the straightforward meaning of (MAP 'STRING ...) is very > much like this! Aha, thanks. I think I understand now. >> My expectation is based on the fact that a deftype is just an abbreviation, and >> in many (all?) other contexts where I use a deftype as a type specifier, it >> expands to its body. > > It may be useful to read the RECURSIVE-DEFTYPE issue writeup (just > follow the link from CLHS page on DEFTYPE). There was a /discussion/ > whether non-terminating recursive type definition should be allowed. > (it's a useful thing to have, not some remote theoretical construct: > > (DEFTYPE LIST-WITH-ELTS-OF-TYPE (INSIDE) > `(CONS ,INSIDE (LIST-WITH-ELTS-OF-TYPE ,INSIDE)))). > > If expanding DEFTYPE fully were the only way for Lisp implementors, > there would be no such discussion (btw, I seem to recall that recursive > deftypes were actually supported by some /pre-Common/ Lisp). My interpretation was that since deftype expansions are required to eventually terminate (or else), it was to allow that kind of full expansion... > (And if it /were/ the only conceivable way, I would expect to find > something like DEFTYPE-EXPAND it the standard: if the cost of full > expansion were inevitable, why not reap the benefits of it?). Thanks. -- Gaby |
From: Anton K. <an...@sw...> - 2011-08-11 20:34:05
|
Gabriel Dos Reis <gd...@in...> writes: > We do not use directly TYPEP or SUBTYPEP. But, we do rely > heavily on function type proclamations involving those type specifiers. > Is such usage also not-recommended? Everything is fine unless you really need 'STRING for some of your declarations (in the sense of accepting/returning both base-strings and non-base strings and not being sure). Note that you may be working with base-strings unwittingly, even if you are not requesting their creation anywhere in your code: (type-of (symbol-name 'list)) => (SIMPLE-BASE-STRING 4) Default stream element type for SBCL's OPEN is BASE-CHAR too, so another possibly-unexpected source of base-strings in your code is READ-LINE. The declaration using a type that expands to STRING is the right one for code that may receive a base-string; if you replace it with a type expanded to (VECTOR CHARACTER), then base-string will cause a failure (btw, for any level of SAFETY but the most reckless one, SBCL will normally detect a type error in this case, instead of doing something dangerous). > OK. So, just to make sure I understand: it is OK to use the type > specifiers as long > as they expand to (VECTOR something), but not to the type specifier STRING > or SIMPLE-STRING. Is that correct? Yes. BASE-STRING and SIMPLE-BASE-STRING are fine too: their specialization is fixed and they aren't "hairy", because there is nothing like VERY-VERY-BASE-STRING specialized for some VERY-VERY-BASE-CHAR subset of possible BASE-CHARs. For /declarations/, any type (be it deftyped or predefined) is acceptable, so when you've figured out the right type to declare, feel free to use a deftype'd name. -- Regards, Anton Kovalenko +7(916)345-34-02 | Elektrostal' MO, Russia |
From: Gabriel D. R. <gd...@in...> - 2011-08-11 20:55:28
|
On Thu, Aug 11, 2011 at 3:33 PM, Anton Kovalenko <an...@sw...> wrote: > Gabriel Dos Reis <gd...@in...> writes: [many useful obvserations elided] > The declaration using a type that expands to STRING is the right one for > code that may receive a base-string; if you replace it with a type > expanded to (VECTOR CHARACTER), then base-string will cause a failure ouch :-( I take from this exchange that (while waiting for 1.0.51), OpenAxiom should expand the deftype %String to (VECTOR CHARACTER) only for object creation. > (btw, for any level of SAFETY but the most reckless one, SBCL will > normally detect a type error in this case, instead of doing something > dangerous). Ah, but we set SAFETY high only in debug mode; in normal builds, the extra checks are usually costly. We rely on type proclamations to hint the compiler about intended data semantics for better code generation. It is just that this particular aspect of the deftypes in object creation has tricked us... Thanks, -- Gaby |
From: Anton K. <an...@sw...> - 2011-08-11 21:07:26
|
Gabriel Dos Reis <gd...@in...> writes: >> The declaration using a type that expands to STRING is the right one for >> code that may receive a base-string; if you replace it with a type >> expanded to (VECTOR CHARACTER), then base-string will cause a failure > > ouch :-( > I take from this exchange that (while waiting for 1.0.51), OpenAxiom should > expand the deftype %String to (VECTOR CHARACTER) only for object creation. If it's indeed the case, I would recommend to use two different deftype's: one for declarations and another one for object creation. (Your wording suggests that you'll be looking for a way to make a single deftype expand differently. Don't go this route, nothing fruitful here). -- Regards, Anton Kovalenko +7(916)345-34-02 | Elektrostal' MO, Russia |
From: Christophe R. <cs...@ca...> - 2011-08-12 08:17:00
|
Christophe Rhodes <cs...@ca...> writes: > I'd prefer this or something like it to any cleverness involving union > types, but I'm aware that I'm only one voice among many these days (and > not a particularly strong voice at that). (What no impassioned defence of cleverness? I'm slightly disappointed, and even willing to be convinced...) Cheers, Christophe |
From: Nikodemus S. <nik...@ra...> - 2011-08-12 09:05:52
|
On 12 August 2011 11:16, Christophe Rhodes <cs...@ca...> wrote: > Christophe Rhodes <cs...@ca...> writes: > >> I'd prefer this or something like it to any cleverness involving union >> types, but I'm aware that I'm only one voice among many these days (and >> not a particularly strong voice at that). > > (What no impassioned defence of cleverness? I'm slightly disappointed, > and even willing to be convinced...) I think making STRING and deftypes that expand directly to STRING magical is technically inferior to making all sorts of subtypes of string equally magical: If someone wants to use base-strings to save space when possible, but doesn't want to pay for (VECTOR NIL) or non-simple strings, a deftype along the lines of (deftype string () '(and simple-string (not (vector nil)))) should work just fine with MAP, COERCE, etc. While I find it conceptually more elegant to implement this by working with general union types, I do agree that practical considerations are probably limited to strings, so I have no particular objections to making subtypes of CL:STRING magical here. (Clearly making deftypes that directly expand to CL:STRING work is an improvement over the current state of affairs, however. I'm perfectly willing to live with that too, but it's not my preference.) Cheers, -- nikodemus |
From: Christophe R. <cs...@ca...> - 2011-08-12 13:09:14
|
Nikodemus Siivola <nik...@ra...> writes: > I think making STRING and deftypes that expand directly to STRING > magical is technically inferior to making all sorts of subtypes of > string equally magical: All sorts? That's the kind of thing to make me wake up with nightmares of type system hacking. Even without talking SATISFIES types, thinking about implementing recognition of "all non-VECTOR-NIL strings of length more than 2" makes me want to cry. > (Clearly making deftypes that directly expand to CL:STRING work is an > improvement over the current state of affairs, however. I'm perfectly > willing to live with that too, but it's not my preference.) Well, I'm willing to live with it enough to fixup and commit my patch, so if someone isn't they at least have a few test cases in tests/ to check any mistakes against. Cheers, Christophe |