function literals cannot be class members

Steven Schveighoffer schveiguy at yahoo.com
Mon Jul 18 06:21:31 PDT 2011


On Sun, 17 Jul 2011 09:49:52 -0400, d coder <dlang.coder at gmail.com> wrote:

> Greetings
>
>
>>
>
> Sure, this does not solve the original problem, if it was really an  
> issue.
>> @d coder: do you have an example where runtime changing of the  
>> comparison
>> function
>> behavior would be required?
>>
>>
> While I do, I am sure there are alternative ways to program to avoid  
> needing
> those.
>
> But I think there is a bigger usability issue in what I mentioned. There
> would be a good number of coders wanting to instantiate
> BinaryHeap!(SomeContainer, SomeComparator) as  a member of another  
> class. I
> agree that more often it would be the case where SomeComparator does not
> depend on a state variable. But even then, D does not allow me to provide
> any function/delegate literal for SomeComparator.
>
> So for example, even this is deemed illegal:
>
> class Foo {
>   BinaryHeap!(uint[], (a, b) {return a > b;}) heap;
>   // ..
> }
>
> To a casual programmer, this would be unacceptable, making BinaryHeap and
> other such structures too problematic to use. Even when you explicitly
> specify the delegate literal as a "function":
>
> class Foo {
>   BinaryHeap!(uint[], function (a, b) {return a > b;}) heap;
>   // ..
> }
>
> You get another Error: this for __funcliteral1 needs to be type Foo not  
> type
> BinaryHeap!(uint[],__funcliteral1)

The issue here is that the *type* of the binary heap depends on the  
functor.  Yet, you cannot define the functor (which depends on having an  
instance pointer) until you've instantiated the object, which in turn  
requires declaring the type.

What is needed is a BinaryHeap solution that accepts a delegate as a  
parameter instead of a template member.  I wonder if there's a reasonable  
mapping from the latter to the former, as I also use alias parameter to  
define functors in dcollections (stolen shamelessly from Andrei's  
design).  Worst case, BinaryHeap grows a branch which stores/calls a  
delegate instead of a template parameter.

Note to Mehrdad:

> I'm actually still confused at why _functions_ should be passed as  
> template parameters

The beauty of alias parameters is they can be *anything*, including:

* functions (not function pointers)
* function pointers  (including function literals)
* inner functions (i.e. functions with context that *aren't* delegates)
* delegates (including delegate literals)
* function objects (i.e. structs with opCall)
* function templates (whose parameters are determined via IFTI)
* strings which are used to build a function out of simple parameters  
(i.e. "a < b")

The big issue is that they cannot be runtime-dependent (to a certain  
degree).  What's interesting is that they *can* be runtime dependent if  
they are inner functions.  So clearly there is a way to get this to work.   
What I'm not sure is if it can be done without some syntax changes.

It's definitely a problem, but the benefits of using alias parameters seem  
to far outweigh these issues.

-Steve


More information about the Digitalmars-d mailing list