July 21, 2023

On Thursday, 20 July 2023 at 13:44:15 UTC, Commander Zot wrote:

>

wouldn't it be possible to have something like first class types (at compile time) to replace tamplates for type logic with regular functions executed at CTFE?

In some programming languages I have used in the past specifically Lisp when you define a type you can give it a list of predicates to define the type, its mostly the same except slightly fancier in scala and haskell, in D we already have support for predicates they are called contracts, and you can apply type checking using in, out, assert, and invariant, this gets you most of the way there.

when you click on references you will also find one mentions theorem proving using contracts, so its been used in that same area before, if you use mixins and anonymous/voldemort types I bet you could create a nicer way of applying these contracts, getting 95% the way there. that last 5 percent would be recursive peano types and verifying coverage etc... which both are still probably possible using structs.

https://dlang.org/spec/contracts.html

reference I mentioned:
https://web.archive.org/web/20080919174640/http://people.cs.uchicago.edu/~robby/contract-reading-list/

I guess the next question is, how far can you take contracts for type level programming, and at that point would first class types be necessary.

//basic example
auto test(float a)
in (a < 255)
out(r; r.x > 0)
{
Struct S {
float x;
float y;
float z;
invariant {
assert(x < 255 && x > -60);
assert(y < 255 && y > -60);
assert(z < 255 && z > -60);
}
}
S ret = S(a, 100.0, 100.0);
return ret;
}

I did not check if the code compiled but that is the basic idea, there are also examples on the docs I linked, hopefully this gave you some more stuff you can try out / research, and this is also something I am interested in so I would like to see updates if you come up with anything.

August 07, 2023

Nice work.

It seems you want to lower types to values representing types.
The problem is that types in single init a declaration.

I think grammar alone could not solve the idea of type as expression and type as declaration on it's own:

int i,short* s;

So is short* s an expression type_t!short * type_t!s or a declaration?
The former is useless but there probably trickier examples I don't know.

Further you still need to write:

type_t min(type_t t1,type_t t2)(){...}

otherwise it would be a runtime function which can't do the alias seq magic.
Maybe adding syntactic sugar for it could alleviate:

type_t min!(type_t t1,type_t t2){...}

but I think it is ambiguous too.

Maybe it would be better to pass strings instead of types and retrieve type with its properties out of the string via reflection/traits?

August 08, 2023

On Monday, 7 August 2023 at 23:06:56 UTC, sighoya wrote:

>

I think grammar alone could not solve the idea of type as expression and type as declaration on it's own:

int i,short* s;

So is short* s an expression type_t!short * type_t!s or a declaration?
The former is useless but there probably trickier examples I don't know.

I could imagine rules where this works, as type_t!short would be known at compiletime, so it could be converted to a type. But I agree, there might be cases where it doesn't work. I don't have enough knowledge of the D compiler to evaluate or implement my Idea.

>

Further you still need to write:

type_t min(type_t t1,type_t t2)(){...}

otherwise it would be a runtime function which can't do the alias seq magic.
the point of my idea is for it to be a runtime function. only that in some cases it can be run in CTFE and the result can be converted back to a type as we are in compiletime.

>

Maybe adding syntactic sugar for it could alleviate:

type_t min!(type_t t1,type_t t2){...}

but I think it is ambiguous too.

Maybe it would be better to pass strings instead of types and retrieve type with its properties out of the string via reflection/traits?

that's basically special type functions again, which just complicate the language, and I don't see much benefit over templates.

August 08, 2023

On Tuesday, 8 August 2023 at 09:27:46 UTC, Commander Zot wrote:

>

I could imagine rules where this works, as type_t!short would be known at compiletime, so it could be converted to a type. But I agree, there might be cases where it doesn't work. I don't have enough knowledge of the D compiler to evaluate or implement my Idea.

>

that's basically special type functions again, which just complicate the language, and I don't see much benefit over templates.

The more I think about your solution, the more I like it. It would really easy complex type calculations using normal functions, and it's not a change to the type system, just sugar on top of templates.

If we could eliminate ambiguities, I would be definitely for it. Though we may need to know more about a type than just the name and the size.

August 10, 2023

On Tuesday, 8 August 2023 at 12:26:06 UTC, sighoya wrote:

>

If we could eliminate ambiguities, I would be definitely for it. Though we may need to know more about a type than just the name and the size.

You need the origin so you can compute a mangle.
f(t1, t2) needs to yield mangle_of(f) ~ mangle(t1) ~ mangle(t2)

August 10, 2023

On Thursday, 10 August 2023 at 04:13:57 UTC, Stefan Koch wrote:

>

On Tuesday, 8 August 2023 at 12:26:06 UTC, sighoya wrote:

>

If we could eliminate ambiguities, I would be definitely for it. Though we may need to know more about a type than just the name and the size.

You need the origin so you can compute a mangle.
f(t1, t2) needs to yield mangle_of(f) ~ mangle(t1) ~ mangle(t2)

you need the fully qualified name anyway, or else you run into ambiguities when turning it back into an alias. but i don't understand why you'd need the mangle.
your function signature should look like this, so the mangle shouldn't be anything special:

struct type_t { string fullyqualifiednameoftype; size_t sizeoftype; }
type_t fun(type_t, type_t);
1 2 3
Next ›   Last »