* 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).