fslang-suggestions icon indicating copy to clipboard operation
fslang-suggestions copied to clipboard

Deprecate places where `seq` can be omitted e.g. `{ 1.. 5 }`

Open Happypig375 opened this issue 4 years ago • 19 comments

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

  1. Consistency
  2. Convenience
  3. 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.

Happypig375 avatar Jun 15 '21 08:06 Happypig375

Too much of a special case. If seq { 1..6 } requires the seq then set(seq { 1..6 }) should require the seq.

charlesroddie avatar Jun 15 '21 08:06 charlesroddie

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

TheJayMann avatar Jun 15 '21 12:06 TheJayMann

Oh, { 1 .. 6 } produces a range. That is interesting actually.

Happypig375 avatar Jun 15 '21 12:06 Happypig375

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.

cartermp avatar Jun 15 '21 15:06 cartermp

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

  1. { x .. y }
  2. { 1; 2 }
  3. { 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

  1. the laziness is made obvious
  2. it makes things distinct from object expressions and record expressions
  3. 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.

dsyme avatar Jun 15 '21 17:06 dsyme