You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Given a type/enum Foo, there should be some mechanism for denoting "static" fields on that type/enum. A "static" field in this context is essentially a global variable which is namespaced to that type/enum, for example, consider the prelude type Map<K, V>:
type Map<K, V> {
size: Int
_entries: MapEntry<K, V>?[] = []
_capacity: Int = 16
_loadFactor: Float = 0.75
func new<K, V>(initialCapacity = 16): Map<K, V> {
// Find a power of 2 >= initialCapacity, if non-default value provided
val capacity = if initialCapacity != 16 {
initialCapacity.nextPowerOf2()
} else {
initialCapacity
}
...
}
...
}
The default values for the _capacity and _loadFactor fields are supplied in those fields' _initializer_s, but the initialCapacity parameter's default value in the new "static" method is a magic number (which is also referenced once again within the function body itself).
This value could be extracted out into a variable outside of the type definition, such as
val MAP_DEFAULT_INITIAL_CAPACITY = 16
but that allows that value to leak out into a scope broader than the scope in which it's intended to be used (ie. just within the Map scope).
Other languages have a notion of "static" values, as in global values which are namespaced within the scope of the type itself. Accessing the default initial capacity if it were defined as a "static"/namespaced variable would look like Map.defaultInitialCapacity (if it were indeed exposed as a public value). These other languages typically use a modifier keyword like static to describe this. Using this, the above would look something like:
type Map<K, V> {
size: Int
_entries: MapEntry<K, V>?[] = []
_capacity: Int = 16
_loadFactor: Float = 0.75
static defaultInitialCapacity: Int = 16
func new<K, V>(initialCapacity = Self.defaultInitialCapacity): Map<K, V> {
// Find a power of 2 >= initialCapacity, if non-default value provided
val capacity = if initialCapacity != Self.defaultInitialCapacity {
initialCapacity.nextPowerOf2()
} else {
initialCapacity
}
...
}
...
}
Note: This uses the Self.<identifier> syntax which is proposed in #497
Note though that this introduces the static keyword, which has previously been omitted - what other languages would call "static methods" are just implemented in Abra as ordinary methods on a type/enum just without the self parameter. So introducing static just for this purpose feels odd. Not to mention that the meaning of "static" differs across programming languages, so it might make more sense to use something that feels a bit more ergonomic.
Since a "static" value is just an ordinary variable, we could leverage the existing val/var variable declaration syntax:
type Map<K, V> {
size: Int
_entries: MapEntry<K, V>?[] = []
_capacity: Int = 16
_loadFactor: Float = 0.75
val defaultInitialCapacity: Int = 16
...
}
This also had the added benefit of representing the reassignability of the static value (which can also be referred to as "type variables", a new category of variable alongside "top-level variables", "local variables", and "instance variables").
Within the type/enum declaration, it must come after field declarations but may be interspersed between method declarations within the scope. It also must have an initializer (much like other variable declarations) and must also have a type annotation (much like other field declarations). Like type methods (static methods), generics are not accessible within a type variable's type annotation.
The text was updated successfully, but these errors were encountered:
Given a type/enum
Foo
, there should be some mechanism for denoting "static" fields on that type/enum. A "static" field in this context is essentially a global variable which is namespaced to that type/enum, for example, consider the prelude typeMap<K, V>
:The default values for the
_capacity
and_loadFactor
fields are supplied in those fields' _initializer_s, but theinitialCapacity
parameter's default value in thenew
"static" method is a magic number (which is also referenced once again within the function body itself).This value could be extracted out into a variable outside of the type definition, such as
but that allows that value to leak out into a scope broader than the scope in which it's intended to be used (ie. just within the
Map
scope).Other languages have a notion of "static" values, as in global values which are namespaced within the scope of the type itself. Accessing the default initial capacity if it were defined as a "static"/namespaced variable would look like
Map.defaultInitialCapacity
(if it were indeed exposed as a public value). These other languages typically use a modifier keyword likestatic
to describe this. Using this, the above would look something like:Note: This uses the
Self.<identifier>
syntax which is proposed in #497Note though that this introduces the
static
keyword, which has previously been omitted - what other languages would call "static methods" are just implemented in Abra as ordinary methods on a type/enum just without theself
parameter. So introducingstatic
just for this purpose feels odd. Not to mention that the meaning of "static" differs across programming languages, so it might make more sense to use something that feels a bit more ergonomic.Since a "static" value is just an ordinary variable, we could leverage the existing
val
/var
variable declaration syntax:This also had the added benefit of representing the reassignability of the static value (which can also be referred to as "type variables", a new category of variable alongside "top-level variables", "local variables", and "instance variables").
Within the type/enum declaration, it must come after field declarations but may be interspersed between method declarations within the scope. It also must have an initializer (much like other variable declarations) and must also have a type annotation (much like other field declarations). Like type methods (static methods), generics are not accessible within a type variable's type annotation.
The text was updated successfully, but these errors were encountered: