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
Axiem
Oct 19, 2005

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

pokeyman posted:

This doesn't really have much to do with Swift, though. We can take it to the Apple dev thread.

On this note, my presumption is that sooner or later (probably when Xcode 6 is formally released), the Swift thread is going to be merged into the Apple dev thread, since a large portion of it is API calls, which are (effectively) the same between languages.

Also, playgrounds are a fantastic way to show off the language to my co-workers, because I can just type some quick code and it shows it live updating. It's kind of nice to feel script-like, instead of having a heavyweight application around to do stuff in.

I'm compiling my list of Radars to file. When I get a chance this weekend, I'll pull code together for them and do a dump. Sorry it's taking me so long.

Adbot
ADBOT LOVES YOU

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
We'll see! If I feel like the thread has outlived its usefulness in a few months, I'll definitely just close it.

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

rjmccall posted:

It makes the associated type functionally dependent on the principal type. With Sequence<T>, it is theoretically sensible for a type to conform to both Sequence<Int> and Sequence<Float>. That's rarely useful, and it makes the type system far more complicated.

That's not to say that we couldn't do something like that as sugar, though.

I'm starting to wish I had protocol<T> (or at least could specify that an associated type is a generic type) because jumping through the hoops necessary to make protocols compose with just associated types is a bit maddening. That might be my failure to understand and/or apply them properly though.

This doesn't work (obviously):
code:
protocol Monadic {
    typealias A
    typealias B
    typealias Amplified
    
    func Bind(a:Amplified<A>, f:(A)->Amplified<B>) -> Amplified<B>
}
I can't see how I can define a protocol such that a generic method taking some type T must take or return values of protocol<T>. In C# I would do this:

code:
interface IIdentity<T> { }
interface IButts<A,B> {
  IIdentity<B> DoIt(IIdentity<A> a, Func<A, IIdentity<B>> b);
}
I can't figure out how to express that in Swift.

Simulated fucked around with this message at 05:28 on Jun 10, 2014

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
I have spent an amusing amount of time talking about making a monad protocol recently.

I don't understand how your C# example works. It looks to me like it both (1) shouldn't type-check because you're not applying the same number of arguments consistently to your protocol and (2) erases the concrete monad type across bind.

Monad is an example of a higher-kinded protocol: the thing that conforms to the protocol is not a type, it's a type function (generally, an unapplied generic type). That's feasible to add as a feature, but seeing as, frankly, the only use I've ever seen for that even in Haskell is Monad, it is not something we are going to fall over ourselves rushing into the language.

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

rjmccall posted:

I have spent an amusing amount of time talking about making a monad protocol recently.

I don't understand how your C# example works. It looks to me like it both (1) shouldn't type-check because you're not applying the same number of arguments consistently to your protocol and (2) erases the concrete monad type across bind.

Monad is an example of a higher-kinded protocol: the thing that conforms to the protocol is not a type, it's a type function (generally, an unapplied generic type). That's feasible to add as a feature, but seeing as, frankly, the only use I've ever seen for that even in Haskell is Monad, it is not something we are going to fall over ourselves rushing into the language.

Sorry, I messed it up. That's what I get for not firing up my VM first. I fixed my previous post.

Anyway Bind in C# is actually an extension method (SelectMany) so I think I see where I need to go now and it makes far more sense. I got distracted trying to model it with a protocol when it doesn't belong there to begin with.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Oh, another question rjmccall:

Is there an underlying type I can use to represent a closure or is typealias the only way to get out of a labyrinth of parens?

For that matter, do you know if/when we will see documentation of the Swift standard library? I'm using unofficial sources out on the net right now. There are a lot more types and protocols than are listed in the official reference.

Third question: What happens when I need a huge Dictionary? Isn't that going to run out of stack space? Would the current suggestion be to create an NSDictionary if we want one on the heap?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Ender.uNF posted:

Is there an underlying type I can use to represent a closure or is typealias the only way to get out of a labyrinth of parens?

You mean, if you need to write a higher-order function type, and it's not just curried so you can't take advantage of the right-associativity of ->, is there a way to write the function type as something like Function<Int, Void> instead of having to parenthesize (Int -> Void)? Not right now, sorry.

Ender.uNF posted:

For that matter, do you know if/when we will see documentation of the Swift standard library? I'm using unofficial sources out on the net right now. There are a lot more types and protocols than are listed in the official reference.

I think it's being worked on.

Note that anything starting with an underscore is logically private and will be actually private when we implement access control.

Ender.uNF posted:

Third question: What happens when I need a huge Dictionary? Isn't that going to run out of stack space? Would the current suggestion be to create an NSDictionary if we want one on the heap?

Dictionaries don't actually store data on the stack. It's like a C++ type: the Dictionary value itself is just a small, fixed-size "header" which owns a reference to data stored on the heap, and the type maintains the abstraction that different Dictionary values have independent collections of values and keys.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Common themes in #swift-lang:

How do I get the length of a string?

Why isn't Swift perfect? Four years is far longer than Apple should need to create a programming language.

Why does Swift make it so hard to just use AnyObject everywhere?

Swift is just like Objective C + X, where X is a language that has very little in common with Swift.

I want to learn Swift but I don't own any Apple products.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...
More adventures in Core Data interop:

If I pass a string to an ObjC method from Swift, and use that string as the name of a Core Data entity, it looks up the NSEntityDescription fine on the simulator, but fails on the device.

That is, the following code:

code:

let foo = Bar("Entity") as NSEntityDescription

(ObjC)
code:

+ NSEntityDescription Bar(NSString *name) {
return [NSEntityDescription entityForName:name inContext:context];
}

On the simulator, this returns an NSEntityDescription for the name. On the device, this returns nil.

I worked around it by passing the string from inside an ObjC method, but it's still some twilight zone stuff.

Edit: in the debugger, I looked: it is filling *name with something that looks to my eyes like "Entity", it even compares with an NSString constructed by the debugger properly... But it doesn't match the key in the entitiesByName dictionary in my object model.

Dessert Rose fucked around with this message at 19:45 on Jun 10, 2014

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Thank you for overflow checking. Punks will bitch about the performance impact, but they are wrong and you are right and you should feel good.

It's too bad that Rust wasn't appropriate for you to get involved with 3 years ago; it would definitely have helped converge it usefully, but I understand the low probability of Apple telegraphing a major platform shift that far ahead.

Surprised that the playground stuff doesn't do whole-program parsing and then execution. Seems like you end up losing a lot of utility of copying working code into a playground can make it be not-working code. Is it for performance reasons or just wanting to make later-on syntax errors less disruptive?

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

rjmccall posted:

I have spent an amusing amount of time talking about making a monad protocol recently.

I don't understand how your C# example works. It looks to me like it both (1) shouldn't type-check because you're not applying the same number of arguments consistently to your protocol and (2) erases the concrete monad type across bind.

Monad is an example of a higher-kinded protocol: the thing that conforms to the protocol is not a type, it's a type function (generally, an unapplied generic type). That's feasible to add as a feature, but seeing as, frankly, the only use I've ever seen for that even in Haskell is Monad, it is not something we are going to fall over ourselves rushing into the language.

Monad, functor,applicative are foundational for the neat abstractions you get. Having parser combinators is pretty great.

And then you can do stuff like ghc.generics, free monads, uniplate and all the stuff that makes life easier when dealing with regular old polymorphism.

F# is stuck because the clr can't deal with it iirc

It would make a lot of sense, especially if you already elaborate into a language that supports it. Mostly for library authors.

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

rjmccall posted:

You mean, if you need to write a higher-order function type, and it's not just curried so you can't take advantage of the right-associativity of ->, is there a way to write the function type as something like Function<Int, Void> instead of having to parenthesize (Int -> Void)? Not right now, sorry.

You know at first I thought "WTF is he talking about?"

Then I opened the book in iBooks and did a search for "curry" and there it is on page 768: Curried functions and methods.

This makes me very happy.



quote:

Dictionaries don't actually store data on the stack. It's like a C++ type: the Dictionary value itself is just a small, fixed-size "header" which owns a reference to data stored on the heap, and the type maintains the abstraction that different Dictionary values have independent collections of values and keys.

I'm sure this is just my confusion but this section from the guide seemed to imply that if the keys or values are structs they will be stack allocated, but that was my incorrect assumption.

quote:

Whenever you assign a Dictionary instance to a constant or variable, or pass a Dictionary instance as an argument to a function or method call, the dictionary is copied at the point that the assignment or call takes place. This process is described in Structures and Enumerations Are Value Types.

If the keys and/or values stored in the Dictionary instance are value types (structures or enumerations), they too are copied when the assignment or call takes place. Conversely, if the keys and/or values are reference types (classes or functions), the references are copied, but not the class instances or functions that they refer to. This copy behavior for a dictionary’s keys and values is the same as the copy behavior for a structure’s stored properties when the structure is copied.


So just to clarify how Dictionary<K,V> actually works:

1. Dictionaries declared let are constant in both size, keys, and values if the values are value types. If the values are references then the underlying object can still be modified. (If you use mutating keys then you deserve what you get.)
2. Dictionaries declared var are mutable.
3. In either case, the keys and values are heap allocated.
4. Passing a dictionary does copy the dictionary, but it's just copying a small header struct
5. When the guide talks about copying the whole dictionary, it just means logically the program behaves as if everyone has their own copy of the dictionary, even though in reality they may share the data until someone attempts a mutation; iow the headers all point to the same hash buckets until someone ruins the party

And Array<T> works the same way, except you can mutate a supposedly constant array if you don't change its size (which still seems crazy to me).

Is this all correct?



Further question: Assume that I want to pass a dictionary around, mutating it along the way. I should wrap that in my own class to avoid the repeated copying behavior, yes? Or possibly vend mutation functions that operate on my closed over dictionary. Or would that be attempting to defeat compiler optimizations?



edit: Anyone have success creating a framework and using unit tests written in Swift? I haven't done anything special whatsoever and my first attempt to run a test fails:

quote:

Undefined symbols for architecture x86_64:
"__TFVSs10SequenceOf4JoinU__fGS_Q__USs8Hashable___FTGS_Qd___11keySelectorFQQ_14resultSelectorFTQQQ__Q0__GS_Q0__", referenced from:
__TFC28SwiftNonStandardLibraryTests28SwiftNonStandardLibraryTests17testJoinSequencesfS0_FT_T_ in SwiftNonStandardLibraryTests.o
ld: symbol(s) not found for architecture x86_64

Doesn't seem to make any sense, both the framework and the test project are set to compile for x86_64.

Simulated fucked around with this message at 04:41 on Jun 11, 2014

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Ender.uNF posted:

You know at first I thought "WTF is he talking about?"

Then I opened the book in iBooks and did a search for "curry" and there it is on page 768: Curried functions and methods.

This makes me very happy.

Hooray. I put that in at a whim a few years ago, and a small cabal of us have been valiantly defending it from getting idly ripped out ever since. It helps that we internally model methods as being curried over self, so some amount of the code would be justified regardless.

Ender.uNF posted:

I'm sure this is just my confusion but this section from the guide seemed to imply that if the keys or values are structs they will be stack allocated, but that was my incorrect assumption.

Like C, all types in Swift have a (direct) storage size and alignment, which is how much (direct) space a value of that type takes up in the entity which contains it. (For this purpose, you can think of a stack frame as being a weird struct that has all of its local variables as fields.) For a class, of course, that's just the size and alignment of a pointer. For a struct or enum, that size and alignment is large enough to include all the stored properties of the type, which is to say, all of the stored properties are stored inline within the struct, which is itself stored inline within its container. Basically, where a value type is stored is dependent on what's holding on to the value.

Ender.uNF posted:

So just to clarify how Dictionary<K,V> actually works:

1. Dictionaries declared let are constant in both size, keys, and values if the values are value types. If the values are references then the underlying object can still be modified. (If you use mutating keys then you deserve what you get.)

Yes, with the proviso that of course you can also declare your own struct type that contains a class reference and makes no effort to feel like a real value type.

Ender.uNF posted:

2. Dictionaries declared var are mutable.
3. In either case, the keys and values are heap allocated.
4. Passing a dictionary does copy the dictionary, but it's just copying a small header struct
5. When the guide talks about copying the whole dictionary, it just means logically the program behaves as if everyone has their own copy of the dictionary, even though in reality they may share the data until someone attempts a mutation; iow the headers all point to the same hash buckets until someone ruins the party

Right.

Ender.uNF posted:

And Array<T> works the same way, except you can mutate a supposedly constant array if you don't change its size (which still seems crazy to me).

We got a lot of great feedback about this; it's under serious discussion.

Ender.uNF posted:

Further question: Assume that I want to pass a dictionary around, mutating it along the way. I should wrap that in my own class to avoid the repeated copying behavior, yes? Or possibly vend mutation functions that operate on my closed over dictionary. Or would that be attempting to defeat compiler optimizations?

If you're just passing it around temporarily, you can use pass-by-reference to avoid unnecessary copies without going so far as to put it on the heap. Otherwise, yes, a class is a reasonable way of sharing a mutable dictionary, and it also gives you an obvious way to start introducing real abstraction around it.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
FYI: you cannot extend a built-in generic type from within a framework with anything that touches the type parameters; the linker will not find the same mangled names and will complain that the symbols are not found. Simplest test case:


1. Create a framework
2. Add swift file with this code:
code:
extension Dictionary {
    func OK() { }
    func NotOK(a:KeyType) {
    }
}
3. In test file, add this code to a test:
code:
        let dict = ["abc": 5, "xyz": 3]
        dict.OK()
        dict.NotOK("")
And you will get an error along these lines:
pre:
Undefined symbols for architecture x86_64:
  "__TFVSs10Dictionary5NotOKUSs8Hashable___fGS_Q_Q0__FQT_", referenced from:
      __TFC23QuickTestFrameworkTests23QuickTestFrameworkTests11testExamplefS0_FT_T_ in QuickTestFrameworkTests.o
ld: symbol(s) not found for architecture x86_64
rdar://17264362 filed


I ran into this while trying to setup a framework and github project for my little non-standard library. I have basic SequenceOf<T> join operations working (left hash join), moving on to group by. I'm not tackling composite keys just yet, just trying to prove the concept. Hopefully this bug is resolved and I can get it out there for comments/contributions.

chaosbreather
Dec 9, 2001

Wry and wise,
but also very sexual.

I've been reading the book and watching the talks and I'm really into it, it seems like a really well designed language. But I was wondering, why have all those global generic functions like enumerate and the like rather than have them attached to the appropriate types as instance methods and computed properties?

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

chaosbreather posted:

I've been reading the book and watching the talks and I'm really into it, it seems like a really well designed language. But I was wondering, why have all those global generic functions like enumerate and the like rather than have them attached to the appropriate types as instance methods and computed properties?

So you don't have to rewrite them over and over, or force everything to inherit from some base class.

geera
May 20, 2003
Are there any options for those who aren't paid developers that want to start tinkering with Swift, other than waiting a couple months for Xcode 6? Even if just to compile examples from the Swift book and run them in a terminal or something.

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

geera posted:

Are there any options for those who aren't paid developers that want to start tinkering with Swift, other than waiting a couple months for Xcode 6? Even if just to compile examples from the Swift book and run them in a terminal or something.

Covered earlier in the thread - not currently. There are hints that people in Apple want to open-source Swift, but either the decision hasn't been made yet or they are still working on cleaning up the repo for public release.


Personally, my expectation is that it will be open source at some point.

geera
May 20, 2003

Ender.uNF posted:

Covered earlier in the thread - not currently. There are hints that people in Apple want to open-source Swift, but either the decision hasn't been made yet or they are still working on cleaning up the repo for public release.


Personally, my expectation is that it will be open source at some point.
Thanks. I understand why Xcode beta requires registration, but it'd be nice if they'd release some CLI developer tools for learning purposes. I'd be happy with just a REPL that I could run in a terminal window for now.

smackfu
Jun 7, 2004

Yeah, it'd be nice if they opened up the XCode download to free developers.

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

smackfu posted:

Yeah, it'd be nice if they opened up the XCode download to free developers.

Do you mean Xcode in general? Because that is available in the Mac App Store right now. Just not the beta version.

lord funk
Feb 16, 2004

The required type casting is feeling brutal. For a function that takes a CGFloat:
code:
CGFloat(fmaxf(CFloat(CGFloat(offset) / view.bounds.width), 0.0))
Old style
code:
fmaxf(offset / view.bounds.width, 0.0)
Any technique to mitigate this that I'm missing? Or am I just whining. :v:

Gul Banana
Nov 28, 2003

can you perhaps write
code:
extension CFloat {
    @conversion func __conversion() -> CGFloat {
        return CGFloat(self)
    }
}

extension CGFloat {
    @conversion func __conversion() -> CFloat {
        return CFloat(self)
    }
}

let result:CGFloat = fmaxf((offset / view.bounds.width), 0.0)
not tested, i'm at a PC. i'm also not sure if there's a way to limit the scope of extensions.. ideally this would be something you import for a specific source file or module.

lord funk
Feb 16, 2004

That worked, thanks.

Gul Banana posted:

not tested, i'm at a PC. i'm also not sure if there's a way to limit the scope of extensions.. ideally this would be something you import for a specific source file or module.

Can you explain why it would be bad to have this project wide? If it's a valid conversion, what's the harm?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

lord funk posted:

The required type casting is feeling brutal. For a function that takes a CGFloat:
code:
CGFloat(fmaxf(CFloat(CGFloat(offset) / view.bounds.width), 0.0))
Old style
code:
fmaxf(offset / view.bounds.width, 0.0)
Any technique to mitigate this that I'm missing? Or am I just whining. :v:

Assuming that offset isn't a CGFloat for some reason:

code:
max(CGFloat(offset) / view.bounds.width, 0)
Bonus: doesn't randomly do unnecessary double->float->double conversions on 64-bit platforms.

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

Gul Banana posted:

can you perhaps write
code:
extension CFloat {
    @conversion func __conversion() -> CGFloat {
        return CGFloat(self)
    }
}

extension CGFloat {
    @conversion func __conversion() -> CFloat {
        return CFloat(self)
    }
}

let result:CGFloat = fmaxf((offset / view.bounds.width), 0.0)
not tested, i'm at a PC. i'm also not sure if there's a way to limit the scope of extensions.. ideally this would be something you import for a specific source file or module.


Where did you find @conversion?


edit: My first /usr/bin/swift eternal loop! Still churning away as I type this. Rebooting the VM to see if it goes away.

edit2: Paste this code in and try to compile:
code:
extension SequenceOf {
    struct GroupByGroup<TKey, TResult> {
        let key:TKey
        var items:TResult[]
        
        init(key:TKey) {
            self.key = key
            self.items = []
        }
        
        mutating func addItem(item: TResult) {
            self.items.append(item)
        }
    }
}
rdar://17277999 filed

Simulated fucked around with this message at 00:01 on Jun 12, 2014

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer
Any idea why this is an issue?

code:
let seq: Sequence = ["1"]
seq.generate() //Error: 'Sequence' does not have a member named 'Generate'
I'm trying to do some generic collection extensions and this is causing me some trouble.

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?

Ender.uNF posted:

edit: Anyone have success creating a framework and using unit tests written in Swift? I haven't done anything special whatsoever and my first attempt to run a test fails:

Doesn't seem to make any sense, both the framework and the test project are set to compile for x86_64.

The issue with this is that the Swift standard library isn't copied into the framework or the test bundle like it is for apps. You may be able to manually copy them into your test bundle so they're available when tests are run.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

ultramiraculous posted:

Any idea why this is an issue?

code:

let seq: Sequence = ["1"]
seq.generate() //Error: 'Sequence' does not have a member named 'Generate'

I'm trying to do some generic collection extensions and this is causing me some trouble.

There are some soundness restrictions about what you can do involving associated types (including Self) when you just have a protocol value.

In this case, we could heroically let you iterate through and bind the elements to Any or something, so feel free to file a bug.

Axiem
Oct 19, 2005

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

Ender.uNF posted:

edit: Anyone have success creating a framework and using unit tests written in Swift? I haven't done anything special whatsoever and my first attempt to run a test fails:

I've been able to get unit tests written in Swift (aside from the lack of mocking), so it's just stuff with the framework. In my opinion, though, the testing stuff for Swift isn't quite there yet--which makes sense with how much work is elsewhere in the language!

On my list of radars to file this weekend is some stuff related to testing, so it'd probably be good to make your voice known there as well.

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

eschaton posted:

The issue with this is that the Swift standard library isn't copied into the framework or the test bundle like it is for apps. You may be able to manually copy them into your test bundle so they're available when tests are run.

The issue isn't running, it's that the tests can't even build due to the linker failure.

There is a build setting EMBEDDED_CONTENT_CONTAINS_SWIFT that seems to indicate that the standard swift libraries will be included in the product when enabled, but it doesn't make any difference. Copying Swift.swiftmodule to the build objects x86_64 directory doesn't help. Neither does import Swift.

Any ideas on how to go about this? I suspect I would have the same problem trying to use the framework from another app but I will test that later tonight.


edit: Unrelated note, I have working filter, join, and group by now. Tuples work excellently for projecting values, though I don't know that they can be used as keys since I presume they aren't hashable. Would be nice if they were though (assuming all of the items in the tuple are hashable).

Simulated fucked around with this message at 03:27 on Jun 12, 2014

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer

rjmccall posted:

There are some soundness restrictions about what you can do involving associated types (including Self) when you just have a protocol value.

In this case, we could heroically let you iterate through and bind the elements to Any or something, so feel free to file a bug.


Is there a reason that Array and Dictionary and whatnot implement only the vanilla Sequence instead of something like SequenceOf<T> (if it wasn't a structl)? Same for Generators (IndexingGenerator, etc) and GeneratorOf<T>. It mostly just seems like all the collections share common roots like Sequence, but they ditch some type information along the way.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

ultramiraculous posted:

Is there a reason that Array and Dictionary and whatnot implement only the vanilla Sequence instead of something like SequenceOf<T> (if it wasn't a structl)? Same for Generators (IndexingGenerator, etc) and GeneratorOf<T>. It mostly just seems like all the collections share common roots like Sequence, but they ditch some type information along the way.

They don't lose information, they just keep it in associated types, which admittedly makes it awkward (impossible?) to talk about Sequences of specific types as types rather than as generic constraints.

Gul Banana
Nov 28, 2003

Ender.uNF posted:

Where did you find @conversion?

dumped the LLVM IR which implements the few builtin conversions.

lord funk posted:

Can you explain why it would be bad to have this project wide? If it's a valid conversion, what's the harm?

implicit conversion is a powerful feature, but it introduces unpredictability: by including a file in your project, you can change the meaning of another file, reducing the type-safety it previously had. if it becomes a documented feature of swift, i'll probably do something like put the implicits in a separate project and import that only in source files which i want to use them, making it opt-in.

the other thing i was going to mention is that this particular conversion will behave differently on 32- and 64-bit systems, but rjmccall already demonstrated an implicit-free way around that:

rjmccall posted:

code:
max(CGFloat(offset) / view.bounds.width, 0)

Gul Banana
Nov 28, 2003

rjmccall posted:

They don't lose information, they just keep it in associated types, which admittedly makes it awkward (impossible?) to talk about Sequences of specific types as types rather than as generic constraints.

is there a moral equivalent, in Swift, of this C# code?

code:
        void IncrementAll(IEnumerable<T> ts) {
            foreach (var t in ts) {
                t.x++;
            }
        }

        var collection1 = new List<T>();
        var collection2 = new HashSet<T>();
        var collection3 = new T[]{};

        //add data to the collections

        IncrementAll(collection1);
        IncrementAll(collection2);
        IncrementAll(collection3);
e.g. can i use multiple generic types which implement the same protocol, and then pass them into a function, preserving the type info necessary for that protocol to work?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Gul Banana posted:

is there a moral equivalent, in Swift, of this C# code?

code:
        void IncrementAll(IEnumerable<T> ts) {
            foreach (var t in ts) {
                t.x++;
            }
        }

        var collection1 = new List<T>();
        var collection2 = new HashSet<T>();
        var collection3 = new T[]{};

        //add data to the collections

        IncrementAll(collection1);
        IncrementAll(collection2);
        IncrementAll(collection3);
e.g. can i use multiple generic types which implement the same protocol, and then pass them into a function, preserving the type info necessary for that protocol to work?

As long as you're just calling the function, there's absolutely no reason for it to not be generic, i.e.:

Swift code:
  func incrementAll<S: Sequence where S.GeneratorType.Element==T>(s: S) {
    for t in s {
      t.x++;
    }
  }
If you need to store values of the sequence, that's what SequenceOf<T> is for, as long as you don't need to recover the original sequence value/type. There is currently no way to externally constrain the associated types of a protocol type, which is a known and unfortunate deficiency.

Gul Banana
Nov 28, 2003

ah, i hadn't realised you could express a constraint on a type's associated type like that. covers some major use cases at least

Meat Street
Oct 17, 2004

knowin' nothin' in life but to be legit
Just noticed that book 2, Using Swift with Cocoa and Objective-C, is up on iBooks: https://itunes.apple.com/us/book/using-swift-cocoa-objective/id888894773?mt=11

Choadmaster
Oct 7, 2004

I don't care how snug they fit, you're nuts!
rjmccall, thanks for the thread and your responsiveness.

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:

code:
let positionToFind = 9
if let somePlanet = Planet.fromRaw(positionToFind) {
    switch somePlanet {
    case .Earth:
        println("Mostly harmless")
    default:
        println("Not a safe place for humans")
    }
} else {
    println("There isn't a planet at position \(positionToFind)")
}
The if statement is somewhat redundant given that switch can already do a conditional check (and capture the actual value into a variable or constant if necessary). It would be nice if using a switch could automatically unwrap an optional, with a requirement that one of the cases be a nil test:

code:
let positionToFind = 9
switch Planet.fromRaw(positionToFind) {
case .Earth:
    println("Mostly harmless")
case nil:
    println("There isn't a planet at position \(positionToFind)")
default:
    println("Not a safe place for humans")
}

Adbot
ADBOT LOVES YOU

Moogs
Jan 25, 2004

Proceeds the Weedian... Nazareth
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?

Edit - DERP, because if it's not optional I need to define it when I name it. Leaving this here in case some idiot has the same question.

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

Moogs fucked around with this message at 21:02 on Jun 14, 2014

  • Locked thread