View mode: basic / threaded / horizontal-split · Log in · Help
December 10, 2012
Type value
Hi!
In some previous post I asked about possibility of declar 
opIndex,that return type.
I thoght about it,and I understood that code like this is legal:

struct Type(T)
{
	alias T m_type;
	alias m_type this;
}

void main()
{
	Type!int Int;
//	Int a;
}

Is it hard to implement possibility of using Int as a type?
It would allow functions,that return types:)
December 11, 2012
Re: Type value
On Monday, 10 December 2012 at 19:54:51 UTC, Zhenya wrote:
> Hi!
> In some previous post I asked about possibility of declar 
> opIndex,that return type.
> I thoght about it,and I understood that code like this is legal:
>
> struct Type(T)
> {
> 	alias T m_type;
> 	alias m_type this;
> }
>
> void main()
> {
> 	Type!int Int;
> //	Int a;
> }
>
> Is it hard to implement possibility of using Int as a type?
> It would allow functions,that return types:)

Type's are compile time concepts that are only used to partition 
data into logical units. Computer memory is just a bunch of 0's 
and 1's and have no logical interpretation.

By creating a type you are taking a group of bits and telling the 
compiler(a static construct) how you want to interpret them. You 
do not tell the cpu this as it does not have any idea of 
types(well, except for basic things like ptr's, bytes, words, 
etc...).

So, when you say "return a type" it means nothing because a type 
is not addressable. How would you return an int as a type? (not a 
group of bits but an actual int type specification)

To help bridge the gap between compile time static type 
constructs and a rather typeless run-time system modern languages 
seem to create a type that wraps Type information into an actual 
object which then you can pass around like "normal" objects.

Remember, compilers simply make it easier to program in binary, 
but ultimately that is all we are doing. To make things more 
logical we use higher level types, the cpu does not understand 
arbitrary types(but we use the types it does understand as basic 
building blocks). In some sense, it doesn't even "understand" 
types at all... it just has some instructions that make dealing 
with different length of binary numbers easier/more efficient.

As far as I know, D does allow you to wrap compile time type info 
into an object to be used at run-time for various things(but it 
will exist as an addressable object).


for example, you can't really do something like this

type return_type(int x) { if x == 1 return int; return fruitType; 
}

c = readkey();
return_type(c) y;
// How do we use y? we don't even know what type it is at this 
point! We are going to have to assume it is one or the other and 
code for both! But then we essentially just have the same as the 
following

alternatively:

c = readkey();
if c == 1 { int y; do whatever; } else { fruitType y; do 
whatever; }

because y is not known at compile time(it is not a static 
construct). y, essentially is a polymorphic type but is too 
arbitrary to be useful. Remember, the compiler ultimately has to 
make an address and a set of bits for y in computer member for 
the cpu to be able to understand it. How, though, can it do this 
for y if the "type" is not known at compile time?

The 2nd case is completely defined at compile time. The first is 
not and essentially is "open ended"(the compiler can't figure out 
all the possibilities that y can be, while in the second case it 
is fixed).

So, you can't pass types around in a run-time fashion. D is nice 
in that it allows you do easily do this sort of stuff at compile 
time. You can pass around type info objects dynamically and even 
create types from such objects at run-time. Doing so, though, 
requires a more difficult approach because, ultimately, the 
compiler still has to be told everything that is being done(it 
can't guess) and it still has to translate the program into 0's 
and 1's.

The variant type is a way to sort of get around the problem for 
some cases as it allows a type to be polymorphic to a degree(but 
not arbitrarily).

If cpu's stored data in logical units then such a system would be 
much easier to do. Instead of storing bytes one would store 
"records" which would contain a type field which would tell the 
cpu information about it(which you have to setup). Unfortunately 
this would bloat the code tremendously(every int would have to 
have a type field). It would be sort of the same though as modern 
compilers and their typing systems but would be more transparent. 
(probably equivalent of just implementing the compiler on the cpu)
December 11, 2012
Re: Type value
I'm sorry for my english.
I know that D != Python and my example don't need
any RTTI.

D has alias this feature.My example shows that we can use alias 
this with types.
And I just want use this:

struct Type(T)
{
   alias T m_type;
   alias m_type this;
}

int main()
{
   Type!int Int;
   Int i;//should compile by definition of alias this
}
December 11, 2012
Re: Type value
On Tuesday, 11 December 2012 at 07:15:38 UTC, Zhenya wrote:
> I'm sorry for my english.
> I know that D != Python and my example don't need
> any RTTI.
>
> D has alias this feature.My example shows that we can use alias 
> this with types.
> And I just want use this:
>
> struct Type(T)
> {
>    alias T m_type;
>    alias m_type this;
> }
>
> int main()
> {
>    Type!int Int;
>    Int i;//should compile by definition of alias this
> }

My I ask, why not just use int directly?

I'm not proficient enough with D yet but it seems to me that the 
example does not make sense.

alias T m_type;
alias m_type this;

should be equivalent to

alias T this;

which, in some sense makes struct Type(T) equal to T... which is 
what you are thinking, I think.

But! I also believe that structs are meant as value types and are 
addressable.

So when you do

Int i; you are essentially doing something like

int x;
x i;

which makes no sense.

If you do this instead,

	alias Type!int Int;
	Int i;

then it will compile, of course.

But your way, when you do Int x; you are specifically trying to 
create a instance of an object. Yet you are not wanting it to be 
an object and I'm not sure what you are wanting x to be. (another 
type? a type of a type?)
December 11, 2012
Re: Type value
On Tuesday, 11 December 2012 at 07:50:10 UTC, js.mdnq wrote:
> On Tuesday, 11 December 2012 at 07:15:38 UTC, Zhenya wrote:
>> I'm sorry for my english.
>> I know that D != Python and my example don't need
>> any RTTI.
>>
>> D has alias this feature.My example shows that we can use 
>> alias this with types.
>> And I just want use this:
>>
>> struct Type(T)
>> {
>>   alias T m_type;
>>   alias m_type this;
>> }
>>
>> int main()
>> {
>>   Type!int Int;
>>   Int i;//should compile by definition of alias this
>> }
>
> My I ask, why not just use int directly?
>
> I'm not proficient enough with D yet but it seems to me that 
> the example does not make sense.
>
> alias T m_type;
> alias m_type this;
>
> should be equivalent to
>
> alias T this;
>
> which, in some sense makes struct Type(T) equal to T... which 
> is what you are thinking, I think.
>
> But! I also believe that structs are meant as value types and 
> are addressable.
>
> So when you do
>
> Int i; you are essentially doing something like
>
> int x;
> x i;
>
> which makes no sense.
>
> If you do this instead,
>
> 	alias Type!int Int;
> 	Int i;
>
> then it will compile, of course.
>
> But your way, when you do Int x; you are specifically trying to 
> create a instance of an object. Yet you are not wanting it to 
> be an object and I'm not sure what you are wanting x to be. 
> (another type? a type of a type?)

In my example Int is value of Type!int.
When I write
Int i;
If Int had not alias this it really would not have sense,because 
type expected
instead of 'Int'.But Int have alias this 'int',and can be 
replaced by it.
My reason is simple:
Operators are functions.But if I want declare some struct like 
std.TypeTuple
I will need opSlice that return type.
It is impossible.
But if my example compiled,I could return value,that can be used 
as type.
It's something like Andrei's Type2Type.
December 11, 2012
Re: Type value
On 12/10/2012 11:54 AM, Zhenya wrote:

> In some previous post I asked about possibility of declar opIndex,that
> return type.

TypeTuple helps with that.

> I thoght about it,and I understood that code like this is legal:
>
> struct Type(T)
> {
> alias T m_type;
> alias m_type this;

For that to work, m_type must be an actual value. It can be a member 
variable or a member function that returns a value.

> }
>
> void main()
> {
> Type!int Int;
> // Int a;
> }
>
> Is it hard to implement possibility of using Int as a type?
> It would allow functions,that return types:)

It is possible to select a type by an index at compile time. It feels 
natural to me that the index is applied by the template instantiation 
syntax as in Type!0, as opposed to Type[0]:

import std.typetuple;

/* A test struct */
struct S
{
    string s;
    int i;
}

/* A test class */
class C
{
    S s;
    int i;
    double d;

    this(S s, int i, double d)
    {
        this.s = s;
        this.i = i;
        this.d = d;
    }
}

/* A mapping from type index to a type */
template Type(size_t index)
{
    alias TypeTuple!(int, double, S, C)[index] Type;
}

/* A generic function that can make an object of any type. */
Type!index make(size_t index, T...)(T args)
{
    static if (is(Type!index == struct)) {
        /* structs are not constructed by 'new' */
        return Type!index(args);

    } else static if (is(Type!index == class)) {
        /* classes are constructed by 'new' */
        return new Type!index(args);

    } else {
        /* Fundamental types must be made differently; probably due to 
syntax
         * issues. I would have expected for the following to work:
         *
         *     return Type!index(args);  // <-- compilation error
         */
        Type!index result;
        result = args[0];
        return result;
    }
}

void main()
{
    Type!0 i;
    Type!1 d;
    Type!2 s;
    Type!3 c;

    static assert(is (typeof(i) == int));
    static assert(is (typeof(d) == double));
    static assert(is (typeof(s) == S));
    static assert(is (typeof(c) == C));

    i = make!0(42);
    d = make!1(1.5);
    s = make!2("hello", 10);
    c = make!3(S("world", 100), 44, 10.75);
}

Actually, the [0] syntax is also possible as TypeTuple enables:

    alias TypeTuple!(int, double, S, C) MyTypes;
    MyTypes[0] i;

Ali
December 11, 2012
Re: Type value
On 12/11/2012 01:05 AM, Ali Çehreli wrote:

> /* Fundamental types must be made differently; probably due to syntax
> * issues. I would have expected for the following to work:
> *
> * return Type!index(args); // <-- compilation error
> */

My mind must have been in C++ mode there. :) The following is not legal 
in D:

int foo()
{
    return int(42);    // not D syntax!
}

But of course the simpler code below works:

/* A generic function that can make an object of any type. */
Type!index make(size_t index, T...)(T args)
{
// ...

    } else {
        return args[0];    // simply return "the" argument
    }
}

Ali
December 11, 2012
Re: Type value
On Tuesday, 11 December 2012 at 09:40:08 UTC, Ali Çehreli wrote:
> On 12/11/2012 01:05 AM, Ali Çehreli wrote:
>
> > /* Fundamental types must be made differently; probably due
> to syntax
> > * issues. I would have expected for the following to work:
> > *
> > * return Type!index(args); // <-- compilation error
> > */
>
> My mind must have been in C++ mode there. :) The following is 
> not legal in D:
>
> int foo()
> {
>     return int(42);    // not D syntax!
> }
>
> But of course the simpler code below works:
>
> /* A generic function that can make an object of any type. */
> Type!index make(size_t index, T...)(T args)
> {
> // ...
>
>     } else {
>         return args[0];    // simply return "the" argument
>     }
> }
>
> Ali
Thank you for you example,I understand.
But how do you think does it make sense to open enhancement
allow alias this with types?
Or it is completely useless?
December 11, 2012
Re: Type value
On 12/11/2012 08:42 AM, Zhenya wrote:

> But how do you think does it make sense to open enhancement
> allow alias this with types?
> Or it is completely useless?

Usual compromises: Is it useful in large number of projects? Does it 
break existing programs? Does it fit well with the existing features of 
the language? etc.

I suggest that you first open another thread on the main D forum to see 
what people who do not frequent D.learn think about this feature.

Ali
Top | Discussion index | About this forum | D home