Types: The Next Generation (Was: Why is phobos so wack?)

Jacob Carlborg via Digitalmars-d digitalmars-d at puremagic.com
Mon Jul 10 04:32:20 PDT 2017


On 2017-07-10 07:54, Nick Sabalausky (Abscissa) wrote:
>   On 07/09/2017 09:21 PM, Nick Sabalausky wrote:
>  >
>  > Ah, I guess it is very similar after all, except it'd be based on top of
>  > and coexist with all of D's design by introspection stuff (rather than
>  > exist without it as with C++), thus avoiding a lot of the downsides and
>  > getting best of both worlds.
> 
> Ha ha, I still feel more than a little silly for pitching what amounts 
> to contracts as "an out-there idea I've been mulling over", but indulge 
> in a little (partially-baked) taste to show this at least has some merit 
> anyway. Hell, call it "concepts++" or "concepts, the D way" (note: I'm 
> NOT pitching this as a suggestion for something D should do. Not saying 
> D should or should'nt, just speaking purely in the realm of "langauge 
> design brainstorming" here...Just because it's been on my mind and the 
> "Why is phobos so wack?" thread brought some relevence)
> 
> Behold! The power of combining constraints/design-by-introspection 
> *with* concepts:
> 
> Current declaration of std.array.join:
> 
> ---------------------------------------------------
> ElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, scope R sep)
> if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)) && 
> isInputRange!R && is(Unqual!(ElementType!(ElementType!RoR)) == 
> Unqual!(ElementType!R)));
> 
> ElementEncodingType!(ElementType!RoR)[] join(RoR, E)(RoR ror, scope E sep)
> if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)) && is(E 
> : ElementType!(ElementType!RoR)));
> 
> ElementEncodingType!(ElementType!RoR)[] join(RoR)(RoR ror)
> if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)));
> ---------------------------------------------------
> 
> (ie, completely incomprehensible at-a-glance)
> 
> Just one possibility of an entirely hypothetical D++ (assuming I'm even 
> interpreting the D version correctly):
> 
> ---------------------------------------------------
> // Note: This assumes the "ElementEncodingType vs ElementType" distinction
> // is nothing but a colossal mistake caused purely by the existance of
> // auto-decoding, which was (as an assumption this psuedo-code is 
> predicated
> // upon) a complete clusterf*** of misdesign (Ie, *such* a huge stretch of
> // the imagination ;)), which in this hypothetical ideal langauge has
> // been killed dead with nuclear fire, and then beaten some more with
> // spiked crowbars, just to be sure.
> 
> /++
>    Params:
>      ror: an input range (or better) of input ranges (or better) of
>           any type (shorthand for 'InputRange!InputRange!Type')
>      sep: a separator that can be any input range ('InputRange!Type').
>    Returns: Shorthand for 'InputRange!Type': Ie, an input range (or 
> better).
>    Note: This is implicitly templated on typeof(ror) and typeof(sep).
> +/
> InputRange join(InputRange!InputRange ror, InputRange sep)
>    // Relationship constraints:
>    if(UnqualTypeMatch!(ror, sep, return))
> 
> /++
>    Like above, but sep is 'Type' instead of 'InputRange!Type'.
>    Since 'Type' is less specific than 'InputRange!Type', the prior overload
>    is preferred.
> +/
> InputRange join(InputRange!InputRange ror, Type sep)
>    // Relationship constraints:
>    if(unqualTypeMatch!(ror, InputRange!sep, return))
> 
> // No separator
> InputRange join(InputRange!InputRange ror)
>    // Relationship constraints:
>    if(unqualTypeMatch!(ror, return))
> 
> // Extra-special specialization:
> // Why multiple if() allowed? Because it makes the formatting less
> // of a mess, thus better readability. Good enough reason to me!
> InputRange join(InputRange!InputRange ror, Type sep)
>    if(unqualTypeMatch!(ror, sep, return))
>    if(hasLength!typeof(sep))
>    {  /+...take advantage of sep.length...+/ }
> 
> // Note: Those constraints have further room for syntactical improvement.
> ---------------------------------------------------
> 
> That example involves some additional things defined by the
> stdlib (*extremely* hypothetical syntax):
> 
> ---------------------------------------------------
> concept InputRange(Element)
> {
>      this()
>      {
>          // Current body of isInputRange here
>      }
> 
>      // Most of isInputRange can *optionally* be replaced with:
>      Element front();
>      void popFront();
>      bool empty();
> }
> 
> concept ForwardRange : InputRange // Builds upon InputRange
> {
>      // Author can opt to do this (more powerful):
>      this()
>      {
>          super.this();
>          typeof(this) x = this.save;
>      }
> 
>      // Or this (more succinct):
>      ForwardRange save();
> }
> 
> // *Anything*: A concrete (instatiable) type, or a templated
> // stand-in for a type (ie "T"), or an alias, or nothing at all.
> // Types *themselves* are first-class types! But implemented as
> // templates, rather than as runtime-OO.
> algebraic Any : Bottom;
> 
> // An actual concrete type
> algrbraic Type : Any
>      if(isType!this);
> 
> // An actual concrete type?
> bool isType(Any any) {/+...introspection magic lies here...+/}
> 
> // This is implicitly a template.
> bool unqualTypeMatch(InputRange!Any args...)
> {
>      return args.map!(GetType).map!(Unqual).equal;
> }
> 
> // If any is a static type, return any.
> // If any is a value, return typeof(any)
> // This is implicitly a template.
> Type GetType(Any any)
> {
>      static if(typeof(any) == Type)
>          return any;
>      else
>          return typeof(any);
> }
> ---------------------------------------------------
> 
> Now, something like THAT is the language *I* would love to see.
> 
> Obviously leaves a TON of details TBD, but one can dream ;)

Something like this has been proposed several times before, but Andrei 
doesn't seem to like it. He think it's a failure that all the conditions 
need to have a name, or something like that. I prefer your approach.

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list