Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
dizzywhip
Dec 23, 2005

I think I finally hit Xcode's breaking point. I can edit code for a few seconds before it crashes, locks up for minutes/indefinitely, or Source Kit Services errors out over and over. Hopefully the next update brings some significant stability improvements. I was still enjoying it even when it was barely usable though, I'm super excited to start transitioning over to Swift full-time for 1.0.

Adbot
ADBOT LOVES YOU

Glimm
Jul 27, 2005

Time is only gonna pass you by

I think I've run into a Swift issue but I'm not sure if it is just me missing something.

This works:
code:

    init(dictionary: [String: AnyObject]) {

        if let startDate: AnyObject = dictionary["startDate"]? {
            if let startDateString = startDate as? String {
                ...
            }
        }
    ...
    }
but this fails to compile, with this error:
Type 'DictionaryIndex<String, AnyObject>' does not conform to protocol 'StringLiteralConvertible'

code:
    init(dictionary: [String: AnyObject]) {

        if let startDate = dictionary["startDate"]? as? String {
           ...
        }
     ...
     }
It seems to me like they should be doing the same thing. Should I be filing a radar?

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

dizzywhip posted:

I think I finally hit Xcode's breaking point. I can edit code for a few seconds before it crashes, locks up for minutes/indefinitely, or Source Kit Services errors out over and over. Hopefully the next update brings some significant stability improvements. I was still enjoying it even when it was barely usable though, I'm super excited to start transitioning over to Swift full-time for 1.0.

If certain constructs are present in the code, any partially typed out statement, unmatched braces, half-complete type name, etc will trigger a SourceKit crash for me. I just ignore them; I have a log directory of hundreds (maybe thousands now) of crash reports.

dizzywhip
Dec 23, 2005

Ender.uNF posted:

If certain constructs are present in the code, any partially typed out statement, unmatched braces, half-complete type name, etc will trigger a SourceKit crash for me. I just ignore them; I have a log directory of hundreds (maybe thousands now) of crash reports.

Hmm, there's probably something like that somewhere in my code, but it'd be pretty tough for me to track down at this point. Maybe if I had been smart and made more incremental commits. It's just for a little side project though, so I don't mind waiting for the next beta.

Axiem
Oct 19, 2005

I want to leave my mind blank, but I'm terrified of what will happen if I do
I had a weird thing happen today. I have a part of my code that owns an enum that's used to keep track of its state. A couple of the states have associated values (because that's a really awesome feature of the enums), and I've set it up to conform to Equatable so that I can do some XCTAssertEquals on them.

This evening, I added a new case to that enum, to represent a new state that I was creating. But when I went to do an XCTAssertEquals, I suddenly get an EXC_BAD_ACCESS at memory address 0x8 when I try to access Enum.NewCase. Switching it to any of the old cases works (in that it doesn't through the bad access exception).

I poked at it for a while, and by adding a few more cases to the enum, I started getting the bad access exceptions (at various memory addresses that were all even and under 0x20) even on the cases that had been working. It tests, it was when trying to access Enum.NewCase. In the code, I could also get it to explode when just doing a switch on the variable that holds an enum. I could not, however, find any rhyme or reason as to when it would explode, except that it was consistent within a set (and particular ordering) of cases in the enum; when I changed that, it changed what broke where.

I did, slightly earlier in the day, attempt to create a recursive enum, which it didn't like, and I've since completely killed DerivedData just in case something weird with that was hanging around.

I'm kind of at my wit's end trying to figure out what I'm failing to implement. Could it be that I'm failing to account for the new case somewhere? Could it just be that the error is erroneous and something else is going wrong? Or could this be a real Swift bug for me to file?




* Yes, yes, I know, there's supposedly a better way to do state machines in functional code. I don't know how to do it, and plan on learning sometime in the future. Right now I just want to get my code to work procedurally.

Axiem fucked around with this message at 06:06 on Jul 17, 2014

Axiem
Oct 19, 2005

I want to leave my mind blank, but I'm terrified of what will happen if I do
Sorry for the double-post, but it has been several days. Now, to change topics entirely.

As I understand it, the @objc attribute makes something available to Objective-C in the same project. Is there a particular reason why protocols need to be @obj in order to define optional methods?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Axiem posted:

Sorry for the double-post, but it has been several days. Now, to change topics entirely.

As I understand it, the @objc attribute makes something available to Objective-C in the same project. Is there a particular reason why protocols need to be @obj in order to define optional methods?

@objc protocols are implemented via Objective-C message sends, so optional methods are easy to do with just conformsToProtocol/respondsToSelector checks. There's an obvious way to implement this for Swift native protocols, but we just haven't done it yet.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



rjmccall posted:

@objc protocols are implemented via Objective-C message sends, so optional methods are easy to do with just conformsToProtocol/respondsToSelector checks. There's an obvious way to implement this for Swift native protocols, but we just haven't done it yet.

something like @objc in the future being an alias for "messagable"?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
That's basically the current design. We're currently trying to figure out how much we want that to imply in terms of crazy ObjC runtime shenanigans.

Axiem
Oct 19, 2005

I want to leave my mind blank, but I'm terrified of what will happen if I do

rjmccall posted:

@objc protocols are implemented via Objective-C message sends, so optional methods are easy to do with just conformsToProtocol/respondsToSelector checks. There's an obvious way to implement this for Swift native protocols, but we just haven't done it yet.

That makes sense. It's just annoying because I have a protocol that I'd like to both have optional methods and also conform (be a sub-protocol of?) Equatable, and those appear to be mutually exclusive. I can survive, though, and just keep a bunch of empty methods around for now.

Would it be worth filing a radar for optionals in non-@objc protocols, or is that the sort of thing y'all have on your board and don't need me to waste your time with?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Axiem posted:

That makes sense. It's just annoying because I have a protocol that I'd like to both have optional methods and also conform (be a sub-protocol of?) Equatable, and those appear to be mutually exclusive. I can survive, though, and just keep a bunch of empty methods around for now.

Would it be worth filing a radar for optionals in non-@objc protocols, or is that the sort of thing y'all have on your board and don't need me to waste your time with?

You can track it more easily with a radar, maybe, but it's definitely already on our board.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
rjmccall - is there a sanctioned way to cast a C struct? e.g. sockaddr which is treated kinda like a union with sockaddr_in, sockaddr_in6, etc. Other than the verbotten function we've previously discussed, I couldn't find a way to convince swift that an UnsafePointer<sockaddr> is really an UnsafePointer<sockaddr_in>. edit: Answered my own question, it's UnsafePointer<sockaddr_in>(pointerToSockaddr) which just casts the pointer types.


2. What's the difference between UnsafePointer's dealloc and destroy?

3. In idiomatic Swift, for a buffer to receive some data like char or Int8, I'm using UnsafePointer.alloc, but I saw an ArrayBuffer class and one can always use an array itself. Is there a simple preferred way to say "make me a UTF8 character buffer X bytes long"? Or is it mostly dealer's choice?

Simulated fucked around with this message at 22:13 on Jul 19, 2014

ljw1004
Jan 18, 2005

rum
I'm trying to wrap my head around "structs+enums as value-types". This code currently crashes Swift so I can't yet experiment...

code:
enum IntList {
    case Tail
    case Head(Int, IntList)

    mutating func append(tail:IntList)
    {
        switch self {
            case .Tail: self = tail
            case .Head(let i, var r): r.append(tail); self = .Head(i, r)
        }
    }
}
But apparently the crash is just due to a bug, and the code will be allowed (link). But if so then it completely blows my mind about what a structure is! What would sizeof(IntList) even return?


edit: some more examples that currently crash and I don't know if they'll be allowed:

code:
struct S {
   var x : S
}

struct S {
   var x : S?
}

ljw1004 fucked around with this message at 20:03 on Jul 20, 2014

ljw1004
Jan 18, 2005

rum
I'm struggling with string interpolation...

The Swift language reference says The [interpolated] expression must evaluate to a value of a type that the String class has an initializer for.. But elsewhere it gives an example that relies on the type implementing the Printable protocol.

The only way I can reconcile this is if the String class had an input initializer which takes in a printable. But it doesn't. Instead, from what I can tell,

(1) String interpolation never uses a String class initializer

(2) If the value's static type implements the Printable protocol, then interpolation uses Printable.description. If not, then interpolation synthesizes a kind of low-level debug string representation.

(3) The playground, presumably as a bug, ignores the Printable protocol, and always synthesizes the debug representation of the type.

Axiem
Oct 19, 2005

I want to leave my mind blank, but I'm terrified of what will happen if I do
I have noticed that there is also a DebugPrintable protocol, though I haven't entirely figured out where it decides which protocol to use. And it doesn't appear to me as though say, XCTAssert* functions use either of them, either.

ljw1004
Jan 18, 2005

rum
I'm really perplexed by "typealias" in Protocols, and the ways they're different from an interface's generic type parameters in C#. Here's an experiment to attempt protocol covariance:

code:
protocol MyProtocol1 {
    typealias T
    func f() -> T
}

class MyClass1 : MyProtocol1 {
    func f() -> Int {return 1}
}

func cov<P:MyProtocol1 where P.T == Any>(x:P) {
    let s:Any = x.f()
}

let c = MyClass1()
cov(c)
Basically I've created MyProtocol1<T>, and I made a concrete instantiation of it MyProtocol1<Int>, and I passed it to a function which takes a MyProtocol1<Any>.

Is this safe? Well, it is type safe in this case because MyProtocol1<T> only ever uses T in an output position. But you'd only expect this to type check in a language that has co/contravariance, which Swift lacks, so you'd expect it to fail to compile. However, it does type check, and it builds okay. It just crashes at runtime when trying to invoke x.f().

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Axiem posted:

I have noticed that there is also a DebugPrintable protocol, though I haven't entirely figured out where it decides which protocol to use. And it doesn't appear to me as though say, XCTAssert* functions use either of them, either.
Just from the name my guess would be that it's used for po in lldb.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Ender.uNF posted:

2. What's the difference between UnsafePointer's dealloc and destroy?

operator delete(ptr) vs. ptr->~T().

Ender.uNF posted:

3. In idiomatic Swift, for a buffer to receive some data like char or Int8, I'm using UnsafePointer.alloc, but I saw an ArrayBuffer class and one can always use an array itself. Is there a simple preferred way to say "make me a UTF8 character buffer X bytes long"? Or is it mostly dealer's choice?

I don't think we have a preferred idiom for this right now. UnsafePointer.alloc is fine.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

ljw1004 posted:

I'm trying to wrap my head around "structs+enums as value-types". This code currently crashes Swift so I can't yet experiment...

But apparently the crash is just due to a bug, and the code will be allowed (link). But if so then it completely blows my mind about what a structure is! What would sizeof(IntList) even return?

Recursive enums can be implemented by making the recursive positions pointers, or by making the value representation itself a pointer, or any number of other tricks. This is easy to do while preserving value semantics because we don't actually provide any way to mutate enum payloads in-place. We'll probably do it by (1) providing an attribute that makes the value representation pointer-ish and (2) inferring that for obviously recursive enums. The virtue of inferring it is that it reduces the boilerplate required to express standard recursive/functional data structures; the virtue of not inferring it is that the implementation model becomes more obvious, which is important in a systems-y language where you want programmers to be able to reason about basic memory behavior without having to trawl through compiler output. So we'll see.

ljw1004 posted:

edit: some more examples that currently crash and I don't know if they'll be allowed:

code:

struct S {
   var x : S
}

struct S {
   var x : S?
}

The former is literally impossible to ever construct (in a non-lazy language). The second is theoretically possible, but I think it's probably a better language decision to forbid it in favor of preserving the obvious implementation model for structs.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

ljw1004 posted:

I'm struggling with string interpolation...

The Swift language reference says The [interpolated] expression must evaluate to a value of a type that the String class has an initializer for.. But elsewhere it gives an example that relies on the type implementing the Printable protocol.

I think the former is a bug in the documentation. String interpolation uses a somewhat magic function that uses a Printable conformance if it exists and otherwise falls back on some built-in logic.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

ljw1004 posted:

Is this safe? Well, it is type safe in this case because MyProtocol1<T> only ever uses T in an output position. But you'd only expect this to type check in a language that has co/contravariance, which Swift lacks, so you'd expect it to fail to compile. However, it does type check, and it builds okay. It just crashes at runtime when trying to invoke x.f().

That should really not type-check; please report that.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Beta 4's out with some awesome changes. I'm very happy about internal being the default access modifier and private being private to the implementation file rather than class. I'm also very happy to see String trying to actually do the right thing by default with unicode and CGFloat being less awful.

ljw1004
Jan 18, 2005

rum
@lazy -- the language guide says that a lazy property is not calculated "until the first time it is used".

It looks like this isn't threadsafe... if one thread reads the lazy property for the first time and starts calculating it, and meanwhile a second starts reading the lazy property as well, then the second thread will also kick off a calculation as well:

code:
var numLazies = UnsafePointer<Int64>.alloc(1)
func side() -> Int64 {OSAtomicIncrement64(numLazies); sleep(1); return 1}
class C { @lazy var x = side()}
var the_c = C()

@objc class EntryPointClass {
    func entryPoint() { let x1 = the_c.x }
}

var thread1 = NSThread(target: EntryPointClass(), selector: "entryPoint", object:nil)
var thread2 = NSThread(target: EntryPointClass(), selector: "entryPoint", object:nil)
thread1.start()
thread2.start()
sleep(10)
println("Count=\(numObjects.memory) Sides=\(numLazies.memory)")
// Count=1 Sides=2
Even if you make the calculation as quick as possible, it looks like you can't get rid of the race condition:

code:
var numObjects = UnsafePointer<Int64>.alloc(1)
var numLazies = UnsafePointer<Int64>.alloc(1)

func side() -> Int64 {OSAtomicIncrement64(numLazies); return 1}

class C {
    init() {OSAtomicIncrement64(numObjects)}
    @lazy var x = side()
}

var the_c = C()

@objc class EntryPointClass {
    func entryPoint() {
        for i in 1...1000 {
            the_c = C()
            let x1 = the_c.x
            let x2 = the_c.x
        }
    }
}

var thread1 = NSThread(target: EntryPointClass(), selector: "entryPoint", object:nil)
var thread2 = NSThread(target: EntryPointClass(), selector: "entryPoint", object:nil)
thread1.start()
thread2.start()
sleep(10)
println("Count=\(numObjects.memory) Sides=\(numLazies.memory)")
// Count=2001 Sides=2025...2050 on multiple repeated runs
I guess we have to be careful that either our lazy property initializers are idempotent, or that we never invoke them from more than one thread.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

ljw1004 posted:

Even if you make the calculation as quick as possible, it looks like you can't get rid of the race condition:

Not to take away from the rest of your post but this excerpt is inevitable if something is to be called a race condition.

dizzywhip
Dec 23, 2005

Plorkyeran posted:

Beta 4's out with some awesome changes. I'm very happy about internal being the default access modifier and private being private to the implementation file rather than class. I'm also very happy to see String trying to actually do the right thing by default with unicode and CGFloat being less awful.

I'm super happy about the private(set) access modifier, I was really hoping for something like that.

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer

dizzywhip posted:

I'm super happy about the private(set) access modifier, I was really hoping for something like that.

Yeah, it like it. Seems like a nice improvement over all the private category extensions I've written over the years.

lord funk
Feb 16, 2004

dizzywhip posted:

I'm super happy about the private(set) access modifier, I was really hoping for something like that.

Can you quick explain this? I'm falling behind in my Swift blog reading / version updates.

Speaking of, which blogs are you all reading?

dizzywhip
Dec 23, 2005

It makes it so that a property can be read from anywhere in the module, but can only be written to from within the same file.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
internal and private(set) are amazing proof that Swift is being written by people who actually write software and aren't just masturbating to PL theory :allears:

(Nothing wrong with masturbating to PL theory; I frequently do it myself. But it's nice to see some truly practical concepts make it into the language too.)

Toady
Jan 12, 2009

Swift is cool.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
Urgh, I just upgraded to beta 4 and it made me sad: I have an app that has a couple custom keyboard extensions, written in Swift. Since both custom keyboards share a lot of common UI code, I also created a Swift framework target in the project that the other targets depend on. This framework references some Obj-C code brought in from various Cocoapods — I have a bridging header that includes those.

This all worked fine in beta 3, but now I get the following error:

code:
<unknown>:0: error: using bridging headers with framework targets is unsupported
Command /Applications/Xcode6-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 1
:(

I'm surprised that it's explicitly unsupported now when it seemed to work fine before. Are there any other options that don't involve just linking the shared code statically into each of the targets?

ljw1004
Jan 18, 2005

rum
Swift doesn't seem to be doing curried functions right (using beta4). The language reference says that these two are equivalent:

code:
func addTwoNumbers1(a:Int)(b:Int) -> Int { return a+b }

func addTwoNumbers2(a:Int) -> (Int->Int) {
    func addTheSecondNumber(b:Int) -> Int { return a+b }
    return addTheSecondNumber
}
However, the first one turns into an external parameter name "b", while the second doesn't:

code:
addTwoNumbers1(3)(b:5)
addTwoNumbers2(3)(5)

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Yeah, that's probably not the right rule for external parameter names in curried positions; they should probably just be ignored. Mind filing a bug?

ljw1004
Jan 18, 2005

rum

rjmccall posted:

Mind filing a bug?

rjmcall, I really appreciate all your posts in this thread. I haven't yet figured out how to use radar, but I'll do that tonight or tomorrow night and file all the bugs I've posted here so far. Am still completely new to Apple development.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

ljw1004 posted:

rjmcall, I really appreciate all your posts in this thread. I haven't yet figured out how to use radar, but I'll do that tonight or tomorrow night and file all the bugs I've posted here so far. Am still completely new to Apple development.

On bugreport.apple.com login and create a new bug (using the now modern iOS 6 UI! At least it isn't original Aqua). Select Developer Tools (it's the Xcode 6 icon).

Much of the stuff it asks about is completely arbitrary because there is no option for "Xcode" vs "Swift compiler" vs "Playgrounds" vs whatever else. It all just goes in the dev tools bucket.

I usually put Swift: in my subject. Down below in the configuration I just put "Xcode 6 Beta X".

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

lord funk posted:

Can you quick explain this? I'm falling behind in my Swift blog reading / version updates.

Speaking of, which blogs are you all reading?


http://www.weheartswift.com/one-month-swift/ has a bunch of links

Obviously https://developer.apple.com/swift/blog/ is a good one to watch

http://andelf.github.io always posts interesting stuff but I have to read it through Bing translate because he mostly posts in Chinese. He's got some posts with dumps of the swift standard library and his github page is my secret sauce for poking at the internals.

Mike Ash is covering Swift topics now https://www.mikeash.com/pyblog/

And Brent Simmons does some too http://inessential.com

David Owens II has some great stuff https://medium.com/@owensd/latest


And there's mine :v:

ljw1004
Jan 18, 2005

rum
The main Swift feature which I hope don't make it into the final release is this:

Optional<T> implements LogicValue protocol

This feature means you can write things like
code:
let x : Foo? = Foo()
if x { x!.f() }

let y : Bool? = false
if y { println("didn't expect this did you!") }
The first example "x" is deadly if x happens to be a weak reference. That's because x might become nil after the check "x" but before the forced unwrapping "x!". (there are other cases where this might happen, of course, but I reckon that weak references will be the biggest source of bugs). The better way of writing it "if let x2 = x { x2.f() }" is fine, and you should be pushing users harder into this safe-by-default idiom.

The second example is confusing as heck. The language guide even has a few paragraphs describing how confusing it is. It ends up giving the same behavior as SQL (which is confusing) and as Visual Basic (where it is a huge source of bugs).

Both examples are hard to read. I can't understand what they mean without having to stop and stare and squint. They're easy to trip me up.

rjmcall Please remove this feature, and instead implement a method ".HasValue" on Optional<T>. That way we can write code that's easy to read:

code:
if x.HasValue {...}

if y.HasValue {...}
Edit: I guess the feature is present for the benefit of C folks who are used to writing "if (pointer) {...}". I understand that, but it just seems like the benefit of catering to them is outweighed by the harm.

ljw1004 fucked around with this message at 18:41 on Jul 23, 2014

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

ljw1004 posted:


rjmcall Please remove this feature, and instead implement a method ".HasValue" on Optional<T>. That way we can write code that's easy to read:

code:
if x.HasValue {...}

if y.HasValue {...}

I implemented these extensions for similar reasons and the fact that 9/10 times I just want to provide an alternate value, I don't really care if it is nil.

code:
extension Optional {
    func valueOrDefault(defaultValue:@auto_closure ()->T) -> T {
        return apply(self!, defaultValue())
    }
    
    var hasValue: Bool {
    get { return apply(true, false) }
    }
    
    private func apply<U>(caseSome:@auto_closure ()->U, _ caseNone:@auto_closure ()->U) -> U {
        switch(self) {
        case .Some:
            return caseSome()
        case .None:
            return caseNone()
        }
    }
}

var s:String? = nil
let s2 = s.valueOrDefault("alt")

if s.hasValue {
    println("Has value!")
}
This guy also provides an operator to perform a similar function as C#'s "??":

code:
operator infix ||| {}

@infix func |||<T> (left: T?, right: T) -> T  {
    if let l = left { return l }
    return right
}

@infix func |||<T,V> (left: T?, right: V) -> Any  {
    if let l = left { return l }
    return right
}

Simulated fucked around with this message at 18:36 on Jul 23, 2014

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
rdar://17782662 filed to add the ability to export a module's internal members to another specified module. This makes unit tests on internal members much easier and allows two modules by the same developer to cooperate as if they were the same module, but without making that part of the public API.

See also: http://www.russbishop.net/swift-testing-privates

Adbot
ADBOT LOVES YOU

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
I'm not sure if .HasValue even makes all that much sense. I can't think of any situations where you'd want to check if an optional has a value but not do anything with that value if it exists that aren't insane or dumb. I don't find the optional bool scenario all that confusing, but I definitely don't think that if x { ... x! ... } is something that the language should be encouraging when it has a much better construct for that.

  • Locked thread