fslang-suggestions
fslang-suggestions copied to clipboard
Deprecate places where `seq` can be omitted e.g. `{ 1.. 5 }`
I propose we make this consistent:
let f = Seq.head
let a = f { 1..6 }
let b = f { 1; 2 } // error FS0740: Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq { ... }'
Now we don't have to allocate entire lists or arrays just to make sets.
let a = set { 1..6 }
let b = set { 1; 2 } // error FS0740: Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq { ... }'
The existing way of approaching this problem in F# is
let a = set { 1..6 }
let b = set (seq { 1; 2 })
Pros and Cons
The advantages of making this adjustment to F# are
- Consistency
- Convenience
- Less allocation
The disadvantage of making this adjustment to F# is that this may cause confusion as set here isn't a computation expression. However, syntax can be quickly learnt.
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S
Related suggestions: (put links to related suggestions here)
Affidavit (please submit!)
Please tick this by placing a cross in the box:
- [x] This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
- [x] I have searched both open and closed suggestions on this site and believe this is not a duplicate
- [x] This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.
Please tick all that apply:
- [x] This is not a breaking change to the F# language design
- [x] I or my company would be willing to help implement and/or test this
For Readers
If you would like to see this issue implemented, please click the :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.
Too much of a special case. If seq { 1..6 } requires the seq then set(seq { 1..6 }) should require the seq.
I believe you misunderstood the request. In both seq { 1..6 } and set(seq { 1..6 }), the seq is already optional today. The request is that seq also be optional for { 1;2 } as well.
Also worth noting that { 1..6 } and seq { 1..6 } does not produce the same code, as the former creates Operators.OperatorIntrinsics.RangeInt32(1, 1, 6) while the latter creates Operators.CreateSequence(Operators.OperatorIntrinsics.RangeInt32(1, 1, 6)).
Oh, { 1 .. 6 } produces a range. That is interesting actually.
I think I like this, since it's pretty confusing that you don't need to do seq { x..y } but you need to do seq { x; y }. Since we can't remove the ability to do { x..y } I'd be in favor of this provided there isn't a breaking change.
Since we can't remove the ability to do { x..y } I'd be in favor of this provided there isn't a breaking change.
TBH I think I'd rather force the addition of seq through a warning or informational message.
There are three cases
{ x .. y }{ 1; 2 }{ if true then yield 1 }and other computations
Only (1) allows you to omit seq today. This case snuck through in F# 2.0 and should really have always requried a seq.
However I do like that set and other future collection construction operations can omit the seq without making those full computation expressions. That is, if the seq is being immediately consumed eagerly into a collection construction then I'm happy to omit it. However we have no specific way of telling if that's the case
The reasons I like seq are
- the laziness is made obvious
- it makes things distinct from object expressions and record expressions
- it introduces people to computation expressions.
As an aside (really a different issue) we should consider a .. b in computation expressions more generally - currently these are only allowed in sequence, list, array expressions.