Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating empty arrays with {} #1286

Closed
spinkney opened this issue Mar 7, 2023 · 13 comments
Closed

Creating empty arrays with {} #1286

spinkney opened this issue Mar 7, 2023 · 13 comments
Labels
feature New feature or request

Comments

@spinkney
Copy link
Contributor

spinkney commented Mar 7, 2023

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].

@spinkney spinkney added the feature New feature or request label Mar 7, 2023
@WardBrian
Copy link
Member

It’s definitely intentional in the sense that it’s what our parser encodes:

| LBRACE xs=separated_nonempty_list(COMMA, expression) RBRACE

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.

@nhuurre
Copy link
Collaborator

nhuurre commented Mar 7, 2023

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?
  }
}

@WardBrian
Copy link
Member

I think your right. We actually would disallow it in the typechecker even if it parsed, see

let check_array_expr loc es =
match es with
| [] ->
(* NB: This is actually disallowed by parser *)
Semantic_error.empty_array loc |> error

C++ allows empty initializer lists but only if they're unambiguous, e.g. https://godbolt.org/z/MdEKhsdMh

@spinkney
Copy link
Contributor Author

spinkney commented Mar 7, 2023

Would it be possible to allow unambiguous null arrays then? Like int {}, real {}, etc.? Or maybe it's better to have {} int?

@WardBrian
Copy link
Member

That is still ambiguous in the number of dimensions. How often is this something somebody would want to have?

@spinkney
Copy link
Contributor Author

spinkney commented Mar 7, 2023

Wouldn't 2d be {,} int? Or am I missing something?

@spinkney
Copy link
Contributor Author

spinkney commented Mar 7, 2023

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.

@WardBrian
Copy link
Member

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] ints are identical, and they're initialized by the compiler to the only value they can have.

@spinkney
Copy link
Contributor Author

spinkney commented Mar 7, 2023

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.

@nhuurre
Copy link
Collaborator

nhuurre commented Mar 7, 2023

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.

@bob-carpenter
Copy link
Contributor

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;
}

@spinkney
Copy link
Contributor Author

spinkney commented Mar 8, 2023

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.

@WardBrian
Copy link
Member

I'm going to close this in favor of the docs issue you created @spinkney

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants