www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Function Literals and "extern(...)"

reply John Reimer <brk_6502 yahoo.com> writes:
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.
Feb 22 2005
next sibling parent reply John Reimer <brk_6502 yahoo.com> writes:
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.
Feb 23 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"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.
Feb 28 2005
parent John Reimer <brk_6502 yahoo.com> writes:
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
Mar 01 2005
prev sibling parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
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. 

Feb 26 2005