* function arguments optional default values
@ 2024-07-03 21:21 Heime
2024-07-03 21:51 ` Stephen Berman
2024-07-06 12:43 ` Jean Louis
0 siblings, 2 replies; 11+ messages in thread
From: Heime @ 2024-07-03 21:21 UTC (permalink / raw)
To: Heime via Users list for the GNU Emacs text editor
Does elisp support function arguments optional default values ?
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: function arguments optional default values
2024-07-03 21:21 function arguments optional default values Heime
@ 2024-07-03 21:51 ` Stephen Berman
2024-07-03 21:56 ` Heime
2024-07-06 12:43 ` Jean Louis
1 sibling, 1 reply; 11+ messages in thread
From: Stephen Berman @ 2024-07-03 21:51 UTC (permalink / raw)
To: Heime; +Cc: Heime via Users list for the GNU Emacs text editor
On Wed, 03 Jul 2024 21:21:34 +0000 Heime <heimeborgia@protonmail.com> wrote:
> Does elisp support function arguments optional default values ?
The answer is in the Elisp manual (info "(elisp) Argument List"):
If actual arguments for the optional and rest variables are omitted,
then they always default to ‘nil’. There is no way for the function to
distinguish between an explicit argument of ‘nil’ and an omitted
argument. However, the body of the function is free to consider ‘nil’
an abbreviation for some other meaningful value. This is what
‘substring’ does; ‘nil’ as the third argument to ‘substring’ means to
use the length of the string supplied.
Common Lisp note: Common Lisp allows the function to specify what
default value to use when an optional argument is omitted; Emacs
Lisp always uses ‘nil’. Emacs Lisp does not support ‘supplied-p’
variables that tell you whether an argument was explicitly passed.
Steve Berman
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: function arguments optional default values
2024-07-03 21:51 ` Stephen Berman
@ 2024-07-03 21:56 ` Heime
2024-07-03 22:04 ` Stephen Berman
0 siblings, 1 reply; 11+ messages in thread
From: Heime @ 2024-07-03 21:56 UTC (permalink / raw)
To: Stephen Berman; +Cc: Heime via Users list for the GNU Emacs text editor
Sent with Proton Mail secure email.
On Wednesday, July 3rd, 2024 at 9:51 PM, Stephen Berman <stephen.berman@gmx.net> wrote:
> On Wed, 03 Jul 2024 21:21:34 +0000 Heime heimeborgia@protonmail.com wrote:
>
> > Does elisp support function arguments optional default values ?
>
>
> The answer is in the Elisp manual (info "(elisp) Argument List"):
>
> If actual arguments for the optional and rest variables are omitted,
> then they always default to ‘nil’. There is no way for the function to
> distinguish between an explicit argument of ‘nil’ and an omitted
> argument. However, the body of the function is free to consider ‘nil’
> an abbreviation for some other meaningful value. This is what
> ‘substring’ does; ‘nil’ as the third argument to ‘substring’ means to
> use the length of the string supplied.
>
> Common Lisp note: Common Lisp allows the function to specify what
> default value to use when an optional argument is omitted; Emacs
> Lisp always uses ‘nil’. Emacs Lisp does not support ‘supplied-p’
> variables that tell you whether an argument was explicitly passed.
>
> Steve Berman
So not like common lisp (var default)
I have to use UNLESS, perhaps OR.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: function arguments optional default values
2024-07-03 21:56 ` Heime
@ 2024-07-03 22:04 ` Stephen Berman
2024-07-03 22:24 ` Stephen Berman
0 siblings, 1 reply; 11+ messages in thread
From: Stephen Berman @ 2024-07-03 22:04 UTC (permalink / raw)
To: Heime; +Cc: Heime via Users list for the GNU Emacs text editor
On Wed, 03 Jul 2024 21:56:48 +0000 Heime <heimeborgia@protonmail.com> wrote:
> Sent with Proton Mail secure email.
>
> On Wednesday, July 3rd, 2024 at 9:51 PM, Stephen Berman
> <stephen.berman@gmx.net> wrote:
>
>> On Wed, 03 Jul 2024 21:21:34 +0000 Heime heimeborgia@protonmail.com wrote:
>>
>> > Does elisp support function arguments optional default values ?
>>
>>
>> The answer is in the Elisp manual (info "(elisp) Argument List"):
>>
>> If actual arguments for the optional and rest variables are omitted,
>> then they always default to ‘nil’. There is no way for the function to
>> distinguish between an explicit argument of ‘nil’ and an omitted
>> argument. However, the body of the function is free to consider ‘nil’
>> an abbreviation for some other meaningful value. This is what
>> ‘substring’ does; ‘nil’ as the third argument to ‘substring’ means to
>> use the length of the string supplied.
>>
>> Common Lisp note: Common Lisp allows the function to specify what
>> default value to use when an optional argument is omitted; Emacs
>> Lisp always uses ‘nil’. Emacs Lisp does not support ‘supplied-p’
>> variables that tell you whether an argument was explicitly passed.
>>
>> Steve Berman
>
> So not like common lisp (var default)
>
> I have to use UNLESS, perhaps OR.
Or other such alternatives, yes.
Steve Berman
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: function arguments optional default values
2024-07-03 22:04 ` Stephen Berman
@ 2024-07-03 22:24 ` Stephen Berman
0 siblings, 0 replies; 11+ messages in thread
From: Stephen Berman @ 2024-07-03 22:24 UTC (permalink / raw)
To: Heime; +Cc: Heime via Users list for the GNU Emacs text editor
On Thu, 04 Jul 2024 00:04:58 +0200 Stephen Berman <stephen.berman@gmx.net> wrote:
> On Wed, 03 Jul 2024 21:56:48 +0000 Heime <heimeborgia@protonmail.com> wrote:
>
>> Sent with Proton Mail secure email.
>>
>> On Wednesday, July 3rd, 2024 at 9:51 PM, Stephen Berman
>> <stephen.berman@gmx.net> wrote:
>>
>>> On Wed, 03 Jul 2024 21:21:34 +0000 Heime heimeborgia@protonmail.com wrote:
>>>
>>> > Does elisp support function arguments optional default values ?
>>>
>>>
>>> The answer is in the Elisp manual (info "(elisp) Argument List"):
>>>
>>> If actual arguments for the optional and rest variables are omitted,
>>> then they always default to ‘nil’. There is no way for the function to
>>> distinguish between an explicit argument of ‘nil’ and an omitted
>>> argument. However, the body of the function is free to consider ‘nil’
>>> an abbreviation for some other meaningful value. This is what
>>> ‘substring’ does; ‘nil’ as the third argument to ‘substring’ means to
>>> use the length of the string supplied.
>>>
>>> Common Lisp note: Common Lisp allows the function to specify what
>>> default value to use when an optional argument is omitted; Emacs
>>> Lisp always uses ‘nil’. Emacs Lisp does not support ‘supplied-p’
>>> variables that tell you whether an argument was explicitly passed.
>>>
>>> Steve Berman
>>
>> So not like common lisp (var default)
>>
>> I have to use UNLESS, perhaps OR.
>
> Or other such alternatives, yes.
But you can also use cl-defun (after requiring 'cl-lib), see the CL
manual (info "(cl) Argument Lists"):
-- Macro: cl-defun name arglist body...
This form is identical to the regular ‘defun’ form, except that
ARGLIST is allowed to be a full Common Lisp argument list.
[...]
The full form of a Common Lisp argument list is
(VAR...
&optional (VAR INITFORM SVAR)...
&rest VAR
&key ((KEYWORD VAR) INITFORM SVAR)...
&aux (VAR INITFORM)...)
Each of the five argument list sections is optional. The SVAR,
INITFORM, and KEYWORD parts are optional; if they are omitted, then
‘(VAR)’ may be written simply ‘VAR’.
The first section consists of zero or more “required” arguments.
These arguments must always be specified in a call to the function;
there is no difference between Emacs Lisp and Common Lisp as far as
required arguments are concerned.
The second section consists of “optional” arguments. These arguments
may be specified in the function call; if they are not, INITFORM
specifies the default value used for the argument. (No INITFORM means
to use ‘nil’ as the default.) [...]
Steve Berman
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: function arguments optional default values
2024-07-03 21:21 function arguments optional default values Heime
2024-07-03 21:51 ` Stephen Berman
@ 2024-07-06 12:43 ` Jean Louis
2024-07-06 15:03 ` [External] : " Drew Adams
1 sibling, 1 reply; 11+ messages in thread
From: Jean Louis @ 2024-07-06 12:43 UTC (permalink / raw)
To: Heime; +Cc: Heime via Users list for the GNU Emacs text editor
* Heime <heimeborgia@protonmail.com> [2024-07-04 00:23]:
>
> Does elisp support function arguments optional default values ?
I solve that problem with following:
(defun my-function (arg &optional other-arg)
(let* ((other-arg (or other-arg my-default)))
other-arg))
--
Jean
Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns
✡️🛡️ Proudly standing with Israel, a nation rooted in history and culture. Let's condemn hatred and promote understanding.
In support of Richard M. Stallman
https://stallmansupport.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [External] : Re: function arguments optional default values
2024-07-06 12:43 ` Jean Louis
@ 2024-07-06 15:03 ` Drew Adams
2024-07-06 15:55 ` Stefan Monnier via Users list for the GNU Emacs text editor
0 siblings, 1 reply; 11+ messages in thread
From: Drew Adams @ 2024-07-06 15:03 UTC (permalink / raw)
To: Jean Louis, Heime; +Cc: Heime via Users list for the GNU Emacs text editor
> > Does elisp support function arguments optional default values ?
>
> I solve that problem with following:
>
> (defun my-function (arg &optional other-arg)
> (let* ((other-arg (or other-arg my-default)))
> other-arg))
Simpler - no reason for another binding,
just change the value (it's a local var).
(defun my-function (arg &optional other-arg)
(setq other-arg (or other-arg my-default))
...)
or
(defun my-function (arg &optional other-arg)
(unless other-arg (setq other-arg my-default))
...)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [External] : Re: function arguments optional default values
2024-07-06 15:03 ` [External] : " Drew Adams
@ 2024-07-06 15:55 ` Stefan Monnier via Users list for the GNU Emacs text editor
2024-07-06 16:06 ` Drew Adams
2024-07-06 21:48 ` Heime
0 siblings, 2 replies; 11+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2024-07-06 15:55 UTC (permalink / raw)
To: help-gnu-emacs
>> > Does elisp support function arguments optional default values ?
>> I solve that problem with following:
>> (defun my-function (arg &optional other-arg)
>> (let* ((other-arg (or other-arg my-default)))
>> other-arg))
> Simpler - no reason for another binding,
> just change the value (it's a local var).
>
> (defun my-function (arg &optional other-arg)
> (setq other-arg (or other-arg my-default))
> ...)
FWIW, assuming you're using `lexical-binding` (which you should), this
tends to result in less efficient byte-code.
The difference is marginal in most cases (and efficiency of ELisp code
is irrelevant in most cases as well), but the point is that bindings
don't "cost" as much as mutation.
Here is how this usually plays out: with (setq x (or x <default>)) the
evaluation pushes the result of (or x <default>) on the stack, does the
`setq` which consumes the value on the stack and modifies the value of
`x`, which itself lives on the stack.
With (let ((x1 (or x <default>))) ...), the beginning is the same,
pushing the result of (or x <default>) on the stack, but then the
execution of the `let` is the "free" act of keeping that value on the
stack (i.e. doing nothing), and instead of referring to the stack
element that holds `x`, we will simply refer to the stack element that
holds `x1`.
[ There is still a cost to `let` in the fact that the stack grows a bit
more, of course, but it's usually of no consequence. ]
Compare
(let ((lexical-binding t))
(disassemble '(lambda (y &optional x)
(setq x (or x 5)) (+ y x))))
=>
byte code:
doc: ...
args: (arg1 &optional arg2)
0 dup
1 goto-if-not-nil-else-pop 1
4 constant 5
5:1 stack-set 1
7 stack-ref 1
8 stack-ref 1
9 plus
10 return
with
(let ((lexical-binding t))
(disassemble '(lambda (y &optional x)
(let ((x1 (or x 5))) (+ y x1)))))
=>
byte code:
doc: ...
args: (arg1 &optional arg2)
0 dup
1 goto-if-not-nil-else-pop 1
4 constant 5
5:1 stack-ref 2
6 stack-ref 1
7 plus
8 return
The difference is more drastic when the variable is captured by
a closure because our closure conversion is too naïve to understand that
the `setq` happens "once and forall" before we capture the variable, so
it presumes that the var may still be mutated after the closure is
constructed, which means that the closure can't just hold a copy of the
var's value but really needs to hold a "reference to the variable",
which we do by storing the variable's value inside a cons-cell:
Compare
(let ((lexical-binding t))
(disassemble '(lambda (&optional x)
(setq x (or x 5)) (lambda (y) (+ x y))))):
=>
byte code:
doc: ...
args: (&optional arg1)
0 dup
1 list1
2 dup
3 stack-ref 1
4 car-safe
5 goto-if-not-nil-else-pop 1
8 constant 5
9:1 setcar
10 discard
11 constant make-closure
12 constant <byte-code-function>
doc: ...
args: (arg1)
0 constant V0
1 car-safe
2 stack-ref 1
3 plus
4 return
13 stack-ref 2
14 call 2
15 return
with
(let ((lexical-binding t))
(disassemble '(lambda (&optional x)
(let ((x1 (or x 5))) (lambda (y) (+ x1 y))))))
=>
byte code:
doc: ...
args: (&optional arg1)
0 dup
1 goto-if-not-nil-else-pop 1
4 constant 5
5:1 constant make-closure
6 constant <byte-code-function>
doc: ...
args: (arg1)
0 constant V0
1 stack-ref 1
2 plus
3 return
7 stack-ref 2
8 call 2
9 return
- Stefan
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [External] : Re: function arguments optional default values
2024-07-06 15:55 ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2024-07-06 16:06 ` Drew Adams
2024-07-06 19:04 ` Stefan Monnier via Users list for the GNU Emacs text editor
2024-07-06 21:48 ` Heime
1 sibling, 1 reply; 11+ messages in thread
From: Drew Adams @ 2024-07-06 16:06 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'
[-- Attachment #1: Type: text/plain, Size: 2160 bytes --]
> >> > Does elisp support function arguments optional default values ?
> >> I solve that problem with following:
> >> (defun my-function (arg &optional other-arg)
> >> (let* ((other-arg (or other-arg my-default)))
> >> other-arg))
> > Simpler - no reason for another binding,
> > just change the value (it's a local var).
> >
> > (defun my-function (arg &optional other-arg)
> > (setq other-arg (or other-arg my-default))
> > ...)
>
> FWIW, assuming you're using `lexical-binding` (which you should), this
> tends to result in less efficient byte-code.
>
> The difference is marginal in most cases (and efficiency of ELisp code
> is irrelevant in most cases as well), but the point is that bindings
> don't "cost" as much as mutation.
>
> Here is how this usually plays out: with (setq x (or x <default>)) the
> evaluation pushes the result of (or x <default>) on the stack, does the
> `setq` which consumes the value on the stack and modifies the value of
> `x`, which itself lives on the stack.
>
> With (let ((x1 (or x <default>))) ...), the beginning is the same,
> pushing the result of (or x <default>) on the stack, but then the
> execution of the `let` is the "free" act of keeping that value on the
> stack (i.e. doing nothing), and instead of referring to the stack
> element that holds `x`, we will simply refer to the stack element that
> holds `x1`.
> [ There is still a cost to `let` in the fact that the stack grows a bit
> more, of course, but it's usually of no consequence. ]
> ...
>
> The difference is more drastic when the variable is captured by
> a closure because our closure conversion is too naïve to understand that
> the `setq` happens "once and forall" before we capture the variable, so
> it presumes that the var may still be mutated after the closure is
> constructed, which means that the closure can't just hold a copy of the
> var's value but really needs to hold a "reference to the variable",
> which we do by storing the variable's value inside a cons-cell:
> ...
Interesting! Thanks.
I wonder what the case is with various
Common Lisp implementations.
[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 15576 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [External] : Re: function arguments optional default values
2024-07-06 16:06 ` Drew Adams
@ 2024-07-06 19:04 ` Stefan Monnier via Users list for the GNU Emacs text editor
0 siblings, 0 replies; 11+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2024-07-06 19:04 UTC (permalink / raw)
To: help-gnu-emacs
> Interesting! Thanks.
>
> I wonder what the case is with various
> Common Lisp implementations.
Good implementations probably generate about the same code. BTW, the
same kind of thing applies in pretty much all languages, which is why
SSA is such a popular intermediate compiler representation (the
conversion to SSA form basically changes your code from the `setq`
version to the `let` version).
Stefan
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [External] : Re: function arguments optional default values
2024-07-06 15:55 ` Stefan Monnier via Users list for the GNU Emacs text editor
2024-07-06 16:06 ` Drew Adams
@ 2024-07-06 21:48 ` Heime
1 sibling, 0 replies; 11+ messages in thread
From: Heime @ 2024-07-06 21:48 UTC (permalink / raw)
To: Stefan Monnier; +Cc: help-gnu-emacs
On Saturday, July 6th, 2024 at 3:55 PM, Stefan Monnier via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote:
> > > > Does elisp support function arguments optional default values ?
> > > > I solve that problem with following:
> > > > (defun my-function (arg &optional other-arg)
> > > > (let* ((other-arg (or other-arg my-default)))
> > > > other-arg))
> > > > Simpler - no reason for another binding,
> > > > just change the value (it's a local var).
> >
> > (defun my-function (arg &optional other-arg)
> > (setq other-arg (or other-arg my-default))
> > ...)
>
>
> FWIW, assuming you're using `lexical-binding` (which you should), this
> tends to result in less efficient byte-code.
>
> The difference is marginal in most cases (and efficiency of ELisp code
> is irrelevant in most cases as well), but the point is that bindings
> don't "cost" as much as mutation.
Does the mutation occur with 'setq' ? And the binding is about the use of
'let' and 'let*' ? Then using the 'let' version would be preferred, right?
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2024-07-06 21:48 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-03 21:21 function arguments optional default values Heime
2024-07-03 21:51 ` Stephen Berman
2024-07-03 21:56 ` Heime
2024-07-03 22:04 ` Stephen Berman
2024-07-03 22:24 ` Stephen Berman
2024-07-06 12:43 ` Jean Louis
2024-07-06 15:03 ` [External] : " Drew Adams
2024-07-06 15:55 ` Stefan Monnier via Users list for the GNU Emacs text editor
2024-07-06 16:06 ` Drew Adams
2024-07-06 19:04 ` Stefan Monnier via Users list for the GNU Emacs text editor
2024-07-06 21:48 ` Heime
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).