January 30, 2014
On Thursday, 30 January 2014 at 18:02:05 UTC, Namespace wrote:
> On Thursday, 30 January 2014 at 17:46:19 UTC, Frustrated wrote:
>> Also,
>>
>> http://dlang.org/operatoroverloading.html#Dispatch
>>
>> and possible solution to your problem:
>>
>> http://www.digitalmars.com/d/archives/digitalmars/D/opDispatch_and_template_parameters_117095.html
>>
>> Couldn't get code to compile though... but if it did, it should
>> solve your problem.
>
> opDispatch is called if you try to call a non existing member. But in this case you don't call a member. ;)

Right, but maybe you can use the same technique as in the archive
link? (use an eponymous template for opCall?)
January 30, 2014
BTW,

a() is replaced with a.opCall()

and you can use opDispatch on it.

an opCall is a member.

Either approach should work if you can get that archive example
to compile.
January 30, 2014
On Thursday, 30 January 2014 at 18:11:49 UTC, Frustrated wrote:
> BTW,
>
> a() is replaced with a.opCall()
>
> and you can use opDispatch on it.
>
> an opCall is a member.
>
> Either approach should work if you can get that archive example
> to compile.

I am sure that the error is thrown before.
But please show me your attempts.
January 30, 2014
import std.stdio;

struct B
{
	template opCall(T)
	{
		void opCall(T x)
		{
			writeln(x);
		}
	}
}

template a(T)
{
	
}

void main() {
	B a;
	a(3);	// works because template parameter can be deduced from
arguments
	a.opCall!(int)(3); // same as about but explicit
	a!(int)(3); // works but calls template because a! refers to a
template
	// no way to use the above syntax to initiate an opCall on a
because it is template notation.
	// at most one might get away with a.!(int)(3) but this is
invalid
}



You'll never be able to do a!()() for the reasons give above. At
most it would have to be implemented the compiler and I doubt it
will ever happen. (for example, one could have the opExclamation
but then one has ambiguity, which is why ! was chosen to avoid in
the first place)


I think for your example, the first case works fine using
deduction.
January 30, 2014
> I think for your example, the first case works fine using
> deduction.

Sure but this is not always possible. ;)

It seems that the problem occurs also with opIndex and so probably with all op* methods. See:
http://forum.dlang.org/thread/bug-12043-3@https.d.puremagic.com%2Fissues%2F#post-lcegar:241ld2:241:40digitalmars.com
January 30, 2014
On Thursday, 30 January 2014 at 21:33:09 UTC, Namespace wrote:
>> I think for your example, the first case works fine using
>> deduction.
>
> Sure but this is not always possible. ;)
>
> It seems that the problem occurs also with opIndex and so probably with all op* methods. See:
> http://forum.dlang.org/thread/bug-12043-3@https.d.puremagic.com%2Fissues%2F#post-lcegar:241ld2:241:40digitalmars.com

Yes, because they all are implicit. It looks like you are calling
a template. D could figure this out but I think it will end up
having similar issues as >> has in C++. Is it an a templated op*
on an object or is it template function call?
January 31, 2014
On Thursday, 30 January 2014 at 22:34:52 UTC, Frustrated wrote:
> On Thursday, 30 January 2014 at 21:33:09 UTC, Namespace wrote:
>>> I think for your example, the first case works fine using
>>> deduction.
>>
>> Sure but this is not always possible. ;)
>>
>> It seems that the problem occurs also with opIndex and so probably with all op* methods. See:
>> http://forum.dlang.org/thread/bug-12043-3@https.d.puremagic.com%2Fissues%2F#post-lcegar:241ld2:241:40digitalmars.com
>
> Yes, because they all are implicit. It looks like you are calling
> a template. D could figure this out but I think it will end up
> having similar issues as >> has in C++. Is it an a templated op*
> on an object or is it template function call?

Explan it please with examples. I'm convinced that D is smarter as C++ with the '>>' problem.
---
class Foo {
    void opCall(size_t count) { }
}

Foo f = new Foo();
f(42); /// no template
----

----
class Foo {
    void opCall(T)(size_t count) { }
}

Foo f = new Foo();
f!int(42); /// template
----
No ambiguity.

As far as I understand you, you mean something like this:
----
import std.stdio;

class Foo {
	void opCall(size_t count) {
		writeln("F()");
	}
}

void f(T)(size_t count) {
	writeln("f()");
}

void main()
{
	Foo f = new Foo();
	f(42);
}
----
which prints correctly "F()"
January 31, 2014
Ask yourself this: in regards to overload resolution, when should template instantiation occur?

January 31, 2014
On Friday, 31 January 2014 at 00:29:20 UTC, Namespace wrote:
> On Thursday, 30 January 2014 at 22:34:52 UTC, Frustrated wrote:
>> On Thursday, 30 January 2014 at 21:33:09 UTC, Namespace wrote:
>>>> I think for your example, the first case works fine using
>>>> deduction.
>>>
>>> Sure but this is not always possible. ;)
>>>
>>> It seems that the problem occurs also with opIndex and so probably with all op* methods. See:
>>> http://forum.dlang.org/thread/bug-12043-3@https.d.puremagic.com%2Fissues%2F#post-lcegar:241ld2:241:40digitalmars.com
>>
>> Yes, because they all are implicit. It looks like you are calling
>> a template. D could figure this out but I think it will end up
>> having similar issues as >> has in C++. Is it an a templated op*
>> on an object or is it template function call?
>
> Explan it please with examples. I'm convinced that D is smarter as C++ with the '>>' problem.
> ---
> class Foo {
>     void opCall(size_t count) { }
> }
>
> Foo f = new Foo();
> f(42); /// no template
> ----
>
> ----
> class Foo {
>     void opCall(T)(size_t count) { }
> }
>
> Foo f = new Foo();
> f!int(42); /// template
> ----
> No ambiguity.
>
> As far as I understand you, you mean something like this:
> ----
> import std.stdio;
>
> class Foo {
> 	void opCall(size_t count) {
> 		writeln("F()");
> 	}
> }
>
> void f(T)(size_t count) {
> 	writeln("f()");
> }
>
> void main()
> {
> 	Foo f = new Foo();
> 	f(42);
> }
> ----
> which prints correctly "F()"

no, f(42) is not a template call and f!(42) is not ambiguous
because opCall is not templated. So no ambiguity here.

But if you have

class Foo {
  	void opCall(T)(size_t count) {
  		writeln("F()");
  	}
  }

then do

f!(42);

AND had the notation you wanted to use earlier.

then which f is to be called?

is f!(string)(42) referring to the templates opCall? OR
is f!(string)(42) calling the template(which it normally would)?


The point being there can be no unambiguous way to use the
template call notation with a templated opCall if the template
parameter must be explicitly given. If it can be deduced then
it's call looks like a normal function call and no ! is needed,
and then no ambiguity.

C++ had the issues where it crapped out on >>. When used in
template calls, say two nested ones), one would end up with >>,
which the compiler would think it was a left shift operation and
not part of the template. One would always have to put a space
between them to make the templates work properly. This has been
recently fixed.

Somewhere on the D site, Walter(I guess) explains that he chose
to use ! for template call syntax because it is not used anywhere
else in any ambiguous way so when you see a template call YOU
know it is a template call, unambiguously. So it becomes easy to
deal with semantically.

So, if your notation was implemented, it would no longer be easy
to know. The compiler would have to be context sensitive, which
is more complex and not perfect. I doubt Walter would go for that
so you'll never be able to use an explicit templated opCall...
but implicit are ok.
January 31, 2014
> So, if your notation was implemented, it would no longer be easy
> to know. The compiler would have to be context sensitive, which
> is more complex and not perfect. I doubt Walter would go for that
> so you'll never be able to use an explicit templated opCall...
> but implicit are ok.

I never wanted a new notation. I only want that the bug gets fixed. :)