Function argument order of evaluation

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Function argument order of evaluation

Tadeus Prastowo
Hello,

In C/C++, the following code has an undefined behavior (UB):

int my_var = 1;
my_function((my_var = 10), 2 * my_var);

It is because their respective standards do not specify that the
assignment `(my_var = 10)' as the first argument must be evaluated
before the second argument `2 * my_var' is evaluated.  So,
`my_function' can see as its arguments either `10' and `20' or `10'
and `2'.  Compiling the following code with GCC 5.5 that comes with
Ubuntu 16.04 gives the latter:

#include <stdio.h>
void my_function(int a, int b) {
  printf("%d, %d\n", a, b);
}
int main() {
  int my_var = 1;
  my_function((my_var = 10), 2 * my_var);
  return 0;
}

Does Emacs Lisp behave the same or does it provide a guarantee that
the function arguments are always evaluated from left to right?

I have searched Emacs Lisp manual and the archive of this mailing list
for the keyword "order of evaluation" but have not found the answer.
So, I ask directly here.  Sorry if I might have missed the obvious.

Thank you for your kind help.

--
Best regards,
Tadeus

Reply | Threaded
Open this post in threaded view
|

Re: Function argument order of evaluation

YUE Daian
On 2019-02-11 10:53, Tadeus Prastowo <[hidden email]> wrote:

> Hello,
>
> In C/C++, the following code has an undefined behavior (UB):
>
> int my_var = 1;
> my_function((my_var = 10), 2 * my_var);
>
> It is because their respective standards do not specify that the
> assignment `(my_var = 10)' as the first argument must be evaluated
> before the second argument `2 * my_var' is evaluated.  So,
> `my_function' can see as its arguments either `10' and `20' or `10'
> and `2'.  Compiling the following code with GCC 5.5 that comes with
> Ubuntu 16.04 gives the latter:
>
> #include <stdio.h>
> void my_function(int a, int b) {
>   printf("%d, %d\n", a, b);
> }
> int main() {
>   int my_var = 1;
>   my_function((my_var = 10), 2 * my_var);
>   return 0;
> }
>
> Does Emacs Lisp behave the same or does it provide a guarantee that
> the function arguments are always evaluated from left to right?
>
> I have searched Emacs Lisp manual and the archive of this mailing list
> for the keyword "order of evaluation" but have not found the answer.
> So, I ask directly here.  Sorry if I might have missed the obvious.
>
> Thank you for your kind help.
>
> --
> Best regards,
> Tadeus

Hi Tadeus,

From the Emacs Lisp reference:
...then the forms in the function body are evaluated in order, and the
value of the last body form becomes the value of the function call.

You see, the forms in the function body are evaluated *in order*.

I think it can be treated as a guarantee? ;-)

Reference:
https://ftp.gnu.org/old-gnu/Manuals/elisp-manual-20-2.5/html_chapter/elisp_9.html#SEC114

Danny

Reply | Threaded
Open this post in threaded view
|

Re: Function argument order of evaluation

Tomas Zerolo
In reply to this post by Tadeus Prastowo
On Mon, Feb 11, 2019 at 10:53:06AM +0100, Tadeus Prastowo wrote:
> Hello,

[about C's funcall arguments evaluation order]

> Does Emacs Lisp behave the same or does it provide a guarantee that
> the function arguments are always evaluated from left to right?

It's left-to-right. From the Elisp manual, "10.2.5 Evaluation of Function
Forms":

  "If the first element of a list being evaluated is a Lisp function
   object, byte-code object or primitive function object [...]  The
   first step in evaluating a function call is to evaluate the remaining
   elements of the list from left to right."

This seems to be consensus in most of the (traditional) Lisps. Scheme
departed from that, specifying unspecified evaluation order, which
created some stir at the time in comp.lang.scheme. There were (are?)
Schemes which evaluate the arguments left-to-right.

Cheers
-- tomás

signature.asc (205 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Function argument order of evaluation

Tadeus Prastowo
In reply to this post by YUE Daian
On Mon, Feb 11, 2019 at 4:01 PM YUE Daian <[hidden email]> wrote:

>
> On 2019-02-11 10:53, Tadeus Prastowo <[hidden email]> wrote:
> > Hello,
> >
> > In C/C++, the following code has an undefined behavior (UB):
> >
> > int my_var = 1;
> > my_function((my_var = 10), 2 * my_var);
> >
> > It is because their respective standards do not specify that the
> > assignment `(my_var = 10)' as the first argument must be evaluated
> > before the second argument `2 * my_var' is evaluated.  So,
> > `my_function' can see as its arguments either `10' and `20' or `10'
> > and `2'.

[...]

> Hi Tadeus,

Hi Danny,

> From the Emacs Lisp reference:
> ...then the forms in the function body are evaluated in order, and the
> value of the last body form becomes the value of the function call.
>
> You see, the forms in the function body are evaluated *in order*.
>
> I think it can be treated as a guarantee? ;-)

Thank you for responding.  But, my question is not about the
evaluation of the function body but about the invocation of the
function itself.

> Reference:
> https://ftp.gnu.org/old-gnu/Manuals/elisp-manual-20-2.5/html_chapter/elisp_9.html#SEC114
>
> Danny

--
Best regards,
Tadeus

Reply | Threaded
Open this post in threaded view
|

Re: Function argument order of evaluation

Tadeus Prastowo
In reply to this post by Tomas Zerolo
On Mon, Feb 11, 2019 at 4:03 PM <[hidden email]> wrote:

>
> On Mon, Feb 11, 2019 at 10:53:06AM +0100, Tadeus Prastowo wrote:
> > Hello,
>
> [about C's funcall arguments evaluation order]
>
> > Does Emacs Lisp behave the same or does it provide a guarantee that
> > the function arguments are always evaluated from left to right?
>
> It's left-to-right. From the Elisp manual, "10.2.5 Evaluation of Function
> Forms":
>
>   "If the first element of a list being evaluated is a Lisp function
>    object, byte-code object or primitive function object [...]  The
>    first step in evaluating a function call is to evaluate the remaining
>    elements of the list from left to right."

Yes, this is the answer.  I really have missed the obvious statement
there.  Thank you very much for your help.

> This seems to be consensus in most of the (traditional) Lisps. Scheme
> departed from that, specifying unspecified evaluation order, which
> created some stir at the time in comp.lang.scheme. There were (are?)
> Schemes which evaluate the arguments left-to-right.

Interesting.  Once again, thank you.

> Cheers
> -- tomás

--
Best regards,
Tadeus