On Sat, Jan 2, 2016, at 12:13 PM, Brent Royal-Gordon wrote:
> > Why should we absolutely add methods with unclear meanings or behavior,
> > when there are already perfectly clear, if verbose, alternatives?
> > seq.generate().next() may not be nice, but no one can get fooled by it.
>
> Well, for one thing, because it doesn't work. You can't call a mutating
> method directly on a return value without assigning it to a variable first.
> And put simply, a temporary variable seems a bridge too far to me.
Exactly. If `seq.generate().next()` worked, I'd be perfectly happy with that.
I'd be tempted to submit a proposal saying this should be legal, but I believe
that disallowing mutating methods on temporaries is an intentional decision
that was intended to prevent the user from writing code that looks like it's
mutating something that it isn't.
For example, given the following interface:
struct Foo {
var ary: [Int] { get }
}
Allowing mutating of temporaries would let me write code like
func foo(x: Foo) -> Int? {
return x.ary.popLast()
}
and yet this won't actually mutate the array at all (and it will incur an
unwanted copy of the array storage that is immediately thrown away).
We could try and come up with some workaround, like maybe an attribute on
`mutating func next()` that says "this may be called on a temporary", but it
seems kind of hacky. And I can't think of anything other than
`GeneratorType.next` that actually wants this behavior anyway (the closest
alternative I can think of is passing a scalar as an UnsafePointer or
UnsafeMutablePointer to a C function where you don't actually care about the
output, where in C you can actually say something like `&(int){42}` if you
want, but I haven't actually hit that case in Swift yet and it's pretty rare
anyway).
Incidentally, the same rule is also what prohibits arrays from being passed to
an inout parameter where a downcast is required. Arrays implicitly downcast as
needed to simulate covariance on its element type, e.g. if U <: T then [U] can
be used where a [T] is expected because an implicit downcasted copy is made.
But you cannot pass a [U] to a function that expects an inout [T] because
temporaries are immutable (and implicit array conversion produces a temporary).
-Kevin Ballard
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution