implicit construction operator

WebFreak001 d.forum at webfreak.org
Mon Feb 26 19:25:06 UTC 2018


hi, I had an idea from using some C# which I think would be 
really cool in D. Basically allow modifying implicit construction 
of a type. Right now we only have struct opAssign/constructor 
implicit conversion, but this addition would also add it to 
classes and make it even more convenient.

Changes in code (example Nullable):

---
struct Nullable(T) {
     this(typeof(null)) @implicit {} // <-- @implicit is new
}

void foo(Nullable!int a, Nullable!int b) {}
---

Now before you would have only been able to do this:

---
Nullable!Foo a;
foo(a, Nullable!int(5));
---

but now you should also be able to do:

---
Nullable!Foo x = null;
Nullable!Foo y = 5;

foo(null, 5);

// while this would be nice, I am not sure how well this is 
possible right now:
Nullable!int[] foo = [1, 2, 3, null, 5];
---
The array syntax might not be possible if it looks at consistency 
inside the array before attempting to cast it, but for function 
arguments and quicker

This is especially making this case less of a pain to deal with:
---
void sendMessage(string content, Nullable!Snowflake nonce = 
Nullable!Snowflake.init, Nullable!Embed embed = 
Nullable!Embed.init);
Nullable!Embed embed = Embed.init;
sendMessage("a", Nullable!Snowflake.init, embed)

// ->

void sendMessage(string content, Nullable!Snowflake nonce = null, 
Nullable!Embed embed = null);
sendMessage("a", null, Embed.init);
---

Now this would be really useful for Variant:

---
struct Variant {
     this(U)(U value) @implicit { ... }
}

void bar(Variant x, Variant y) {}

Variant[] myObjects = [1, 2, "abc", new Node()];
Variant a = 4;
bar(4, "asdf");
---

Just a few examples where it could be used in phobos, especially 
when passing them function arguments: Variant, JSONValue, 
eventual XML node, Nullable, BigInt, Unique, scoped, NullableRef, 
Rebindable, AsciiString, Latin1String, etc and many more. Plus 
also many libraries will be able to make use of this like vibe.d 
Json, Bson or msgpack or dyaml etc etc etc. Additionally this 
will make many duplicate functions which are just there for 
emulating this behaviour disappear, std.regex could accept just 
regex as argument and strings will be implicitly cast to it, 
reducing template/overload usage and possibly also making it 
faster to import.

What's your opinion on this? I think it is really useful to have 
when interoping with scripting languages or doing 
(de)serialization or for these attribute wrappers which are there 
because of no function attribute UDAs. I was looking into 
implementing this to dmd myself but the code on the implicit cast 
checks looks a bit hardcoded for the types that are in right now 
and not really suitable to implement this, but maybe someone with 
more knowledge about dmd internals can do this with ease.

This is only a single direction T -> Wrapper and I think this 
would actually be enough, but it would maybe be possible to add 
@implicit to opCast in the future.


More information about the Digitalmars-d mailing list