Introduce vec<T> array type #6451

Closed
dlreeves opened this Issue Oct 30, 2015 · 6 comments

Projects

None yet

5 participants

@dlreeves
Contributor

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

Adding Elements

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

@dlreeves
Contributor

@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<int | string>. 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

@simonwelsh
Contributor

Would this be used in place of the current single type-argument array? (e.g., array<string>) Likewise, would dict replace the dual type-argument array? (e.g., array<int, string>)

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<string> $vec = ['a', 'b', 'c'];
}

If the array types remain, will the new types (vec, dict and keyset) type as array too?

@Orvid
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
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.

@simonwelsh
Contributor

@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).

@jwatzman jwatzman added the hack label Nov 8, 2015
@hhvm-bot hhvm-bot pushed a commit that referenced this issue May 4, 2016
@ricklavoie ricklavoie + Hhvm Bot 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 hhvm-bot pushed a commit that referenced this issue May 4, 2016
@ricklavoie ricklavoie + Hhvm Bot 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 hhvm-bot pushed a commit that referenced this issue May 5, 2016
@ricklavoie ricklavoie + Hhvm Bot 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 hhvm-bot pushed a commit that referenced this issue May 5, 2016
@ricklavoie ricklavoie + Hhvm Bot 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 hhvm-bot pushed a commit that referenced this issue May 5, 2016
@ricklavoie ricklavoie + Hhvm Bot 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 hhvm-bot pushed a commit that referenced this issue May 5, 2016
@ricklavoie ricklavoie + Hhvm Bot 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 hhvm-bot pushed a commit that referenced this issue May 5, 2016
@ricklavoie ricklavoie + Hhvm Bot 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

fb-gh-sync-id: bfbfa145b05ae32d72101c0e74adbfae399c3cb2
fbshipit-source-id: bfbfa145b05ae32d72101c0e74adbfae399c3cb2
1ae5680
@hhvm-bot hhvm-bot pushed a commit that referenced this issue May 6, 2016
@ricklavoie ricklavoie + Hhvm Bot 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 hhvm-bot pushed a commit that referenced this issue May 6, 2016
@ricklavoie ricklavoie + Hhvm Bot 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

fb-gh-sync-id: 76988820f6cb41b822adae833253fdeacd8c046a
fbshipit-source-id: 76988820f6cb41b822adae833253fdeacd8c046a
1fd5b92
@hhvm-bot hhvm-bot pushed a commit that referenced this issue May 6, 2016
@ricklavoie ricklavoie + Hhvm Bot 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

fb-gh-sync-id: e46412c2ef4685f55b7857bb254b6fead799a82c
fbshipit-source-id: e46412c2ef4685f55b7857bb254b6fead799a82c
4066ec6
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3162677

fb-gh-sync-id: d75e1b554d3c153511177ee2564dfe183c90b888
fbshipit-source-id: d75e1b554d3c153511177ee2564dfe183c90b888
ebd5313
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3162696

fb-gh-sync-id: 65e1f247c315884923ca2733999ba548c78081eb
fbshipit-source-id: 65e1f247c315884923ca2733999ba548c78081eb
11adbc8
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3163072

fb-gh-sync-id: a20a2b4a136dcf42754587e836f79b4cd0941e9e
fbshipit-source-id: a20a2b4a136dcf42754587e836f79b4cd0941e9e
055a2ca
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3163304

fb-gh-sync-id: 21928f4091d5cd129b7f7991a80c151316cf2673
fbshipit-source-id: 21928f4091d5cd129b7f7991a80c151316cf2673
958d882
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3163367

fb-gh-sync-id: 5491448dfa2e2e43e37f5269d3abcabd7dcf8b25
fbshipit-source-id: 5491448dfa2e2e43e37f5269d3abcabd7dcf8b25
af6cb16
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3163710

fb-gh-sync-id: 230644c2c932e5849015c36bf15609872f8c1573
fbshipit-source-id: 230644c2c932e5849015c36bf15609872f8c1573
c42064e
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3163779

fb-gh-sync-id: bfbfa145b05ae32d72101c0e74adbfae399c3cb2
fbshipit-source-id: bfbfa145b05ae32d72101c0e74adbfae399c3cb2
d48bc6d
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3163925

fb-gh-sync-id: 8054b19e501a5cc5c5df9679de5401360d4b89dd
fbshipit-source-id: 8054b19e501a5cc5c5df9679de5401360d4b89dd
a676be2
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3164001

fb-gh-sync-id: 76988820f6cb41b822adae833253fdeacd8c046a
fbshipit-source-id: 76988820f6cb41b822adae833253fdeacd8c046a
e8d342f
@racardoso racardoso added a commit to PPC64/hhvm that referenced this issue May 17, 2016
@ricklavoie @racardoso ricklavoie + racardoso 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 facebook#6451
Related to facebook#6454

Reviewed By: paulbiss

Differential Revision: D3164026

fb-gh-sync-id: e46412c2ef4685f55b7857bb254b6fead799a82c
fbshipit-source-id: e46412c2ef4685f55b7857bb254b6fead799a82c
18e9c9c
@Orvid Orvid closed this Sep 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment