Discussion:
BOA constructor and supplied-p argument
Tamas K Papp
2011-06-10 14:53:06 UTC
Permalink
Content preview: Hi, I tried to save a supplied-p parameter from a BOA constructor
like this: (defstruct (delayed-iseq (:constructor iseq (start-or-end &optional
(end 0 end?) (by 1) strict-direction?))) "Delayed index sequence evaluation."
start-or-end end end? by strict-direction?) [...]

Content analysis details: (-2.3 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
0.0 FREEMAIL_FROM Sender email is freemail (tkpapp[at]gmail.com)
-2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium
trust
[80.91.229.12 listed in list.dnswl.org]
-0.0 SPF_HELO_PASS SPF: HELO matches SPF record
-0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay
domain
-0.0 SPF_PASS SPF: sender matches SPF record
0.0 T_TO_NO_BRKTS_FREEMAIL T_TO_NO_BRKTS_FREEMAIL
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/419>

Hi,

I tried to save a supplied-p parameter from a BOA constructor like this:

(defstruct (delayed-iseq
(:constructor iseq (start-or-end
&optional (end 0 end?) (by 1)
strict-direction?)))
"Delayed index sequence evaluation."
start-or-end end end? by strict-direction?)

but SBCL complained that end? was not used. After rereading the CLHS
page for defstruct, I am still not 100% sure why this is. My
intepretation is that END? is an argument like any other, but probably I
am not getting something.

Anyhow, instead I used

(defstruct delayed-iseq
"Delayed index sequence evaluation."
start-or-end end end? by strict-direction?)

(defun iseq (start-or-end &optional (end 0 end?) (by 1) strict-direction?)
(make-delayed-iseq :start-or-end start-or-end :end end :end? end? :by by
:strict-direction? strict-direction?))

Is there a way to do it in a single defstruct definition?

Best,

Tamas

PS.: (eq end nil) is different from when it is not supplied, hence the
need to save end?.
Nick Levine
2011-06-10 15:14:35 UTC
Permalink
Content preview: I'm sure we all knew there had to be a good reason for &aux,
but maybe we had trouble remembering what it might be? (defstruct (delayed-iseq
(:constructor iseq (start-or-end &optional (end 0 endp) (by 1) strict-direction?
&aux (end? endp)))) "Delayed index sequence evaluation." start-or-end end
end? by strict-direction?) [...]

Content analysis details: (-0.0 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay
domain
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/420>

I'm sure we all knew there had to be a good reason for &aux, but maybe
we had trouble remembering what it might be?

(defstruct (delayed-iseq
(:constructor iseq (start-or-end
&optional (end 0 endp) (by 1) strict-direction? &aux (end? endp))))
"Delayed index sequence evaluation."
start-or-end end end? by strict-direction?)

- n
Pascal Costanza
2011-06-10 19:09:50 UTC
Permalink
Content preview: I think this is a bug in SBCL, and should be reported with
its maintainers. Pascal On 10 Jun 2011, at 16:53, Tamas K Papp wrote: [...]


Content analysis details: (-102.3 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-100 USER_IN_WHITELIST From: address is in the user's white-list
-2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium
trust
[134.184.129.112 listed in list.dnswl.org]
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/421>

I think this is a bug in SBCL, and should be reported with its maintainers.

Pascal
Post by Tamas K Papp
Hi,
(defstruct (delayed-iseq
(:constructor iseq (start-or-end
&optional (end 0 end?) (by 1)
strict-direction?)))
"Delayed index sequence evaluation."
start-or-end end end? by strict-direction?)
but SBCL complained that end? was not used. After rereading the CLHS
page for defstruct, I am still not 100% sure why this is. My
intepretation is that END? is an argument like any other, but probably I
am not getting something.
Anyhow, instead I used
(defstruct delayed-iseq
"Delayed index sequence evaluation."
start-or-end end end? by strict-direction?)
(defun iseq (start-or-end &optional (end 0 end?) (by 1) strict-direction?)
(make-delayed-iseq :start-or-end start-or-end :end end :end? end? :by by
:strict-direction? strict-direction?))
Is there a way to do it in a single defstruct definition?
Best,
Tamas
PS.: (eq end nil) is different from when it is not supplied, hence the
need to save end?.
_______________________________________________
pro mailing list
http://lists.common-lisp.net/cgi-bin/mailman/listinfo/pro
--
Pascal Costanza
Nikodemus Siivola
2011-06-10 20:20:33 UTC
Permalink
I think this is a bug in SBCL, and should be reported with its > maintainers.
It is. I'll commit a fix later today. Cheers, [...]

Content analysis details: (-100.7 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-100 USER_IN_WHITELIST From: address is in the user's white-list
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low
trust
[209.85.210.51 listed in list.dnswl.org]
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/422>
I think this is a bug in SBCL, and should be reported with its
maintainers.
It is. I'll commit a fix later today.

Cheers,

-- nikodemus
Nick Levine
2011-06-11 08:42:30 UTC
Permalink
Content preview: Actually, looking through my code base, I find I've used &aux
half a dozen times in the last ten years. Always in a BOA constructor. -
n pro mailing list pro-***@public.gmane.org http://lists.common-lisp.net/cgi-bin/mailman/listinfo/pro
[...]

Content analysis details: (-0.0 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay
domain
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/423>

Actually, looking through my code base, I find I've used &aux half a
dozen times in the last ten years. Always in a BOA constructor.

- n
Pascal Costanza
2011-06-11 10:42:38 UTC
Permalink
Content preview: On 11 Jun 2011, at 10:42, Nick Levine wrote: > Actually, looking
through my code base, I find I've used &aux half a > dozen times in the last
ten years. Always in a BOA constructor. I have a tendency to use &aux more
and more often, even outside of BOA constructors. There are two main reasons:
[...]

Content analysis details: (-102.3 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-100 USER_IN_WHITELIST From: address is in the user's white-list
-2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium
trust
[134.184.129.112 listed in list.dnswl.org]
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/424>
Post by Nick Levine
Actually, looking through my code base, I find I've used &aux half a
dozen times in the last ten years. Always in a BOA constructor.
I have a tendency to use &aux more and more often, even outside of BOA constructors. There are two main reasons:

- It saves horizontal space in the source code. Compare the following two pieces of code:

(defun foo1 (a b c &aux d e f)
...)

(defun foo2 (a b c)
(let (d e f)
...))

The use of &aux saves one level of indentation here, which can sometimes make a piece of code look more beautiful.


- The more important reason is that I sometimes want to derive some value from an argument that is "very close" to the value of the original argument. Here is an example:

(defun required-args (args)
(loop for arg in args until (member arg lambda-list-keywords) collect arg))

(defun process-method-arguments (args &aux (required-args (required-args args)))
...)

This is, of course, only a subjective quality, but in cases like this, the function actually only wants to do something with the required arguments for a method definition, but it also wants the client code not to worry too much about what it passes to the function. To me, &aux perfectly expresses that idea.


Best,
Pascal

--
Pascal Costanza
The views expressed in this email are my own, and not those of my employer.
Didier Verna
2011-06-11 11:03:23 UTC
Permalink
Content preview: Pascal Costanza wrote: > - The more important reason is that
I sometimes want to derive some > value from an argument that is "very close"
to the value of the > original argument. Here is an example: [...]

Content analysis details: (-99.3 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-100 USER_IN_WHITELIST From: address is in the user's white-list
0.0 FREEMAIL_FROM Sender email is freemail (didier.verna[at]gmail.com)
0.7 SPF_NEUTRAL SPF: sender does not match SPF record (neutral)
0.0 RFC_ABUSE_POST Both abuse and postmaster missing on sender domain
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/425>
Post by Pascal Costanza
- The more important reason is that I sometimes want to derive some
value from an argument that is "very close" to the value of the
I would go even farther than that. Sometimes, you want to slightly
frob the original argument and not use it anymore afterwards. In such
situations, you can even use the same variable name (one might consider
this either very stylized or very ugly ;-).


CL-USER> (defun foo (arg &aux (arg (1+ arg)))
arg)
FOO
CL-USER> (foo 1)
2
--
Resistance is futile. You will be jazzimilated.

Scientific site: http://www.lrde.epita.fr/~didier
Music (Jazz) site: http://www.didierverna.com
Thomas M. Hermann
2011-06-11 15:24:45 UTC
Permalink
I find &AUX useful for setting global parameters, like:

(defun read-data (data-source &aux (*read-default-float-format*
'double-float)) ...)

I think it better expresses the change than in a LET* form or using WITH at
the top of a LOOP.

Tom
----------------------------------------------------------------
Thomas M. Hermann
Odonata Research LLC
http://www.odonata-research.com/
http://www.linkedin.com/in/thomasmhermann
Post by Didier Verna
Post by Pascal Costanza
- The more important reason is that I sometimes want to derive some
value from an argument that is "very close" to the value of the
I would go even farther than that. Sometimes, you want to slightly
frob the original argument and not use it anymore afterwards. In such
situations, you can even use the same variable name (one might consider
this either very stylized or very ugly ;-).
CL-USER> (defun foo (arg &aux (arg (1+ arg)))
arg)
FOO
CL-USER> (foo 1)
2
--
Resistance is futile. You will be jazzimilated.
Scientific site: http://www.lrde.epita.fr/~didier
Music (Jazz) site: http://www.didierverna.com
_______________________________________________
pro mailing list
http://lists.common-lisp.net/cgi-bin/mailman/listinfo/pro
Pascal Costanza
2011-06-11 23:01:29 UTC
Permalink
I don't like (let (a b c) ...) any more than I do &aux. I suppose
it's because I'm trying to think "functionally", with "let"
as much as possible being "compute this value
and give it a name" rather than "declare this
variable so I can start side-effecting it.
In general, I agree about (let (a b c) ...), but there are situations where it's hard to avoid.
I wish there were an idiomatic way to have a let
where the variable cannot be set later. I do
have a macro for this in our library, but I
don't use it since it's not part of our general
programming style and consistency of
style is so important.
There is, actually:

(flet ((a () 5))
;; now (a) can only be read, but not assigned to
...)

I don't think this is as bad as it may seem at first sight, especially making this look like a variable again is easy:

(flet ((a () 5))
(symbol-macrolet ((a (a)))
...))
I'm not saying there's no place for let followed
by side effects. It's just not the way I usually
think of it.
Right.
Also, putting things in the parameter list that aren't
parameters just feels weird.
...but they are parameters, just not parameters passed by the client code explicitly. ;)
If I were designing Lisp again, I would also consider
not having &rest at all, and instead pass in "maps",
i.e. like alists, so that it would be easier to pass on
these arguments to other functions without
having to deal with "apply".
A lot of the original motivation of &rest was to
avoid consing. In the original implementation,
the list values of &rest parameters were
stack-consed, and you were supposed to
be careful not to retain them beyond the
scope of the function, a trap for the unwary,
which could have very bad consequences.
The fact that &rest can avoid consing is a major win in performance-critical code. Any alternative design that doesn't support this in some way can lead to problems here.

I'm a bit less happy by now about the separation of required arguments and keyword arguments. Python makes the use of keywords optional for the same arguments, and I think that's actually better. I think this can in principle be implemented very efficiently.
And I would get rid of the supplied-p business,
which REALLY makes it hard to pass values
on to other functions. Function composition
should not be hard to do.
Agreed.
But it's way to late to redesign Common Lisp.
No need to be pessimistic. We're still way ahead of everybody else. ;)

Pascal

--
Pascal Costanza
The views expressed in this email are my own, and not those of my employer.
Daniel Herring
2011-06-12 04:40:50 UTC
Permalink
Content preview: On Sun, 12 Jun 2011, Pascal Costanza wrote: > On 11 Jun 2011,
at 21:25, Daniel Weinreb wrote: > > But it's way to late to redesign Common
Lisp. > > No need to be pessimistic. We're still way ahead of everybody else.
;) [...]

Content analysis details: (-100.0 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, low
trust
[66.33.216.122 listed in list.dnswl.org]
-100 USER_IN_WHITELIST From: address is in the user's white-list
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/428>
But it's way to late to redesign Common Lisp.
No need to be pessimistic. We're still way ahead of everybody else. ;)
Actually, I think its nearing time to design CL's successor. (Each
generation should get a chance.) Fortunately, CL gives us many tools to
start designing a successor in CL itself; and that replacement should be
able to compile existing code with a little macro magic...

- Daniel

Loading...