shortcut for dynamic dispatch and operators

Bill Baxter wbaxter at gmail.com
Tue Dec 1 09:27:07 PST 2009


On Tue, Dec 1, 2009 at 8:58 AM, Steven Schveighoffer
<schveiguy at yahoo.com> wrote:
> On Tue, 01 Dec 2009 11:24:17 -0500, Bill Baxter <wbaxter at gmail.com> wrote:
>
>> On Tue, Dec 1, 2009 at 6:30 AM, Steven Schveighoffer
>> <schveiguy at yahoo.com> wrote:
>>>
>>> An idea I just had when thinking about how ugly opDispatch and opBinary
>>> operators will be if we get those was, wouldn't it be cool if the
>>> compiler
>>> could translate:
>>>
>>> myTemplateMethod("abc" || "def")() if(condition) {}
>>>
>>> to
>>>
>>> myTemplateMethod(string __x)() if((__x == "abc" || __x == "def") &&
>>> condition) {}
>>>
>>> It makes dispatch based on compile-time strings much more palatable, for
>>> example:
>>>
>>> opDispatch("foo" || "bar")() {...}
>>> opBinary("+" || "-" || "*")(int rhs) {...}
>>>
>>> instead of:
>>>
>>> opDispatch(string fn)() if(fn == "foo" || fn == "bar") {...}
>>> opBinary(string op)() if(op == "+" || op == "-" || op == "*")(int rhs)
>>> {...}
>>>
>>> In fact, it can be generalized to any type which has literals:
>>>
>>> factorial(int x)(){ return factorial!(x-1)() * x;}
>>> factorial(1)() { return 1;}
>>>
>>> What I don't know is if the || works in all cases -- because something
>>> like
>>> true || false is a valid expression.  Maybe someone can come up with a
>>> better way.
>>
>> The closest thing is the specialization syntax:
>>
>>    factorial(int x : 1)() { return 1;}
>>
>> The main problem with your suggestion is that for most practical uses
>> you actually need to know what the parameter was, not just that it was
>> either "foo" or "bar".
>
> Yeah, I thought the __x in my example would have to be some pre-defined
> symbol, but I realized that if you had multiple such parameters it wouldn't
> work...
>
>> So you need to put a symbol somewhere in that
>> signature to bind the actual value to.
>>
>> But I agree, some syntax like
>>   opDispatch(x : "foo" || "bar")() {  /* use x */ ...}
>
> I like that, that works for me.  I'd even like:
>
> opDispatch(string x : "foo" || "bar")() {}
>
> better than having to do the if clause at the end of the signature.
>
>>
>> would look much nicer.  And it's pretty close to current
>> specialization syntax for values.  The type "string" can be
>> auto-deduced from the stuff after the colon.  But there are more
>> conditions that you'd like to test than just "||".  I guess I'd prefer
>> to just be able to move a whole if clause to after a colon.
>>
>>    void opDispatch(fn : fn == "foo" || fn == "bar")(Variant arg...) {}
>
> You can do the full if clause with the current syntax if you need more
> complex situations than just matching against a list.  I wasn't looking to
> replace the template contracts, I just think the most common case for
> opDispatch and opBinary is going to be "if symbol is this or that or the
> other thing", so it should be easier to use than the template contracts.
>  With your syntax, it's almost an extension of current syntax, so it might
> be doable (type inference would be a nice bonus).

Well with "x in array" syntax you could do

   void opDispatch(fn : fn in ["foo","bar"])(Variant arg...) {}

Part of what annoys me about the if clauses is just that they are
separated from the template arguments by the function arguments (or by
other template arguments), so I'd like to see a way to put those
conditions closer to the parameters they're constraining, regardless
of the brevity aspect.  In fact something like this would be nice:

void aTemplate(
       fn  if(fn in ["foo","bar"]),
       Args... if (Args.length == 2))
(Args x)
{
       ...
}


--bb



More information about the Digitalmars-d mailing list