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

Reply via email to