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.

Introduce vec<T> array type #6451

Closed
opened this Issue Oct 30, 2015 · 6 comments

Projects
None yet
5 participants
Contributor

dlreeves commented Oct 30, 2015

This is a part of the Hack array proposal

A `vec` array is a container whose keys are zero-based continuous integers. This mirrors the behavior of the `Vector` class. This will be an array at runtime with extra restrictions to allow it to be used safely like a `Vector` from the type checkers perspective. This focuses mainly on the desired runtime behavior, but if there are questions for how it will interact with the type checker I'll be happy to discuss.

Literal Constructor

A `vec` is constructed using the literal expression `vec[]`.

```\$vec = vec[]; // Empty vec-array
\$vec = vec['a', 'b', 'c']; // vec-array of 3 elements```

This is a static expression, so it can be used in a static initializer.

```class C {
public static \$vec = vec['a', 'b', 'c'];
}```

Traversable Constructor

A `vec` can also be constructed from any `Traversable` type, using the traversable constructor.

```\$array = array('a', 'b', 'c');
\$vec = vec(\$array); // constructs vec-array from another array```

To preserve the property of having continuous integer keys new elements can only be added to a `vec` using the array append operator.

```\$vec = vec[];
\$vec[] = 1; // Allowed
\$vec[0] = 2; // Allowed
\$vec[10] = 3; // Error: 10 is out of bounds for the vec-array```

Removing Elements

Using unset on a `vec` type will demote it to the `dict` type. If you want to preserve the `vec` property then you will need to use the various array functions that operate at the beginning or end of an array such as `array_pop`, `array_push`, `array_shift`, `array_unshift`, etc.

```\$vec = vec[1, 2, 3, 4];
array_pop(\$vec); // Now vec[1, 2, 3]
array_shift(\$vec); // Now vec[2, 3]
unset(\$vec[1]); // unsetting changes a vec to a dict[ 0 => 2]```
Contributor

Orvid commented Oct 31, 2015

 In both this and #6452, how do you propose to handle typing the typing of a `vec` or `dict` that's initialized to be empty? Would this be allowed: ```\$vec = vec[]; \$vec[] = 1; \$vec[] = '1'; // Would we error here?``` And what happens when multiple code paths use it differently (ignore the fact that there is nothing at index 0 yet, I just needed something to illustrate the point of the branch): ```\$vec = vec[]; \$vec[] = is_int(\$vec[0]) ? 1 : '1';``` I think it would be reasonable to allow a syntax for initializing an empty `vec` or `dict` that allows keys/values only of a certain type.
Contributor

dlreeves commented Oct 31, 2015

 @Orvid - This isn't a new issue in this proposal. The same thing can occur with Collections today. ```\$vec = Vector {}; \$vec[] = 1; \$vec[] = '1';``` The type is considered "unresolved" of `Vector`. The `vec` type would work the same. Here is a talk which goes into more detail on how the type checker works if you are interested. https://www.youtube.com/watch?v=aN22-V-b8RM
Contributor

simonwelsh commented Oct 31, 2015

 Would this be used in place of the current single type-argument array? (e.g., `array`) Likewise, would `dict` replace the dual type-argument array? (e.g., `array`) If so, would both type be equivalent, would the current `array` types be deprecated, or would they stay the same? If they become equivalent, would using the current array syntax also be valid when the type of the array is known? Eg: ```class C { public static vec \$vec = ['a', 'b', 'c']; }``` If the `array` types remain, will the new types (`vec`, `dict` and `keyset`) type as `array` too?
Contributor

Orvid commented Nov 1, 2015

 If it's being brought into the language, then wouldn't this be the right time to solve that limitation?

ozzus666 commented Nov 1, 2015

 Yes! 1 lis 2015 01:40 Orvid King notifications@github.com napisał(a):If it's being brought into the language, then wouldn't this be the right time to solve that limitation? —Reply to this email directly or view it on GitHub.
Contributor

simonwelsh commented Nov 1, 2015

 @Orvid that problem exists for anything using generics, it isn't specific to this, so isn't being brought into the language. The actual type isn't known until it is passed through somewhere that makes it concrete (usually, an argument or return type).

hhvm-bot pushed a commit that referenced this issue May 4, 2016

``` Add new array-data operations for Hack arrays ```
```Summary:
Add new array-data operations NvTryGetInt, NvTryGetStr, LValIntRef, and
LValStrRef. NvTryGetInt and NvTryGetStr are similar to NvGetInt and NvGetStr
except they're allowed (but not required) to throw if the key isn't
present. LValIntRef and LValStrRef are likewise similar to LValInt and LValStr
except they indicate to the array that the retrieved value will be boxed into a
ref. This is for array types which don't allow refs. In addition, formalize
LValNewRef, which indicates to the array that the new value will be boxed into a
ref.

Try to use the DISPATCH macro in array-data.cpp consistently, using constexpr
aliases in the array implementations to re-use functions.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3162677

fb-gh-sync-id: d75e1b554d3c153511177ee2564dfe183c90b888
fbshipit-source-id: d75e1b554d3c153511177ee2564dfe183c90b888```
``` d7e80f6 ```

hhvm-bot pushed a commit that referenced this issue May 4, 2016

``` Some misc pre-vec cleanup ```
```Summary:
- Modify throwInvalidArrayKeyException() to take a pointer to the array in
question. This allows it to provide a more accurate message depending on the
array type. In addition, move the definition of throwInvalidArrayKeyException
and throwOOBArrayException into array-data.cpp since there's no need to inline
them.

- Modify Variant::toKey() to take a pointer to the array meant for the key. This
is needed to thread the array pointer to the throwInvalidArrayKeyException()
call. With this pointer, the boolean about whether to perform key conversion
is no longer needed (it can be retrieved from the array directly).

- Modify array_key_exists() to use the same logic regarding key conversion for
arrays without weak keys as is now used in Variant::toKey.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3162696

fb-gh-sync-id: 65e1f247c315884923ca2733999ba548c78081eb
fbshipit-source-id: 65e1f247c315884923ca2733999ba548c78081eb```
``` c1df0f7 ```

hhvm-bot pushed a commit that referenced this issue May 5, 2016

``` Make PackedArray helpers more generic ```
```Summary:
Make the helper functions used by PackedArray more generic by now longer
assuming the array kind is Packed. The functions will now either copy the kind
of the source parameter, or take the kind as an explicit parameter. In the later
case, the helpers are forced inline, so that the kind parameter will be constant
propagated. This is in preparation of the hack array vec kind, which uses most
of the packed array machinery, but has a different kind.

In addition, move PackedArray::MakePacked (where it isn't used) from
mixed-array.cpp to packed-array.cpp.

There was an implicit invariant that packed arrays all have a non-zero capacity
(thus Grow won't be called on them when empty), which isn't necessarily true for
hack vec arrays, so avoid a memcpy when growing an empty array.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3163072

fb-gh-sync-id: a20a2b4a136dcf42754587e836f79b4cd0941e9e
fbshipit-source-id: a20a2b4a136dcf42754587e836f79b4cd0941e9e```
``` aea733f ```

hhvm-bot pushed a commit that referenced this issue May 5, 2016

``` Add basic support for Hack vec array ```
```Summary:
Add basic support for Hack vec arrays. Vec arrays are similar to packed arrays
except they cannot contain references, they throw on trying to access
non-present keys, their keys don't undergo automatic conversions, and they never
change to non-packed representation (under most conditions). This commit only
adds basic support in the runtime, no support for creating them, nor any support
for builtins, nor any JIT support.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3163304

fb-gh-sync-id: 21928f4091d5cd129b7f7991a80c151316cf2673
fbshipit-source-id: 21928f4091d5cd129b7f7991a80c151316cf2673```
``` 9c4df2b ```

hhvm-bot pushed a commit that referenced this issue May 5, 2016

``` Add VecArrayInit ```
```Summary:
Add VecArrayInit, a class used to create Hack vec arrays in the runtime. Since
you can only add new elements to a vec array by appending, appending is the only
operation supported.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3163367

fb-gh-sync-id: 5491448dfa2e2e43e37f5269d3abcabd7dcf8b25
fbshipit-source-id: 5491448dfa2e2e43e37f5269d3abcabd7dcf8b25```
``` 0815949 ```

hhvm-bot pushed a commit that referenced this issue May 5, 2016

``` Add ToVec array-data function ```
```Summary:
Add a new function to array-data, ToVec. This converts the array to an
equivalent Hack vec array. The conversion is done by discarding the keys and
inserting the values into the new vec array in iteration order. If the array is
already a vec array, itself is returned unchanged. For all array types except
PackedArray, the implementation of the conversion is the same, so defer to a
common helper function to perform it. For a non-vec PackedArray, the conversion
can be done more efficiently since it shares a representation with vec
arrays. The conversion can throw if the source array contains a non-collapsable
reference.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3163710

fb-gh-sync-id: 230644c2c932e5849015c36bf15609872f8c1573
fbshipit-source-id: 230644c2c932e5849015c36bf15609872f8c1573```
``` 7cb0511 ```

hhvm-bot pushed a commit that referenced this issue May 5, 2016

``` Add serializer/unserializer support for Hack vec arrays ```
```Summary:
Add serializer/unserializer support for Hack vec arrays. Unlike normal PHP
arrays, no keys are serialized (because they're implicit by the ordering), and
the code 'v' is used to mark them. An additional check is needed during
deserializer to check for references.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3163779

``` 1ae5680 ```

hhvm-bot pushed a commit that referenced this issue May 6, 2016

``` Add HHBC and HHIR support for Hack vec arrays ```
```Summary:
Add a new HHBC instruction to create a Hack vec array. Also add new HHIR
instructions to allocate a vec array and to convert a PHP array to a vec array.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3163925

fb-gh-sync-id: 8054b19e501a5cc5c5df9679de5401360d4b89dd
fbshipit-source-id: 8054b19e501a5cc5c5df9679de5401360d4b89dd```
``` e055a63 ```

hhvm-bot pushed a commit that referenced this issue May 6, 2016

``` Add parser support for Hack vec arrays ```
```Summary:
Add parser support for Hack vec arrays. This includes literal vecs like "vec[1,
2, 3]" and the converting constructor named "vec()".

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3164001

``` 1fd5b92 ```

hhvm-bot pushed a commit that referenced this issue May 6, 2016

``` Add test cases for Hack vec arrays ```
```Summary:
Add test cases for Hack vec arrays. This was separated out into the final diff
to allow for easier to review.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
Related to #6451
Related to #6454

Reviewed By: paulbiss

Differential Revision: D3164026

``` 4066ec6 ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Add new array-data operations for Hack arrays ```
```Summary:
Add new array-data operations NvTryGetInt, NvTryGetStr, LValIntRef, and
LValStrRef. NvTryGetInt and NvTryGetStr are similar to NvGetInt and NvGetStr
except they're allowed (but not required) to throw if the key isn't
present. LValIntRef and LValStrRef are likewise similar to LValInt and LValStr
except they indicate to the array that the retrieved value will be boxed into a
ref. This is for array types which don't allow refs. In addition, formalize
LValNewRef, which indicates to the array that the new value will be boxed into a
ref.

Try to use the DISPATCH macro in array-data.cpp consistently, using constexpr
aliases in the array implementations to re-use functions.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack

Reviewed By: paulbiss

Differential Revision: D3162677

fb-gh-sync-id: d75e1b554d3c153511177ee2564dfe183c90b888
fbshipit-source-id: d75e1b554d3c153511177ee2564dfe183c90b888```
``` ebd5313 ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Some misc pre-vec cleanup ```
```Summary:
- Modify throwInvalidArrayKeyException() to take a pointer to the array in
question. This allows it to provide a more accurate message depending on the
array type. In addition, move the definition of throwInvalidArrayKeyException
and throwOOBArrayException into array-data.cpp since there's no need to inline
them.

- Modify Variant::toKey() to take a pointer to the array meant for the key. This
is needed to thread the array pointer to the throwInvalidArrayKeyException()
call. With this pointer, the boolean about whether to perform key conversion
is no longer needed (it can be retrieved from the array directly).

- Modify array_key_exists() to use the same logic regarding key conversion for
arrays without weak keys as is now used in Variant::toKey.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack

Reviewed By: paulbiss

Differential Revision: D3162696

fb-gh-sync-id: 65e1f247c315884923ca2733999ba548c78081eb
fbshipit-source-id: 65e1f247c315884923ca2733999ba548c78081eb```
``` 11adbc8 ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Make PackedArray helpers more generic ```
```Summary:
Make the helper functions used by PackedArray more generic by now longer
assuming the array kind is Packed. The functions will now either copy the kind
of the source parameter, or take the kind as an explicit parameter. In the later
case, the helpers are forced inline, so that the kind parameter will be constant
propagated. This is in preparation of the hack array vec kind, which uses most
of the packed array machinery, but has a different kind.

In addition, move PackedArray::MakePacked (where it isn't used) from
mixed-array.cpp to packed-array.cpp.

There was an implicit invariant that packed arrays all have a non-zero capacity
(thus Grow won't be called on them when empty), which isn't necessarily true for
hack vec arrays, so avoid a memcpy when growing an empty array.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack

Reviewed By: paulbiss

Differential Revision: D3163072

fb-gh-sync-id: a20a2b4a136dcf42754587e836f79b4cd0941e9e
fbshipit-source-id: a20a2b4a136dcf42754587e836f79b4cd0941e9e```
``` 055a2ca ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Add basic support for Hack vec array ```
```Summary:
Add basic support for Hack vec arrays. Vec arrays are similar to packed arrays
except they cannot contain references, they throw on trying to access
non-present keys, their keys don't undergo automatic conversions, and they never
change to non-packed representation (under most conditions). This commit only
adds basic support in the runtime, no support for creating them, nor any support
for builtins, nor any JIT support.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack

Reviewed By: paulbiss

Differential Revision: D3163304

fb-gh-sync-id: 21928f4091d5cd129b7f7991a80c151316cf2673
fbshipit-source-id: 21928f4091d5cd129b7f7991a80c151316cf2673```
``` 958d882 ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Add VecArrayInit ```
```Summary:
Add VecArrayInit, a class used to create Hack vec arrays in the runtime. Since
you can only add new elements to a vec array by appending, appending is the only
operation supported.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack

Reviewed By: paulbiss

Differential Revision: D3163367

fb-gh-sync-id: 5491448dfa2e2e43e37f5269d3abcabd7dcf8b25
fbshipit-source-id: 5491448dfa2e2e43e37f5269d3abcabd7dcf8b25```
``` af6cb16 ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Add ToVec array-data function ```
```Summary:
Add a new function to array-data, ToVec. This converts the array to an
equivalent Hack vec array. The conversion is done by discarding the keys and
inserting the values into the new vec array in iteration order. If the array is
already a vec array, itself is returned unchanged. For all array types except
PackedArray, the implementation of the conversion is the same, so defer to a
common helper function to perform it. For a non-vec PackedArray, the conversion
can be done more efficiently since it shares a representation with vec
arrays. The conversion can throw if the source array contains a non-collapsable
reference.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack

Reviewed By: paulbiss

Differential Revision: D3163710

fb-gh-sync-id: 230644c2c932e5849015c36bf15609872f8c1573
fbshipit-source-id: 230644c2c932e5849015c36bf15609872f8c1573```
``` c42064e ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Add serializer/unserializer support for Hack vec arrays ```
```Summary:
Add serializer/unserializer support for Hack vec arrays. Unlike normal PHP
arrays, no keys are serialized (because they're implicit by the ordering), and
the code 'v' is used to mark them. An additional check is needed during
deserializer to check for references.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack

Reviewed By: paulbiss

Differential Revision: D3163779

``` d48bc6d ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Add HHBC and HHIR support for Hack vec arrays ```
```Summary:
Add a new HHBC instruction to create a Hack vec array. Also add new HHIR
instructions to allocate a vec array and to convert a PHP array to a vec array.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack

Reviewed By: paulbiss

Differential Revision: D3163925

fb-gh-sync-id: 8054b19e501a5cc5c5df9679de5401360d4b89dd
fbshipit-source-id: 8054b19e501a5cc5c5df9679de5401360d4b89dd```
``` a676be2 ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Add parser support for Hack vec arrays ```
```Summary:
Add parser support for Hack vec arrays. This includes literal vecs like "vec[1,
2, 3]" and the converting constructor named "vec()".

See: http://hhvm.com/blog/10649/improving-arrays-in-hack

Reviewed By: paulbiss

Differential Revision: D3164001

``` e8d342f ```

racardoso pushed a commit to PPC64/hhvm that referenced this issue May 17, 2016

``` Add test cases for Hack vec arrays ```
```Summary:
Add test cases for Hack vec arrays. This was separated out into the final diff
to allow for easier to review.

See: http://hhvm.com/blog/10649/improving-arrays-in-hack
``` 18e9c9c ```