January 02, 2021
On Saturday, 2 January 2021 at 08:31:26 UTC, Jacob Carlborg wrote:
> On 2021-01-02 00:26, Stefan Koch wrote:
>
>> Specification wise type functions require two statements to be added.
>> 
>> "Under certain conditions a type may be implicitly converted to a value of type __type__."
>> and
>> "Under certain conditions a value of type __type__ may be converted to a type."
>
> "certain conditions" is not suitable for a specification. You need to specify all conditions, all details.
>
>> That's it.
>
> You need to specify what __type__ is as well. A keyword? A special symbol like __FILE__?

Condition for type -> type value :
  you need to use a type in a place where a type value is needed.

Conditions for type value -> type :
  - you need to use a type value in place where a type is needed AND
  - the type value needs to be a constant expression.

correct __type__ is a basic type just like int, and therefore a keyword.
the reason for the four underscores it that __type is already used in the glibc binding.
January 02, 2021
On Saturday, 2 January 2021 at 08:47:07 UTC, Jacob Carlborg wrote:
> On 2021-01-02 01:05, Stefan Koch wrote:
>
>> Also I am not sure how I want the api to look like.
>> 
>> Perhaps like this?
>> struct StructField
>> {
>>      __type__ type;
>>      string name
>> }
>> __type__ makeStruct (string name, StructField[] fields)
>> {
>>      __struct__ sresult = __interal__magic__makeStruct(name);
>>      foreach(f;fields) { sresult.addField(f.name, f.type); }
>>      return __internal__magic__registerType(sresult);
>> }
>
> I'm not sure if it needs to have an API. Just look at how Zig does it.
>
> __type__ LinkedList(__type__ ElementType)
> {
>     return struct {
>         static struct Node
>         {
>             ElementType element;
>             Node* next;
>             Node* prev;
>         }
>
>         Node* first;
>         Node* last;
>     }
> }
>
> LinkedList(int) list;

The issue here is knowing when the type is complete.
Imagine you did not put int into there, but some template or another typefunction result.
At which point can I take the lock and register myself in the type universe?
And how do I make sure I don't have to type LinkedList(f(x, g(y), j(z))) to reference the type?

I guess I could create the name to just be "LinkedList(f(x, g(y), j(z)))" where f(x, g(y), j(z))) is eagerly evaluated, and then the name is LinkedList(float) or something like that.

But that seems like reinventing templates with all their troubles...
perhaps it's still worthwhile though?

it's certainly better than a string mixin.

> If you want to pass in the field names, I guess you'll have to resort to string mixins. Sure, there could be better alternatives than string mixins, but I think that's a separate issue.
>
>> See the sketch of a possible API above.
>> 
>> And feel free to suggest your own!
>
> Here I've experimented in exposing the compiler AST [1].
>
> [1] https://github.com/jacob-carlborg/druntime/blob/517dafcf54ad73049fb35d1ed5fa2ad6619b9ac4/src/core/ast/expression.d

Hmm I wanted to avoid having to puzzle ast nodes together, as I find it rather counter verbose to use.
simple stuff like;
mixin(f(a, b));
becomes
new CallExp(findFunction("f"), [findVariableExpression("a"), findVariableExpression("b")].insertIntoTreeInPlace();

January 02, 2021
On Friday, 1 January 2021 at 23:26:58 UTC, Stefan Koch wrote:
> Good Evening and Happy new year to everyone.
>
> After a stressful move to the UK in uncertain times, I am now free and able to enjoy the last day of my holiday.

Welcome to the UK. Some small advice for the newcomer ;)

If someone says "how are you" or "alright", it's a greeting, they dont actually want to know if you are alright. They would be happy with a concise "Im OK", or "Not bad" in response but they dont generally want more than one sentence.

An awkward silence after the initial greeting is perfectly acceptable.

Almost everything is "Not bad" in the UK, it's not good enough to be excited about anything, but not bad enough to be miserable. The range of life events that fit within the definition of "Not bad" is quite large, family members dying, losing a leg, wining the lottery etc.. are all "Not bad".

The weather. Be sure to have an opinion about the weather, it is the most important thing to talk about. Even if you have just seen the person 10 minutes earlier the weather changes so often that you can mention it again.

Recently it has become fashionable to say something about the lack of snow in the winter compared with when you were a child, or that it's like summer all year round because of global warming. (British summers are mostly indistinguishable from a mild winter)

If in doubt assume British people are being mildly sarcastic whenever they speak.

"Spotted dick" is a pudding made with suet and dried fruit.


January 02, 2021
On Saturday, 2 January 2021 at 11:59:39 UTC, claptrap wrote:
> On Friday, 1 January 2021 at 23:26:58 UTC, Stefan Koch wrote:
>> [...]
>
> Welcome to the UK. Some small advice for the newcomer ;)
>
> If someone says "how are you" or "alright", it's a greeting, they dont actually want to know if you are alright. They would be happy with a concise "Im OK", or "Not bad" in response but they dont generally want more than one sentence.
>
> [...]

Hmm that wasn't exactly the response I was expecting.
But thanks for the advise anyways!

Luckily my social contacts are minimal :)
January 02, 2021
On Saturday, 2 January 2021 at 09:13:42 UTC, Stefan Koch wrote:
> Condition for type -> type value :
>   you need to use a type in a place where a type value is needed.
>
> Conditions for type value -> type :
>   - you need to use a type value in place where a type is needed AND
>   - the type value needs to be a constant expression.
>
> correct __type__ is a basic type just like int, and therefore a keyword.
> the reason for the four underscores it that __type is already used in the glibc binding.

At first, thanks for working on first class types.

Second, why we need at all __type__ and can't just reuse TypeInfo?

TypeInfo already gives us the opportunity to compare types for equality and some other ops.

We have `typeid(SecondClassType)` turning a second class type into a first class type, i.e. a value we can do operations on it.

We just need the counterpart `asType(FirstClassType)` turning a TypeInfo into an second class type back, this must be done at compile time.

And we need to support to call typeid at compile time.

Maybe I'm wrong, just want to hear your opinion about it.

I appreciate the use of first class types as they allow replacing the ugly nuts of alias seqs and recursion. I think executing a normal function mapping types to types could be faster than macro expansion, though I don't know that exactly.
January 02, 2021
On Friday, 1 January 2021 at 23:26:58 UTC, Stefan Koch wrote:
> [snip]
> I do hope you get as excited as me when reading this.
>
> Regards,
> Stefan

Looks interesting.
January 02, 2021
On Saturday, 2 January 2021 at 14:34:39 UTC, sighoya wrote:
> On Saturday, 2 January 2021 at 09:13:42 UTC, Stefan Koch wrote:
>> Condition for type -> type value :
>>   you need to use a type in a place where a type value is needed.
>>
>> Conditions for type value -> type :
>>   - you need to use a type value in place where a type is needed AND
>>   - the type value needs to be a constant expression.
>>
>> correct __type__ is a basic type just like int, and therefore a keyword.
>> the reason for the four underscores it that __type is already used in the glibc binding.
>
> At first, thanks for working on first class types.
>
> Second, why we need at all __type__ and can't just reuse TypeInfo?
>
> TypeInfo already gives us the opportunity to compare types for equality and some other ops.
>
> We have `typeid(SecondClassType)` turning a second class type into a first class type, i.e. a value we can do operations on it.
>
> We just need the counterpart `asType(FirstClassType)` turning a TypeInfo into an second class type back, this must be done at compile time.
>
> And we need to support to call typeid at compile time.
>
> Maybe I'm wrong, just want to hear your opinion about it.
>
> I appreciate the use of first class types as they allow replacing the ugly nuts of alias seqs and recursion. I think executing a normal function mapping types to types could be faster than macro expansion, though I don't know that exactly.

The reason I use the new primitive type __type__ is because typeid is meant for RTTI, and it's runtime dependent.
Whereas __type__ is a proper langauge builtin.
And therefore it can use builtin properties.
I would not be able to expose .sizeof as the .sizeof property for example if I used some typeinfo class.
In short the look & feel would suffer.
By using a less integrated design.

January 02, 2021
On Saturday, 2 January 2021 at 16:29:17 UTC, Stefan Koch wrote:

> The reason I use the new primitive type __type__ is because typeid is meant for RTTI, and it's runtime dependent.

Yes, but I think not for types.
> Whereas __type__ is a proper langauge builtin.
> And therefore it can use builtin properties.
> I would not be able to expose .sizeof as the .sizeof property for example if I used some typeinfo class.

I don't understand this, could we define properties on any type? Or are built-in properties only allowed for built-in types.

Note, we have tsized and talign properties for a TypeInfo structure.

See: https://dlang.org/library/object/type_info.html

> In short the look & feel would suffer.

Hmm, what about extending TypeInfo to have sizeof and the other properties referring to tsize and talign?

> By using a less integrated design.

My thought is to reuse existing structures.


January 02, 2021
On Saturday, 2 January 2021 at 08:47:07 UTC, Jacob Carlborg wrote:
> On 2021-01-02 01:05, Stefan Koch wrote:
>
>> [...]
>
> I'm not sure if it needs to have an API. Just look at how Zig does it.
>
> __type__ LinkedList(__type__ ElementType)
> {
>     return struct {
>         static struct Node
>         {
>             ElementType element;
>             Node* next;
>             Node* prev;
>         }
>
>         Node* first;
>         Node* last;
>     }
> }
>
> LinkedList(int) list;
>
> If you want to pass in the field names, I guess you'll have to resort to string mixins. Sure, there could be better alternatives than string mixins, but I think that's a separate issue.
>
>> [...]
>
> Here I've experimented in exposing the compiler AST [1].
>
> [1] https://github.com/jacob-carlborg/druntime/blob/517dafcf54ad73049fb35d1ed5fa2ad6619b9ac4/src/core/ast/expression.d

Did you get as far as actually emitting it to be used during compilation? I'm not about the best way of actually using the AST structure inside the compiler
January 02, 2021
On Saturday, 2 January 2021 at 17:28:20 UTC, sighoya wrote:
>
> My thought is to reuse existing structures.

So now in templates you write sizeof and in typefunctions you write tsize?
In  a template you write alingof and in a typefunction you have to write talign?
That's needlessly increasing surface knowledge one needs to have.

Yes I can see the appeal but in this case I think it's a misplaced urge to reuse existing structure.

The reason that the existing structure typeinfo is not used much at all is because it's less appealing than using the template approach, even if that has other issues.