Creating empty arrays with {}
spinkney opened this issue · 13 comments
Is it intended that {} can't be parsed as an empty arrray?
I was trying to pass an empty array into a recursive function with the first iteration and found that I needed to create it as array[0]
.
It’s definitely intentional in the sense that it’s what our parser encodes:
stanc3/src/frontend/parser.mly
Line 579 in c8bae8b
Now I’m not sure whether or not it’s necessary. My first guess is that you might get ambiguities between an empty array expression and an empty block, but I can try it out today and see.
I think the main problem is type inference. It would be weirdly limiting if the type of {}
was always e.g. array[] int
but guessing the type from context is not implemented and is sometimes ambiguous anyway.
functions {
real f(array[,] real x) {
return 1.0;
}
real f(array[] vector x) {
return 0.0;
}
real g() {
return f({}); // which overload is it?
}
}
I think your right. We actually would disallow it in the typechecker even if it parsed, see
stanc3/src/frontend/Typechecker.ml
Lines 317 to 321 in c8bae8b
C++ allows empty initializer lists but only if they're unambiguous, e.g. https://godbolt.org/z/MdEKhsdMh
Would it be possible to allow unambiguous null arrays then? Like int {}
, real {}
, etc.? Or maybe it's better to have {} int
?
That is still ambiguous in the number of dimensions. How often is this something somebody would want to have?
Wouldn't 2d be {,} int
? Or am I missing something?
That is still ambiguous in the number of dimensions. How often is this something somebody would want to have?
I just think it seems like you should be able to construct an empty array like you can a non-empty one. At the minimum, pointing out in the docs that empty arrays cannot be initialized like this seems necessary.
Huh, that would be a kind of expression altogether. I don't think that makes a ton of sense, since {1,2}
is a 1-d thing, but { , }
would be a 2-d thing?
You could write { {} }
, but that's really an array[1, 0]
. I think writing down a true array[0, 0]
is functionally impossible without a specific syntax just for that.
Initializing an empty array is not necessary, since there is only one empty array of a given type, e.g. all array[0] int
s are identical, and they're initialized by the compiler to the only value they can have.
Good example and I wouldn't want a ton of work put into this because it wouldn't be something people do that often. There's also the easy work around of creating the empty array before using the array[0]
declaration.
I think writing down a true array[0, 0] is functionally impossible without a specific syntax just for that.
You can write rep_array({1.0}, 0)
or whatever.
At the minimum, pointing out in the docs that empty arrays cannot be initialized like this seems necessary.
Agreed. Where do you think that should go in the reference manual and/or user's guide? Would you mind opening a docs issue for this?
it seems like you should be able to construct an empty array like you can a non-empty one
It's easy to think that until you consider what the type should be. While it's tempting to assign {}
to array[] int
type, it could really be an empty array of anything.
The only solution now with an expression is what @nhuure suggests---just use the array constructors rep_array()
. Or we could have typed empty array constructors of some kind, such as empty_int_array()
, empty_real_array()
, and so on. Super clunky, but easy to type. You can also define specific empty things in transformed data,
transformed data {
array[0] int empty_int_array;
}
Agreed. Where do you think that should go in the reference manual and/or user's guide? Would you mind opening a docs issue for this?
Opened a docs issue at stan-dev/docs#621. I believe the relevant section is in the reference manual linked at the aforementioned docs issue.