ErrorType enums

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

Please let us know what of that doesn’t work. Silver supports generics, and we’re like 90% complete for Swift 2.0 support, in the 8.2 beta.

These are some of the issues with those libraries:

  1. use of ‘where’ in generic types or extensions:

       public extension AsyncType where Value: AsyncType {
       extension ResultType where Value: ResultType, Error == Value.Error {
    
  2. generic constructors (and/or with a where)

        init<A: AsyncType where A.Value == Value>(other: A) 
    
  3. 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
         }
     }
    
  4. annotations - @noescape, @autoclosure, @available - these are littered through both libraries

  5. Using a non Int as the raw type of an enum eg

    enum MyEnum: String 
    { 
           case Hello = "Hello"
           case World = "World"
    }
    
  6. 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:

     internal func doJsonRequest<T: JsonConvertible>(request: HttpRequest, promise: ControllerPromise<T>)
     internal func doJsonRequest<T: JsonConvertible>(request: HttpRequest, promise: ControllerPromise<Array<T>>)
    
  7. Silver doesnt know about the change to CustomStringConvertible yet?

I think no 5. is the most important as String enums are very useful. That and the ErrorType protocol working with enums.

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.

Thanks, logged as

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?

thanx!

Sorry I missed the questions in here

(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:

https://developer.apple.com/library/prerelease/ios//documentation/Swift/Reference/Swift_CustomStringConvertible_Protocol/index.html#//apple_ref/swift/intf/s:PSs23CustomStringConvertible

I work around this in my Fire code with

      public protocol CustomStringConvertible : Swift.Printable
      {}

bugs://73685 got closed with status fixed.