digitalmars.D.announce - Open Methods: From C++ to D
- Mike Parker (8/8) Aug 28 2017 Jean-Louis Leroy posted about his open methods library here in
- rikki cattermole (3/13) Aug 28 2017 Neat. Good to see articles in support of TypeInfo/ClassInfo!
- Jean-Louis Leroy (8/22) Aug 28 2017 Agreed.
- rikki cattermole (5/31) Aug 28 2017 Instead of hacking new features in, we should work on a full redesign.
- Mark (2/10) Aug 29 2017 Nice. This does seem superior to the visitor pattern.
- Jean-Louis Leroy (3/4) Aug 29 2017 Here is another example - AST traversal:
- Arun Chandrasekaran (4/8) Aug 29 2017 Thanks for this library. Just a suggestion. Would it possible to
- Jean-Louis Leroy (16/25) Aug 30 2017 Ah, I think it's a little late for that. A while ago I asked if
- Arun Chandrasekaran (4/6) Aug 30 2017 Just that `openmethod` precisely expresses it's intent and
- Jean-Louis Leroy (10/16) Aug 30 2017 I sort of agree, and somewhat regret not picking 'openmethod'. I
- rikki cattermole (3/20) Aug 30 2017 Rename, alias to old and have it deprecated.
- Jean-Louis Leroy (4/21) Aug 30 2017 Deprecated, already? :-D Hmmm maybe...Let's see if anyone speaks
- jmh530 (25/33) Aug 30 2017 We had some discussion about what to name it in the original
- Jean-Louis Leroy (13/30) Aug 30 2017 What happens here is that kick(Animal) is shadowed by kick(Dog).
- jmh530 (23/35) Aug 30 2017 I can submit this as an issue on the github page, but I figured
- Jean-Louis Leroy (3/11) Aug 30 2017 Gosh Windows I completely forgot about that...I'll take a look
- Jean-Louis Leroy (5/16) Aug 30 2017 Fixed. Committed to master and it should show up in dub soon.
- jmh530 (3/7) Aug 30 2017 Ha. Cheers.
- EntangledQuanta (8/47) Aug 31 2017 I was getting similar errors and simply added a cast(size_t)[used
- Jean-Louis Leroy (18/74) Aug 31 2017 It's fixed now, in master and in release v1.0.0-rc.2.
- EntangledQuanta (8/37) Aug 31 2017 I'll check it out. I don't think the last errors I was getting
- Jean-Louis Leroy (9/15) Aug 31 2017 Only size issues. Two lines in fact, see
- EntangledQuanta (22/38) Aug 31 2017 I'll try again at some point. I haven't got around to messing
- Jean-Louis Leroy (3/6) Sep 02 2017 Did you get a chance?
- EntangledQuanta (30/36) Sep 02 2017 I'll try real quick again. I'll have to rewrite the code as I
- Jean-Louis Leroy (21/34) Sep 02 2017 Yes I meant that. The README.md says "Every module that declares
- EntangledQuanta (27/60) Sep 02 2017 hmm, surely there is a mechanism which can be used? Possibly
- jmh530 (24/36) Aug 31 2017 I had a chance to try out what I had suggested above and it
- Jean-Louis Leroy (26/68) Aug 31 2017 Indeed I misunderstood.
- jmh530 (13/20) Aug 31 2017 I can see that it's a uphill battle, but there's a lot to like
- Atila Neves (4/13) Aug 31 2017 alias openmethod = method;
- aberba (3/17) Aug 31 2017 What happens when there is UDA name collision? if its
- Jean-Louis Leroy (3/11) Aug 31 2017 After tightening a few screws, the library now supports static
- Atila Neves (6/25) Aug 31 2017 import otherpackage: funkyMethod = openmethod;
- jmh530 (5/10) Aug 31 2017 There are no limits to his criticism. If there are conflicts with
- Q. Schroll (9/13) Aug 30 2017 If the something has to be done at the beginning, we have a tool
- Jean-Louis Leroy (5/18) Aug 30 2017 We had a discussion about automating the call to updateMethods
- jmh530 (7/11) Aug 30 2017 Ali had suggested something similar[1]. I think your concern was
- Jean-Louis Leroy (5/17) Aug 30 2017 Ah yes...So the problem is that registerMethods emits static
- Jean-Louis Leroy (10/29) Aug 30 2017 Yes I remember now...even if we arrange to put the call to
Jean-Louis Leroy posted about his open methods library here in the forums some time ago. Now, he's written a blog post that explains what open methods are, and describes the D implementation and how it compares to his C++ library. The blog: https://dlang.org/blog/2017/08/28/open-methods-from-c-to-d/ Reddit: https://www.reddit.com/r/programming/comments/6wj0ev/open_methods_from_c_to_d/
Aug 28 2017
On 28/08/2017 1:19 PM, Mike Parker wrote:Jean-Louis Leroy posted about his open methods library here in the forums some time ago. Now, he's written a blog post that explains what open methods are, and describes the D implementation and how it compares to his C++ library. The blog: https://dlang.org/blog/2017/08/28/open-methods-from-c-to-d/ Reddit: https://www.reddit.com/r/programming/comments/6wj0ev/open_methods_from_c_to_d/Neat. Good to see articles in support of TypeInfo/ClassInfo! I do wish we extended it for full reflection capabilities though...
Aug 28 2017
On Monday, 28 August 2017 at 12:31:20 UTC, rikki cattermole wrote:On 28/08/2017 1:19 PM, Mike Parker wrote:Agreed. Andrei suggested using rtlInfo but AFAICT this requires building a custom druntime. It would be easy to support this method in addition to 'deallocator' and 'hash' but I suspect it would not be a very popular option. Maybe we could have a void*[] in TypeInfo and a global integer index that extensions could use to allocate entries?Jean-Louis Leroy posted about his open methods library here in the forums some time ago. Now, he's written a blog post that explains what open methods are, and describes the D implementation and how it compares to his C++ library. The blog: https://dlang.org/blog/2017/08/28/open-methods-from-c-to-d/ Reddit: https://www.reddit.com/r/programming/comments/6wj0ev/open_methods_from_c_to_d/Neat. Good to see articles in support of TypeInfo/ClassInfo! I do wish we extended it for full reflection capabilities though...
Aug 28 2017
On 28/08/2017 9:06 PM, Jean-Louis Leroy wrote:On Monday, 28 August 2017 at 12:31:20 UTC, rikki cattermole wrote:Instead of hacking new features in, we should work on a full redesign. Clearly its needed between TypeInfo not cross the dll boundary on Windows (yay no classes!), -betterC and of course full reflection that we can do significantly better in this department.On 28/08/2017 1:19 PM, Mike Parker wrote:Agreed. Andrei suggested using rtlInfo but AFAICT this requires building a custom druntime. It would be easy to support this method in addition to 'deallocator' and 'hash' but I suspect it would not be a very popular option. Maybe we could have a void*[] in TypeInfo and a global integer index that extensions could use to allocate entries?Jean-Louis Leroy posted about his open methods library here in the forums some time ago. Now, he's written a blog post that explains what open methods are, and describes the D implementation and how it compares to his C++ library. The blog: https://dlang.org/blog/2017/08/28/open-methods-from-c-to-d/ Reddit: https://www.reddit.com/r/programming/comments/6wj0ev/open_methods_from_c_to_d/Neat. Good to see articles in support of TypeInfo/ClassInfo! I do wish we extended it for full reflection capabilities though...
Aug 28 2017
On Monday, 28 August 2017 at 12:19:26 UTC, Mike Parker wrote:Jean-Louis Leroy posted about his open methods library here in the forums some time ago. Now, he's written a blog post that explains what open methods are, and describes the D implementation and how it compares to his C++ library. The blog: https://dlang.org/blog/2017/08/28/open-methods-from-c-to-d/ Reddit: https://www.reddit.com/r/programming/comments/6wj0ev/open_methods_from_c_to_d/Nice. This does seem superior to the visitor pattern.
Aug 29 2017
On Tuesday, 29 August 2017 at 12:09:01 UTC, Mark wrote:Nice. This does seem superior to the visitor pattern.Here is another example - AST traversal: https://github.com/jll63/openmethods.d/blob/master/examples/acceptnovisitors/source/app.d
Aug 29 2017
On Tuesday, 29 August 2017 at 12:45:50 UTC, Jean-Louis Leroy wrote:On Tuesday, 29 August 2017 at 12:09:01 UTC, Mark wrote:Thanks for this library. Just a suggestion. Would it possible to use ` openmethod` instead of ` method`?Nice. This does seem superior to the visitor pattern.Here is another example - AST traversal: https://github.com/jll63/openmethods.d/blob/master/examples/acceptnovisitors/source/app.d
Aug 29 2017
On Wednesday, 30 August 2017 at 04:48:11 UTC, Arun Chandrasekaran wrote:On Tuesday, 29 August 2017 at 12:45:50 UTC, Jean-Louis Leroy wrote:Ah, I think it's a little late for that. A while ago I asked if anyone had suggestions regarding that sort of things...But now that the article has been published I think it would be a very bad idea to break all the exmaples in it. What was your rationale for `openmethod` instead of just `method`? I will push a commit tonight that will make this work: import openmethods : virtual, openmethod = method, next, registerMethods, updateMethods; // ... openmethod // implement 'kick' for dogs string _kick(Dog x) // note the underscore { return "bark"; }On Tuesday, 29 August 2017 at 12:09:01 UTC, Mark wrote:Thanks for this library. Just a suggestion. Would it possible to use ` openmethod` instead of ` method`?Nice. This does seem superior to the visitor pattern.Here is another example - AST traversal: https://github.com/jll63/openmethods.d/blob/master/examples/acceptnovisitors/source/app.d
Aug 30 2017
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.
Aug 30 2017
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: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.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.
Aug 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:Rename, alias to old and have it deprecated. Keep around for a couple of releases, done!On Wednesday, 30 August 2017 at 13:35:22 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.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.
Aug 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:Deprecated, already? :-D Hmmm maybe...Let's see if anyone speaks in favor of just method.On Wednesday, 30 August 2017 at 14:37:14 UTC, Arun Chandrasekaran wrote:Rename, alias to old and have it deprecated. Keep around for a couple of releases, done![...]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.
Aug 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 }
Aug 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.
Aug 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.
Aug 30 2017
On Wednesday, 30 August 2017 at 18:16:47 UTC, jmh530 wrote: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:Gosh Windows I completely forgot about that...I'll take a look tonight.
Aug 30 2017
On Wednesday, 30 August 2017 at 18:16:47 UTC, jmh530 wrote:..\..\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.Fixed. Committed to master and it should show up in dub soon. Gosh, all that mind bending meta polymorphic mixin reflection multi-dimensional fu and then fall prey to ints and uints and size_ts. Sobering...
Aug 30 2017
On Wednesday, 30 August 2017 at 23:40:59 UTC, Jean-Louis Leroy wrote:Fixed. Committed to master and it should show up in dub soon. Gosh, all that mind bending meta polymorphic mixin reflection multi-dimensional fu and then fall prey to ints and uints and size_ts. Sobering...Ha. Cheers.
Aug 30 2017
On Wednesday, 30 August 2017 at 18:16:47 UTC, jmh530 wrote:On Wednesday, 30 August 2017 at 15:59:32 UTC, Jean-Louis Leroy wrote:I was getting similar errors and simply added a cast(size_t)[used in the indexing, as he used ulongs for indexes rather than size_t] to all those you mention. After that I got more errors that I can't recall now but was much more cryptic. I did updateMethods and added the mixin but things wern't working so I gave up. Seems like a nice idea, although, the downside that I see is one doesn't get encapsulation.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.
Aug 31 2017
On Thursday, 31 August 2017 at 20:42:36 UTC, EntangledQuanta wrote:On Wednesday, 30 August 2017 at 18:16:47 UTC, jmh530 wrote:It's fixed now, in master and in release v1.0.0-rc.2. Actually not getting encapsulation is good. With vfuncs, if you want polymorphism you get access to private parts, need it or not. And most of the time you neither need nor want it. If you need polymorphism and privileged access, you should use a vfunc but it's usually a sign of bad design, because a vfunc is meant to be overridden. And the override won't have access to the private parts so you may end up changing access from private to protected and usually trouble follows. I can imagine legitimate cases though. Fox example, the DiagonalMatrix addition example. In that case you can write a public final member function that performs addition using privileged access and call that from the 2-method 'plus'. ANother approach is to write the fvunc - or the 1-method - in terms of the public interface. Usually it's feasible and yields a better design.On Wednesday, 30 August 2017 at 15:59:32 UTC, Jean-Louis Leroy wrote:I was getting similar errors and simply added a cast(size_t)[used in the indexing, as he used ulongs for indexes rather than size_t] to all those you mention. After that I got more errors that I can't recall now but was much more cryptic. I did updateMethods and added the mixin but things wern't working so I gave up. Seems like a nice idea, although, the downside that I see is one doesn't get encapsulation.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.
Aug 31 2017
On Thursday, 31 August 2017 at 21:02:26 UTC, Jean-Louis Leroy wrote:On Thursday, 31 August 2017 at 20:42:36 UTC, EntangledQuanta wrote:I'll check it out. I don't think the last errors I was getting were due to the sizing issues though, so is that all you fixed or was there some other stuff related to windows?On Wednesday, 30 August 2017 at 18:16:47 UTC, jmh530 wrote:It's fixed now, in master and in release v1.0.0-rc.2.[...]I was getting similar errors and simply added a cast(size_t)[used in the indexing, as he used ulongs for indexes rather than size_t] to all those you mention. After that I got more errors that I can't recall now but was much more cryptic. I did updateMethods and added the mixin but things wern't working so I gave up. Seems like a nice idea, although, the downside that I see is one doesn't get encapsulation.Actually not getting encapsulation is good. With vfuncs, if you want polymorphism you get access to private parts, need it or not. And most of the time you neither need nor want it. If you need polymorphism and privileged access, you should use a vfunc but it's usually a sign of bad design, because a vfunc is meant to be overridden. And the override won't have access to the private parts so you may end up changing access from private to protected and usually trouble follows. I can imagine legitimate cases though. Fox example, the DiagonalMatrix addition example. In that case you can write a public final member function that performs addition using privileged access and call that from the 2-method 'plus'.Yeah, but one should always be allowed to shoot themselves in the foot. You never know when you might do it. Maybe an alligator has attached itself to your foot and is about to drag you under water?ANother approach is to write the fvunc - or the 1-method - in terms of the public interface. Usually it's feasible and yields a better design.
Aug 31 2017
On Thursday, 31 August 2017 at 21:42:50 UTC, EntangledQuanta wrote:Only size issues. Two lines in fact, see https://github.com/jll63/openmethods.d/commit/b63a88132e639bb23bb7 b305f4457450f865c6a but errors can cascade. I ran a few examples using the current dmd on Windows. Worked OK. It would be nice to have the Windows equivalent of dev/run-everything, maybe someone can PR me that?It's fixed now, in master and in release v1.0.0-rc.2.I'll check it out. I don't think the last errors I was getting were due to the sizing issues though, so is that all you fixed or was there some other stuff related to windows?Yeah, but one should always be allowed to shoot themselves in the foot.I agree, wholeheartedly. In C++, yomm11 has macros that you can use to make a specific override or an entire method friend of a class. But alas no friendship in D.
Aug 31 2017
On Thursday, 31 August 2017 at 23:21:03 UTC, Jean-Louis Leroy wrote:On Thursday, 31 August 2017 at 21:42:50 UTC, EntangledQuanta wrote:I'll try again at some point. I haven't got around to messing with it again. I was testing it out on something and ran in to those errors, fixed them, then ran in to some more and just went a different direction. I will try to start using them more at some point as I think the concept, at least, can be useful. I haven't used it yet though to know just how useful. I like how it extends object functionality without having to mess directly with the objects. I think the more complex the project the more useful they become. What is good though is that one can mingle oop and openmethods and finding a proper balance should result in a simpler design.Only size issues. Two lines in fact, see https://github.com/jll63/openmethods.d/commit/b63a88132e639bb23bb7 b305f4457450f865c6a but errors can cascade. I ran a few examples using the current dmd on Windows. Worked OK. It would be nice to have the Windows equivalent of dev/run-everything, maybe someone can PR me that?It's fixed now, in master and in release v1.0.0-rc.2.I'll check it out. I don't think the last errors I was getting were due to the sizing issues though, so is that all you fixed or was there some other stuff related to windows?Yeah, D does some weird things. For all it's power it just screws the pooch in certain cases that really casts a shadow on what might be a great design. Usually there are work-arounds, but they always fill like a kludge and require an excessive amount of code to do something that could be done very simple, all in the name of XXX(whatever XXX is: backwards compatibility, "safety"(no guns on the beach! PERIOD! Even if the beach is full of alligators! We don't want anyone shooting anyone else! Better that they be eaten by alligators!), or some other "excuse").Yeah, but one should always be allowed to shoot themselves in the foot.I agree, wholeheartedly. In C++, yomm11 has macros that you can use to make a specific override or an entire method friend of a class. But alas no friendship in D.
Aug 31 2017
On Thursday, 31 August 2017 at 23:37:03 UTC, EntangledQuanta wrote:[Windows] I'll try again at some point. I haven't got around to messing with it again.Did you get a chance?
Sep 02 2017
On Saturday, 2 September 2017 at 14:04:07 UTC, Jean-Louis Leroy wrote:On Thursday, 31 August 2017 at 23:37:03 UTC, EntangledQuanta wrote:I'll try real quick again. I'll have to rewrite the code as I moved on but: When I just add the mixin and update(to main) I get the error openmethods.d(1432): Error: function `main` has no members main.d-mixin-15(15): Error: CTFE failed because of previous errors in _registerMethods This is when I have the mixin(registerMethods) in a module that doesn't use any open methods. It says add once per module in the help, but I think it means once per module where open methods are used? Removing that mixin from main allows it to compile(but I haven't created any methods yet). You might look in to adding updateMethods in a static this() since it will be ran per process and do everything necessary, I think. After a few stupid bugs by me, I was able to get it to work! Pretty much a drop in replacement! I didn't do anything fancy, very basic, but it did work. It's not a real test but does show it can, for the most part, replace traditional code. Strangely enough, I had a protected member that I was using and it works, I guess because I defined the openmethod in the same module. I changed it to private and it worked too. So the issues about encapsulation I thought about before may be irrelevant as long as the openmethods are used in the same module(which is a nice feature of D). So, everything looks good on my end. Once I get around to creating something new or rewriting some old stuff I'll try to use them more and see what happens.[Windows] I'll try again at some point. I haven't got around to messing with it again.Did you get a chance?
Sep 02 2017
On Saturday, 2 September 2017 at 20:55:13 UTC, EntangledQuanta wrote:This is when I have the mixin(registerMethods) in a module that doesn't use any open methods. It says add once per module in the help, but I think it means once per module where open methods are used?Yes I meant that. The README.md says "Every module that declares methods or define implementations must include the following line". Ah yes the ddoc. I should update it. Also I think I should allow the mixin to silently do nothing in this case. Good catch.You might look in to adding updateMethods in a static this() since it will be ran per process and do everything necessary, I think.Alas it won't work. Method registration is done via static ctors and they have to run - all of them - before updateMethods can do its work. In simple, one-module programs updateMethods in a static ctor will work, but in general it won't.Strangely enough, I had a protected member that I was using and it works, I guess because I defined the openmethod in the same module. I changed it to private and it worked too. So the issues about encapsulation I thought about before may be irrelevant as long as the openmethods are used in the same module(which is a nice feature of D).Neither the methods nor their overrides enjoy special privileges. Unless the override (i.e. the thing preceded by method) is a static member function? But I don't think so. Currently my code just scans the direct member of the module in which mixin(registerMethods) is called. Although I could change that, thus giving privileged access to some overrides. Could be useful for 1-methods. But anyway, probably there's something you don't notice...hmmm...can you share that code? Thanks for the feedback.
Sep 02 2017
On Saturday, 2 September 2017 at 21:16:50 UTC, Jean-Louis Leroy wrote:On Saturday, 2 September 2017 at 20:55:13 UTC, EntangledQuanta wrote:hmm, surely there is a mechanism which can be used? Possibly hooking in to druntime or some other hack? Not that it's a big deal but if you could get off the dependencies then it would be a sort of "compiler solution".This is when I have the mixin(registerMethods) in a module that doesn't use any open methods. It says add once per module in the help, but I think it means once per module where open methods are used?Yes I meant that. The README.md says "Every module that declares methods or define implementations must include the following line". Ah yes the ddoc. I should update it. Also I think I should allow the mixin to silently do nothing in this case. Good catch.You might look in to adding updateMethods in a static this() since it will be ran per process and do everything necessary, I think.Alas it won't work. Method registration is done via static ctors and they have to run - all of them - before updateMethods can do its work. In simple, one-module programs updateMethods in a static ctor will work, but in general it won't.In D, encapsulation is voided at the module level. So private members are public to the module. struct S { private int x; } void foo(S s) { writeln(s.x); } works. If foo is declared outside the module it will fail. It's like friend in C++ but automatic and per module. Pretty nice but that is about as far as it goes in D. My code was pretty simple. I couldn't share it all because it's too large, but I simply replaced a single member with an open method. It had a few lines of code. One was accessing a protected member, which I changed to private... all compiled. Then I remembered about D's encapsulation rules for the module. So that nullified my issues that I though openmethods might have. So, I think, in fact, this might be a pretty good solution to many problems. It allows extensibility without tying the methods to the classes directly. I'm still imagine encapsulation will be an issue for larger designs since the openmethods won't be defined in the same module, but I haven't used them enough to know what kinda faults will creep up yet. I haven't used openmethods enough to really see their power but hopefully with this solution I can ;) Thanks!Strangely enough, I had a protected member that I was using and it works, I guess because I defined the openmethod in the same module. I changed it to private and it worked too. So the issues about encapsulation I thought about before may be irrelevant as long as the openmethods are used in the same module(which is a nice feature of D).Neither the methods nor their overrides enjoy special privileges. Unless the override (i.e. the thing preceded by method) is a static member function? But I don't think so. Currently my code just scans the direct member of the module in which mixin(registerMethods) is called. Although I could change that, thus giving privileged access to some overrides. Could be useful for 1-methods. But anyway, probably there's something you don't notice...hmmm...can you share that code?
Sep 02 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 had a chance to try out what I had suggested above and it behaves exactly as I would have expected (i.e. it prints the line "lassie.kick(): ctbark"). You seemed to emphasize UFCS in your response, but that really wasn't what I was intending to focus on. I just as easily could have re-written Dog as below and compiled the program and it would have printed the same thing. Similarly, any Dog or Pitbull type that call kick would return "ctbark", just Animals would return the original results. class Dog : Animal { final string kick() { return "ctbark"; } } My point is one can easily mix your openmethods's dynamic dispatch and D's static dispatch. That seems like a great thing that you could emphasize. Simply stated: if you use openmethods, you're not forced to only use openmethods. If you know the type at compile-time, then you can use it. It's only if you want to dynamically dispatch it that you would need openmethods.
Aug 31 2017
On Thursday, 31 August 2017 at 14:52:43 UTC, jmh530 wrote:On Wednesday, 30 August 2017 at 15:59:32 UTC, Jean-Louis Leroy wrote:Indeed I misunderstood. Well, I am very pleased that my stuff interacts well with the rest of the language - I strive for that. However, I found that it is difficult to get people to open their mind to the idea of open methods, initially. Unless they come from Lisp, polymorphism and membership are almost indissociable for them. I often have to jump three hurdles. 1/ They're multi-methods, and I never actually had a use for that. That is why I insist so much on openness in the article, and throw multiple dispatch in as a bonus only half way through. That's also why I call them "open methods" and not "multi-methods" or "open multi-methods". 2/ It's just function overloading. Hmmm, polymorphism? But once I get past that, it's actually a good thing. People know (more or less) how overload resolution (or partial template specialization for the more expert) works. So I don't need to explain the rules governing dispatch and ambiguities in an abstract way. Usually I just say "you already know which override will be picked - it's the same as with compile-time overload resolution". 3/ This one is specific to D - UFCS gives me the same thing. Hmmm, polymorphism again? But you see why I am very careful with anything that may obscure or confuse the message. I find the interaction of open methods and UFCS particularly cool when implementing the "call chain" idiom (e.g. a.plus(b).times(c).invert()).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 had a chance to try out what I had suggested above and it behaves exactly as I would have expected (i.e. it prints the line "lassie.kick(): ctbark"). You seemed to emphasize UFCS in your response, but that really wasn't what I was intending to focus on. I just as easily could have re-written Dog as below and compiled the program and it would have printed the same thing. Similarly, any Dog or Pitbull type that call kick would return "ctbark", just Animals would return the original results. class Dog : Animal { final string kick() { return "ctbark"; } } My point is one can easily mix your openmethods's dynamic dispatch and D's static dispatch. That seems like a great thing that you could emphasize. Simply stated: if you use openmethods, you're not forced to only use openmethods. If you know the type at compile-time, then you can use it. It's only if you want to dynamically dispatch it that you would need openmethods.
Aug 31 2017
On Thursday, 31 August 2017 at 16:55:17 UTC, Jean-Louis Leroy wrote:Indeed I misunderstood. Well, I am very pleased that my stuff interacts well with the rest of the language - I strive for that. However, I found that it is difficult to get people to open their mind to the idea of open methods, initially. Unless they come from Lisp, polymorphism and membership are almost indissociable for them. I often have to jump three hurdles.I can see that it's a uphill battle, but there's a lot to like about it as well for those who listen. Maybe it would be a good idea to allow the method to take an argument, like method(Animal), then you could mixin string kick(virtual!Animal); without having to define kick. I think the ideal would be if you could just write something like below: string(Animal) string kick(virtual!Dog dog) { return "bark"; } but I don't really know how to get that to work.
Aug 31 2017
On Wednesday, 30 August 2017 at 04:48:11 UTC, Arun Chandrasekaran wrote:On Tuesday, 29 August 2017 at 12:45:50 UTC, Jean-Louis Leroy wrote:alias openmethod = method; AtilaOn Tuesday, 29 August 2017 at 12:09:01 UTC, Mark wrote:Thanks for this library. Just a suggestion. Would it possible to use ` openmethod` instead of ` method`?Nice. This does seem superior to the visitor pattern.Here is another example - AST traversal: https://github.com/jll63/openmethods.d/blob/master/examples/acceptnovisitors/source/app.d
Aug 31 2017
On Thursday, 31 August 2017 at 10:30:38 UTC, Atila Neves wrote:On Wednesday, 30 August 2017 at 04:48:11 UTC, Arun Chandrasekaran wrote:What happens when there is UDA name collision? if its catastrophic, then openmethods makes it unique.On Tuesday, 29 August 2017 at 12:45:50 UTC, Jean-Louis Leroy wrote:alias openmethod = method; AtilaOn Tuesday, 29 August 2017 at 12:09:01 UTC, Mark wrote:Thanks for this library. Just a suggestion. Would it possible to use ` openmethod` instead of ` method`?Nice. This does seem superior to the visitor pattern.Here is another example - AST traversal: https://github.com/jll63/openmethods.d/blob/master/examples/acceptnovisitors/source/app.d
Aug 31 2017
On Thursday, 31 August 2017 at 11:39:30 UTC, aberba wrote:After tightening a few screws, the library now supports static and selective imports.What happens when there is UDA name collision? if its catastrophic, then openmethods makes it unique.Thanks for this library. Just a suggestion. Would it possible to use ` openmethod` instead of ` method`?alias openmethod = method; Atila
Aug 31 2017
On Thursday, 31 August 2017 at 11:39:30 UTC, aberba wrote:On Thursday, 31 August 2017 at 10:30:38 UTC, Atila Neves wrote:import otherpackage: funkyMethod = openmethod; import openmethod: openmethod = method; Or use the fully qualified name. Either way, nothing that can't be dealt with by D's modules as they are now. AtilaOn Wednesday, 30 August 2017 at 04:48:11 UTC, Arun Chandrasekaran wrote:What happens when there is UDA name collision? if its catastrophic, then openmethods makes it unique.On Tuesday, 29 August 2017 at 12:45:50 UTC, Jean-Louis Leroy wrote:alias openmethod = method; AtilaOn Tuesday, 29 August 2017 at 12:09:01 UTC, Mark wrote:Thanks for this library. Just a suggestion. Would it possible to use ` openmethod` instead of ` method`?Nice. This does seem superior to the visitor pattern.Here is another example - AST traversal: https://github.com/jll63/openmethods.d/blob/master/examples/acceptnovisitors/source/app.d
Aug 31 2017
On Thursday, 31 August 2017 at 13:30:27 UTC, Atila Neves wrote:import otherpackage: funkyMethod = openmethod; import openmethod: openmethod = method; Or use the fully qualified name. Either way, nothing that can't be dealt with by D's modules as they are now. AtilaThere are no limits to his criticism. If there are conflicts with method, then what happens when someone writes another project with openmethod as a UDA. I don't think it needs to get changed.
Aug 31 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.
Aug 30 2017
On Wednesday, 30 August 2017 at 16:37:20 UTC, Q. Schroll wrote:In the article it says: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...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.
Aug 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
Aug 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: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.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
Aug 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: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.On Wednesday, 30 August 2017 at 17:24:55 UTC, Jean-Louis Leroy wrote: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.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
Aug 30 2017