Initializing an array from sequence or by repeating an element is not implemented

swift

(Marko Havu) #1

Array initializers init<S>(S) and init(repeating: Array.Element, count: Int) don’t seem to be implemented:

  • Array(array[0 ... 3]) gives ‘Parameter should be labeled “of”’
  • [Int](0..<256) gives ‘No overloaded constructor with these parameters for type “Array<Int64!>”, best matching overload is “init(_ sequence: INSFastEnumeration) -> Array<Int64!>!”’, which in turn results in ‘parameter 1 is “Range” should be “INSFastEnumeration”’
  • [UInt8](repeating: 0, count: padding) gives “No matching overload”
  • etc.

(marc hoffman) #2

hmm, I do see

    public init(sequence: ISequence<T>) {

on SwiftArray, in Swift Base Library (https://github.com/remobjects/SwiftBaseLibrary/blob/master/Source/Array.swift). Does that not do what you need? I’ll look at adding init(repeating: count).

Fwiw, contributions to SBL are appreciated :wink:


(marc hoffman) #3

Update:

maybe this just needs to be renamed, to drop the external sequence: name prefix? Ranges should be sequences…


(Marko Havu) #4

Ah yes, that must be it: dropping the prefix should work. Thanks for the GitHub link. You can expect a bunch of pull requests now. :slight_smile:


(marc hoffman) #5

Oddly, I do see a convenience init that takes a sequence, w.o the prefix. weird that that didn’t get used. I;ll need to check more…


(marc hoffman) #6

Excellent!


(Marko Havu) #7

@mh, did you find out what is causing this? It still doesn’t work in Elements 10.0.0.2351. I just set out to implement all the parts I’m missing in SwiftBaseLibrary (including Array.contains), but they are all there. They just don’t work for some reason.


(marc hoffman) #8

My apologies,. this had dropped ff my radar :(. Can you remind me what platform you’re using?


(Marko Havu) #9

No worries. I’m using Toffee (macOS 10.14.2). I will target Island, but not until I can compile with Silver on macOS.


(marc hoffman) #10

Ok, it does look like we have a couple compiler bugs here, what I can reproduce on .NET is:

let x = Array(array[0 ... 3]) // E122 Cannot instantiate abstract class "Array!"

(different/odd error, but definitively wrong)

let z = [UInt8](repeating: 0, count: 5) // E317 No overloaded constructor with these parameters for type "Array<UInt8>"

that one’s also wrong, as the .ctor is there.

I’ll log these two as compiler bugs.

as for the ranges, there are two issues, for one, the name-less .ctor that takes a sequence was not implemented for .NET (fixed); for another, Range does jot current;y implement the ISequence protocol, so it’s not directly compatible with that. I’ll fix this (needs some more work than I can do right this second), but this workaround works:

let s: ISequence<Int64> = (0..<256).GetSequence()
let y1 = [Int](s)

or

let y2 = [Int]((0..<256).GetSequence())

(marc hoffman) #11

On macOS, slightly different results:

let x = Array(array[0 ... 3]) // E46 Unknown identifier "array"

kinda m makes sense now that I look at that closer. what’s that syntax supposed to be, array[0 ... 3]? this one works, instead:

let x = Array(array: [0 ... 3])

The other one

let z = [UInt8](repeating: 0, count: 5) // E317 No overloaded constructor with these parameters for type "Array<UInt8>" // E317 No overloaded constructor with these parameters for type "Swift.Array<Byte!>"

fails the same.


(marc hoffman) #12

Oops. egg on face. that ctor was simply missing a public. fixed.


(Marko Havu) #13

My bad: array was any array longer than four elements here, for example:

let array = [UInt8](0 ..< 8)

(RemObjects) #14

Thanks, logged as bugs://81651 for the Array(array...) issue


(marc hoffman) #15

Ah. checking…


(Marko Havu) #16

Apparently that [UInt8](0 ..< 8) doesn’t compile either (“No matching overload”).


(marc hoffman) #17

that one gives me

let array = [UInt8]()

let x1 = Array(array[0 ... 3]) // E599 Parameter labels do not match. Parameter 1 is unlabeled, but should should be labeled "contentsOfURL" in call to "init(contentsOfURL url: NSURL) -> NSArray<id!>!"
let x2 = Array(array: [0 ... 3])

which seems correct (ignoring that it suggests the wrong overloaded .ctor). the parameter is named, array: should be needed?


(Marko Havu) #18

Xcode does not like this:

let x2 = Array(array: [0 ... 3])

(Array does not have a constructor with named parameter array.) In any case, [0 ... 3] and array[0 ... 3] are sequences, so Array(sequence:) should work in Silver. Swift Base Library also has a convenience init without the prefix, but that doesn’t work yet.


(marc hoffman) #19

The problem is arrays aren’t sequences on Cocoa, since we concerted the Array class to be a struct (on popular request), and structs cannot implement protocols (right now), that’s a platform limitation on Cocoa.

What I’ll do for now is add a name-less .ctor that takes arrays.


(Marko Havu) #20

In Apple’s implementation, neither [0 ... 3] nor array[0 ... 3] is an array. The former is a ClosedRange and the latter is an ArraySlice, both of which are sequences.