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

Introduce keyset<T> array type #6453

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

Comments

Projects
None yet
5 participants
@dlreeves
Contributor

dlreeves commented Oct 30, 2015

This is a part of the Hack array proposal

A keyset is a set that can only contain valid array keys. It is implemented as a dict whose values and keys are the same. For example:

$set = keyset[1, 2, 3];
// Logically expands to
dict[
  1 => 1,
  2 => 2,
  3 => 3,
]

This will be an array at runtime with extra restrictions to allow it to be used safely like a Set 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 keyset is constructed using the literal expression keyset[].

$set = keyset[]; // Empty set-array
$set = keyset['a', 'b', 'c']; // set-array of 3 elements

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

class C {
  public static $set = keyset['a', 'b', 'c'];
}

Traversable Constructor

A keyset can also be constructed from any Traversable type, using the traversable constructor.
We will also have a function keyset_from_keys to construct a keyset from the keys of a KeyedTraversable.

$array = array('a', 'b', 'c');
$set = keyset($array); // constructs set-array from another array

Checking Membership

isset is used to check membership in a keyset

$set = keyset[4, 5, 6];
isset($set[0]);

Adding Elements

To add a new element to a keyset we will introduce a new “set append” operator. From the type checkers perspective setting a key directly will be an error, but the runtime will behave the same as a dict.

$set = keyset[];
$set{} = 2; // "Set-append" that sets (2 => 2) in $set
$set[$x] = 4; // Type error, but not a runtime error

Removing Elements

Removing an element from a keyset is identical to removing an element from a PHP array by using the unset function.

@Orvid

This comment has been minimized.

Show comment
Hide comment
@Orvid

Orvid Oct 31, 2015

Contributor

Any chance you have an example of a specific use-case for this? I can see it being reasonable as a hashset, but I'm not sure something needs to be built into the language for that.

Contributor

Orvid commented Oct 31, 2015

Any chance you have an example of a specific use-case for this? I can see it being reasonable as a hashset, but I'm not sure something needs to be built into the language for that.

@SiebelsTim

This comment has been minimized.

Show comment
Hide comment
@SiebelsTim

SiebelsTim Oct 31, 2015

Contributor

Why do you have to introduce a new operator for appending? Wouldn't $set[] = 2 just do fine? Is this for technical reasons? Furthermore, what happend when I try to use array append?

Contributor

SiebelsTim commented Oct 31, 2015

Why do you have to introduce a new operator for appending? Wouldn't $set[] = 2 just do fine? Is this for technical reasons? Furthermore, what happend when I try to use array append?

@simonwelsh

This comment has been minimized.

Show comment
Hide comment
@simonwelsh

simonwelsh Oct 31, 2015

Contributor

@Orvid think of it as a value-version of the Set collection class. Having it built into the language, rather than just using plain arrays for it like most people currently do in PHP, also allows for optimisations based on the type of array to be applied.

Contributor

simonwelsh commented Oct 31, 2015

@Orvid think of it as a value-version of the Set collection class. Having it built into the language, rather than just using plain arrays for it like most people currently do in PHP, also allows for optimisations based on the type of array to be applied.

@dlreeves

This comment has been minimized.

Show comment
Hide comment
@dlreeves

dlreeves Oct 31, 2015

Contributor

@SiebelsTim - I've gotten similar feedback before around the $set{} = 2 syntax. It is definitely possible to have $set[] = 2 be treated like $set[2] = 2 for the keyset. One consideration was what if one of these arrays accidentally leaks to code expecting a regular PHP array. If that occurs then we could have operations like $set[] = 2 or $set[$x] = 2 demote the set-like array to a standard PHP array. If we overload these operations based on if the array is set-like then there is slightly more danger in a migration.

But yea it's a solid point to make

Contributor

dlreeves commented Oct 31, 2015

@SiebelsTim - I've gotten similar feedback before around the $set{} = 2 syntax. It is definitely possible to have $set[] = 2 be treated like $set[2] = 2 for the keyset. One consideration was what if one of these arrays accidentally leaks to code expecting a regular PHP array. If that occurs then we could have operations like $set[] = 2 or $set[$x] = 2 demote the set-like array to a standard PHP array. If we overload these operations based on if the array is set-like then there is slightly more danger in a migration.

But yea it's a solid point to make

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment