April 20, 2009
Hello BCS,

That didn't sound like I intended it to so...

Clarification: I think most of us could convince most of the rest of us of the our point given face time because I don't think there are near as many opposing views as it seems. (That is with points of operation, not with issues of syntax and or inclusion of features for which there will never be agreement ;)

> [ot] the annoying thing about this whole thread is that I'd bet a
> small amount of money that I could convince anyone here of my point in
> about 5 minuets if I had me, them and a chalkboard in the same room.

About 3 minutes me to figure out what they are arguing and about 2 minutes to show how what I'm arguing is orthogonal to it.

> I think almost all the confusion is not because people would disagree
> with what I'm trying to say but because there are about 5 different
> and almost unconnected things people are arguing about: a sort of "A
> is true"/"No, B is true" where A != B and A != !B and !A != B ...
> 
> Written language has the advantage that you can be very precise and
> thought out but has zero real time feedback like you get in a
> face-to-face and an insanely long delay for what feedback it does
> have.
> 


April 20, 2009
Hello Christopher,

> The utility is when you are looking for methods to invoke via runtime
> reflection, you can determine that a given function is one of these
> runtime opDotExp equivalents.

So it is being argued that there should be a standard way to do a run time function invocation system? I'll buy that.

> 
> I don't know how useful this is, in point of fact. Unless there's a
> standard system in D for integrating with scripting languages, anyway.
> 

Maybe there should be.


April 20, 2009
Hello Steven,


> Also, I don't think the requirement for this feature needs to be for
> the  arguments to be templated, it should be sufficient to have a
> single string  template argument.  This way, you can overload opDotExp
> functions via  argument lists.

split the difference and allow either (but not both):

R opDotExp(char[] name)(ArgList)
R opDotExp(char[] name, T...)(T)


April 20, 2009
On 20/04/2009 01:13, BCS wrote:
> Hello Yigal,
>
>> everything you said is true. there is some sort of a compile-time
>> since
>> the code is getting compiled. But in the above scheme there isn't any
>> real difference between run-time and compile-time and this distinction
>> has lost its meaning.
>> compare the following:
>> process A:
>> 1) use runtime dispatch based on run-time user input
>> 2) generate source code for the above case "on the fly"
>> 2) compile the above code and call it
>> process B:
>> 1) generete templated source code at runtime
>> 2) call run-time compiler module on the above code
>> 3) compiler instantiates the template based on the input at
>> *compile-time* (i.e. compile time dispatch)
>> 4) call the templated instance
>> the above are identical even if implemented differently since that
>> compile-time above is actually part of the run-time.
>> the only difference is the style of coding and I'd argue that the
>> second
>> process is unnecessarily more complex without any gains.
>> if nothing else than the source code generated will be shorter since
>> you
>> wouldn't need to stick "static" everywhere.
>
> I think you understand my point about what is possible but I'm not sure
> you are spotting what I'm saying regarding what should be done. I'll try
> and cleanly state what I'm asserting:
>
>
> a number of red hearings seem to be floating about based on cool uses
> for truly runtime dynamic function lookup (that we just agreed doesn't
> exist for the given syntax as for that case, the binding happens at sort
> sort of compile time). I'm calling them red herrings because those uses
> can be done with other functionalties that already exist.
>
> If we throw those out, the only new functionality remanding that any of
> this thread has provided is allowing the following syntax:
>
> a.b(args);
>
> to be used when the type of 'a' doesn't define a 'b'. What a lot of
> debate seems to be about is if that should be translated to:
>
> a.opDotExp("b", args);
>
> or
>
> a.opDotExp!("b", typeof(args))(args);
>
> but that's an easy question (go with option 2) if you note that the
> transformation is always at /some sort/ of compile time. If you want
> this and the non-static (a.k.a. the non compile time binding (where you
> thinking of static like static member and not static if/assert?)) form
> you can implement the non-static version using existing devices and make
> the above a trivial shell around.
>
> Trying to go the other way doesn't work as there is no way to make
> static decisions (static if or template specialization) in a purely
> runtime mode using runtime values.

I was meaning static as in "static if".
I agree with what you've written here. I think my point in this sub-thread is a bit side-tracked from the main topic.
again, what you said is correct, but since in our example we are discussing compile-time as part of run-time, that means there's no difference between static if and regular if (both are executed at run-time).
therefore, you can simplify code by re-factoring it to be regular run-time instead of complicated compile-time that is compiled at run-time. you gain nothing by using compile-time techniques here.

in other words, if I'm generating code at *run-time*, there's no point in providing a *compile-time* trivial shell as you mention above.

I think my main point was to answer Andrei's post - that an eval() function in a compiled language is possible and that nothing about a compiled language implies that we shouldn't be able to have this.
April 20, 2009
Hello Yigal,

> I was meaning static as in "static if".
> I agree with what you've written here. I think my point in this
> sub-thread is a bit side-tracked from the main topic.

there seems to be a lot of that in this thread

> again, what you said is correct, but since in our example we are
> discussing compile-time as part of run-time, that means there's no
> difference between static if and regular if (both are executed at
> run-time).

But one is interpreted and the other manifests as machine code, one can happen before the types of variable are resolved the other after, one only evaluates once during the runtime-compiletime and the other runs every time the function is actually called. Seems like a big enough difference to me.

> therefore, you can simplify code by re-factoring it to be regular
> run-time instead of complicated compile-time that is compiled at
> run-time. you gain nothing by using compile-time techniques here.

Bare in mind that I'm a compile time techniques junky but I think there is a LOT to be gained (if not in what can be done, it's already Turing compleat after all, then in how and how fast things can be done)

> in other words, if I'm generating code at *run-time*, there's no point
> in providing a *compile-time* trivial shell as you mention above.
> 

I see what your saying, but based on that you can ague that given a pre compile time code generator (lex/yacc?) compile time code generation (Boost::spirit, my dparse or templates in general) is pointless. Using compile time stuff in runtime generated code could be handy where it makes the generation of the code simpler (think swaths of boilerplate)

> I think my main point was to answer Andrei's post - that an eval()
> function in a compiled language is possible and that nothing about a
> compiled language implies that we shouldn't be able to have this.

My point is that there is no reason that having eval should make a difference in how opDotExp works because there is something akin to a compile time between text and evaluation anyway. 


April 20, 2009
On Mon, 20 Apr 2009 06:09:28 +0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> Yes, there are many things that opDotExp can do that opDot or alias this (which is essentially opDot without any code).  Hooking every function call on a type seems to be one of the two killer use cases of this feature (the other being defining a large range of functions from which only a small number need to exist).  But call forwarding seems not to be one of them.  There are better ways to simply forward a call (such as in your variant example).
>
> I'm pretty convinced that this is a useful feature, I still have qualms about how it's really easy to define a runtime black hole where the compiler happily compiles empty functions that do nothing instead of complaining about calling a function that does not exist.
>
> Also, I don't think the requirement for this feature needs to be for the arguments to be templated, it should be sufficient to have a single string template argument.  This way, you can overload opDotExp functions via argument lists.
>

That way you loose type safety of arguments.

> And BTW, the answer to your question above I think:
>
> mixin("return inner."~name~"(args)");
>
> Andrei demonstrated this usage in his Pascalize example.
>
> -Steve

Oh, right, I saw his post but forgot that solution. Thanks you!

April 20, 2009
BCS wrote:
> Hello Christopher,
> 
>> The utility is when you are looking for methods to invoke via runtime
>> reflection, you can determine that a given function is one of these
>> runtime opDotExp equivalents.
> 
> So it is being argued that there should be a standard way to do a run time function invocation system? I'll buy that.
> 
>>
>> I don't know how useful this is, in point of fact. Unless there's a
>> standard system in D for integrating with scripting languages, anyway.
>>
> 
> Maybe there should be.

But there isn't, so this is YAGNI. And if there were, then this particular issue would immediately be solved.
April 20, 2009
On Mon, 20 Apr 2009 06:54:21 -0400, Denis Koroskin <2korden@gmail.com> wrote:

> On Mon, 20 Apr 2009 06:09:28 +0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>
>> Yes, there are many things that opDotExp can do that opDot or alias this (which is essentially opDot without any code).  Hooking every function call on a type seems to be one of the two killer use cases of this feature (the other being defining a large range of functions from which only a small number need to exist).  But call forwarding seems not to be one of them.  There are better ways to simply forward a call (such as in your variant example).
>>
>> I'm pretty convinced that this is a useful feature, I still have qualms about how it's really easy to define a runtime black hole where the compiler happily compiles empty functions that do nothing instead of complaining about calling a function that does not exist.
>>
>> Also, I don't think the requirement for this feature needs to be for the arguments to be templated, it should be sufficient to have a single string template argument.  This way, you can overload opDotExp functions via argument lists.
>>
>
> That way you loose type safety of arguments.

No

class C
{
   int y;
   void opDotExp(string fname)(int x)
   {
      y = x;
   }
}

auto c = new C;
c.foo(1); // ok
c.foo("hi"); // compile error, no such function.

-Steve
April 20, 2009
Steven Schveighoffer wrote:
> On Mon, 20 Apr 2009 06:54:21 -0400, Denis Koroskin <2korden@gmail.com> wrote:
> 
>> On Mon, 20 Apr 2009 06:09:28 +0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>>
>>> Yes, there are many things that opDotExp can do that opDot or alias this (which is essentially opDot without any code).  Hooking every function call on a type seems to be one of the two killer use cases of this feature (the other being defining a large range of functions from which only a small number need to exist).  But call forwarding seems not to be one of them.  There are better ways to simply forward a call (such as in your variant example).
>>>
>>> I'm pretty convinced that this is a useful feature, I still have qualms about how it's really easy to define a runtime black hole where the compiler happily compiles empty functions that do nothing instead of complaining about calling a function that does not exist.
>>>
>>> Also, I don't think the requirement for this feature needs to be for the arguments to be templated, it should be sufficient to have a single string template argument.  This way, you can overload opDotExp functions via argument lists.
>>>
>>
>> That way you loose type safety of arguments.
> 
> No
> 
> class C
> {
>    int y;
>    void opDotExp(string fname)(int x)
>    {
>       y = x;
>    }
> }
> 
> auto c = new C;
> c.foo(1); // ok
> c.foo("hi"); // compile error, no such function.
> 
> -Steve

Good point. My take is, just have the compiler rewrite a.b(c, d, e) into a.opDot!("b")(c, d, e) and call it a day. After that, the usual language rules enter in action.


Andrei
April 20, 2009
On Mon, 20 Apr 2009 09:47:53 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Steven Schveighoffer wrote:
>> On Mon, 20 Apr 2009 06:54:21 -0400, Denis Koroskin <2korden@gmail.com> wrote:
>>
>>> On Mon, 20 Apr 2009 06:09:28 +0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>>>
>>>> Yes, there are many things that opDotExp can do that opDot or alias this (which is essentially opDot without any code).  Hooking every function call on a type seems to be one of the two killer use cases of this feature (the other being defining a large range of functions from which only a small number need to exist).  But call forwarding seems not to be one of them.  There are better ways to simply forward a call (such as in your variant example).
>>>>
>>>> I'm pretty convinced that this is a useful feature, I still have qualms about how it's really easy to define a runtime black hole where the compiler happily compiles empty functions that do nothing instead of complaining about calling a function that does not exist.
>>>>
>>>> Also, I don't think the requirement for this feature needs to be for the arguments to be templated, it should be sufficient to have a single string template argument.  This way, you can overload opDotExp functions via argument lists.
>>>>
>>>
>>> That way you loose type safety of arguments.
>>  No
>>  class C
>> {
>>    int y;
>>    void opDotExp(string fname)(int x)
>>    {
>>       y = x;
>>    }
>> }
>>  auto c = new C;
>> c.foo(1); // ok
>> c.foo("hi"); // compile error, no such function.
>>  -Steve
>
> Good point. My take is, just have the compiler rewrite a.b(c, d, e) into a.opDot!("b")(c, d, e) and call it a day. After that, the usual language rules enter in action.

Haven't used D2 for much stuff, but does this work?  I remember reading something about partial IFTI, so if you have

opDotExp(string fname, T...) (T args){}

and you call

opDotExp!("b")(c, d, e)

Does it implicitly define T?

-Steve