|
Quick question on doing interval matching in a switch statement:code:
|
# ? Jun 23, 2015 09:14 |
|
|
# ? May 14, 2024 22:15 |
|
Yeah I ran into that at some point. You can't make a half open interval where the start is not included, and you can't make one where the end is greater than the start (i.e. Double.infinity..<0.0). It seems like an <.. or a more relaxed HalfOpenInterval is what's needed. Edit: Relatedly, I tried to make a <.. operator earlier and got stuck on this: code:
ultramiraculous fucked around with this message at 15:47 on Jun 23, 2015 |
# ? Jun 23, 2015 10:27 |
|
Yes, . is restricted to only appear in a sequence, with ..< as a dumb special case.
|
# ? Jun 24, 2015 01:37 |
|
Amazingly (and as an awesome sign of the progress Swift has made) I just now ran into my first eternal loop in the compiler. code:
|
# ? Jun 24, 2015 04:12 |
|
Is the idea of a 'strict' version of typealias (eg typealias Gram = Int and have the compiler complain if you try to pass an Int to a Gram parameter or add an Int to a Gram) a really bad one for an obvious dumb reason I haven't spotted? If not, is there any way to implement this in Swift, or would it be a possible future feature?
|
# ? Jun 25, 2015 10:53 |
|
Could use a struct.
|
# ? Jun 25, 2015 12:30 |
|
It would be nice if there was a way to “clone” the functionality of a struct, and then optionally extend it with new functionality, for cases like that. Then you wouldn't have to manually forward a bunch of methods to an underlying Int.
|
# ? Jun 25, 2015 12:52 |
|
I suppose. Though a struct also lets you choose not to forward certain operations at your option. Dividing grams by grams may not make sense.
|
# ? Jun 25, 2015 12:56 |
|
99% of the time when wrapping an Int you'll want equality operations and nothing else.
|
# ? Jun 25, 2015 15:40 |
|
That makes me think it might be cool to have some kind of type system for units where the product of newtons and meters has the type newton-meters, etc. It would probably realistically have to be a piece of data attached to the value rather than the actual type of the value.
|
# ? Jun 25, 2015 16:23 |
|
fleshweasel posted:That makes me think it might be cool to have some kind of type system for units where the product of newtons and meters has the type newton-meters, etc. It would probably realistically have to be a piece of data attached to the value rather than the actual type of the value. "Units-of-measure" are part of the type system in the F# language, e.g. code:
|
# ? Jun 25, 2015 16:54 |
|
There was a kinda neat Scala library that did all of that too: https://github.com/zzorn/ScalaQuantity
|
# ? Jun 26, 2015 00:42 |
|
I solved this sort of problem in my own code with generics:code:
code:
|
# ? Jun 26, 2015 01:11 |
|
Axiem posted:stuff You can extend this sort of thing quite easily: code:
If you want to get fancier, you can allow arbitrary units on the result: code:
|
# ? Jun 26, 2015 03:00 |
|
Ender.uNF posted:more stuff This is really awesome! I didn't end up doing anything like that because it's not something I much need to do; my stuff is mostly multiplication and division (and I intentionally chose UInts instead of Doubles for my purposes; I could very much see doing it Doubles if it suits your needs) Because my game has an NSTimer firing a tick every so often, I went in the direction of also capturing a DeltaQuantity, so e.g. my "income increase per tick" is a DeltaQuantity<Dollar>, to expressly capture the act of the quantity changing. For whatever reason, it just bothers me to be able to do + and - directly on quantities (what does it mean to do 3 meters - 5 meters? -2 meters? What does that even mean in terms of measuring (as opposed to position)). There's a lot of cool ways someone could take this if so inclined.
|
# ? Jun 26, 2015 03:54 |
|
Most of you have probably seen this newsletter, but for those who haven't: https://swiftnews.curated.co
|
# ? Jun 26, 2015 19:45 |
|
NS*WindowLevel constants don't seem to be imported into Swift. Is this an appropriate workaround? Swift code:
EDIT: reported as rdar://21640539 Doctor w-rw-rw- fucked around with this message at 22:46 on Jul 1, 2015 |
# ? Jul 1, 2015 22:40 |
|
Possibly dumb question:code:
|
# ? Jul 1, 2015 23:42 |
|
(looking at 1.2 docs) enumerate() returns the tuple of n and item where n is always an Int (running index of the enumeration) not all collections are indexed by Ints?
|
# ? Jul 1, 2015 23:57 |
|
Well, this errors with: Type 'Index' constrained to non-protocol type 'Int'code:
|
# ? Jul 2, 2015 00:18 |
|
Doctor w-rw-rw- posted:Well, this errors with: Type 'Index' constrained to non-protocol type 'Int' Since Int isn't a protocol (nor is it inheritable), you need to say where Index == Int here (assuming Swift 2... I think Swift 1 uses single =). Which begs the question, what's the difference between "where X == Y" and "where X : Y" if Y is a protocol? The compiler seems to allow both.
|
# ? Jul 2, 2015 02:07 |
|
One is a constraint that the type has to conform to the protocol, the other is a constraint that the type has to literally be that protocol type. In theory, what you're looking for is: Swift code:
|
# ? Jul 2, 2015 03:17 |
|
Have I explained protocol types in this thread? The distinction between them and protocols is both interesting (I think) and important; it's probably discussed in the book, if you haven't checked it out.
|
# ? Jul 2, 2015 03:18 |
|
rjmccall posted:Have I explained protocol types in this thread? The distinction between them and protocols is both interesting (I think) and important; it's probably discussed in the book, if you haven't checked it out. Can you elaborate on the distinction? I searched through the book but couldn't find anything that about "protocol types" that seemed like anything outside the normal realm of protocols that I'm already familiar with. (I may have missed it.)
|
# ? Jul 2, 2015 03:42 |
|
rjmccall posted:Maybe you should just extend Array unless you have a need to be more generic? Thanks!
|
# ? Jul 2, 2015 04:34 |
|
fleshweasel posted:
You shouldn't be checking errorPtr here, as with everything that deals with NSError you'll only get one back if the init fails and that's what you need to check for in Swift pre-2.0 or ObjC. (I can't tell you how many times I've seen [managedObjectContext save:&error]; if (error) { ... }, whoever told people they should do that is wrong wrong wrong.)
|
# ? Jul 2, 2015 09:17 |
|
That's the convention and I know in this case it isn't true but there are many older Apple API that don't follow it. It's simplistic to say that you should never check if error is set to see if an error occurred. I could be mis remembering or there could be more modern methods but there are some signatures that return void and accept the error pointer.
|
# ? Jul 2, 2015 13:52 |
|
Kallikrates posted:It's simplistic to say that you should never check if error is set to see if an error occurred. Good thing that's not the rule! The rule is "check the return value to see if an error occurred". Which is exactly as simple as it should be.
|
# ? Jul 2, 2015 15:02 |
|
Okay I wrote that before coffee, I've run across methods that accept an error pointer, and return void. Or maybe I am mis remembering but I remember hitting something from some big Framework that was essentially: -(void)foo:(NSError **)error;
|
# ? Jul 2, 2015 15:18 |
|
Why does this succeed:code:
code:
EDIT: I think I'm dumb and need to use Element, not T. EDIT 2: Nope. "'T' is not convertible to 'Element'" for "let item : Element = self[otherIndex]" EDIT 3: Okay, using 'T' as a name is foolish, because it collides. When you're being told "'T' is not convertible to 'T'" best to use a different parameter name. EDIT 4: All I really want is to define an operation (for calculating array diffs) on an Array where the elements are equatable. What the hell am I doing wrong?! Doctor w-rw-rw- fucked around with this message at 18:23 on Jul 2, 2015 |
# ? Jul 2, 2015 17:33 |
|
I'm working on a library that is starting to push the sane limits of what generics and protocols can do in Swift, and I'm running into some weird situations where I feel like what I'm doing is going to bite me in the rear end later. First, I've defined a protocol FloatingPointArithmetical that just defines all the standard arithmetic operators and math functions (sin, cos, sqrt, etc), and I have Double, Float, and CGFloat all extended to conform to those. Straight forward. (It would be great if the standard library already did this in FloatingPointType!) Then, let's say I have a struct Foo<T> that contains an array of T and some other state and methods, and I have a likewise-defined protocol with an associated type: code:
My first thought was to extend the struct with a where clause (extension struct Foo where Value: FloatingPointArithmetical) but that doesn't work because you can only extend protocols with where-clauses. Fair enough, I can extend FooProtocol instead, but that would require me to lift up any private data from Foo as vars/funcs in FooProtocol so that my extension methods can see it. I don't want to expose that. I thought, what if I created a private _FooProtocol that defined manglePrivates, and had FooProtocol inherit from that? Can't do it—a public protocol can't inherit from a less-accessible protocol. It turns out what I can do is this: code:
It compiles and runs, but I look at that and see two things that make me a little worried: 1. I've got a struct extending a private protocol; why is this allowed but it's not for protocol inheritance? 2. I've got that bizarre Self constraint in my extension to fake a composed protocol extension (I tried extending protocol<FooProtocol, _FooProtocol> but non-nominal types can't be extended, and I couldn't define my own named protocol that inherits from both because of the same access control issue above). Am I going to regret this?
|
# ? Jul 2, 2015 17:38 |
|
Flobbster posted:Can you elaborate on the distinction? I searched through the book but couldn't find anything that about "protocol types" that seemed like anything outside the normal realm of protocols that I'm already familiar with. (I may have missed it.) A protocol is a set of requirements: methods, operators, associated types, implied protocol requirements, etc. It can be used in three ways in the language: in a conformance, in a generic requirement, and as a type. Conformances are straightforward: you can declare that a type conforms to a protocol, in which case the compiler checks that the requirements are satisfied and registers the conformance. Generic requirements are also simple: if you have generic code, you can declare that one of your type parameters (or an associated type thereof) has to conform to a protocol, in which case the generic code can now assume that conformance, but uses of it will have to check that the conformance exists. The third use is as a type, or as part of a protocol composition type (protocol<A,B,C>). A value of a protocol (composition) type is a value of an unknown type that conforms to the protocol(s). In type theory, this is what's called an existential type, because one way you can interpret the type MyProto is ∃ t : MyProto . t. When you create a value of the protocol type from a value of a concrete type, you're erasing information about the concrete type (from the static type system; you can dynamically cast a value of protocol type back out to the concrete type); the compiler just checks that the concrete type conforms to the protocol. If you have a variable of protocol type, reassignment can change the concrete type that's stored in the variable. There are some limits on what you can do with protocol types. Consider calling a method on a value of a protocol type. You know that the value has some type T that conforms to the protocol; but what you can't know (or at least the compiler can't know) is how that type is related to the type of any other given value, or the type stored in another value of the protocol type. So, for example, a protocol type for the protocol Equatable just wouldn't work, because you'd never be able to use the equality operator, because you'd never actually know that the types are the same. (Now, equality is something of a special case, because it's tempting to say "well, just say that they're not equal if the types aren't the same". But that's not a general answer; consider what it would do to the inequality operator.) Anyway, that's the difference between protocols and protocol types.
|
# ? Jul 2, 2015 18:50 |
|
Doctor w-rw-rw- posted:Xcode already tells me item is of type T, but adding as! T prevents "Could not find an overload for '==' that accepts the supplied arguments". code:
|
# ? Jul 2, 2015 21:16 |
|
Flobbster posted:I want to extend Foo with additional methods only when T conforms to FloatingPointArithmetical. The catch is, my extension methods need to be able to call the private manglePrivates method inside Foo. That was fixed in Beta 2. I'm going to hope that that works well enough for you and ignore the rest of your question.
|
# ? Jul 2, 2015 21:19 |
|
rjmccall posted:That was fixed in Beta 2. That'll teach me to fall behind on my betas Thanks, upgrading to beta 2 did the trick and simplified my code quite a bit! The only hang-up I ran into that had me scratching my head for a minute: my extension's constraint had to be applied to the generic type parameter name T and not to the protocol's typealias Value; trying to do the latter (a holdover from the protocol-based extension) caused the compiler to segfault. I filed rdar://21659734 for this. Thanks for the write-up about protocols vs. protocol types. Clearly I wish my graduate PL course had been more theoretical instead of a survey of languages But that definitely makes sense in the way that protocols with Self requirements can't be used as types in the context of variable decls and whatnot.
|
# ? Jul 2, 2015 22:34 |
|
Kallikrates posted:Okay I wrote that before coffee, I've run across methods that accept an error pointer, and return void. Or maybe I am mis remembering but I remember hitting something from some big Framework that was essentially: -(void)foo:(NSError **)error; None that I’ve seen in the Cocoa APIs are like that. It wouldn’t surprise me though if there were some developers who misunderstood the conventions and made frameworks like that. There are places in Cocoa where an error itself is passed as a parameter, and nil is used to indicate “no error.” But that's different then checking whether an error out-parameter was set.
|
# ? Jul 2, 2015 22:37 |
|
Flobbster posted:That'll teach me to fall behind on my betas Same. I was trying stuff, not realizing I was on an old Xcode 7.0 beta.
|
# ? Jul 3, 2015 02:09 |
|
Both in the project, and even in a barebones playground (rdar://21673413). Huh. (Yes, I've changed Element to T, and it's fine.)
|
# ? Jul 4, 2015 08:16 |
|
Oh, sorry, I should have checked on the actual beta. (We're renaming generic arguments to be more meaningful.)
|
# ? Jul 4, 2015 09:41 |
|
|
# ? May 14, 2024 22:15 |
|
I was excited yesterday to find a situation where a particular combination of property declarations in a harmless looking generic struct compiled fine, but deadlocked at runtime when I tried initializing the struct (rdar://21664816) code:
Storage and memory layout requirements aside, I guess one big blocker would be that initializers on the main struct wouldn't be able to initialize properties in an extension, so non-optional things would be broken. Flobbster fucked around with this message at 17:17 on Jul 4, 2015 |
# ? Jul 4, 2015 15:51 |