digitalmars.D - The worst overload system that actualy works
- Basile B. (5/5) Dec 21 2020 Overloads can be confusing because of implict conversions and
- Timon Gehr (11/16) Dec 21 2020 Proposing this for D would not do much. This is already in D:
- Basile B. (2/18) Dec 21 2020 yeah but I think the way the overloads are tried is different.
- Timon Gehr (3/13) Dec 21 2020 So what you don't mean to propose for D is to try overloads in order,
- sighoya (10/15) Dec 21 2020 But they need anyway overload resolution for this.
- Basile B. (4/20) Dec 21 2020 Yes but it's simple. If Indentifier resolution gives an overload
- Petar Kirov [ZombineDev] (52/57) Dec 22 2020 I know that semantics was perhaps the main point of your post,
- Basile B. (24/83) Dec 22 2020 To make it less verbose it should be possible to use an
Overloads can be confusing because of implict conversions and promotion rules. So here are the explicit overloads[1]. Note that there is no plan to propose this for D ;)... destroy. [1] https://styx-lang.gitlab.io/styx/overload_declaration.html
Dec 21 2020
On 21.12.20 14:35, Basile B. wrote:Overloads can be confusing because of implict conversions and promotion rules. So here are the explicit overloads[1]. Note that there is no plan to propose this for D ;)... destroy. ...Proposing this for D would not do much. This is already in D: void createFromBytes(ubyte[] values) {} void createFromFile(string name) {} alias create = createFromBytes; alias create = createFromFile; void main(){ const string name = "test.txt"; create(name); // calls createFromFile } :P
Dec 21 2020
On Monday, 21 December 2020 at 16:48:27 UTC, Timon Gehr wrote:On 21.12.20 14:35, Basile B. wrote:yeah but I think the way the overloads are tried is different.Overloads can be confusing because of implict conversions and promotion rules. So here are the explicit overloads[1]. Note that there is no plan to propose this for D ;)... destroy. ...Proposing this for D would not do much. This is already in D: void createFromBytes(ubyte[] values) {} void createFromFile(string name) {} alias create = createFromBytes; alias create = createFromFile; void main(){ const string name = "test.txt"; create(name); // calls createFromFile } :P
Dec 21 2020
On 21.12.20 17:59, Basile B. wrote:On Monday, 21 December 2020 at 16:48:27 UTC, Timon Gehr wrote:So what you don't mean to propose for D is to try overloads in order, ignoring implicit conversions. Makes sense.On 21.12.20 14:35, Basile B. wrote:yeah but I think the way the overloads are tried is different.Overloads can be confusing because of implict conversions and promotion rules. So here are the explicit overloads[1]. Note that there is no plan to propose this for D ;)... destroy. ......
Dec 21 2020
On Monday, 21 December 2020 at 13:35:10 UTC, Basile B. wrote:Overloads can be confusing because of implict conversions and promotion rules. So here are the explicit overloads[1]. Note that there is no plan to propose this for D ;)... destroy. [1] https://styx-lang.gitlab.io/styx/overload_declaration.htmlBut they need anyway overload resolution for this. The advantage is that method could be assigned to more than one overloaded set (multi method). The disadvantage is the manual disambiguation of method names by defining their types. That sucks and they can't always be demangled in meaningful way than simply enumerating their param types. I find explicit implicit converions in D useful, but I didn't appreciate how overload resolution handles this that much.
Dec 21 2020
On Monday, 21 December 2020 at 19:36:22 UTC, sighoya wrote:On Monday, 21 December 2020 at 13:35:10 UTC, Basile B. wrote:Yes but it's simple. If Indentifier resolution gives an overload set then the set members are tried, e.g O(n). https://gitlab.com/styx-lang/styx/-/blob/master/src/styx/semantic/expressions.d#L395Overloads can be confusing because of implict conversions and promotion rules. So here are the explicit overloads[1]. Note that there is no plan to propose this for D ;)... destroy. [1] https://styx-lang.gitlab.io/styx/overload_declaration.htmlBut they need anyway overload resolution for this.The advantage is that method could be assigned to more than one overloaded set (multi method). The disadvantage is the manual disambiguation of method names by defining their types. That sucks and they can't always be demangled in meaningful way than simply enumerating their param types. I find explicit implicit converions in D useful, but I didn't appreciate how overload resolution handles this that much.
Dec 21 2020
On Monday, 21 December 2020 at 13:35:10 UTC, Basile B. wrote:Overloads can be confusing because of implict conversions and promotion rules. So here are the explicit overloads[1]. Note that there is no plan to propose this for D ;)... destroy. [1] https://styx-lang.gitlab.io/styx/overload_declaration.htmlI know that semantics was perhaps the main point of your post, but I must say that I have never thought that overloading can have an explicit syntax and I like it a lot :) Even from a developer maintenance, and likely compiler implementation point of view, I think it's a good property to only allow overloading with an explicit syntax, as that way you can assume that all symbol declarations names in a module/namespace are unique, as overloading can't happen by accident. And using "Go to definition" in an IDE will always point you to right location. And just in general it's less error prone and on the good side of explicit vs verbose ;) The last few months we mainly use TypeScript at work, and I'm really fond of their type aliases syntax (like D aliases, but more powerful): https://www.carlrippon.com/when-to-use-type-aliases-v-interfaces/ https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases So, if it was me, I'd I use an assignment syntax like this: alias create = overload( createFromBytes, createFromFile, ); Where `overload` is a symbol constructor (just like `*`, `[]` `const`, `shared` are type constructors in D). Hmm, re-reading the example, I think we can even implement it in pure D: alias create = overload!( createFromBytes, createFromFile, ); template overload(symbols...) { static foreach (sym; symbols) alias overload = sym; } Of course, we still leave the actual overload resolution to the compiler, but if necessary, we can easily implement it like this: template overload(functions...) { auto ref overload(Args...)(auto ref Args args) { static foreach (fun; functions) {{ static if (__traits(compiles, () => fun(args))) return fun(args); }} } } (^ Not tested, so there may be bugs, but it should be enough to show the idea). So dare I say, we can deprecate implicit overloading in D with a workable migration path to something like this :O
Dec 22 2020
On Tuesday, 22 December 2020 at 21:14:07 UTC, Petar Kirov [ZombineDev] wrote:On Monday, 21 December 2020 at 13:35:10 UTC, Basile B. wrote:To make it less verbose it should be possible to use an attribute, e.g overload("create") createFromStuff(); Although then there's a loose of control on the manual ordering.Overloads can be confusing because of implict conversions and promotion rules. So here are the explicit overloads[1]. Note that there is no plan to propose this for D ;)... destroy. [1] https://styx-lang.gitlab.io/styx/overload_declaration.htmlI know that semantics was perhaps the main point of your post, but I must say that I have never thought that overloading can have an explicit syntax and I like it a lot :) Even from a developer maintenance, and likely compiler implementation point of view, I think it's a good property to only allow overloading with an explicit syntax, as that way you can assume that all symbol declarations names in a module/namespace are unique, as overloading can't happen by accident. And using "Go to definition" in an IDE will always point you to right location. And just in general it's less error prone and on the good side of explicit vs verbose ;)The last few months we mainly use TypeScript at work, and I'm really fond of their type aliases syntax (like D aliases, but more powerful): https://www.carlrippon.com/when-to-use-type-aliases-v-interfaces/ https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases So, if it was me, I'd I use an assignment syntax like this: alias create = overload( createFromBytes, createFromFile, ); Where `overload` is a symbol constructor (just like `*`, `[]` `const`, `shared` are type constructors in D). Hmm, re-reading the example, I think we can even implement it in pure D: alias create = overload!( createFromBytes, createFromFile, ); template overload(symbols...) { static foreach (sym; symbols) alias overload = sym; } Of course, we still leave the actual overload resolution to the compiler, but if necessary, we can easily implement it like this: template overload(functions...) { auto ref overload(Args...)(auto ref Args args) { static foreach (fun; functions) {{ static if (__traits(compiles, () => fun(args))) return fun(args); }} } } (^ Not tested, so there may be bugs, but it should be enough to show the idea).Nice. Fixed: --- struct overload(functions...) { static auto opCall(Args...)(auto ref Args args) { static foreach (fun; functions) {{ static if (__traits(compiles, () => fun(args))) return fun(args); }} } } alias MySet = overload!()... --- only problem is that it does not support member func (+ the infamous not reachable thing) but well, I get that this was more a joke.So dare I say, we can deprecate implicit overloading in D with a workable migration path to something like this :O
Dec 22 2020