On Tue, 01 Dec 2009 12:27:07 -0500, Bill Baxter <[email protected]> wrote:

On Tue, Dec 1, 2009 at 8:58 AM, Steven Schveighoffer
<[email protected]> wrote:
On Tue, 01 Dec 2009 11:24:17 -0500, Bill Baxter <[email protected]> wrote:

On Tue, Dec 1, 2009 at 6:30 AM, Steven Schveighoffer
<[email protected]> 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...) {}

That would also work for me. But I prefer not having to repeat the template parameter name. My goal is to have templated operators as straightforward to type out as it is today:

opAdd(int rhs)

=>

opBinary(op: "+")(int rhs)

This looks like the closest so far that is consistent with current syntax.

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)
{
       ...
}

Yes, that can be annoying, but you still need the global 'if' in case you want to constrain on multiple arguments. However, it seems like a reasonable optimization to allow placing if statements after a template parameter. It definitely would make for better readability when the if clauses are complex, but it's still a little more clunky than I would like for implementing an individual operator.

-Steve

Reply via email to