August 30, 2017
On 30/08/2017 4:10 PM, Jean-Louis Leroy wrote:
> On Wednesday, 30 August 2017 at 14:37:14 UTC, Arun Chandrasekaran wrote:
>> On Wednesday, 30 August 2017 at 13:35:22 UTC, Jean-Louis Leroy wrote:
>>> On Wednesday, 30 August 2017 at 04:48:11 UTC, Arun What was your rationale for `openmethod` instead of just `method`?
>>
>> Just that `openmethod` precisely expresses it's intent and `method` is too generic.
> 
> I sort of agree, and somewhat regret not picking 'openmethod'. I considered both. Also @specialize. If anyone had pushed for @openmethod before the article, I would almost certainly have given in.
> 
> My reasoning was, I hope to promote the term 'method' as the standard name for polymorphism from outside, as opposed to vfunc. We usually say "virtual functions", rarely "virtual member functions". Membership is implicit.
> 

Rename, alias to old and have it deprecated.
Keep around for a couple of releases, done!
August 30, 2017
On Wednesday, 30 August 2017 at 15:14:04 UTC, rikki cattermole wrote:
> On 30/08/2017 4:10 PM, Jean-Louis Leroy wrote:
>> On Wednesday, 30 August 2017 at 14:37:14 UTC, Arun Chandrasekaran wrote:
>>> [...]
>> 
>> I sort of agree, and somewhat regret not picking 'openmethod'. I considered both. Also @specialize. If anyone had pushed for @openmethod before the article, I would almost certainly have given in.
>> 
>> My reasoning was, I hope to promote the term 'method' as the standard name for polymorphism from outside, as opposed to vfunc. We usually say "virtual functions", rarely "virtual member functions". Membership is implicit.
>> 
>
> Rename, alias to old and have it deprecated.
> Keep around for a couple of releases, done!

Deprecated, already? :-D Hmmm maybe...Let's see if anyone speaks in favor of just @method.
August 30, 2017
On Wednesday, 30 August 2017 at 15:10:03 UTC, Jean-Louis Leroy wrote:
>
> I sort of agree, and somewhat regret not picking 'openmethod'. I considered both. Also @specialize. If anyone had pushed for @openmethod before the article, I would almost certainly have given in.
>
> My reasoning was, I hope to promote the term 'method' as the standard name for polymorphism from outside, as opposed to vfunc. We usually say "virtual functions", rarely "virtual member functions". Membership is implicit.

We had some discussion about what to name it in the original announce thread, but I didn't want to get too focused on bikeshedding the names and you had made good points. @method is probably better than @specialize. Not sure what additional information you get from @openmethod, given that you're already importing from openmethods, but I don't really care that much.

One thing you didn't really cover is how seamlessly interacts with normal polymorphism. For instance, what if to your first example, I add the following function (note: without @method) and adjust main as below. I see no reason why this shouldn't work. But you wouldn't be able to create a string kick(Animal animal) function since that is created by the mixin.

string kick(Dog dog) { return "ct bark"; }

void main()
{
  updateMethods();
  import std.stdio : writeln;
  Animal snoopy = new Dog, hector = new Pitbull;
  writeln("snoopy.kick(): ", snoopy.kick()); // bark
  writeln("hector.kick(): ", hector.kick()); // bark an dbite
  Dog lassie = new Dog;
  writeln("lassie.kick(): ", lassie.kick()); // ct bark
}
August 30, 2017
On Wednesday, 30 August 2017 at 15:42:09 UTC, jmh530 wrote:
> One thing you didn't really cover is how seamlessly interacts with normal polymorphism. For instance, what if to your first example, I add the following function (note: without @method) and adjust main as below. I see no reason why this shouldn't work. But you wouldn't be able to create a string kick(Animal animal) function since that is created by the mixin.
>
> string kick(Dog dog) { return "ct bark"; }
>
> void main()
> {
>   updateMethods();
>   import std.stdio : writeln;
>   Animal snoopy = new Dog, hector = new Pitbull;
>   writeln("snoopy.kick(): ", snoopy.kick()); // bark
>   writeln("hector.kick(): ", hector.kick()); // bark an dbite
>   Dog lassie = new Dog;
>   writeln("lassie.kick(): ", lassie.kick()); // ct bark
> }

What happens here is that kick(Animal) is shadowed by kick(Dog). kick(Animal) is a method but it appears to the user and the compiler as an ordinary function - which is generally good. As such it is eligible for UFCS. I would not recommend this sort of coding, but it's everyone's choice, methods or not.

Likewise, methods can be overloaded (like here https://github.com/jll63/openmethods.d/blob/1.0.0-rc.1/examples/matrix/source/matrix.d#L12).

A current limitation is that default arguments are not supported (yet), although I think it's just a matter of putting the effort in.

UFCS interacts nicely with methods because you can say a.plus(b) even if 'plus' is an open method.


August 30, 2017
In the article it says:
> Finally, main calls updateMethods. This should be done before calling any method (typically first thing in main) and each time a library containing methods is dynamically loaded or unloaded.

If the something has to be done at the beginning, we have a tool for that: static this (on module level). The mixin(registerMethods); at the top should therefore mix in.

  static this() { updateMethods(); }

It's never wrong: Calling it in main, too, will at most be redundant. You can still call it manually, but for the part of main, you cannot inadvertently forget it. You can still have static this in that module as you may have multiple static this.
August 30, 2017
On Wednesday, 30 August 2017 at 16:37:20 UTC, Q. Schroll wrote:
> In the article it says:
>> Finally, main calls updateMethods. This should be done before calling any method (typically first thing in main) and each time a library containing methods is dynamically loaded or unloaded.
>
> If the something has to be done at the beginning, we have a tool for that: static this (on module level). The mixin(registerMethods); at the top should therefore mix in.
>
>   static this() { updateMethods(); }
>
> It's never wrong: Calling it in main, too, will at most be redundant. You can still call it manually, but for the part of main, you cannot inadvertently forget it. You can still have static this in that module as you may have multiple static this.

We had a discussion about automating the call to updateMethods but I don't think that anybody thought of putting it in registerMethods. It might work. I'll look into it. Thanks for the suggestion...
August 30, 2017
On Wednesday, 30 August 2017 at 17:24:55 UTC, Jean-Louis Leroy wrote:
>
> We had a discussion about automating the call to updateMethods but I don't think that anybody thought of putting it in registerMethods. It might work. I'll look into it. Thanks for the suggestion...

Ali had suggested something similar[1]. I think your concern was that it would get called multiple times, but shared static module constructors runs once a program (static module constructor runs once per thread).

[1] http://forum.dlang.org/post/okljj1$ktb$1@digitalmars.com
August 30, 2017
On Wednesday, 30 August 2017 at 15:59:32 UTC, Jean-Louis Leroy wrote:
> What happens here is that kick(Animal) is shadowed by kick(Dog). kick(Animal) is a method but it appears to the user and the compiler as an ordinary function - which is generally good. As such it is eligible for UFCS. I would not recommend this sort of coding, but it's everyone's choice, methods or not.
>
> Likewise, methods can be overloaded (like here https://github.com/jll63/openmethods.d/blob/1.0.0-rc.1/examples/matrix/source/matrix.d#L12).
>
> A current limitation is that default arguments are not supported (yet), although I think it's just a matter of putting the effort in.
>
> UFCS interacts nicely with methods because you can say a.plus(b) even if 'plus' is an open method.

I can submit this as an issue on the github page, but I figured I'd mention it here in case there was some easy fix.

I tried installing the latest release from github. Compiling (Windows 7 on DMD with default options) the simple program below

import openmethods;
mixin(registerMethods);

void main()
{
}

gives me the errors:

..\..\dubFolder\openmethods.d-1.0.0-rc.1\source\openmethods.d(970,21): Error: ca
nnot implicitly convert expression h of type ulong to uint
..\..\dubFolder\openmethods.d-1.0.0-rc.1\source\openmethods.d(1076,34): Error: c
annot implicitly convert expression dim of type ulong to uint
..\..\dubFolder\openmethods.d-1.0.0-rc.1\source\openmethods.d(1177,23): Error: c
annot implicitly convert expression h of type ulong to uint
dmd failed with exit code 1.

The error at line 1076 can be fixed by changing the type of dim in the function to size_t. I couldn't fix the other errors. I tried having the hash function return size_t also, but that just causes other problems.
August 30, 2017
On Wednesday, 30 August 2017 at 18:05:38 UTC, jmh530 wrote:
> On Wednesday, 30 August 2017 at 17:24:55 UTC, Jean-Louis Leroy wrote:
>>
>> We had a discussion about automating the call to updateMethods but I don't think that anybody thought of putting it in registerMethods. It might work. I'll look into it. Thanks for the suggestion...
>
> Ali had suggested something similar[1]. I think your concern was that it would get called multiple times, but shared static module constructors runs once a program (static module constructor runs once per thread).
>
> [1] http://forum.dlang.org/post/okljj1$ktb$1@digitalmars.com

Ah yes...So the problem is that registerMethods emits static ctors that fill data structures representing the methods and the specializations. They have to run - all of them - before updateMethods. Thus, sadly Q's suggestion won't work.
August 30, 2017
On Wednesday, 30 August 2017 at 18:20:46 UTC, Jean-Louis Leroy wrote:
> On Wednesday, 30 August 2017 at 18:05:38 UTC, jmh530 wrote:
>> On Wednesday, 30 August 2017 at 17:24:55 UTC, Jean-Louis Leroy wrote:
>>>
>>> We had a discussion about automating the call to updateMethods but I don't think that anybody thought of putting it in registerMethods. It might work. I'll look into it. Thanks for the suggestion...
>>
>> Ali had suggested something similar[1]. I think your concern was that it would get called multiple times, but shared static module constructors runs once a program (static module constructor runs once per thread).
>>
>> [1] http://forum.dlang.org/post/okljj1$ktb$1@digitalmars.com
>
> Ah yes...So the problem is that registerMethods emits static ctors that fill data structures representing the methods and the specializations. They have to run - all of them - before updateMethods. Thus, sadly Q's suggestion won't work.

Yes I remember now...even if we arrange to put the call to updateMethods in its own static ctor, coming after all the other static ctors, we don't know if there will be more modules with more methods afterwards. So we would have to do the updateMethods work each time, lest this module is the last. And updateMethods is costly: not only does it figure out all the dispatch tables, it also calculates a perfect hash (if @mptr is used) using a random algorithm.