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