Hi Damian -

> I am after a value type which does not need 'new'

In Chapel, to create a record value while passing parameters
to the initializer, one uses `new MyRecord(args)`. Unlike in C++,
the difference between allocating on the stack or the heap
(for a local variable) is not the use of `new` but rather the use
of a class or a record.

So `new MyClass(arg)` will allocate a class instance on the heap,
but `new MyRecord(arg)` will allocate a record variable on the stack.

Here is a version of your program that does that:

type a6 = [1..6] int;

record element
{
  type T;
  var data : T;
}

proc main
{
  var x : [1..6] int = [ 1, 2, 3, 4, 5, 6 ];
  var t = new element(x);

  writeln(t);
}

Note that because `element` is a record, `new element(x)`
corresponds to what in C++ one would write as `element(x)`.

Let's talk about the ways you could create a record variable
without using `new`.

First, you can default-initialize a record variable. This in effect
runs the initializer with zero arguments (or, for generic records,
type/param arguments for the components of the type known
at compile time).

  var a: MyRecord;
  var b: MyGenericRecord(int); // runs MyGenericRecord.init(type t)

Second, you can use initialization or split initialization to
initialize the record from something else. You can even
write a custom `init=` function to support these patterns.
I think this is probably what you were trying to write in
the first place.

Here is a variant of your program that does that and works
for me:

type a6 = [1..6] int;
  
record element
{
  type T;
  var data : T;

  // this is the same-type copy initializer
  proc init=(other : element)
  {
    this.T = other.T;
    this.data = other.data;
  }

  // this allows typed initialization from a value of type T
  proc init=(other : [])
  {
    this.T = other.type;
    this.data = other;
  }
}

proc main
{
  var x : [1..6] int = [ 1, 2, 3, 4, 5, 6 ];
  var t: element = x;

  writeln(t);
}

If you wanted to use split initialization, you would
write

  var t: element;
  ... other statements possible here ...
  t = x;

Anyway if you are trying to run an `init=` that uses a different
type, you have to declare the type at the variable declaration:

  var t = x; // t is just a copy of x (i.e. an array in the example)

  var t: element = x; // requests init= from an array to an element

The second issue is with the `init=` itself.

The original code here:

  proc init=(other : this.type.T)

is only going to work when `this.type.T` is already defined;
such as with `var t: element(a6) = x`. But the init= has the
capability to compute the type of the field T you want to use in
the new variable - that is what `proc init=(other : [])` allows.
Either way, the `init=` has to include a line like
`this.T = other.type` to be a valid initializer. The compiler
will check that the types match if you already had defined T,
as in with `var t: element(a6) = x`.

Hope that helps,

-michael

    
    Hi Weekend Workers,
    
    I copied the Wrapper record and tried to include an array of size known at 
    compile time. I am after a value type which does not need 'new'. Ideally 
    this should all come off the stack but Chapel seems to shy away from the 
    stack. But that is another question.
    
    For now, I just want to stuff an array into a generic record which works
    for any sized array.  This is a 'finite element' which has a connectivity
    vector full of integers, which are node numbers.
    
        type a6 = [1..6] int;
    
        record element
        {
                type T;
                var data : T;
    
                proc init=(other : this.type.T)
                {
                        this.T = other.type;
                        this.data = other;
                }
        }
    
        proc main
        {
                var x : [1..6] int = [ 1, 2, 3, 4, 5, 6 ];
                var t = element(x);
    
                writeln(t);
        }
    
    The above is rejected with
    
    v.chpl:15: In function 'main':
    v.chpl:18: error: invalid type specifier 'element([domain(1,int(64),false)] 
int(64))'
    v.chpl:18: note: type specifier did not match: element(type T)
    v.chpl:18: note: cannot instantiate type field 'T' with non-type
    
    What am I missing in this generic record?
    
    The type of x is '[1..6] int'.
    
    Is the type of an array really not a type in the strict sense?
    
    Thanks - Damian
    
    Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
    Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
    Views & opinions here are mine and not those of any past or present employer
    
    
    _______________________________________________
    Chapel-developers mailing list
    [email protected]
    https://lists.sourceforge.net/lists/listinfo/chapel-developers 
    


_______________________________________________
Chapel-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-developers

Reply via email to