Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-09-09 Thread Dave Abrahams via swift-evolution


on Fri Aug 18 2017, Erica Sadun 
 wrote: 

On Aug 17, 2017, at 9:29 PM, Taylor Swift 
 
wrote: 
On Thu, Aug 17, 2017 at 9:06 PM, Erica Sadun via 
swift-evolution 
> 
wrote: 


 
On Aug 17, 2017, at 6:56 PM, Xiaodi Wu 
> 
wrote:  On Thu, Aug 17, 2017 at 7:51 PM, Erica Sadun 
> wrote: 
What people are doing is taking a real set of values (1, 2, 3, 
4, 5, for example), then discarding them via `_ in`, which is 
different from `Void -> T` or `f(x) = 0 * x`. The domain could 
just as easily be (Foo(), "b", , UIColor.red, { x: Int in 
x^x }). There are too many semantic shifts away from "I would 
like to collect the execution of this closure n times" for it 
to sit comfortably.   What arguments might help to alleviate 
this discomfort? Clearly, functions exist that can map this 
delightfully heterogeneous domain to some sort of range that 
the user wants. Would you feel better if we wrote instead the 
following?   ``` repeatElement((), count: 5).map { UIView() } 
``` 
 My favorite solution is the array initializer. Something along 
the lines of `Array(count n: Int, generator: () -> T)`. I'm 
not sure it _quite_ reaches standard library but I think it is 
a solid way to say "produce a collection with a generator run n 
times". It's a common task. I was asking around about this, and 
found that a lot of us who work with both macOS and iOS and 
want to stress test interfaces do this very often. Other use 
cases include "give me n random numbers", "give me n records 
from this database", etc. along similar lines.   The difference 
between this and the current `Array(repeating:count:)` 
initializer is switching the arguments and using a trailing 
closure (or an autoclosure) rather than a set value. That API 
was designed without the possibility that you might want to 
repeat a generator, so there's a bit of linguistic turbulence. 
-- E   To me at least, this is a very i-Centric complaint, 
since I can barely remember the last time I needed something 
like this for anything that didn’t involve UIKit. What you’re 
asking for is API sugar for generating reference types with 
less typing. 


No, that's what the original thread poster wanted. 

I want to avoid breaking math. 


I know it's late to chime in here, but IMO (mutable) reference 
types and the exposure of === “break math,” and I think that's the 
real effect you're seeing here.


--
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-19 Thread Daryle Walker via swift-evolution
> On Aug 17, 2017, at 1:06 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> Also, for those of you here who haven't heard my previous rant on the 
> subject, I dislike using map for generating values that don't depend on 
> transforming a domain to a range. (It has been argued that `_ in` is mapping 
> from `Void`, but I still dislike it immensely)
> 
> Here are the ways that I have approached this:
> 
> // Ugh
> [UIView(), UIView(), UIView(), UIView(), UIView()]

What if we got a duplication “macro”:

[ #dup(5 ; UIView()) ]

It’s not a true macro because it reads the count when “constexpr” objects would 
be evaluated.

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-18 Thread Taylor Swift via swift-evolution
On Fri, Aug 18, 2017 at 1:23 PM, Erica Sadun  wrote:

> I want to avoid breaking math.
>

it’s not that deep,,, the `for _ in 0 ..< n` loop is exactly the same thing
except more verbose. In fact, that’s how your proposed `
Array.init(count:generator:)` would be implemented. But I don’t see anyone
saying we should get rid of the underscore pattern or `@discardableResult`,,
so…
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-18 Thread Erica Sadun via swift-evolution

> On Aug 17, 2017, at 9:29 PM, Taylor Swift  wrote:
> On Thu, Aug 17, 2017 at 9:06 PM, Erica Sadun via swift-evolution 
> > wrote:
> 
>> On Aug 17, 2017, at 6:56 PM, Xiaodi Wu > > wrote:
>> 
>> On Thu, Aug 17, 2017 at 7:51 PM, Erica Sadun > > wrote:
>> What people are doing is taking a real set of values (1, 2, 3, 4, 5, for 
>> example), then discarding them via `_ in`, which is different from `Void -> 
>> T` or `f(x) = 0 * x`. The domain could just as easily be (Foo(), "b", ,  
>> UIColor.red, { x: Int in x^x }). There are too many semantic shifts away 
>> from "I would like to collect the execution of this closure n times" for it 
>> to sit comfortably.
>> 
>> What arguments might help to alleviate this discomfort? Clearly, functions 
>> exist that can map this delightfully heterogeneous domain to some sort of 
>> range that the user wants. Would you feel better if we wrote instead the 
>> following?
>> 
>> ```
>> repeatElement((), count: 5).map { UIView() }
>> ```
> 
> My favorite solution is the array initializer. Something along the lines of 
> `Array(count n: Int, generator: () -> T)`. I'm not sure it _quite_ reaches 
> standard library but I think it is a solid way to say "produce a collection 
> with a generator run n times". It's a common  task. I was asking around about 
> this, and found that a lot of us who work with both macOS and iOS and want to 
> stress test interfaces do this very often. Other use cases include "give me n 
> random numbers", "give me n records from this database", etc. along similar 
> lines.
> 
> The difference between this and the current `Array(repeating:count:)` 
> initializer is switching the arguments and using a trailing closure  (or an 
> autoclosure) rather than a set value. That API was designed without the 
> possibility that you might want to repeat a generator, so there's a bit of 
> linguistic turbulence.
> 
> -- E
> 
> 
> To me at least, this is a very i-Centric complaint, since I can barely 
> remember the last time I needed something like this for anything that didn’t 
> involve UIKit. What you’re asking for is API sugar for generating reference 
> types with less typing. 

No, that's what the original thread poster wanted.

I want to avoid breaking math. For any x passed to a function, I expect f(x) to 
produce the same result. To map is to create a relation so that for every x in 
a domain, there is a single y that it produces. You can hand-wave and say the 
map is "producing" the closure, but it's not. It's executing it and recovering 
a value.

How we get past the `(n ... m).map({ _ in ... })` pattern may be through 
language guidance or through language evolution. Either way, it doesn't make 
this pattern not problematic and worthy of discussion.

Finally, I don't think Swift Evolution _can_ be considered entirely outside the 
auspices of the Apple halo. Look at SE-0005, SE-0006, and SE-0023 for example. 
i-Centricity is inescapable given the core team and the hosting domain for this 
project.

-- E

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Erica Sadun via swift-evolution

> On Aug 17, 2017, at 7:38 PM, Xiaodi Wu  wrote:
> 
> On Thu, Aug 17, 2017 at 8:25 PM, Erica Sadun  > wrote:
> `repeatElement((), count: 5)` is better than `1 ... 5`, but `Count(3).map({ 
> UIView() })` is far more elegant.  I'd still probably go with an array 
> initializer or `5.elements(of: UIView())`. I don't think I'm overstating how 
> common this pattern is, and `Array(repeating:count:)` feels _close_ but not 
> close enough.
> 
> The first two have the benefit of being currently existing APIs;

I'm pretty sure Count isn't an  existing API. And as I said before, while I 
don't think this rises to stdlib inclusion, it's been a common problem domain 
for people both inside and outside Apple so it deserves a full discussion.

That said, `Count` is neat. It encapsulates an idea in a way that I haven't 
seen in Swift. 

-- E


> they capture the semantics perfectly, as I've argued, and I simply don't see 
> how they are impaired in elegance in any way--certainly not enough to justify 
> a standard library addition to create a third way of spelling the same thing. 
> Ultimately, any user is free to define something like:
> 
> ```
> func * (lhs: Int, rhs: @autoclosure () throws -> T) rethrows -> [T] {
>   return try repeatElement((), count: lhs).map { try rhs() }
> }
> 
> 5 * UIView()
> ```
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Xiaodi Wu via swift-evolution
On Thu, Aug 17, 2017 at 8:25 PM, Erica Sadun  wrote:

> `repeatElement((), count: 5)` is better than `1 ... 5`, but
> `Count(3).map({ UIView() })` is far more elegant.  I'd still probably go
> with an array initializer or `5.elements(of: UIView())`. I don't think I'm
> overstating how common this pattern is, and `Array(repeating:count:)` feels
> _close_ but not close enough.
>

The first two have the benefit of being currently existing APIs; they
capture the semantics perfectly, as I've argued, and I simply don't see how
they are impaired in elegance in any way--certainly not enough to justify a
standard library addition to create a third way of spelling the same thing.
Ultimately, any user is free to define something like:

```
func * (lhs: Int, rhs: @autoclosure () throws -> T) rethrows -> [T] {
  return try repeatElement((), count: lhs).map { try rhs() }
}

5 * UIView()
```
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Erica Sadun via swift-evolution
`repeatElement((), count: 5)` is better than `1 ... 5`, but `Count(3).map({ 
UIView() })` is far more elegant.  I'd still probably go with an array 
initializer or `5.elements(of: UIView())`. I don't think I'm overstating how 
common this pattern is, and `Array(repeating:count:)` feels _close_ but not 
close enough.

-- E

> On Aug 17, 2017, at 7:13 PM, Robert Bennett  wrote:
> 
> Xiaodi, you pretty much took the words out of my mouth. I was going to 
> suggest a Count collection whose Element was Void and with the sole 
> initializer init(_ count: Int). The type would just contain its count and 
> pretty much fake its collection interface, in the sense that no elements are 
> actually stored. Then you could do Count(3).map { UIView() }
> 
> On Aug 17, 2017, at 9:06 PM, Erica Sadun via swift-evolution 
> > wrote:
> 
>> 
>>> On Aug 17, 2017, at 6:56 PM, Xiaodi Wu >> > wrote:
>>> 
>>> On Thu, Aug 17, 2017 at 7:51 PM, Erica Sadun >> > wrote:
>>> What people are doing is taking a real set of values (1, 2, 3, 4, 5, for 
>>> example), then discarding them via `_ in`, which is different from `Void -> 
>>> T` or `f(x) = 0 * x`. The domain could just as easily be (Foo(), "b", ,  
>>> UIColor.red, { x: Int in x^x }). There are too many semantic shifts away 
>>> from "I would like to collect the execution of this closure n times" for it 
>>> to sit comfortably.
>>> 
>>> What arguments might help to alleviate this discomfort? Clearly, functions 
>>> exist that can map this delightfully heterogeneous domain to some sort of 
>>> range that the user wants. Would you feel better if we wrote instead the 
>>> following?
>>> 
>>> ```
>>> repeatElement((), count: 5).map { UIView() }
>>> ```
>> 
>> My favorite solution is the array initializer. Something along the lines of 
>> `Array(count n: Int, generator: () -> T)`. I'm not sure it _quite_ 
>> reaches standard library but I think it is a solid way to say "produce a 
>> collection with a generator run n times". It's a common  task. I was asking 
>> around about this, and found that a lot of us who work with both macOS and 
>> iOS and want to stress test interfaces do this very often. Other use cases 
>> include "give me n random numbers", "give me n records from this database", 
>> etc. along similar lines.
>> 
>> The difference between this and the current `Array(repeating:count:)` 
>> initializer is switching the arguments and using a trailing closure  (or an 
>> autoclosure) rather than a set value. That API was designed without the 
>> possibility that you might want to repeat a generator, so there's a bit of 
>> linguistic turbulence.
>> 
>> -- E
>> 
 On Aug 17, 2017, at 3:53 PM, Xiaodi Wu > wrote:
 
 This is, I would argue, much too limiting in the way of semantics and not 
 at all required by “map”. It’s unclear to me how _any_ result with 
 reference semantics or any function with side effects could be used in a 
 way that comports with that definition.
 
 On the other hand, just as y = 0x is a function, { _ in Foo() } is a 
 closure that very much does project from a domain to a range. I’m not sure 
 I understand what wins are to be had by having “collect {}” as a synonym 
 for “map { _ in }”.
 
 On Thu, Aug 17, 2017 at 16:01 Erica Sadun via swift-evolution 
 > wrote:
 
> On Aug 17, 2017, at 12:04 PM, Max Moiseev  > wrote:
> 
> 
>> On Aug 17, 2017, at 10:05 AM, Erica Sadun via swift-evolution 
>> > wrote:
>> 
>> Also, for those of you here who haven't heard my previous rant on the 
>> subject, I dislike using map for generating values that don't depend on 
>> transforming a domain to a range. (It has been argued that `_ in` is 
>> mapping from `Void`, but I still dislike it immensely)
> 
> Can you please elaborate why (or maybe point me at the rant)? 
 
 
 Summary:
 
 . Since this application is a generator and not a transformative function, 
 `map` is a misfit to usage semantics. It breaks the contract that map 
 means to project from a domain to a range via a function. More languages 
 conventionally use `collect` than `map` to collect n applications of a 
 generator closure
 
 -- E
 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
>>> 
>>> 
>> 
>> 

Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Robert Bennett via swift-evolution
Xiaodi, you pretty much took the words out of my mouth. I was going to suggest 
a Count collection whose Element was Void and with the sole initializer init(_ 
count: Int). The type would just contain its count and pretty much fake its 
collection interface, in the sense that no elements are actually stored. Then 
you could do Count(3).map { UIView() }

> On Aug 17, 2017, at 9:06 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> 
>> On Aug 17, 2017, at 6:56 PM, Xiaodi Wu  wrote:
>> 
>>> On Thu, Aug 17, 2017 at 7:51 PM, Erica Sadun  wrote:
>>> What people are doing is taking a real set of values (1, 2, 3, 4, 5, for 
>>> example), then discarding them via `_ in`, which is different from `Void -> 
>>> T` or `f(x) = 0 * x`. The domain could just as easily be (Foo(), "b", ,  
>>> UIColor.red, { x: Int in x^x }). There are too many semantic shifts away 
>>> from "I would like to collect the execution of this closure n times" for it 
>>> to sit comfortably.
>> 
>> What arguments might help to alleviate this discomfort? Clearly, functions 
>> exist that can map this delightfully heterogeneous domain to some sort of 
>> range that the user wants. Would you feel better if we wrote instead the 
>> following?
>> 
>> ```
>> repeatElement((), count: 5).map { UIView() }
>> ```
> 
> My favorite solution is the array initializer. Something along the lines of 
> `Array(count n: Int, generator: () -> T)`. I'm not sure it _quite_ reaches 
> standard library but I think it is a solid way to say "produce a collection 
> with a generator run n times". It's a common  task. I was asking around about 
> this, and found that a lot of us who work with both macOS and iOS and want to 
> stress test interfaces do this very often. Other use cases include "give me n 
> random numbers", "give me n records from this database", etc. along similar 
> lines.
> 
> The difference between this and the current `Array(repeating:count:)` 
> initializer is switching the arguments and using a trailing closure  (or an 
> autoclosure) rather than a set value. That API was designed without the 
> possibility that you might want to repeat a generator, so there's a bit of 
> linguistic turbulence.
> 
> -- E
> 
 On Aug 17, 2017, at 3:53 PM, Xiaodi Wu  wrote:
 
 This is, I would argue, much too limiting in the way of semantics and not 
 at all required by “map”. It’s unclear to me how _any_ result with 
 reference semantics or any function with side effects could be used in a 
 way that comports with that definition.
 
 On the other hand, just as y = 0x is a function, { _ in Foo() } is a 
 closure that very much does project from a domain to a range. I’m not sure 
 I understand what wins are to be had by having “collect {}” as a synonym 
 for “map { _ in }”.
 
 On Thu, Aug 17, 2017 at 16:01 Erica Sadun via swift-evolution 
  wrote:
> 
>>> On Aug 17, 2017, at 12:04 PM, Max Moiseev  wrote:
>>> 
>>> 
>>> On Aug 17, 2017, at 10:05 AM, Erica Sadun via swift-evolution 
>>>  wrote:
>>> 
>>> Also, for those of you here who haven't heard my previous rant on the 
>>> subject, I dislike using map for generating values that don't depend on 
>>> transforming a domain to a range. (It has been argued that `_ in` is 
>>> mapping from `Void`, but I still dislike it immensely)
>> 
>> Can you please elaborate why (or maybe point me at the rant)? 
> 
> 
> Summary:
> 
> . Since this application is a generator and not a transformative 
> function, `map` is a misfit to usage semantics. It breaks the contract 
> that map means to project from a domain to a range via a function. More 
> languages conventionally use `collect` than `map` to collect n 
> applications of a generator closure
> 
> -- E
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Xiaodi Wu via swift-evolution
On Thu, Aug 17, 2017 at 8:06 PM, Erica Sadun  wrote:

>
> On Aug 17, 2017, at 6:56 PM, Xiaodi Wu  wrote:
>
> On Thu, Aug 17, 2017 at 7:51 PM, Erica Sadun  wrote:
>
>> What people are doing is taking a real set of values (1, 2, 3, 4, 5, for
>> example), then discarding them via `_ in`, which is different from `Void ->
>> T` or `f(x) = 0 * x`. The domain could just as easily be (Foo(), "b", ,
>>  UIColor.red, { x: Int in x^x }). There are too many semantic shifts away
>> from "I would like to collect the execution of this closure n times" for it
>> to sit comfortably.
>>
>
> What arguments might help to alleviate this discomfort? Clearly, functions
> exist that can map this delightfully heterogeneous domain to some sort of
> range that the user wants. Would you feel better if we wrote instead the
> following?
>
> ```
> repeatElement((), count: 5).map { UIView() }
> ```
>
>
> My favorite solution is the array initializer. Something along the lines
> of `Array(count n: Int, generator: () -> T)`. I'm not sure it _quite_
> reaches standard library but I think it is a solid way to say "produce a
> collection with a generator run n times". It's a common  task. I was asking
> around about this, and found that a lot of us who work with both macOS and
> iOS and want to stress test interfaces do this very often. Other use cases
> include "give me n random numbers", "give me n records from this database",
> etc. along similar lines.
>
> The difference between this and the current `Array(repeating:count:)`
> initializer is switching the arguments and using a trailing closure  (or an
> autoclosure) rather than a set value. That API was designed without the
> possibility that you might want to repeat a generator, so there's a bit of
> linguistic turbulence.
>

...but, again, why would such an API be superior to `map`, which is already
widely used and clear? My point above was that, if your problem with using
`(0..<5).map { _ in UIView() }` is the discarding of a set of values (which
I argue is semantically unproblematic in the first place, since it's still
mapping from a domain to a range), then `repeatElement((), count: 5).map {
UIView() }` produces the same result without violating your stipulated
semantics.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Erica Sadun via swift-evolution
What people are doing is taking a real set of values (1, 2, 3, 4, 5, for 
example), then discarding them via `_ in`, which is different from `Void -> T` 
or `f(x) = 0 * x`. The domain could just as easily be (Foo(), "b", ,  
UIColor.red, { x: Int in x^x }). There are too many semantic shifts away from 
"I would like to collect the execution of this closure n times" for it to sit 
comfortably.

-- E


> On Aug 17, 2017, at 3:53 PM, Xiaodi Wu  wrote:
> 
> This is, I would argue, much too limiting in the way of semantics and not at 
> all required by “map”. It’s unclear to me how _any_ result with reference 
> semantics or any function with side effects could be used in a way that 
> comports with that definition.
> 
> On the other hand, just as y = 0x is a function, { _ in Foo() } is a closure 
> that very much does project from a domain to a range. I’m not sure I 
> understand what wins are to be had by having “collect {}” as a synonym for 
> “map { _ in }”.
> 
> On Thu, Aug 17, 2017 at 16:01 Erica Sadun via swift-evolution 
> > wrote:
> 
>> On Aug 17, 2017, at 12:04 PM, Max Moiseev > > wrote:
>> 
>> 
>>> On Aug 17, 2017, at 10:05 AM, Erica Sadun via swift-evolution 
>>> > wrote:
>>> 
>>> Also, for those of you here who haven't heard my previous rant on the 
>>> subject, I dislike using map for generating values that don't depend on 
>>> transforming a domain to a range. (It has been argued that `_ in` is 
>>> mapping from `Void`, but I still dislike it immensely)
>> 
>> Can you please elaborate why (or maybe point me at the rant)? 
> 
> 
> Summary:
> 
> . Since this application is a generator and not a transformative function, 
> `map` is a misfit to usage semantics. It breaks the contract that map means 
> to project from a domain to a range via a function. More languages 
> conventionally use `collect` than `map` to collect n applications of a 
> generator closure
> 
> -- E
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Xiaodi Wu via swift-evolution
This is, I would argue, much too limiting in the way of semantics and not
at all required by “map”. It’s unclear to me how _any_ result with
reference semantics or any function with side effects could be used in a
way that comports with that definition.

On the other hand, just as y = 0x is a function, { _ in Foo() } is a
closure that very much does project from a domain to a range. I’m not sure
I understand what wins are to be had by having “collect {}” as a synonym
for “map { _ in }”.

On Thu, Aug 17, 2017 at 16:01 Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Aug 17, 2017, at 12:04 PM, Max Moiseev  wrote:
>
>
> On Aug 17, 2017, at 10:05 AM, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Also, for those of you here who haven't heard my previous rant on the
> subject, I dislike using map for generating values that don't depend on
> transforming a domain to a range. (It has been argued that `_ in` is
> mapping from `Void`, but I still dislike it immensely)
>
>
> Can you please elaborate why (or maybe point me at the rant)?
>
>
>
> Summary:
>
> . Since this application is a generator and not a transformative function,
> `map` is a misfit to usage semantics. It breaks the contract that map means
> to project from a domain to a range via a function. More languages
> conventionally use `collect` than `map` to collect n applications of a
> generator closure
>
> -- E
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Max Moiseev via swift-evolution

> On Aug 17, 2017, at 10:05 AM, Erica Sadun via swift-evolution 
>  wrote:
> 
> Also, for those of you here who haven't heard my previous rant on the 
> subject, I dislike using map for generating values that don't depend on 
> transforming a domain to a range. (It has been argued that `_ in` is mapping 
> from `Void`, but I still dislike it immensely)

Can you please elaborate why (or maybe point me at the rant)? Does the same 
argument apply to `for _ in 1.. [C] {
  var result: [C] = []
  result.reserveCapacity(n)
  for _ in 1...n {
result.append(C())
  }
  return result
}

@inline(never)
func bar(n: Int) -> [C] {
  return (1...n).map { _ in C() }
}

Version using map wins in both the size of sil and performance. It is also 
easier to implement right (fewer moving parts, I guess). If one forgets to call 
`reserveCapacity` on `result` in the first case, performance drops even further.

Max

> 
> Here are the ways that I have approached this:
> 
> // Ugh
> [UIView(), UIView(), UIView(), UIView(), UIView()]
> 
> // No:
> let viewsA = Array(repeating: UIView(), count: 5) 
> // You end up with 5 of the same view
> 
> // Two statements that really should be one
> var views: [UIView] = []
> for _ in 1 ... 5 { views.append(UIView()) }
> 
> // Wrong use of `map`,  because it's mapping over `Void`
> let viewsA = (1 ... 5).map({ _ in UIView() }) 
> 
> // You can introduce `collect` specifically for the `_ in` in case, matching 
> other languages:
> public func collect(_ generator: () throws -> T) rethrows -> [T]
> 
> // I think these are just ugly
> let viewsA__ = sequence(first: UIView(), next: { _ in UIView() 
> }).lazy.prefix(5)
> let viewsB__ = sequence(state: 5, next: { defer { $0 -= 1 }; $0 == 0 ? nil : 
> UIView() }
> 
> // You can build an iterator
> 
> let labeler = AnyIterator({ return UILabel() })
> let labels4 = Array(labeler.prefix(5))
> 
> // which lets you create multiple "slices" off the iterator
> 
> let randoms = AnyIterator({ return Int(arc4random_uniform(100) )})
> 
> print(Array(randoms.prefix(5)))
> print(Array(randoms.prefix(5)))
> 
> 
> // A little complex and I don't like making this `Int` based, because it 
> pulls the semantics away from sequences/collections
> 
> extension Int {
> func of(_ generator: @autoclosure () -> T) -> [T] {
> assert(self >= 0, "cannot generate negative-count collection")
> return (0 ..< self).map({ _ in generator() })
> }
> }
> 
> 5.of(UIView())
> 
> // Even worse
> protocol Constructable {
> init()
> }
> 
> extension UIView: Constructable {}
> 
> extension Int {
> func of(_ generator: @autoclosure () -> T) -> 
> UnfoldSequence {
> assert(self > 0, "cannot generate negative-count collection")
> return sequence(state: self, next: { (state: inout Int) -> T? in
> defer { state -= 1 }; return state == 0 ? nil : T.init() })
> }
> }
> 
> print(Array(5.of(UIView(
> 
> // or
> 
> extension Int {
> func of(_ generator: @escaping @autoclosure () -> T) -> 
> LazyMapRandomAccessCollection<(CountableRange), T> {
> assert(self > 0, "cannot generate negative-count collection")
> return (0 ..< self).lazy.map({ _ in generator() })
> }
> }
> 
> // where some people preferred calling this `elements`, for example 
> `5.elements(of: UIView())`
> 
> // You can go Array:
> 
> extension Array {
> /// Creates a new array containing the specified number of values created 
> by repeating a generating closure.
> ///
> /// - Parameters:
> ///   - count: The number of times to apply the closure. `count` must be 
> zero or greater.
> ///   - generator: The closure to execute
> public init(count: Int, repeating: () -> Element) {
> precondition(count >= 0, "")
> self.init((1 ... count).map({ _ in repeating() }))
> }
> }
> 
> let labels = Array(count: 4) { UILabel() }
> 
> // Or similarly
> 
> extension Array {
> init(repeat count: Int, byCalling generator: @autoclosure () -> Element) {
> self = (1 ... count).map({ _ in generator() })
> }
> }
> 
> // From Oliver H:
> 
> extension Array {
>   convenience init(count: Int, repeating: () -> Elements) {
> self = Array( (0..   }
> }
> 
> let views: [UIView] = Array(count: 5) { UIView(frame: .zero) }
> 
> // This one is from Soroush K. I think it's clever but I wouldn't really use 
> it
> 
> func * (generator: @autoclosure () -> T, n: Int) -> [T] {
>   (0.. }
> 
> UIView() * 5
> 
> 
>> On Aug 17, 2017, at 10:36 AM, Tony Allevato via swift-evolution 
>> > wrote:
>> 
>> 
>> 
>> On Thu, Aug 17, 2017 at 9:20 AM Ross O'Brien > > wrote:
>> (0..<3).map{ _ in UIView() } - map already returns an Array.
>> 
>> Array((0..<3).map{ _ in UIView() }) is redundant.
>> 
>> Ah, right, 

Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Erica Sadun via swift-evolution
Also, for those of you here who haven't heard my previous rant on the subject, 
I dislike using map for generating values that don't depend on transforming a 
domain to a range. (It has been argued that `_ in` is mapping from `Void`, but 
I still dislike it immensely)

Here are the ways that I have approached this:

// Ugh
[UIView(), UIView(), UIView(), UIView(), UIView()]

// No:
let viewsA = Array(repeating: UIView(), count: 5) 
// You end up with 5 of the same view

// Two statements that really should be one
var views: [UIView] = []
for _ in 1 ... 5 { views.append(UIView()) }

// Wrong use of `map`,  because it's mapping over `Void`
let viewsA = (1 ... 5).map({ _ in UIView() }) 

// You can introduce `collect` specifically for the `_ in` in case, matching 
other languages:
public func collect(_ generator: () throws -> T) rethrows -> [T]

// I think these are just ugly
let viewsA__ = sequence(first: UIView(), next: { _ in UIView() }).lazy.prefix(5)
let viewsB__ = sequence(state: 5, next: { defer { $0 -= 1 }; $0 == 0 ? nil : 
UIView() }

// You can build an iterator

let labeler = AnyIterator({ return UILabel() })
let labels4 = Array(labeler.prefix(5))

// which lets you create multiple "slices" off the iterator

let randoms = AnyIterator({ return Int(arc4random_uniform(100) )})

print(Array(randoms.prefix(5)))
print(Array(randoms.prefix(5)))


// A little complex and I don't like making this `Int` based, because it pulls 
the semantics away from sequences/collections

extension Int {
func of(_ generator: @autoclosure () -> T) -> [T] {
assert(self >= 0, "cannot generate negative-count collection")
return (0 ..< self).map({ _ in generator() })
}
}

5.of(UIView())

// Even worse
protocol Constructable {
init()
}

extension UIView: Constructable {}

extension Int {
func of(_ generator: @autoclosure () -> T) -> 
UnfoldSequence {
assert(self > 0, "cannot generate negative-count collection")
return sequence(state: self, next: { (state: inout Int) -> T? in
defer { state -= 1 }; return state == 0 ? nil : T.init() })
}
}

print(Array(5.of(UIView(

// or

extension Int {
func of(_ generator: @escaping @autoclosure () -> T) -> 
LazyMapRandomAccessCollection<(CountableRange), T> {
assert(self > 0, "cannot generate negative-count collection")
return (0 ..< self).lazy.map({ _ in generator() })
}
}

// where some people preferred calling this `elements`, for example 
`5.elements(of: UIView())`

// You can go Array:

extension Array {
/// Creates a new array containing the specified number of values created 
by repeating a generating closure.
///
/// - Parameters:
///   - count: The number of times to apply the closure. `count` must be 
zero or greater.
///   - generator: The closure to execute
public init(count: Int, repeating: () -> Element) {
precondition(count >= 0, "")
self.init((1 ... count).map({ _ in repeating() }))
}
}

let labels = Array(count: 4) { UILabel() }

// Or similarly

extension Array {
init(repeat count: Int, byCalling generator: @autoclosure () -> Element) {
self = (1 ... count).map({ _ in generator() })
}
}

// From Oliver H:

extension Array {
  convenience init(count: Int, repeating: () -> Elements) {
self = Array( (0.. T, n: Int) -> [T] {
  (0.. On Aug 17, 2017, at 10:36 AM, Tony Allevato via swift-evolution 
>  wrote:
> 
> 
> 
> On Thu, Aug 17, 2017 at 9:20 AM Ross O'Brien  > wrote:
> (0..<3).map{ _ in UIView() } - map already returns an Array.
> 
> Array((0..<3).map{ _ in UIView() }) is redundant.
> 
> Ah, right, thanks for pointing that out. I couldn't remember off the top of 
> my head whether it returned an array or some kind of special sequence type 
> that would need to be converted over.
> 
> In that case, I still think the map version wins—it's very clear that a 
> repeated *operation* is occurring, whereas the originally proposed 
> @autoclosure version hides that very important semantic information.
> 
> 
> I've fallen foul before, of trying to create an array of six buttons and 
> getting an array of one button six times; I think that should be easier. But 
> if each button corresponds to an existing value or needs to be initialised 
> based on its index in that array, map transposing values or indices into 
> buttons is already covered.
> 
> On Thu, Aug 17, 2017 at 5:03 PM, Tony Allevato via swift-evolution 
> > wrote:
> Couldn't this be rewritten more simply today as:
> 
> Array((0..<3).map { 

Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Tony Allevato via swift-evolution
On Thu, Aug 17, 2017 at 9:20 AM Ross O'Brien 
wrote:

> (0..<3).map{ _ in UIView() } - map already returns an Array.
>
> Array((0..<3).map{ _ in UIView() }) is redundant.
>

Ah, right, thanks for pointing that out. I couldn't remember off the top of
my head whether it returned an array or some kind of special sequence type
that would need to be converted over.

In that case, I still think the map version wins—it's very clear that a
repeated *operation* is occurring, whereas the originally proposed
@autoclosure version hides that very important semantic information.


I've fallen foul before, of trying to create an array of six buttons and
> getting an array of one button six times; I think that should be easier.
> But if each button corresponds to an existing value or needs to be
> initialised based on its index in that array, map transposing values or
> indices into buttons is already covered.
>
> On Thu, Aug 17, 2017 at 5:03 PM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Couldn't this be rewritten more simply today as:
>>
>> Array((0..<3).map { index in MyView(forIndex: index) })
>>
>> And the version that doesn't need the index could be written:
>>
>> Array((0..<3).map { _ in UIView() })
>>
>> The AnyIterator approach posted above is also nice—I wouldn't have
>> thought of that one. But I suppose that only works in the case where you
>> don't need the index.
>>
>> So the question is, should we increase the API surface of Array for
>> something that (IMO) is already fairly straightforward to do? The nice
>> thing about the approaches above is that they're composable. Array doesn't
>> have to make any assumptions about closures or index arguments to those
>> closures; it just takes a sequence and we already have primitives to
>> construct sequences of new objects using .map. Array(repeating:count:) and
>> repeatedElement(_:count:) are nice when the value being repeated is fixed,
>> but I think once you start getting into questions like "what if I need a
>> different thing each time?" or "what if I need to involve the index as part
>> of the elements?" then it's better suited to compose the features already
>> there to build something up than to add new APIs that try to cover each of
>> these special cases.
>>
>>
>> On Thu, Aug 17, 2017 at 8:40 AM Christopher Kornher via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> We might as well add the index to the call so elements can be created
>>> from other lists, etc.
>>>
>>>  Array(repeatedlyCalling: { (index:Int) in MyView( forIndex:index ) },
>>> count: 3) // This might by syntactically correct...
>>>
>>>
>>>
>>> On Aug 17, 2017, at 9:24 AM, Rob Mayoff via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> On Thu, Aug 17, 2017 at 7:04 AM, Robert Bennett via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 Alternatively, instead of replacing the current definition with an
 autoclosure version, we could leave the current version in place and add a
 version taking a function. This could be especially useful when you’ve
 defined a function like `makeMySpecialKindOfButton() -> UIButton` that does
 a lot of customization to an object before returning it.

 Array(repeating: { return UIView() }, count: 3)
 and
 Array(repeating: makeMySpecialKindOfButton, count: 3)

>>>
>>> This is still source-breaking, because an array of closures is legal. We
>>> need a different name to avoid breaking source:
>>>
>>> Array(repeatedlyCalling: { UIView() }, count: 3)
>>>
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>>
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Ross O'Brien via swift-evolution
(0..<3).map{ _ in UIView() } - map already returns an Array.

Array((0..<3).map{ _ in UIView() }) is redundant.

I've fallen foul before, of trying to create an array of six buttons and
getting an array of one button six times; I think that should be easier.
But if each button corresponds to an existing value or needs to be
initialised based on its index in that array, map transposing values or
indices into buttons is already covered.

On Thu, Aug 17, 2017 at 5:03 PM, Tony Allevato via swift-evolution <
swift-evolution@swift.org> wrote:

> Couldn't this be rewritten more simply today as:
>
> Array((0..<3).map { index in MyView(forIndex: index) })
>
> And the version that doesn't need the index could be written:
>
> Array((0..<3).map { _ in UIView() })
>
> The AnyIterator approach posted above is also nice—I wouldn't have thought
> of that one. But I suppose that only works in the case where you don't need
> the index.
>
> So the question is, should we increase the API surface of Array for
> something that (IMO) is already fairly straightforward to do? The nice
> thing about the approaches above is that they're composable. Array doesn't
> have to make any assumptions about closures or index arguments to those
> closures; it just takes a sequence and we already have primitives to
> construct sequences of new objects using .map. Array(repeating:count:) and
> repeatedElement(_:count:) are nice when the value being repeated is fixed,
> but I think once you start getting into questions like "what if I need a
> different thing each time?" or "what if I need to involve the index as part
> of the elements?" then it's better suited to compose the features already
> there to build something up than to add new APIs that try to cover each of
> these special cases.
>
>
> On Thu, Aug 17, 2017 at 8:40 AM Christopher Kornher via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> We might as well add the index to the call so elements can be created
>> from other lists, etc.
>>
>>  Array(repeatedlyCalling: { (index:Int) in MyView( forIndex:index ) },
>> count: 3) // This might by syntactically correct...
>>
>>
>>
>> On Aug 17, 2017, at 9:24 AM, Rob Mayoff via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> On Thu, Aug 17, 2017 at 7:04 AM, Robert Bennett via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> Alternatively, instead of replacing the current definition with an
>>> autoclosure version, we could leave the current version in place and add a
>>> version taking a function. This could be especially useful when you’ve
>>> defined a function like `makeMySpecialKindOfButton() -> UIButton` that does
>>> a lot of customization to an object before returning it.
>>>
>>> Array(repeating: { return UIView() }, count: 3)
>>> and
>>> Array(repeating: makeMySpecialKindOfButton, count: 3)
>>>
>>
>> This is still source-breaking, because an array of closures is legal. We
>> need a different name to avoid breaking source:
>>
>> Array(repeatedlyCalling: { UIView() }, count: 3)
>>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Tony Allevato via swift-evolution
Couldn't this be rewritten more simply today as:

Array((0..<3).map { index in MyView(forIndex: index) })

And the version that doesn't need the index could be written:

Array((0..<3).map { _ in UIView() })

The AnyIterator approach posted above is also nice—I wouldn't have thought
of that one. But I suppose that only works in the case where you don't need
the index.

So the question is, should we increase the API surface of Array for
something that (IMO) is already fairly straightforward to do? The nice
thing about the approaches above is that they're composable. Array doesn't
have to make any assumptions about closures or index arguments to those
closures; it just takes a sequence and we already have primitives to
construct sequences of new objects using .map. Array(repeating:count:) and
repeatedElement(_:count:) are nice when the value being repeated is fixed,
but I think once you start getting into questions like "what if I need a
different thing each time?" or "what if I need to involve the index as part
of the elements?" then it's better suited to compose the features already
there to build something up than to add new APIs that try to cover each of
these special cases.


On Thu, Aug 17, 2017 at 8:40 AM Christopher Kornher via swift-evolution <
swift-evolution@swift.org> wrote:

> We might as well add the index to the call so elements can be created from
> other lists, etc.
>
>  Array(repeatedlyCalling: { (index:Int) in MyView( forIndex:index ) },
> count: 3) // This might by syntactically correct...
>
>
>
> On Aug 17, 2017, at 9:24 AM, Rob Mayoff via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Thu, Aug 17, 2017 at 7:04 AM, Robert Bennett via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Alternatively, instead of replacing the current definition with an
>> autoclosure version, we could leave the current version in place and add a
>> version taking a function. This could be especially useful when you’ve
>> defined a function like `makeMySpecialKindOfButton() -> UIButton` that does
>> a lot of customization to an object before returning it.
>>
>> Array(repeating: { return UIView() }, count: 3)
>> and
>> Array(repeating: makeMySpecialKindOfButton, count: 3)
>>
>
> This is still source-breaking, because an array of closures is legal. We
> need a different name to avoid breaking source:
>
> Array(repeatedlyCalling: { UIView() }, count: 3)
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Jonathan Hull via swift-evolution
The closure should go on the end though…

> On Aug 17, 2017, at 8:40 AM, Christopher Kornher via swift-evolution 
>  wrote:
> 
> We might as well add the index to the call so elements can be created from 
> other lists, etc.
> 
>  Array(repeatedlyCalling: { (index:Int) in MyView( forIndex:index ) }, count: 
> 3) // This might by syntactically correct...
> 
> 
> 
>> On Aug 17, 2017, at 9:24 AM, Rob Mayoff via swift-evolution 
>> > wrote:
>> 
>> On Thu, Aug 17, 2017 at 7:04 AM, Robert Bennett via swift-evolution 
>> > wrote:
>> Alternatively, instead of replacing the current definition with an 
>> autoclosure version, we could leave the current version in place and add a 
>> version taking a function. This could be especially useful when you’ve 
>> defined a function like `makeMySpecialKindOfButton() -> UIButton` that does 
>> a lot of customization to an object before returning it.
>> 
>> Array(repeating: { return UIView() }, count: 3)
>> and
>> Array(repeating: makeMySpecialKindOfButton, count: 3)
>> 
>> This is still source-breaking, because an array of closures is legal. We 
>> need a different name to avoid breaking source:
>> 
>> Array(repeatedlyCalling: { UIView() }, count: 3)
>>  
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Rintaro Ishizaki via swift-evolution
I don't think it's worthwhile adding new API.
I think this is simple enough:

let views = Array(AnyIterator(UIView.init).prefix(3))

2017-08-17 21:04 GMT+09:00 Robert Bennett via swift-evolution <
swift-evolution@swift.org>:

> Alternatively, instead of replacing the current definition with an
> autoclosure version, we could leave the current version in place and add a
> version taking a function. This could be especially useful when you’ve
> defined a function like `makeMySpecialKindOfButton() -> UIButton` that does
> a lot of customization to an object before returning it.
>
> Array(repeating: { return UIView() }, count: 3)
> and
> Array(repeating: makeMySpecialKindOfButton, count: 3)
>
> On Aug 17, 2017, at 7:54 AM, Haravikk via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On 17 Aug 2017, at 10:38, Adrian Zubarev via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> This is a small pitch which I will abandon if there is not much appetite
> for such improvement. ;)
>
> I would like to propose an improvement to an initializer of all collection
> types that provide: init(repeating repeatedValue: Element, count: Int).
>
> This change is meant to support reference type initialization on each
> iteration of the internal for-loop rather than copying the same references
> n times.
>
> The change would be really straightforward and should not break existing
> code, except that the behavior would change for class types.
>
> Instead of:
>
> init(repeating repeatedValue: Element, count: Int)
>
> let threeViews = Array(repeating: UIView(), count: 3) // contains 1 view 3 
> times
>
> we would have:
>
> init(repeating repeatedValue: @autoclosure () -> Element, count: Int)
>
> This simple change would allow us to construct an array of different
> objects instead of an array with n references to the same object.
>
> let threeViews = Array(repeating: UIView(), count: 3) // contains 3 different 
> view
>
> I don't think that changing the existing initialiser is the way to do
> this, as it's not really clear here that the UIView() will be instantiated
> multiple times rather than the same reference copied multiple times. The
> copying behaviour is in fact desirable as it will be significantly faster,
> especially with very large arrays.
>
> I think the better way to achieve this might be add some closure-based
> sequence that returns a closure's result N times, so we could do something
> like this:
>
> let threeViews = Array(Repeat(count: 3) { return UIView() })
>
> i.e- we would initialise Array from a sequence returning a new UIView
> three times. While we could also do an array initialiser with closure,
> using a separate type is probably the cleaner way to do this.
>
> There is already a Repeater type, but this just does the same as the array
> initialiser already does, could be another type I've missed that might do
> what is needed, otherwise it seems to require types like AnyIterator with
> some counting code.
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Robert Bennett via swift-evolution
Alternatively, instead of replacing the current definition with an autoclosure 
version, we could leave the current version in place and add a version taking a 
function. This could be especially useful when you’ve defined a function like 
`makeMySpecialKindOfButton() -> UIButton` that does a lot of customization to 
an object before returning it.

Array(repeating: { return UIView() }, count: 3)
and
Array(repeating: makeMySpecialKindOfButton, count: 3)

> On Aug 17, 2017, at 7:54 AM, Haravikk via swift-evolution 
>  wrote:
> 
> 
>> On 17 Aug 2017, at 10:38, Adrian Zubarev via swift-evolution 
>>  wrote:
>> 
>> This is a small pitch which I will abandon if there is not much appetite for 
>> such improvement. ;)
>> 
>> I would like to propose an improvement to an initializer of all collection 
>> types that provide: init(repeating repeatedValue: Element, count: Int).
>> 
>> This change is meant to support reference type initialization on each 
>> iteration of the internal for-loop rather than copying the same references n 
>> times.
>> 
>> The change would be really straightforward and should not break existing 
>> code, except that the behavior would change for class types.
>> 
>> Instead of:
>> 
>> init(repeating repeatedValue: Element, count: Int)
>> 
>> let threeViews = Array(repeating: UIView(), count: 3) // contains 1 view 3 
>> times
>> we would have:
>> 
>> init(repeating repeatedValue: @autoclosure () -> Element, count: Int)
>> 
>> This simple change would allow us to construct an array of different objects 
>> instead of an array with n references to the same object.
>> 
>> let threeViews = Array(repeating: UIView(), count: 3) // contains 3 
>> different view
> I don't think that changing the existing initialiser is the way to do this, 
> as it's not really clear here that the UIView() will be instantiated multiple 
> times rather than the same reference copied multiple times. The copying 
> behaviour is in fact desirable as it will be significantly faster, especially 
> with very large arrays.
> 
> I think the better way to achieve this might be add some closure-based 
> sequence that returns a closure's result N times, so we could do something 
> like this:
> 
>   let threeViews = Array(Repeat(count: 3) { return UIView() })
> 
> i.e- we would initialise Array from a sequence returning a new UIView three 
> times. While we could also do an array initialiser with closure, using a 
> separate type is probably the cleaner way to do this.
> 
> There is already a Repeater type, but this just does the same as the array 
> initialiser already does, could be another type I've missed that might do 
> what is needed, otherwise it seems to require types like AnyIterator with 
> some counting code.
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Haravikk via swift-evolution

> On 17 Aug 2017, at 10:38, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> This is a small pitch which I will abandon if there is not much appetite for 
> such improvement. ;)
> 
> I would like to propose an improvement to an initializer of all collection 
> types that provide: init(repeating repeatedValue: Element, count: Int).
> 
> This change is meant to support reference type initialization on each 
> iteration of the internal for-loop rather than copying the same references n 
> times.
> 
> The change would be really straightforward and should not break existing 
> code, except that the behavior would change for class types.
> 
> Instead of:
> 
> init(repeating repeatedValue: Element, count: Int)
> 
> let threeViews = Array(repeating: UIView(), count: 3) // contains 1 view 3 
> times
> we would have:
> 
> init(repeating repeatedValue: @autoclosure () -> Element, count: Int)
> 
> This simple change would allow us to construct an array of different objects 
> instead of an array with n references to the same object.
> 
> let threeViews = Array(repeating: UIView(), count: 3) // contains 3 different 
> view
I don't think that changing the existing initialiser is the way to do this, as 
it's not really clear here that the UIView() will be instantiated multiple 
times rather than the same reference copied multiple times. The copying 
behaviour is in fact desirable as it will be significantly faster, especially 
with very large arrays.

I think the better way to achieve this might be add some closure-based sequence 
that returns a closure's result N times, so we could do something like this:

let threeViews = Array(Repeat(count: 3) { return UIView() })

i.e- we would initialise Array from a sequence returning a new UIView three 
times. While we could also do an array initialiser with closure, using a 
separate type is probably the cleaner way to do this.

There is already a Repeater type, but this just does the same as the array 
initialiser already does, could be another type I've missed that might do what 
is needed, otherwise it seems to require types like AnyIterator with some 
counting code.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Adrian Zubarev via swift-evolution
In terms of functionality yes potentially a breaking change, because the 
behavior would change for objects that were initialized through the passed 
expression.

Personally it always bugged me that it does not work for objects and forced map 
usage over a range to create an array of different objects.
However, this change feels like a fix to the intended behavior, but yes it 
might be very source breaking.


Yet again it’s up to the community to decide if we need this or not. ;)


Am 17. August 2017 um 12:59:06, Xiaodi Wu (xiaodi...@gmail.com) schrieb:

This would be very source-breaking, no?
On Thu, Aug 17, 2017 at 04:47 Jonathan Hull via swift-evolution 
 wrote:
+1

On Aug 17, 2017, at 2:38 AM, Adrian Zubarev via swift-evolution 
 wrote:

This is a small pitch which I will abandon if there is not much appetite for 
such improvement. ;)

I would like to propose an improvement to an initializer of all collection 
types that provide: init(repeating repeatedValue: Element, count: Int).

This change is meant to support reference type initialization on each iteration 
of the internal for-loop rather than copying the same references n times.

The change would be really straightforward and should not break existing code, 
except that the behavior would change for class types.

Instead of:

init(repeating repeatedValue: Element, count: Int)

let threeViews = Array(repeating: UIView(), count: 3) // contains 1 view 3 times
we would have:

init(repeating repeatedValue: @autoclosure () -> Element, count: Int)

This simple change would allow us to construct an array of different objects 
instead of an array with n references to the same object.

let threeViews = Array(repeating: UIView(), count: 3) // contains 3 different 
views




___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Xiaodi Wu via swift-evolution
This would be very source-breaking, no?
On Thu, Aug 17, 2017 at 04:47 Jonathan Hull via swift-evolution <
swift-evolution@swift.org> wrote:

> +1
>
> On Aug 17, 2017, at 2:38 AM, Adrian Zubarev via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> This is a small pitch which I will abandon if there is not much appetite
> for such improvement. ;)
>
> I would like to propose an improvement to an initializer of all collection
> types that provide: init(repeating repeatedValue: Element, count: Int).
>
> This change is meant to support reference type initialization on each
> iteration of the internal for-loop rather than copying the same references
> n times.
>
> The change would be really straightforward and should not break existing
> code, except that the behavior would change for class types.
>
> Instead of:
>
> init(repeating repeatedValue: Element, count: Int)
>
> let threeViews = Array(repeating: UIView(), count: 3) // contains 1 view 3 
> times
>
> we would have:
>
> init(repeating repeatedValue: @autoclosure () -> Element, count: Int)
>
> This simple change would allow us to construct an array of different
> objects instead of an array with n references to the same object.
>
> let threeViews = Array(repeating: UIView(), count: 3) // contains 3 different 
> views
>
>
>
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Jonathan Hull via swift-evolution
+1

> On Aug 17, 2017, at 2:38 AM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> This is a small pitch which I will abandon if there is not much appetite for 
> such improvement. ;)
> 
> I would like to propose an improvement to an initializer of all collection 
> types that provide: init(repeating repeatedValue: Element, count: Int).
> 
> This change is meant to support reference type initialization on each 
> iteration of the internal for-loop rather than copying the same references n 
> times.
> 
> The change would be really straightforward and should not break existing 
> code, except that the behavior would change for class types.
> 
> Instead of:
> 
> init(repeating repeatedValue: Element, count: Int)
> 
> let threeViews = Array(repeating: UIView(), count: 3) // contains 1 view 3 
> times
> we would have:
> 
> init(repeating repeatedValue: @autoclosure () -> Element, count: Int)
> 
> This simple change would allow us to construct an array of different objects 
> instead of an array with n references to the same object.
> 
> let threeViews = Array(repeating: UIView(), count: 3) // contains 3 different 
> views
> 
> 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Adrian Zubarev via swift-evolution
This is a small pitch which I will abandon if there is not much appetite for 
such improvement. ;)

I would like to propose an improvement to an initializer of all collection 
types that provide: init(repeating repeatedValue: Element, count: Int).

This change is meant to support reference type initialization on each iteration 
of the internal for-loop rather than copying the same references n times.

The change would be really straightforward and should not break existing code, 
except that the behavior would change for class types.

Instead of:

init(repeating repeatedValue: Element, count: Int)

let threeViews = Array(repeating: UIView(), count: 3) // contains 1 view 3 times
we would have:

init(repeating repeatedValue: @autoclosure () -> Element, count: Int)

This simple change would allow us to construct an array of different objects 
instead of an array with n references to the same object.

let threeViews = Array(repeating: UIView(), count: 3) // contains 3 different 
views


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution