Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 22:41:13 UTC, Ali Çehreli wrote: On 07/16/2017 10:24 AM, Jean-Louis Leroy wrote: Hello, TL;DR: see here https://github.com/jll63/methods.d/blob/master/README.md Added D to the Wikipedia entry, which can be expanded. :) https://en.wikipedia.org/wiki/Multiple_dispatch Ali Haha that settles it then, openmethods it is! I'll rename the repo and upload to the registry momentarily.
Re: New library: open multi-methods
On 07/16/2017 10:24 AM, Jean-Louis Leroy wrote: Hello, TL;DR: see here https://github.com/jll63/methods.d/blob/master/README.md Added D to the Wikipedia entry, which can be expanded. :) https://en.wikipedia.org/wiki/Multiple_dispatch Ali
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 21:20:04 UTC, jmh530 wrote: On Tuesday, 18 July 2017 at 21:16:11 UTC, jmh530 wrote: I may not have been clear enough. My ideal solution wouldn't make any changes to that densematrix.d file, just the interface. So I don't have any issue with the matrix modules doing the math and the app doing the printing. Well, I suppose the matrix interface would be saying that it can print, so maybe not as split up as you would like. While you could define a separate interface for printing, that would require a change to densematrix. Exactly. Orthogonality is essential for good composition, that is the reason why OOP - well, the OOP that follows the Simula/Smalltalk tradition - failed so badly. CLOS got it right 40 years ago; Simula, Smalltalk, C++, Java, etc they all got it wrong.
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 21:16:11 UTC, jmh530 wrote: I may not have been clear enough. My ideal solution wouldn't make any changes to that densematrix.d file, just the interface. So I don't have any issue with the matrix modules doing the math and the app doing the printing. Well, I suppose the matrix interface would be saying that it can print, so maybe not as split up as you would like. While you could define a separate interface for printing, that would require a change to densematrix.
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 19:22:38 UTC, Jean-Louis Leroy wrote: Look at https://github.com/jll63/methods.d/blob/master/examples/matrix/source/matrix.d and https://github.com/jll63/methods.d/blob/master/examples/matrix/source/densematrix.d They know nothing about printing. They don't want to. The matrix modules do math, the app does printing. J-L I may not have been clear enough. My ideal solution wouldn't make any changes to that densematrix.d file, just the interface. So I don't have any issue with the matrix modules doing the math and the app doing the printing. For instance, consider the traits in Rust https://doc.rust-lang.org/book/first-edition/traits.html My idea is like making the interfaces in D similar to the traits in Rust (or at least having the option to do something similar with them). Your @method void _print(Matrix m) would be similar to impl print for Matrix in Rust. Nevertheless, I get that it may be a difficult thing to implement.
Re: New library: open multi-methods
On 07/18/2017 12:22 PM, Jean-Louis Leroy wrote: > Look at > https://github.com/jll63/methods.d/blob/master/examples/matrix/source/matrix.d > and > https://github.com/jll63/methods.d/blob/master/examples/matrix/source/densematrix.d > They know nothing about printing. They don't want to. The matrix modules > do math, the app does printing. Related, our friend Luís Marques was the speaker in January 2016 here at the DLang Silicon Valley meetup. "A defense of so-called anemic domain models": https://www.meetup.com/D-Lang-Silicon-Valley/events/228027468/ I'm totally sold on the idea. Ali
Re: DMD library available as DUB package
On Tuesday, 18 July 2017 at 12:07:27 UTC, Jacob Carlborg wrote: During the dconf hackathon I set out to create a DUB package for DMD to be used as a library. This has finally been merged [1] and is available here [2]. It contains the lexer and the parser. A minimal example: #!/usr/bin/env dub /++ dub.sdl: name "dmd_lexer_example" dependency "dmd" version="~master" +/ void main() { import ddmd.lexer; import ddmd.tokens; import std.stdio; immutable sourceCode = "void test() {} // foobar"; scope lexer = new Lexer("test", sourceCode.ptr, 0, sourceCode.length, 0, 0); while (lexer.nextToken != TOKeof) writeln(lexer.token.value); } [1] https://github.com/dlang/dmd/pull/6771 [2] http://code.dlang.org/packages/dmd Awesome, was waiting for this.
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 18:03:30 UTC, jmh530 wrote: On Tuesday, 18 July 2017 at 16:57:30 UTC, Ali Çehreli wrote: Perhaps they are all needed but I'm thinking about the need for forward declaration, the need for the underscore prefix, etc. He might be able to at least get rid of the forward declaration (not sure on the underscore). The way it works now is that a class that inherits from an interface is not required in any way to implement the methods. Suppose he adds another attribute to an interface such that any class that inherits from it is required to have methods defined for specific functions. So for instance, the Matrix example might look something like @trait interface Matrix { @property int rows() const; @property int cols() const; @property double at(int i, int j) const; @trait void print(); } I'm not sure this would work because anything that derives from Matrix must implement print. However, if it is possible to use the attribute to allow the derived classes to ignore print, then it might work. Alternately, if there is a way to process the interface and tell the compiler to somehow ignore the @trait member functions. I don't know if it'll work, but it's an idea. Anyway, the mixin(registerMethods); could then be adjusted so that void print(virtual!Matrix m); is mixed in automatically because we now know how to construct it. There are at least problems with this. Firstly it is intrusive - something I strive to avoid (although I could be 100% orthogonal only because I hijack a deprecated pointer in ClassInfo). Also, some methods may want to treat Matrix as a virtual argument, and some not. Look at https://github.com/jll63/methods.d/blob/master/examples/matrix/source/matrix.d and https://github.com/jll63/methods.d/blob/master/examples/matrix/source/densematrix.d They know nothing about printing. They don't want to. The matrix modules do math, the app does printing. J-L
Re: static foreach is now in github master
On Tuesday, 18 July 2017 at 10:02:10 UTC, Seb wrote: On Monday, 17 July 2017 at 21:27:40 UTC, Martin Nowak wrote: On Monday, 17 July 2017 at 18:14:35 UTC, Andrei Alexandrescu wrote: For those who want to play with our new static foreach feature and are willing to take the steps to building their own dmd, Or just wait for the next nightly until tomorrow around 5AM UTC. curl -fsS https://dlang.org/install.sh | bash -s dmd-nightly the feature is now merged in master: https://github.com/dlang/dmd/pull/6760 Great news. And thanks to dmd-nightly, also on run.dlang.io: https://run.dlang.io/?compiler=dmd-nightly=void%20main(string%5B%5D%20args)%0A%7B%0A%20%20%20%20static%20foreach%20(i;%20%5B0,1,2,3%5D)%0A%09%7B%0A%20%20%20%20%09pragma(msg,%20i);%0A%09%7D%0A%7D Cool! Thank you!
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 18:21:21 UTC, Ali Çehreli wrote: That reminds me: Would the following be possible and better? // From void main() { updateMethods(); // ... } // To mixin(constructMethods()); void main() { // ... } constructMethods() could return the following string: string constructMethods() { return q{ shared static this() { updateMethods(); } }; } If I'm not missing something, this is better because nothing needs to be added to main and the methods are available before main starts executing (module initialization order issues still apply.). Ah, I would love to get rid of that call in main(), but think beyond a one module program. The matrix example (https://github.com/jll63/methods.d/tree/master/examples/matrix/source) consists in three separate modules, plus an app, all defining specializations. They need the mixin, but if we put updateMehods() in there, it will be called many times. And it is a costly operation. Guarding the call with a flag will not work, because more methods may be registered afterwards. Unless you can think of a way the last mixin can detect it's the last? Incidentally, in yomm11 that function (it's called initialize()) has to be called before any method is called, after any shared object/DLL is loaded and after a DLL is unloaded. I still have to write the code to de-register the methods and the specializations in that case by the way... J-L J-L
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 16:57:30 UTC, Ali Çehreli wrote: > As for performance, I have a first result: > https://github.com/jll63/methods.d/blob/master/benchmarks/source/benchmarks.d#L122 > but I still have to implement the "first argument optimization". I am > working on it. I could use some explanation for the results but I can for the blog article. ;) I pit a method-based call against its equivalent using virtual functions. First calling a virtual function via a base class is pitted against a method with one virtual parameter. Then the same but calling via an interface. Lastly, I compare double dispatch with a method with two virtual arguments. I use std.datetime.comparingBenchmark, which reports the result as time(base)/time(target). So open methods are a bit slower than ordinary virtual function calls but not that much. In the meantime I have applied a second optimization for unary methods and this brings them within 33% of an ordinary, compiler implemented vfunc call. Which is OK because the situation is highly artificial. If the function does anything, the difference will be imperceptible. I am more annoyed by double dispatch beating binary methods. I will have to look at the assembler, but it may be that the index pointer is too far from the object. To begin the real work, I need to fetch that pointer form an object. Currently it is stored in ClassInfo.deallocator, so I have to 1/ fetch the vptr 2/ fetch the ClassInfo* 3/ fetch 'deallocator'. What happens next depends on the arity. Any chance of Walter giving me a pointer in the vtable? Aside the ClassInfo*? Or at least a pointer in ClassInfo, or reassign the deallocator when it is eventually retired? It's not surprising that ldc (and gdc) can be much better than dmd in optimization. I would like to try gdc but it conflicts with ldc2 - you know, the "alias __va_list = __va_list_tag;" issue. I found suggestions via google but nothing worked for me so far. By the way, I'm in awe of your D skills in such a short time! Thanks :) I found out that D was much more natural, "predictable" than C++. The most cryptic error messages happened when I forgot the "!", IIRC. I'm sure there are parts of the code that can be cleaned up but it's taking advantage of many powerful features of the language. I still think the usage can be made easier but I'm not sure yet. I hope others will take a look at the code and come up with an easier interface. Perhaps they are all needed but I'm thinking about the need for forward declaration, the need for the underscore prefix, etc. (in reverse order) Regarding the prefix, it is needed to prevent overload resolution from trumping dynamic dispatch - see here: https://github.com/jll63/methods.d/blob/master/examples/whytheunderscore/source/app.d Allowing the same name would necessitate compiler support. As for the the forward declaration - I don't think it is possible to dispense with it. All open methods systems I know of have it (defgeneric in CLOS, defmulti in Clojure, Stroustrup's proposal...). Consider: class A { } class B : A { } class X : B { } class Y : B { } @method void _foo(virtual!X x) { ... } @method void _foo(virtual!Y x) { ... } What is the base method? foo(B)? foo(A)? It may well be the latter. Also don't forget that the complete specialization set is known, at the earliest, at link time. If you (arbitrarily) pick foo(B), another module may introduce a B or an A specialization. As for suggestions and advise, they are very welcome :) already got a couple of PRs. Here are the remaining questions on my mind: - the module/package name: I am pretty much set on openmethods though... - throw an exception if a method is not define for the argument set, or ambiguous: having big doubts about this. We want the possibility of @nothrow methods, don't we? So I will probably call a delegate via a pointer (a la C++) which, by default, will abort(). - the method prefix: hesitating between just _ or maybe m_ ??? - replace version(explain) with debug levels?
Re: New library: open multi-methods
On 07/18/2017 11:03 AM, jmh530 wrote: > the mixin(registerMethods); could then be adjusted so that void > print(virtual!Matrix m); is mixed in automatically because we now know > how to construct it. That reminds me: Would the following be possible and better? // From void main() { updateMethods(); // ... } // To mixin(constructMethods()); void main() { // ... } constructMethods() could return the following string: string constructMethods() { return q{ shared static this() { updateMethods(); } }; } If I'm not missing something, this is better because nothing needs to be added to main and the methods are available before main starts executing (module initialization order issues still apply.). Ali
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 16:57:30 UTC, Ali Çehreli wrote: Perhaps they are all needed but I'm thinking about the need for forward declaration, the need for the underscore prefix, etc. He might be able to at least get rid of the forward declaration (not sure on the underscore). The way it works now is that a class that inherits from an interface is not required in any way to implement the methods. Suppose he adds another attribute to an interface such that any class that inherits from it is required to have methods defined for specific functions. So for instance, the Matrix example might look something like @trait interface Matrix { @property int rows() const; @property int cols() const; @property double at(int i, int j) const; @trait void print(); } I'm not sure this would work because anything that derives from Matrix must implement print. However, if it is possible to use the attribute to allow the derived classes to ignore print, then it might work. Alternately, if there is a way to process the interface and tell the compiler to somehow ignore the @trait member functions. I don't know if it'll work, but it's an idea. Anyway, the mixin(registerMethods); could then be adjusted so that void print(virtual!Matrix m); is mixed in automatically because we now know how to construct it.
Re: New library: open multi-methods
On 07/18/2017 12:06 AM, Jean-Louis Leroy wrote: > Yes I will probably write something. You mean on the D Blog? Not necessarily but why not. :) > As for performance, I have a first result: > https://github.com/jll63/methods.d/blob/master/benchmarks/source/benchmarks.d#L122 > but I still have to implement the "first argument optimization". I am > working on it. I could use some explanation for the results but I can for the blog article. ;) It's not surprising that ldc (and gdc) can be much better than dmd in optimization. By the way, I'm in awe of your D skills in such a short time! I'm sure there are parts of the code that can be cleaned up but it's taking advantage of many powerful features of the language. I still think the usage can be made easier but I'm not sure yet. I hope others will take a look at the code and come up with an easier interface. Perhaps they are all needed but I'm thinking about the need for forward declaration, the need for the underscore prefix, etc. Ali
Re: static foreach is now in github master
On Tuesday, 18 July 2017 at 10:06:33 UTC, Vladimir Panteleev wrote: On Tuesday, 18 July 2017 at 10:02:10 UTC, Seb wrote: And thanks to dmd-nightly, also on run.dlang.io: https://run.dlang.io/?compiler=dmd-nightly=void%20main(string%5B%5D%20args)%0A%7B%0A%20%20%20%20static%20foreach%20(i;%20%5B0,1,2,3%5D)%0A%09%7B%0A%20%20%20%20%09pragma(msg,%20i);%0A%09%7D%0A%7D This link doesn't work, looks like it cuts off at the first ; ... Oh - seems like that was due to a different behavior between FF and Chrome :/ (Chrome unescapes the semi-colon by default). This has been fixed now, so the link above or this shortlink should work: https://is.gd/1TCQOh
Re: DMD library available as DUB package
On Tuesday, 18 July 2017 at 12:07:27 UTC, Jacob Carlborg wrote: During the dconf hackathon I set out to create a DUB package for DMD to be used as a library. This has finally been merged [1] and is available here [2]. It contains the lexer and the parser. A minimal example: #!/usr/bin/env dub /++ dub.sdl: name "dmd_lexer_example" dependency "dmd" version="~master" +/ void main() { import ddmd.lexer; import ddmd.tokens; import std.stdio; immutable sourceCode = "void test() {} // foobar"; scope lexer = new Lexer("test", sourceCode.ptr, 0, sourceCode.length, 0, 0); while (lexer.nextToken != TOKeof) writeln(lexer.token.value); } [1] https://github.com/dlang/dmd/pull/6771 [2] http://code.dlang.org/packages/dmd Nice, I was not aware that DMD as a library was so close to being a reality.
Re: DMD library available as DUB package
On 2017-07-18 14:35, Suliman wrote: Could you explain where it can be helpful? As Dukc said, for tools that need to analyze D source code. -- /Jacob Carlborg
Re: DMD library available as DUB package
On Tuesday, 18 July 2017 at 12:35:10 UTC, Suliman wrote: Could you explain where it can be helpful? For tools, such as source code formatters. They do not have to write the parsers themselves if they use a library such as this one.
Re: DMD library available as DUB package
Could you explain where it can be helpful?
DMD library available as DUB package
During the dconf hackathon I set out to create a DUB package for DMD to be used as a library. This has finally been merged [1] and is available here [2]. It contains the lexer and the parser. A minimal example: #!/usr/bin/env dub /++ dub.sdl: name "dmd_lexer_example" dependency "dmd" version="~master" +/ void main() { import ddmd.lexer; import ddmd.tokens; import std.stdio; immutable sourceCode = "void test() {} // foobar"; scope lexer = new Lexer("test", sourceCode.ptr, 0, sourceCode.length, 0, 0); while (lexer.nextToken != TOKeof) writeln(lexer.token.value); } [1] https://github.com/dlang/dmd/pull/6771 [2] http://code.dlang.org/packages/dmd -- /Jacob Carlborg
Re: DCompute: GPGPU with Native D for OpenCL and CUDA
On Tuesday, 18 July 2017 at 09:48:47 UTC, John Colvin wrote: On Tuesday, 18 July 2017 at 00:49:11 UTC, Nicholas Wilson wrote: Oh and @JohnColvin do you like the solution for the lambdas? I do, very nice :) You're essentially achieving what I set out to do and got stuck with, just much better. Thanks. There's still a way to go, we haven't conquered the world yet! I'll be trying to get a minimally useable base going soon before the start of semester and Laeeth climbs out from under his mound of paperwork. Once the base is done I think the direction will become more clear and contributes more easy to come by, and they can do the things I don't want to do like like queuing devices for info ;)
Re: static foreach is now in github master
On Tuesday, 18 July 2017 at 10:02:10 UTC, Seb wrote: And thanks to dmd-nightly, also on run.dlang.io: https://run.dlang.io/?compiler=dmd-nightly=void%20main(string%5B%5D%20args)%0A%7B%0A%20%20%20%20static%20foreach%20(i;%20%5B0,1,2,3%5D)%0A%09%7B%0A%20%20%20%20%09pragma(msg,%20i);%0A%09%7D%0A%7D This link doesn't work, looks like it cuts off at the first ; ...
Re: static foreach is now in github master
On Monday, 17 July 2017 at 21:27:40 UTC, Martin Nowak wrote: On Monday, 17 July 2017 at 18:14:35 UTC, Andrei Alexandrescu wrote: For those who want to play with our new static foreach feature and are willing to take the steps to building their own dmd, Or just wait for the next nightly until tomorrow around 5AM UTC. curl -fsS https://dlang.org/install.sh | bash -s dmd-nightly the feature is now merged in master: https://github.com/dlang/dmd/pull/6760 Great news. And thanks to dmd-nightly, also on run.dlang.io: https://run.dlang.io/?compiler=dmd-nightly=void%20main(string%5B%5D%20args)%0A%7B%0A%20%20%20%20static%20foreach%20(i;%20%5B0,1,2,3%5D)%0A%09%7B%0A%20%20%20%20%09pragma(msg,%20i);%0A%09%7D%0A%7D
Re: DCompute: GPGPU with Native D for OpenCL and CUDA
On Tuesday, 18 July 2017 at 00:49:11 UTC, Nicholas Wilson wrote: On Monday, 17 July 2017 at 13:50:22 UTC, Mike Parker wrote: Nicholas Wilson has put together a blog post on his progress with DCompute, expanding on his DConf talk. I have to admit that this is one of the D projects I'm most excited about, even though I'll probably never have a need to use it. I'd love to find an excuse to do so, though! Blog: https://dlang.org/blog/2017/07/17/dcompute-gpgpu-with-native-d-for-opencl-and-cuda/ Reddit: https://www.reddit.com/r/programming/comments/6nt4ba/dcompute_gpgpu_with_native_d_for_opencl_and_cuda/ Thanks for that. Oh and @JohnColvin do you like the solution for the lambdas? I do, very nice :) You're essentially achieving what I set out to do and got stuck with, just much better.
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 07:06:10 UTC, Jean-Louis Leroy wrote: As for performance, I have a first result: https://github.com/jll63/methods.d/blob/master/benchmarks/source/benchmarks.d#L122 but I still have to implement the "first argument optimization". I am working on it. Now this is funny, after implementing that optimization (https://github.com/jll63/methods.d/blob/94ad5a945b3c719bd8f8402bb0aa6fda8e7a6be0/source/openmethods.d#L388, https://github.com/jll63/methods.d/blob/94ad5a945b3c719bd8f8402bb0aa6fda8e7a6be0/benchmarks/source/benchmarks.d#L139) it runs faster with ldc2 but slower with dmd. I may be testing the limits of dmd's willingness to inline my mess ;-) J-L
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 04:26:42 UTC, Ali Çehreli wrote: On 07/16/2017 10:24 AM, Jean-Louis Leroy wrote: > TL;DR: see here https://github.com/jll63/methods.d/blob/master/README.md Woot! :) I'm so happy to see this project complete. Honestly, growing up with languages without this feature (C and C++), I've not even known that I needed this feature but your example (e.g. matrix multiplication) are very convincing. Thanks :) I added another example that shows how open methods are a superior alternative to Visitor: https://github.com/jll63/methods.d/blob/master/examples/novisitor/source/app.d If there are enough differences compared to your C++ articles, perhaps you may consider following this up with a blog post. It would be nice to see some performance results as well like you have on your C++ articles. Yes I will probably write something. You mean on the D Blog? As for performance, I have a first result: https://github.com/jll63/methods.d/blob/master/benchmarks/source/benchmarks.d#L122 but I still have to implement the "first argument optimization". I am working on it. J-L Ali
Re: New library: open multi-methods
On Tuesday, 18 July 2017 at 02:22:15 UTC, Jay Norwood wrote: An excerpt statement from this wiki page is : " dynamically dispatched based on the run-time (dynamic) type or, in the more general case some other attribute, of more than one of its arguments" Based on the 'some other attribute', I wonder if the library could conceivably be extended to dispatch based on the User Defined Attribute info https://dlang.org/spec/attribute.html @('c') string s; pragma(msg, __traits(getAttributes, s)); // prints tuple('c') For example, CLOS allows you to specialize on a value (google for "eql specialize"). IIRC Clojure allows you to specify your own dispatcher. As for specializing on D attributes, I don't think it's feasible. They are a purely compile-time mechanism. In your example, the type of "s" is "string", not "@('c') string". J-L
Re: static foreach is now in github master
On Tuesday, 18 July 2017 at 06:48:29 UTC, Jacob Carlborg wrote: On 2017-07-17 20:14, Andrei Alexandrescu wrote: For those who want to play with our new static foreach feature and are willing to take the steps to building their own dmd, the feature is now merged in master: https://github.com/dlang/dmd/pull/6760 Happy hacking! That was quick, and awesome :) Great work to Timon and everyone else involved. wow! Now, just how am I supposed to be able to work today (using C) and not play with this pure awesomeness?!
Re: DIP 1010--Static foreach--Accepted
On 2017-07-17 14:39, Steven Schveighoffer wrote: Awesome! Super glad and looking forward to this in 2.076? ;) It's already merged [1] so..., why not :) [1] http://forum.dlang.org/post/okiuqb$1eti$1...@digitalmars.com -- /Jacob Carlborg
Re: static foreach is now in github master
On 2017-07-17 20:14, Andrei Alexandrescu wrote: For those who want to play with our new static foreach feature and are willing to take the steps to building their own dmd, the feature is now merged in master: https://github.com/dlang/dmd/pull/6760 Happy hacking! That was quick, and awesome :) Great work to Timon and everyone else involved. -- /Jacob Carlborg