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