www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - The worst overload system that actualy works

reply Basile B. <b2.temp gmx.com> writes:
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
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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
parent reply Basile B. <b2.temp gmx.com> writes:
On Monday, 21 December 2020 at 16:48:27 UTC, Timon Gehr wrote:
 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
yeah but I think the way the overloads are tried is different.
Dec 21 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 21.12.20 17:59, Basile B. wrote:
 On Monday, 21 December 2020 at 16:48:27 UTC, Timon Gehr wrote:
 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.
 ...
...
yeah but I think the way the overloads are tried is different.
So what you don't mean to propose for D is to try overloads in order, ignoring implicit conversions. Makes sense.
Dec 21 2020
prev sibling next sibling parent reply sighoya <sighoya gmail.com> writes:
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.html
But 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
parent Basile B. <b2.temp gmx.com> writes:
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:
 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
But they need anyway overload resolution for this.
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#L395
 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
prev sibling parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
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.html
I 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
parent Basile B. <b2.temp gmx.com> writes:
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:
 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
I 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 ;)
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.
 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