Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

D has nested functions that can access the enclosing function's variables (and it's enclosing function's variables, on up the call stack!).

It's a feature I first encountered with Pascal.

It's simple to implement. After using them extensively for years now, they're a big improvement.



Are D's nested functions truly functions - for example are they ABI-compatible with a top-level function? If so, how do they get access to the stack frame?

gcc has this feature, it is implemented by constructing a trampoline-style function on the stack. This requires an executable stack, so isn't really a thing any more.


> Are D's nested functions truly functions

Yes. They're even inlinable!

> for example are they ABI-compatible with a top-level function?

If they are annotated with `static`, yes. If they are not so annotated, they are ABI-compatible with non-static member functions. In fact, in D, a pointer to a non-static member is interchangeable with a pointer to a non-static nested function. This makes for much convenience when dealing with algorithms that accept such pointers (called "delegates" in D):

> how do they get access to the stack frame?

And extra argument is passed to the function which is the frame pointer to the calling function. (This is called a "static link". The "dynamic link" is the return address.) This can be thought of as the "this" pointer to the "struct" that represents the caller's stack frame, hence the binary compatibility with member functions.

To go back to the enclosing enclosing enclosing function's stack frame, you dereference the static link 3 times. The tricky part is optimizing these dereferences away when there are no captured variables in a stack frame.


D has native support for 'delegates'; closures, essentially. Function literals that reference objects from an outer scope are delegates, and ABI-compatible with other delegates. Regular function pointers can trivially be converted to delegates, so if you want to store function pointers, you should store delegates instead and convert transparently as needed. You can't pass delegates into C functions (because they're only in the D abi, not the C abi), though most C libraries that take a callback also take a 'state' pointer that you can use instead.

Tl;dr: it's a bit complicated, especially wrt communication with c libraries, but in general they're interchangeable with other functions.


Part of why I miss programming in Pascal, which was only in school. Not enough minutes in the week to get to enjoy D.


Both Pascal and C borrow heavily from ALGOL, which both languages tried to simplify by leaving out various features.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: