I was afraid of that.

Another wart in the CLHS.  Even if the Type Police will tell me that "it's
for my own good". :)

Cheers
--
MA

On Thu, Feb 22, 2024 at 12:38 PM Martin Simmons <mar...@lispworks.com>
wrote:

> Assuming CURRY1 returns a function, then that is not portable.  The
> predicate-name given to SATISFIES is expected to be a symbol with a global
> function definition and there is no way to pass extra arguments.
>
> LispWorks TYPEP is not checking for this (but SUBTYPEP does).
>
> --
> Martin Simmons
> LispWorks Ltd
> http://www.lispworks.com/
>
>
>
> >>>>> On Thu, 22 Feb 2024 11:09:02 +0100, Marco Antoniotti said:
> >
> > Hi Pascal
> >
> > this works in LW
> >
> > CL-USER 21 >
> > (deftype msb (&optional (bits 8))               `(satisfies ,(curry1
> > 'msb-test bits)))
> > MSB
> >
> > CL-USER 22 > (typep 42 '(msb 6)) ; Less than or equal to 6, fail.
> > NIL
> >
> > CL-USER 23 > (typep 42 '(msb 7)) ; Greater than or equal to 7, succeed.
> >
> > T
> >
> > The function CURRY1 just curries one argument and MSB-TEST does the
> > check, taking two arguments, the second being the object to typep
> > (details irrelevant; trust me: it works).
> >
> > I know: done too much Haskell recently.
> >
> > MA
> >
> > On Wed, Feb 21, 2024 at 11:45 PM Pascal Bourguignon <
> p...@informatimago.com>
> > wrote:
> >
> > > Le 21/02/2024 à 22:10, Marco Antoniotti a écrit :
> > > > Hi
> > > >
> > > > I just stumbled upon this and I need confirmation.
> > > >
> > > > You cannot do anything like this, can you?
> > > >
> > > > (defstruct foo x)
> > > >
> > > >
> > > > (deftype foo-with-x (x) (satisfies 'foo-with-x-p)) ; No `x'!
> > >
> > > deftype is like defmacro really.
> > >
> > > So you could write:
> > >
> > > (deftype foo-with-x (x)
> > >    `(satisfies ',(intern (format nil "FOO-WITH-~S-P" x)))
> > >
> > > But you would need to have defined also the predicate with the same
> name
> > > at compilation-time (or, when the type is used).
> > >
> > >
> > >
> > > cl-user> (deftype foo-with-x (x)
> > >             `(satisfies ,(intern (with-standard-io-syntax (format nil
> > > "FOO-WITH-~S-P" x)))))
> > > FOO-WITH-X
> > > cl-user> (defstruct foo x)
> > > FOO
> > > cl-user> (defstruct bar y)
> > > BAR
> > > cl-user> (defun foo-with-x-p (o) (typep o 'foo))
> > > FOO-WITH-X-P
> > > cl-user> (defun foo-with-y-p (o) (typep o 'bar))
> > > FOO-WITH-Y-P
> > > cl-user> (typep (make-foo) '(foo-with-x x))
> > > T
> > > cl-user> (typep (make-foo) '(foo-with-x y))
> > > NIL
> > > cl-user> (typep (make-bar) '(foo-with-x y))
> > > T
> > > cl-user> (typep (make-bar) '(foo-with-x x))
> > > NIL
> > > cl-user>
> > >
> > > > (typep (make-foo :x 42) '(foo-with-x 42))
> > > >
> > > > I.e., there is no way to pass the x to foo-with-x-p, is there?
> > >
> > > Nope.  foo-with-x-p ie. the function given to satisfies must be the
> name
> > > of a predicate of the whole object.
> > >
> > > For something like: (typep (make-foo :x 42) '(foo-with-x 42))
> > > you'd have to do:
> > >
> > >
> > > cl-user> (deftype foo-with-x (value)
> > >             `(satisfies ,(intern (with-standard-io-syntax (format nil
> > > "FOO-WITH-X=~S-P" value)))))
> > > FOO-WITH-X
> > > cl-user> (defun foo-with-x=42-p (s) (= (foo-x s) 42))
> > > FOO-WITH-X=42-P
> > > cl-user> (typep (make-foo :x 42) '(foo-with-x 42))
> > > T
> > > cl-user> (typep (make-foo :x 33) '(foo-with-x 42))
> > > NIL
> > > cl-user>
> > >
> > > Of course, what we'd want, is to generate the function or closure when
> > > the deftype is expanded.  This is difficult, since we need to provide
> > > satisfies a function name, and it must be defined at compilation-time.
> > >
> > >
> > > I had a CLRFI that proposed to have lambda in satisfies, and that shows
> > > an example of what has to be done without a lambda. Cf. attachments.
> > >
> > > Note: this clrfi is not completely thought out, since for forms such
> as:
> > >
> > > (deftype restricted-list (element-type)
> > >        `(and (satisfies proper-list-p)
> > >              (satisfies ,(lambda (list)
> > >                            (every (lambda (item) (typep item
> > > ',element-type))
> > >                                   list)))))
> > >
> > > there is no closure (we build a new lambda expression for each use of
> > > the type.
> > >
> > > If we allowed (satisfies (lambda (...) ...))) we'd have to indicate in
> > > what lexical environment the lambda expression would be evaluated
> > > (assumedly, the lexical environment of the deftype body).  I have not
> > > thought about the consequences of that.
> > >
> > > --
> > > __Pascal Bourguignon__
> > >
> >
>

Reply via email to