I have also tested the semantics of nested function purity:

import std.c.stdio: printf;
import std.conv: to;

pure int double_sqr(int x) {
    pure int sqr(int y) { return y * y; }
    return sqr(x) + sqr(x);
}

void main(string[] args) {
    int x = args.length == 2 ? to!(int)(args[1]) : 10;
    int y = double_sqr(x) + double_sqr(x);
    printf("4 * x * x = %d\n", y);
}

Compiled without inlining:
-O -release

double_sqr.sqr:
        mov EAX,4[ESP]
        imul    EAX,EAX
        ret 4

double_sqr:
L0:     push    EAX
        push    EAX
        xor EAX,EAX
        call    near ptr double_sqr.sqr
        push    EAX
        sub ESP,4
        xor EAX,EAX
        push    dword ptr 8[ESP]
        call    near ptr double_sqr.sqr
        add ESP,4
        mov ECX,EAX
        pop EAX
        add EAX,ECX
        pop ECX
        ret

main:
L0:     push    EAX
        cmp dword ptr 8[ESP],2
        jne L1D
        mov EDX,0Ch[ESP]
        mov EAX,8[ESP]
        push    dword ptr 0Ch[EDX]
        push    dword ptr 8[EDX]
        call    near ptr to!(int)()
        jmp short   L22
L1D:        mov EAX,0Ah
L22:        call    near ptr double_sqr
        add EAX,EAX
        mov ECX,offset FLAT:_DATA
        push    EAX
        push    ECX
        call    near ptr printf

There's one call to double_sqr but unfortunately two to double_sqr.sqr.

Bye,
bearophile

Reply via email to