Hi guys,
I’ve been trying to get a Promise implementation compiling into my cross platform POC.
I first tried PromiseKit (http://promisekit.org/) and then BrightFutures (https://github.com/Thomvis/BrightFutures) but gave up because there was just too much unsupported syntax - they are using generic everything and all the new shiny stuff in Swift 2.0 .
So I’m rolling my own much simpler implementation based on another bit of other code I found.
But I’m coming across the fact that Silver doesn’t know about the ErrorType protocol, and that even if you define it, you can’t then define an enum based on it, which as I understand it is how you are supposed to define exception types in Swift.
Here’s the sample that fails to compile: (in Fire 8.2.88.1865)
#if COOPER
// not currently defined in Silver ??
public protocol ErrorType
{
}
#endif
public enum PromiseError: ErrorType // fails to compile with TypeMismatch, fine in XCode
{
case UndefinedError
}
public class Promise<T:Any>
{
....
public var error: ErrorType?
I also tried this, which compiles, but doesnt actually allow the enum value to be used as an ErrorType
public enum PromiseError
{
case UndefinedError
}
extension PromiseError : ErrorType
{
}
This workaround compiles and works, but is a bit naff:
public class PromiseError : ErrorType
{
}
let UndefinedError = PromiseError()
Is there any other way to define custom error types?
Also, FYI, currently it’s a compile error to declare a closure type with throws, which again is fine in XCode:
public func then(body: (T) -> () throws )
Also the implicit error variable of course doesn’t have the ErrorType type
These are some of the issues with those libraries:
use of ‘where’ in generic types or extensions:
public extension AsyncType where Value: AsyncType {
extension ResultType where Value: ResultType, Error == Value.Error {
generic constructors (and/or with a where)
init<A: AsyncType where A.Value == Value>(other: A)
complex switch statements
/// Returns `true` if `left` and `right` are both of the same case ignoring .External associated value
public func ==<E: Equatable>(lhs: BrightFuturesError<E>, rhs: BrightFuturesError<E>) -> Bool {
switch (lhs, rhs) {
case (.NoSuchElement, .NoSuchElement): return true
case (.InvalidationTokenInvalidated, .InvalidationTokenInvalidated): return true
case (.External(let lhs), .External(let rhs)): return lhs == rhs
default: return false
}
}
annotations - @noescape, @autoclosure, @available - these are littered through both libraries
Using a non Int as the raw type of an enum eg
enum MyEnum: String
{
case Hello = "Hello"
case World = "World"
}
Overloading based on generic specialisation - Silver treats these as duplicate methods for example, whereas XCode is fine and picks the right one based on the type from the calling site:
Thanx, this is good feedback! I’ll make sure this gets logged and looked at asap. No promises on any timeline at this stage; we’re pretty locked down for the upcoming 8.2 release, but I’ll give these high prio for 8.3.
bugs://73685: Silver: cannot declare closure with "throws"
bugs://73686: doe issue 1-3, 7 above
bugs://73687: Silver: need support for @noescape, @autoclosure attributes
(4) @available should be in 8.1
(5) i dont believe we can support cross-platform, but i’ll check with the team.
(7) what changes is that?
(5) It should be possible to transform an arbitary string backed enums by making rawValue a field on the generated Java / .NET enum?
eg Swift:
enum MyEnum: String
{
case X = "X"
case Y = "Y"
}
func test()
{
var s: String = MyEnum.X.rawValue
}
Transforms to Java:
public enum MyEnum
{
X("X"),
Y("Y");
public final String rawValue;
MyEnum(String rawValue)
{
this.rawValue = rawValue;
}
}
A switch using the rawvalue would then need converting to if/then but you do that anyway from looking at decompiled code?
(7) the Printable protocol got renamed to CustomStringConvertible in Swift 2. Because… Apple. I can’t find the reference of the change, but here’s the doco on current state: