Thread overview
Function Literals and "extern(...)"
Feb 23, 2005
John Reimer
Feb 23, 2005
John Reimer
Mar 01, 2005
Walter
Mar 01, 2005
John Reimer
Feb 26, 2005
Matthew
February 23, 2005
This subject came up before; I'm bringing it up again in the hopes that it won't disappear. I really, really need the feature I describe here, and I'm sure others do to (or will eventually).

The addition of D's function literal has added another great tool to the language.  In its current form though, these literals will only work when interfacing with other D code; that is, all function literals default to the extern(D) calling convention... and there's no way to change that.  For example:

# module callback;
#
# extern(Windows) alias int function() Callback;
#
# void main()
# {
#    int result;
#    Callback[100] functionList;
#
#    functionList[0] =
#        function int() { printf("hello\n"); return 1; }
#
#    result = functionList[0]();
# }

This code is invalid because the "functionList[0]" pointer is decorated extern(Windows) while the assigned function literal is extern(D). The attempt to assign the function literal will result in a compile error. This can't be changed for a couple of reasons:

1) extern(...)'s are not permitted within a function block.  Thus you cannot explicitly apply an extern(Windows) to the function literal assignment.

2) Using a typed callback as a function literal is not allowed.

To fix this, I think we should decide whether to allow extern's to be applied within function scope. I don't know the technical difficulties involved, but it seems like a simple solution since it has to do with calling convention alone (of course, extern's have a decidedly multi-faceted purpose in D, so it may be more complicated than one thinks).

The other solution is to fix #2 above so that the following works:

# module callback;
#
# extern(Windows) alias int function() Callback;
#
# void main()
# {
#    int result;
#    Callback[100] functionList;
#
#    /** "typed" function literal applied **/
#    functionList[0] =
#        Callback { printf("hello\n"); return 1; }
#
#    result = functionList[0]();
# }

Or something similar.

If we could get function literals to work properly with externs, I think D would have it made.  Yet, without fine control of the calling convention, function literals are relegated to D use only.  DWT and some OpenGL projects I'm working on would benefit greatly from this change, since both libraries really on interfacing with C or Windows API type code (callbacks).  Without function literals (or even local functions) being able to have different calling conventions, I'm prevented from making simple, intuitive coding solutions.  Instead, I am required to generate subtle, complex workarounds or lengthy replacements.  This shouldn't be the D way. It's a C world out there... we need to be able to adequately interface with it; and I think that's what D was designed to do afterall.

Walter, please?

- John R.
February 23, 2005
On further examination of assembler ouput of a D program, I've found that function literals are really no different than module level functions:

1) Function literals are given a mangled name; and their code segment is listed along with other module level functions of all types -- extern(C), extern(D), and extern(Windows) type functions all share the same segment. (in short function literals are not /local/ to a function that they are defined in, as it may seem.)

2) Function literals appear with D calling convention and assembler output takes the same form and location as non-literal D functions.

3) Data segment access follows the same form and location as normal function access.

In short, function literals are just normal functions in which the compiler has chosen the name for you.  No surprise to some, I'm sure; but it was important for me to figure this out to assure myself that I wasn't requesting the impossible.

Since function literals are implemented the same way as normal functions, it should be straight-forward to allow an extern(...) decoration for them via a compiler update.

- John R.
February 26, 2005
Agreed. I came up with a nice implementation of FindChild in D many moons ago, and it was stymied by the fact that nested funcs cannot be extern(Windows). I can't remember Walter's precise response back then, but it wasn't terribly encouraging. Maybe time may wear on him ...

"John Reimer" <brk_6502@yahoo.com> wrote in message news:cvh81c$2ujp$1@digitaldaemon.com...
> This subject came up before; I'm bringing it up again in the hopes that it won't disappear. I really, really need the feature I describe here, and I'm sure others do to (or will eventually).
>
> The addition of D's function literal has added another great tool to the language.  In its current form though, these literals will only work when interfacing with other D code; that is, all function literals default to the extern(D) calling convention... and there's no way to change that.  For example:
>
> # module callback;
> #
> # extern(Windows) alias int function() Callback;
> #
> # void main()
> # {
> #    int result;
> #    Callback[100] functionList;
> #
> #    functionList[0] =
> #        function int() { printf("hello\n"); return 1; }
> #
> #    result = functionList[0]();
> # }
>
> This code is invalid because the "functionList[0]" pointer is decorated extern(Windows) while the assigned function literal is extern(D). The attempt to assign the function literal will result in a compile error. This can't be changed for a couple of reasons:
>
> 1) extern(...)'s are not permitted within a function block.  Thus you cannot explicitly apply an extern(Windows) to the function literal assignment.
>
> 2) Using a typed callback as a function literal is not allowed.
>
> To fix this, I think we should decide whether to allow extern's to be applied within function scope. I don't know the technical difficulties involved, but it seems like a simple solution since it has to do with calling convention alone (of course, extern's have a decidedly multi-faceted purpose in D, so it may be more complicated than one thinks).
>
> The other solution is to fix #2 above so that the following works:
>
> # module callback;
> #
> # extern(Windows) alias int function() Callback;
> #
> # void main()
> # {
> #    int result;
> #    Callback[100] functionList;
> #
> #    /** "typed" function literal applied **/
> #    functionList[0] =
> #        Callback { printf("hello\n"); return 1; }
> #
> #    result = functionList[0]();
> # }
>
> Or something similar.
>
> If we could get function literals to work properly with externs, I think D would have it made.  Yet, without fine control of the calling convention, function literals are relegated to D use only.  DWT and some OpenGL projects I'm working on would benefit greatly from this change, since both libraries really on interfacing with C or Windows API type code (callbacks).  Without function literals (or even local functions) being able to have different calling conventions, I'm prevented from making simple, intuitive coding solutions.  Instead, I am required to generate subtle, complex workarounds or lengthy replacements.  This shouldn't be the D way. It's a C world out there... we need to be able to adequately interface with it; and I think that's what D was designed to do afterall.
>
> Walter, please?
>
> - John R.


March 01, 2005
"John Reimer" <brk_6502@yahoo.com> wrote in message news:cvhpdo$kcu$1@digitaldaemon.com...
> In short, function literals are just normal functions in which the compiler has chosen the name for you.  No surprise to some, I'm sure; but it was important for me to figure this out to assure myself that I wasn't requesting the impossible.

No, it isn't impossible.

> Since function literals are implemented the same way as normal functions, it should be straight-forward to allow an extern(...) decoration for them via a compiler update.

It isn't quite straightforward due to the way declarations are parsed, but it's doable.


March 01, 2005
Walter wrote:
> "John Reimer" <brk_6502@yahoo.com> wrote in message
> news:cvhpdo$kcu$1@digitaldaemon.com...
> 
>>In short, function literals are just normal functions in which the
>>compiler has chosen the name for you.  No surprise to some, I'm sure;
>>but it was important for me to figure this out to assure myself that I
>>wasn't requesting the impossible.
> 
> 
> No, it isn't impossible.
> 
> 
>>Since function literals are implemented the same way as normal
>>functions, it should be straight-forward to allow an extern(...)
>>decoration for them via a compiler update.
> 
> 
> It isn't quite straightforward due to the way declarations are parsed, but
> it's doable.
> 
> 

Thanks for responding.  I hope you can make the change sometime!

- JJR