New programming paradigm
Paul Backus
snarwin at gmail.com
Sun Jun 3 15:48:41 UTC 2018
On Monday, 4 September 2017 at 03:26:23 UTC, EntangledQuanta
wrote:
> Take a variant type. It contains the "type" and the data. To
> simplify, we will treat look at it like
>
> (pseudo-code, use your brain)
>
> enum Type { int, float }
>
> foo(void* Data, Type type);
>
> The normal way to deal with this is a switch:
>
> switch(type)
> {
> case int: auto val = *(cast(int*)Data);
> case float: auto val = *(cast(float*)Data);
> }
>
>
> But what if the switch could be generated for us?
>
> [...]
>
> But, in fact, since we can specialize on the type we don't have
> to use switch and in some cases do not even need to specialize:
>
> for example:
>
> foo(T)(T* Data) { writeln(*Data); }
>
> is a compile time template that is called with the correct type
> value at run-time due to the "magic" which I have yet to
> introduce.
>
> Note that if we just use a standard runtime variant, writeln
> would see a variant, not the correct type that Data really is.
> This is the key difference and what makes this "technique"
> valuable. We can treat our dynamic variables as compile time
> types(use the compile time system) without much hassle. They
> fit naturally in it and we do not clutter our code switches. We
> can have a true auto/var like C# without the overhead of the
> IR. The cost, of course, is that switches are still used, they
> are generated behind the scenes though and the runtime cost is
> a few instructions that all switches have and that we cannot
> avoid.
>
> To get a feel for what this new way of dealing with dynamic
> types might look like:
>
> void foo(var y) { writeln(y); }
>
> var x = "3"; // or possibly var!(string, int) for the explicit
> types used
> foo(x);
> x = 3;
> foo(x);
It sounds like what you are describing is a sum type. There is an
implementation of one in the standard library,
std.variant.Algebraic, as well as several alternative
implementations on code.dlang.org, including my own, "sumtype"
[1].
Using sumtype, your example would look like this:
alias Var = SumType!(string, int);
void foo(Var y) {
var.match!(
(value) { writeln(value); } // template lambda
);
}
Var x = "3";
foo(x);
x = 3;
foo(x);
The match method takes a list of functions as template arguments,
and generates a switch statement that maps each possible type of
Var to one of those functions. All type checking is done at
compile time.
[1] https://code.dlang.org/packages/sumtype
More information about the Digitalmars-d-learn
mailing list