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