October 01, 2020
On Wednesday, 30 September 2020 at 23:17:27 UTC, Timon Gehr wrote:
> On 29.09.20 01:37, Stefan Koch wrote:
>> On Monday, 28 September 2020 at 21:27:56 UTC, Timon Gehr wrote:
>>> On 28.09.20 23:08, claptrap wrote:
>>>> Instead of first class types
>>>
>>> (Stefan's type functions do not give you first-class types. A first-class type you could put in a runtime variable.)
>> 
>> That's true. At least as it stands right now.
>> I _could_ give  the alias a physical form at runtime.
>> (By doing the same thing that the reify template does (or rather will eventually do), that is exporting _all_ the properties of the type into an object)
>> 
>> However I am not actually sure what the use of this would be.
>> All usage that I have seen, is in generating code, which is kindof useless if it does not happen at compile time.
>> 
>> Perhaps there are others?
>
> It's not a first-class type if you can't declare a variable of that type. If this does not work, it's not first-class, it's syntax sugar for reification:
>
> type t = int;
> auto f = (t x)=>x;

Yes I do understand that.
I was wondering about practical usecases.
As far as I an aware, if I made the leap to first class types, that would make all usage of them into static polymorphism. (equivalent to templates)
And with that all the issues come back.
September 30, 2020
On 9/28/2020 3:46 PM, Bruce Carneal wrote:
> Finally, I'd love to hear your comments on type functions vs reify/dereify.  It's certainly possible that I've missed something.  Maybe it's a type functions+ solution we should be seeking (type functions for everything they can do, and some LDM for anything beyond their capability).

Andrei and I have been mulling over what to do for a while, and have gone through several ideas.

What we're looking for is not a top level solution. We want a fundamental building block, upon which the rest of D's features can exploit naturally and productively. Something that can be explained in 30 seconds.

An example of this is the recent PR for __totype(string), which is the complement to .mangleof. It's main shortcoming is it only works with types. I'm currently working on an idea to make that work for any alias. It's so stupidly simple I'm afraid I'm missing something terribly obvious, so I beg your indulgence while exploring it.

Stay tuned!

September 30, 2020
On 9/29/2020 12:30 PM, Steven Schveighoffer wrote:
> I think there's some disconnect here -- AAs as a language feature are a resounding success. They way they are implemented in the language is not. I wouldn't call it a failure, but it definitely is not as useful as a fully supported library type could be.

Yes, that is a better statement of my opinion on it.

The implementation's problems are, of course, because D's AAs were designed before there were templates and before there was const and immutable.

October 01, 2020
On Thursday, 1 October 2020 at 01:49:02 UTC, Andrei Alexandrescu wrote:
> On 9/30/20 7:36 PM, H. S. Teoh wrote:
>> I think there's a lot of value to be had in making typeid(T) as the
>> reification of T.  At compile-time, we treat it specially by augmenting
>> it with the ability to do things that can only be done at compile-time,
>> such as recover T given typeid(T) (pass it into a template parameter,
>> construct new types out of it, etc.). At runtime, it reverts to the
>> current behaviour of typeid(T).
>> 
>> Only trouble is, according to Andrei, typeid has been written over so
>> many times that even Walter doesn't understand how it works anymore.
>> Meaning there are probably weird corner cases and quirky behaviours that
>> we may not want to duplicate at compile-time. So I dunno, this seems
>> like a roadblock to further progress.
>
> Yah, that would be my favorite by far. It's a one-liner change in the definition of the language. "Since version x.xx, the result of typeid() is usable during compilation." It's also the best /kind/ of change to the language, i.e. lifts a gratuitous restriction that prevents composition of distinct features (here, ctfe and typeid).
>
> A promising path according to Walter is to develop a parallel enhanced feature - newtypeid! :o) - and then deprecate typeid.

Glad to see that you're open to changing the language in order to achieve better power/complexity ratio.  Right there with you on that sentiment!

Two questions:

1) How many additional additions do you estimate you'll need for this? and

2) How do the type function addition(s) compare?  Are they also of the "best kind of change" variety?




October 01, 2020
On Thursday, 1 October 2020 at 04:08:26 UTC, Walter Bright wrote:
> On 9/28/2020 3:46 PM, Bruce Carneal wrote:
>> [...]
>
> Andrei and I have been mulling over what to do for a while, and have gone through several ideas.
>
> What we're looking for is not a top level solution. We want a fundamental building block, upon which the rest of D's features can exploit naturally and productively. Something that can be explained in 30 seconds.
>
> An example of this is the recent PR for __totype(string), which is the complement to .mangleof. It's main shortcoming is it only works with types. I'm currently working on an idea to make that work for any alias. It's so stupidly simple I'm afraid I'm missing something terribly obvious, so I beg your indulgence while exploring it.
>
> Stay tuned!

Sounds exciting!  Good luck!
October 01, 2020
On Wednesday, 30 September 2020 at 23:17:27 UTC, Timon Gehr wrote:
> On 29.09.20 01:37, Stefan Koch wrote:
>> ...
>
> It's not a first-class type if you can't declare a variable of that type. If this does not work, it's not first-class, it's syntax sugar for reification:
>
> type t = int;
> auto f = (t x)=>x;

Can anything computable using just the source as input be considered a first class type?

If so, what do we call type variables that can not be?







October 01, 2020
On Thursday, 1 October 2020 at 04:08:26 UTC, Walter Bright wrote:
> On 9/28/2020 3:46 PM, Bruce Carneal wrote:
>> Finally, I'd love to hear your comments on type functions vs reify/dereify.  It's certainly possible that I've missed something.  Maybe it's a type functions+ solution we should be seeking (type functions for everything they can do, and some LDM for anything beyond their capability).
>
> Andrei and I have been mulling over what to do for a while, and have gone through several ideas.
>
> What we're looking for is not a top level solution. We want a fundamental building block, upon which the rest of D's features can exploit naturally and productively. Something that can be explained in 30 seconds.

Type functions take less than 30 seconds.
They take zero seconds.

Do you remember Andrei's non working example?

> alias MostDerived(Args...) = dereify!({
>     auto ids = reify!Args;
>     sort!((a, b) => is(dereify!a : dereify!b))(ids);
>     return ids;
> }());

Here is the correct type function which actually works!

alias[] MostDerived(alias[] types ...)
{
    sort!((alias a, alias b) => is(a : b))(types);
    return types;
}

It is Andrei thought would work.
With type functions it just works.
October 01, 2020
On 01.10.20 04:49, Stefan Koch wrote:
> On Wednesday, 30 September 2020 at 23:17:27 UTC, Timon Gehr wrote:
>> On 29.09.20 01:37, Stefan Koch wrote:
>>> On Monday, 28 September 2020 at 21:27:56 UTC, Timon Gehr wrote:
>>>> On 28.09.20 23:08, claptrap wrote:
>>>>> Instead of first class types
>>>>
>>>> (Stefan's type functions do not give you first-class types. A first-class type you could put in a runtime variable.)
>>>
>>> That's true. At least as it stands right now.
>>> I _could_ give  the alias a physical form at runtime.
>>> (By doing the same thing that the reify template does (or rather will eventually do), that is exporting _all_ the properties of the type into an object)
>>>
>>> However I am not actually sure what the use of this would be.
>>> All usage that I have seen, is in generating code, which is kindof useless if it does not happen at compile time.
>>>
>>> Perhaps there are others?
>>
>> It's not a first-class type if you can't declare a variable of that type. If this does not work, it's not first-class, it's syntax sugar for reification:
>>
>> type t = int;
>> auto f = (t x)=>x;
> 
> Yes I do understand that.
> I was wondering about practical usecases.
> As far as I an aware, if I made the leap to first class types, that would make all usage of them into static polymorphism. (equivalent to templates)
> And with that all the issues come back.

Well, no, the restriction to compile-time-known values makes types not first-class. E.g., this is something you could do with first-class types but not with templates: (type T)=>(T x)=>x;

(In terms of compiler implementation, the runtime representation of `T` would contain all information that is necessary to figure out calling conventions of functions that take a T, it would contain sizeof, pointers to destructor/postblit, etc, so basically it's typeid.)

Templates are an untyped macro language on top of a simple type system without any form of polymorphism. Types are first-class values only inside that macro language, but the macro language is evaluated only at compile time. I.e., templates are a tool for code generation that is integrated with the type system, but they are not really a part of the type system.
October 01, 2020
On 01.10.20 07:37, Bruce Carneal wrote:
> On Wednesday, 30 September 2020 at 23:17:27 UTC, Timon Gehr wrote:
>> On 29.09.20 01:37, Stefan Koch wrote:
>>> ...
>>
>> It's not a first-class type if you can't declare a variable of that type. If this does not work, it's not first-class, it's syntax sugar for reification:
>>
>> type t = int;
>> auto f = (t x)=>x;
> 
> Can anything computable using just the source as input be considered a first class type?
> 
> If so, what do we call type variables that can not be?
> 

Unfortunately I am not sure understand the question. What is an example of a "type variable that cannot be computed using just the source"? (Which source?)

Maybe this is related to what you mean?

type t = readln().strip()=="int"?int:double;
auto f = (t x)=>x;
October 01, 2020
On 10/1/2020 12:48 AM, Timon Gehr wrote:
> (In terms of compiler implementation, the runtime representation of `T` would contain all information that is necessary to figure out calling conventions of functions that take a T, it would contain sizeof, pointers to destructor/postblit, etc, so basically it's typeid.)

I had looked into this. Unfortunately, many aspects of types are simply too complex to try and represent at run time. For example, is type T1 implicitly convertible to T2? This seemingly simple question is very complex. Yes, `alias this` makes it much worse :-/

I initially had high hopes for typeid back when it was originally designed 20 years ago. It ably fulfills its original purpose of enabling the GC and associative arrays in a language with no templates.

I don't see much future for it other than being kept around for legacy compatibility.