vectorgraphics / asymptote

2D & 3D TeX-Aware Vector Graphics Language
https://asymptote.sourceforge.io/
GNU General Public License v3.0
542 stars 90 forks source link

Is it guaranteed that default arguments evaluated at call site and not definition site? #325

Closed jamadagni closed 2 years ago

jamadagni commented 2 years ago

Hello. Say I have a draw function for my custom object which takes optional pen arguments for drawing parts of the object. I would in fact like to default to the currentpen, but was worrying that the currentpen would be evaluated at function definition time. The documentation reads:

The value of a default argument is determined by evaluating the given Asymptote expression in the scope where the called function is defined.

However, testing with the following code indicates that it is in fact evaluated at the time of function being actually called:

size(10cm, 0);

struct tri
{
    pair a, b, c;
    void operator init(pair p, pair q, pair r)
    {
        a = p; b = q; r = c;
    }
}

currentpen = red;

void draw(tri t, pen pn = currentpen)
{
    draw(t.a -- t.b -- t.c -- cycle, pn);
}

currentpen = green;

tri t = tri((1, 2), (5, 4), (4, -6));
draw(t);

currentpen = blue;

tri u = tri((-6, 4), (4, 5), (2, 1));
draw(u);

With the Asymptote 2.78 which came with my Kubuntu 22.04 install, I do get green and blue (which is what I want) and not the red which was active at the time of function definition. But the documentation seems to speak otherwise. Hence I request for clarification.

Especially in case of currentpen etc, the current behaviour greatly simplifies things, else we would have to default to nullpen and within the function body, test for it and assign currentpen instead. Hence it seems the documentation might need to be corrected.

johncbowman commented 2 years ago

I think you misunderstood the word scope.

The value of a default argument is determined by evaluating the given code Asymptote expression at call time in the scope where the called function is defined.