On Design of Tuples #21
kimmywork
started this conversation in
Ideas, Proposals, RFCs
Replies: 3 comments
-
|
For unit type values, currently just leave it as |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
Tuple literals implemented in #25 |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
Unit literals implemented in #25 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Tuple is just series values with different type grouped together.
There's few convenient things for tuple:
Examples:
Ranges
To support
...(spread overator), we need also add..operator support or consider as an invalid token. Here I am considering adding it as range operator. For example,1..10creates a range between 1 (inclusive) and 10 (exclusive) for all integers.In Ruby,
..considered as an end-inclusive range operator, where...considered as a end-exclusive one,1...10creates a range[1, 2, .., 9]. There's also a feature that using range as unary operator,1..creates an infinite range starting from1. And..10creates a range ends with10.In C#,
..only creates an end-exclusive range, but there's another operator^that creates "from-end" index (Similar to Python/Ruby's negative index). Likesome_array[^2..^0]returns last two elements from the array. "from-end" index also counting from 0, but represents not last element, but the end of the collection (since the operator is exclusive). For example:In C# usually a Range is only used to access collections (using index operator
[]). Not for other things like Pythonrangefunction or Ruby's Range.In Ruby, a range can be either a generative collection. And it's even more flexible than Python's
range. Any type that implements#succmethod and<=>operator (Comparable), can use range operator. (Pythonrangeonly supports integer).But there's another shortage for Ruby's Range comparing to Python. In python you can create an descending order range by specifying the third argument (
step) inrangeas negative value, e.g.range(10, 0, -1)generates a range that counting down from10to0(exclusively). In Ruby you can create such object but not everything works as expected.Compare following two code blocks:
(Python)
(Ruby)
In Rust, Range operator are pretty similar to Ruby, but use different syntax where
..for end-exclusive, and..=for end inclusive.There's no such operator in C++ or JavaScript, but they support
...unpacking. C++ also has a fold expression that utilize...syntax to simplify map / reduce actions on packs (which I think that can be expanded to ranges instead). C# also have a way to unpack range, but they use..syntax instead.Fold
Considering add fold expression in NG like C++ but apply to any Collections.
The spread operator have different meanings depend on which kind of way use it. When used as a prefix, it's unpacking, or introduce a new multiple binding. When used as postfix, it is an operator for mapping / filtering or folding. When it used standalone, it can be treated as variadic function declaration or used in pipeline syntax for mapping / filtering / folding operand.
Case 1. Unpacking / Binding
When binding and applying (unpacking then applying to function) mismatches tuple size and array size, and function arity, raise either index out of bound error, or type checking error. This compliances with function optional parameter's rule, for a function that with default value, e.g.
fun (int, bool, string = default) -> unit, apply a tuple(int, bool)to it passes the type checker.Case 2. Mapping / Folding
Variadic functions
There's another feature that might involve
...syntax. In C, there's variadic function (for exampleprintf), which use...for their variable length function parameters.Here we'll introduce a variadic syntax for native function declarations just now. More about variadic functions will covered in other drafts.
fun print(...) -> unit = native;any length tuple of any types,typeof(...)=> a tuple.fun assert(...assertions: [bool]) -> native;any length vector of bool,typeof(assertions)=> a vector of boolTo allow tuple type level operations, we may also need following operators on types:
typeof(<expression>)get type of an expression<tuple>.sizeget arguments length of a tuple<tuple>[<n>]get n-th element type of a tuple typefun (<types>) -> <type>a function type.fun <tuple-type> -> typeNew added syntax and features
Stage 1
(<values>)(<types>)<tuple>.size,<tuple>.<n>, and<tuple>[<n>], and<tuple>.<n> := <value><tuple>[a..b]ranged index will be covered in stage 3...<tuple>or[...vector]valbindings,val (<a>, <b>: <type>) = <tuple>;return (<values>)<fnName>(...<argName>)Stage 2
typeof(<expression>)get type of an expression<tuple>.sizeget arguments length of a tuple<tuple>.<n>get n-th element type of a tuple type(<types>) -> <type>a function type.<tuple-type> -> typeStage 3
a..b,a..^b,^a..^b, (end exclusive) and..a,a..syntax.<fnName>(...<tuple>)arr[a..b],arr[^a][a..b]Stage 4
<fn>(<collection>)...<pred>(collection)?...<fn>(<collection>..., <init>)<fn>(<init>, <collection>...)<fn>(<collection>..., _), Here_used as a place holder thatfnwill take first element in<collection>as<init>.<fn_a>(<fn_b>(<collection>)..., <init>)or[<fn>(<collection>)...]. or[<fn_a>(<fn_b>(<collection>)...)...]<collection> |> <map_fn>(...) |> <filter_fn>(?...) |> fold_fn(..., <init>)Beta Was this translation helpful? Give feedback.
All reactions