The worst overload system that actualy works

Basile B. b2.temp at gmx.com
Wed Dec 23 02:12:35 UTC 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:
>> 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


More information about the Digitalmars-d mailing list