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
Doctor w-rw-rw-
Jun 24, 2008

Moogs posted:

Really, really new to programming (some HTML, JavaScript, CSS, but no real languages) guy here, jumping headfirst into Swift. Surely this is a stupid question, but I'm running the below code from Chapter 1 of the book in a playground (which is a neat thing!) -- why does largeKind need to be optional to not have the console throw errors?

code:
let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25],
]
interestingNumbers["Prime"]

var largest = 0
var largeKind: String?
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
            largeKind = kind
        }
    }
}
largest
largeKind


Because there's no initial value, and String isn't nullable.

Adbot
ADBOT LOVES YOU

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
More specifically, the compiler can't prove that the loop will definitely assign to largeKind. It turns out that it does because there's at least one entry in interestingNumbers whose value contains at least one positive number (and in fact, all the entries contain only positive numbers), but you can't really expect the compiler to prove all that for you just to know that it's safe to use largeKind. So it conservatively expects you to assign it yourself.

I would advise a more advanced programmer to use String! here to encode the assumption that the variable will be assigned before use. For a novice, though, I think it's better to stick with String? so that you can see what's going on more explicitly.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Choadmaster posted:

Looking at an example from the book of unwrapping an optional combined with a switch statement, it seems to me like a case that could easily be simplified:

Right, this is definitely something we want to do.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
edit: wrong thread, I was looking for the general apple thread.

Simulated fucked around with this message at 21:26 on Jun 14, 2014

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
Can we make properties in Swift atomic by default?



:suicide: actually let's not.

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

pokeyman posted:

Can we make properties in Swift atomic by default?



:suicide: actually let's not.


That's not funny. :v:

Choadmaster
Oct 7, 2004

I don't care how snug they fit, you're nuts!
I take it there's not any way to reset/invalidate a lazy property, is there?

Take for example a class that represents a file on disk. It might have some straightforward properties for path, file name, modification date, etc. It might also have a lazy property for checksum, since that may be expensive to calculate. That's all straightforward. But if the file gets modified, it is necessary to throw out the old checksum.

One could recalculate the checksum and replace the old value, but that's wasteful in cases where the checksum isn't actually needed again. It'd be better to invalidate the old value somehow such that it will only be calculated if requested again.

In Objective C it would be as simple as resetting the ivar back to whatever flag was initially used to signify the value wasn't calculated yet (usually nil). In Swift, it would be nice if there was something built in to lazy properties to accomplish the same thing.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Choadmaster posted:

I take it there's not any way to reset/invalidate a lazy property, is there?

No. You can file a bug, though. I suspect we'll say it's not worth complicating the feature over, though, since I actually cannot think of any natural way of resetting it like that.

Gul Banana
Nov 28, 2003

code:
import Foundation

class Lazy<T> {
    let _queue: dispatch_queue_t
    let _factory: () -> T
    let _read_or_reset: dispatch_semaphore_t
    var _box: T[] //XXX this should be an optional, not an array, but a compiler bug prevents it
    
    init(valueFactory: ()->T) {
        _queue = dispatch_queue_create("lazy", nil)
        _factory = valueFactory
        _read_or_reset = dispatch_semaphore_create(0)
        _box = T[]()
        
        reset()
    }
    
    func reset() {
        dispatch_async(_queue) {
            dispatch_semaphore_wait(self._read_or_reset, DISPATCH_TIME_FOREVER)
            
            self._box = T[]()
            self._box.append(self._factory())
            
            dispatch_semaphore_signal(self._read_or_reset)
        }
    }
    
    var value: T {
        dispatch_semaphore_signal(self._read_or_reset)
    
        dispatch_sync(_queue) {}
        
        dispatch_semaphore_wait(self._read_or_reset, DISPATCH_TIME_FOREVER)

        return _box[0]
    }
}
a test program:
code:
var count = 0

let msg = Lazy<String> {
    count++
    return "initialiser run \(count) times"
}

println(msg.value)
println(msg.value)

msg.reset()

println(msg.value)
println(msg.value)
i had to work around a few compiler bugs while writing this:
- classes can't have a variable size layout (some IRgen issue)
- generic types can't contain static/class variables
- dispatch_once doesn't seem to correctly infer the types of its arguments

ljw1004
Jan 18, 2005

rum
I'm struggling to make sense of named parameters. The online docs (and also the book, page 208) give this example code:

https://developer.apple.com/library...97-CH10-XID_213

code:
func halfOpenRangeLength(start: Int, end: Int) -> Int {
    return end - start
}
println(halfOpenRangeLength(1, 10))
// prints "9"
When I type it in, it gives an error saying that my call site failed to specify the name of the second argument, and suggests the fix of invoking "halfOpenRangeLength(1, end: 10)"

I think the current behavior seems to be, "Your call site MUST omit the name of the first argument unless it was specified explicitly in the formal parameter list using "#" or "externalName internalName" syntax. And your call site MUST include the name of all subsequent arguments."

dizzywhip
Dec 23, 2005

What's the best way to iterate over all of the values in an enum? Ideally I'd like to be able to do something like for value in MyEnum { ... }. Is there anything like that in Swift, or is it at least something that's planned for the future?

eschaton
Mar 7, 2007

Don't you just hate when you wind up in a store with people who are in a socioeconomic class that is pretty obviously about two levels lower than your own?

ljw1004 posted:

I'm struggling to make sense of named parameters. The online docs (and also the book, page 208) give this example code:

https://developer.apple.com/library...97-CH10-XID_213

code:

func halfOpenRangeLength(start: Int, end: Int) -> Int {
    return end - start
}
println(halfOpenRangeLength(1, 10))
// prints "9"

When I type it in, it gives an error saying that my call site failed to specify the name of the second argument, and suggests the fix of invoking "halfOpenRangeLength(1, end: 10)"

Did you add this as a free function or as a method within a class? Free functions omit all parameter names by default, while methods within a class omit only the first parameter name.

This is effectively like ObjC where a free function is just a C function, and a method in a class always has its name interspersed with the parameters.

Choadmaster
Oct 7, 2004

I don't care how snug they fit, you're nuts!

Gul Banana posted:

a test program

This is a neat workaround, but creating a new instance of a class with four ivars (heh... properties) for every lazy-loaded property seems a bit heavyweight.


eschaton posted:

Did you add this as a free function or as a method within a class? Free functions omit all parameter names by default, while methods within a class omit only the first parameter name.

Swift uses the "func" keyword for both functions *and* methods, I assume for consistency, but then goes on to give them different behaviors. This I do not like.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

dizzywhip posted:

What's the best way to iterate over all of the values in an enum? Ideally I'd like to be able to do something like for value in MyEnum { ... }. Is there anything like that in Swift, or is it at least something that's planned for the future?

Vaguely planned. I'll add this to the OP, it keeps coming up.

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer
So it seems like there's no Swift changes in this XCode beta, right? Do you have any picture of how changes to the language will be advertised, even if it's just XCode change logs?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Choadmaster posted:

This is a neat workaround, but creating a new instance of a class with four ivars (heh... properties) for every lazy-loaded property seems a bit heavyweight.

I'll mention your use case to people, and you can reinforce it with a bug, but ultimately, the language can't support every possible extension in its convenience features. Eventually, I'd like us to have some ability to meta-program this with user-defined attributes. In the meantime, your pattern can be implemented quite easily with a private optional stored property and a public computed property that adds the laziness.

Choadmaster posted:

Swift uses the "func" keyword for both functions *and* methods, I assume for consistency, but then goes on to give them different behaviors. This I do not like.

It's something I think several of us want to revisit because of exactly this inconsistency. We'll see. This is the general sort of thing we had in mind when we decided to not promise source compatibility yet.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

ultramiraculous posted:

So it seems like there's no Swift changes in this XCode beta, right? Do you have any picture of how changes to the language will be advertised, even if it's just XCode change logs?

Release notes, I think. But yes, this update is just a few major bugfixes back-ported to the WWDC branch.

Choadmaster
Oct 7, 2004

I don't care how snug they fit, you're nuts!

rjmccall posted:

I'll mention your use case to people, and you can reinforce it with a bug, but ultimately, the language can't support every possible extension in its convenience features.

Thanks. I was just hoping it wouldmbe something as simple as resetting a flag you used to indicate a lazy property but if it is (not surprisingly) far more complex than I imagine, thats the way the cookie crumbles.

ultramiraculous, there was one Swift change noted in the Xcode release notes. I dont recall it off the top of my head but it was a bug fix iirc.

Gul Banana
Nov 28, 2003

sadly, just resetting a flag is not thread-safe - particularly if the calculated T doesn't fit in a CASable word

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Well, @lazy isn't thread-safe, either, although the lazy initialization of globals is. The complexity is all in the language design here.

Gul Banana
Nov 28, 2003

whoa, that is a caveat you might want to document - the book does not mention it

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer

rjmccall posted:

Well, @lazy isn't thread-safe, either, although the lazy initialization of globals is.

Woah what. Why is it not thread safe in both cases? It seems like either situation is a place where you'd do a dispatch_once if you were doing it yourself.

Choadmaster
Oct 7, 2004

I don't care how snug they fit, you're nuts!
Thread safety is expensive. I've rarely ensured it in my own lazy-loaded properties unless necessary. I'd make a joke about making atomic properties the default but Ender.uNF would be displeased.

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer

Choadmaster posted:

Thread safety is expensive. I've rarely ensured it in my own lazy-loaded properties unless necessary. I'd make a joke about making atomic properties the default but Ender.uNF would be displeased.

Lazily calculating a property isn't quite as bad as making everything atomic though. An @lazy variable is presumably initialize-once, use-everywhere deal, which mean it's only atomic on the front end/first retrieval. After the value is calculated, dispatch_once is basically a conditional and a return from there on out.

I mean the case in the book, if I recall, is that you have some sort of expensive child that might have to be initialized. If Thread 1 and Thread 2 both try to use that resource around the same time, should it initialize once for each thread? What if that resource has state associated with it?

Gul Banana
Nov 28, 2003

yeah, and my Lazy<T> implementation above uses a semaphore check which does not spin if the sempahore is already signalled. after the first init it's basically Just A Branch. i don't think that's too high a cost for making avoiding a situation where *reading* an otherwise-immutable property can be unsafe, something you'd never have to worry about with unlazy values.

Plorkyeran
Mar 22, 2007

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

ultramiraculous posted:

Woah what. Why is it not thread safe in both cases? It seems like either situation is a place where you'd do a dispatch_once if you were doing it yourself.

dispatch_once_t has to be static (dispatch_once does clever things to avoid the need for synchronization that aren't guaranteed to work if the memory address was ever non-zero), so dispatch_once doesn't really work for member variables.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
We'll provide some way to opt in to thread-safety, but yes, basically the same arguments apply here as with atomic properties. Your objects are almost certainly not designed to be arbitrarily accessed from multiple threads, and going property-by-property is rarely the right way to try to establish safety. @lazy raises the additional question of whether the initializer itself is safe to perform on an arbitrary thread.

And Plorkyeran is right: you should not be using dispatch_once with an ivar token, and @lazy will probably have to do something more expensive on ARM/ARM64. (Not as expensive as actually taking a lock, though.)

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
Mike Ash wrote up an in-depth article recently about the tricks dispatch_once uses.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...
I keep banging my head into this Xcode bug where suddenly it will decide that my target might include its own product for every project I build. Even ones which previously built fine.

Is there at least a reliable workaround? I hit it again and I don't remember what I did to fix it last time.

If I could find a way to get out of this state I could see what was getting me into it.

ed: To be clear, I'm getting this as the entirety of my build output:

code:
Check dependencies

Unable to run command 'CompileSwift normal' - this target might include its own product.
Unable to run command 'Ditto AdultQuest-Swift.h' - this target might include its own product.
Unable to run command 'Ld AdultQuest' - this target might include its own product.
Unable to run command 'Ditto x86_64.swiftmodule' - this target might include its own product.
Unable to run command 'GenerateDSYMFile AdultQuest.app.dSYM' - this target might include its own product.
Unable to run command 'CopySwiftLibs AdultQuest.app' - this target might include its own product.
Unable to run command 'Touch AdultQuest.app' - this target might include its own product.
I get this even when I check out a known-good state that used to build fine.

edit 2: While my Simulator 5s and device targets are broken, my 5 simulator is not, and I was able to get to a buildable state. I then found several issues with Core Data that I'm firing off some radars for now.

The swift-conversion branch of my project is in a perpetually broken state. New features written in Swift work great, though!

Dessert Rose fucked around with this message at 06:26 on Jun 19, 2014

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

Choadmaster posted:

Thread safety is expensive. I've rarely ensured it in my own lazy-loaded properties unless necessary. I'd make a joke about making atomic properties the default but Ender.uNF would be displeased.

I sneak into the Apple campus at night and commit subtle bugs to the repo. SKProductRequest's misuse of weak references? My handiwork. Don't gently caress with me.

lies

eschaton
Mar 7, 2007

Don't you just hate when you wind up in a store with people who are in a socioeconomic class that is pretty obviously about two levels lower than your own?

Dessert Rose posted:

I keep banging my head into this Xcode bug where suddenly it will decide that my target might include its own product for every project I build. Even ones which previously built fine.

Is there at least a reliable workaround? I hit it again and I don't remember what I did to fix it last time.

Do you have something like your app's Info.plist also included in a Copy Bundle Resources build phase? That's often the culprit, typically the result of clicking the "please make this a member of my target" checkbox.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

eschaton posted:

Do you have something like your app's Info.plist also included in a Copy Bundle Resources build phase? That's often the culprit, typically the result of clicking the "please make this a member of my target" checkbox.

No, I've checked my build phases six times. It also only affects a couple of compile targets (5s simulator and my device (a 5s, coincidentally)) so I don't know what it could be.

PleasureKevin
Jan 2, 2011

should this not print in the playground?

println("Hello, world")

EDIT: View > Assistant Editor > Show Assistant Editor

PleasureKevin fucked around with this message at 20:08 on Jun 20, 2014

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

PleasureKevin posted:

should this not print in the playground?

println("Hello, world")

Choadmaster
Oct 7, 2004

I don't care how snug they fit, you're nuts!
I haven't gotten around to installing Xcode 6 yet so forgive the simple question, but while we're on the subject... is there a way to get a line from standard input in the playground? (Presumably using NSFileHandle since there is no readln() function [yet].)

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
How would reading from stdin work with the whole continuous evaluation thing? If it just reads one time then it's pointless, and if it reads every time the expression is evaluated it'd be unusable.

glykose
May 9, 2009
@rjmccall do you have any thoughts on optimizing tail calls in Swift? I have searched high and low, but haven't been able to find the slightest mention of it. I am really unsure if it would fit in a language like Swift, but still wonder if you have discussed it and have an opinion on it.

The rationale behind supporting it, in my mind, is promoting an even more functional style of programming with recursion instead of loops.

Choadmaster
Oct 7, 2004

I don't care how snug they fit, you're nuts!

Plorkyeran posted:

How would reading from stdin work with the whole continuous evaluation thing? If it just reads one time then it's pointless, and if it reads every time the expression is evaluated it'd be unusable.

I haven't played with it or even seen the WWDC vids on it yet so I have no idea how it works, but I was imagining it just reading one time (I was imagining just pasting a chunk of code in there and running it, I guess). I'll have to find some time to play with it this weekend so I don't ask stupid questions!

Choadmaster fucked around with this message at 23:19 on Jun 20, 2014

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

glykose posted:

@rjmccall do you have any thoughts on optimizing tail calls in Swift? I have searched high and low, but haven't been able to find the slightest mention of it. I am really unsure if it would fit in a language like Swift, but still wonder if you have discussed it and have an opinion on it.

The rationale behind supporting it, in my mind, is promoting an even more functional style of programming with recursion instead of loops.

I have three immediate thoughts here.

The first is that I don't think we'd ever go so far as to guarantee that all calls in tail position will actually be emitted as tail calls. There a lot of reasons for this, but the most important one is that it's simply extremely difficult to actually make that guarantee in a non-GC environment, because so many functions end up having implicit clean-up work to do before returning, and it's not necessarily either easy or safe to hoist that work before the tail call. So it would be tricky to produce a model where users felt they could rely on implicit tail calls.

The second is intimately related. Whether or not a tail call is used is sometimes very important. Typically, when something is very important, it's good to let the code be more explicit about it. So I could imagine adding an explicit "use a tail-call here, please" annotation, and we would guarantee to either honor it or report failure (e.g. if it's not actually in a tail position, or if the implementation model cannot possibly support a tail call there). However, that would not lead to particularly attractive functional-style recursive code.

The last is that I, personally, am not even slightly interested in promoting deeply-recursive programming, because it almost certainly means that you're using some sort of terrible data structure, like a singly-linked list or a binary search tree, just because it has a nice recursive form. (And yes, I am aware that there are occasional uses for both, as well as that immutable data structures have a number of nice concurrency advantages.)

Adbot
ADBOT LOVES YOU

Gul Banana
Nov 28, 2003

https://devforums.apple.com/message/989944#989944
arrays are being given consistent semantics, i'm very happy to see this change

  • Locked thread