Azért elég kevés olyan nyelvet láttam eddig, amiben a szubrutinhívás úgy működik, mint amit leírsz; talán csak a BASIC (és már ott is nagy hibának tartottam). Fortranban is van függvény és szubrutin, de csak annyiban különböznek, hogy a szubrutinnak nincs visszatérési értéke. Változót átadni az argumentumlistájukkal tudsz, ugyanúgy mint a C-ben, annyi eltéréssel, hogy név szerint adod át (a függvény/szubrutin módosíthatja mellékhatásként), és már ez is okozhat nehezen debugolható hibákat, pl. az aliasing
c x-et kiírja, y-ba beírja sin(x)-et
subroutine foo(x, y)
y=sin(x)
write (*,*) x
end
c foo dokumentációja alapján arra számítasz, hogy először
c 0.7 jelenik meg, majd sin(0.7), de meglepetés ér
program alias
x = 0.7
call foo(x,x)
write (*,*) x
end
a kimenet:
./alias
0.644217670
0.644217670
Lehet, hogy bizonyos esetekben a gosub-szerű hívással kevesebb gépeléssel megírsz valamit, de egy bonyolult programnál könnyebb hibázni. Az lehet, hogy neked mindegy (nem írsz nagy programokat, vagy nem bánod a hibakeresést, mert nem határidőre dolgozol, vagy minden programot előre megtervezel papíron, fejben végrehajtod lépésről lépésre egyszer, vagy csak baromira koncentrálsz a programírásra), de a gyakorlat azt mutatja, hogy a többségnek jó, ha a compiler/interpreter segít.
A nested function kérdésköre: Fortran-ban Fortran 90 óta van (de csak egy szint, a belső függvényben már nem lehet még egy), C++-ban lambdákkal megoldható (és akkor még gosub-szerű szubrutinhívás is megoldható, egy [&] lambdával).