[swift-evolution] rethrows as first-class type annotation

Alexandre Lopoukhine superlopuh at gmail.com
Sat Dec 19 10:04:28 CST 2015

Hello all,

I’m not sure that I’ve expressed myself correctly, but essentially, I want the following type declaration to be legal: "I rethrows -> O”. I’ve looked through the mailing list and the proposals, and haven’t seen this mentioned, but I apologise if this has already been discussed.

The following example is rather specific, but I’m sure that the solution to this problem can be useful elsewhere. In playing around with the concept of pipes and combinations of functions, I thought that it would be nice to have an operator with the following property:
(Class.instanceFunction `operator` input)(instance) === instance.instanceFunction(input)
, which would allow me to pass the operator construct into “map”, and other higher-order operations.

I attempted to implement this with the following operator functions:

public func |++|<C,TI,TO,O>(classFunc: C -> (TI -> TO) -> O, transform: (TI -> TO)) -> C -> O {
    return {classFunc($0)(transform)}

public func |++|<C,TI,TO,O>(classFunc: C -> (TI -> TO) throws -> O, transform: (TI -> TO)) -> C -> O {
    return {try! classFunc($0)(transform)}

public func |+++|<C,TI,TO,O>(classFunc: C -> (TI throws -> TO) throws -> O, transform: (TI throws -> TO)) -> C throws -> O {
    return {try classFunc($0)(transform)}

They can be used in the following way:

1) (Array.myMap |++| double)([1,2,3]) // Where myMap doesn’t accept a throwing function.

2) (Array.map |++| double)([1,2,3])

3) try? (Array.map |+++| throwIfEven)([1,2,3])

As you can see, this is rather messy. I think that the type system should be extended to have a true equivalent of the rethrows annotation in function declarations. It would then allow the following statement:

public func |++|<T,I,O>(classFunc: T -> I rethrows -> O, input: I) -> T rethrows -> O {
    return {try classFunc($0)(input)}

T rethrows -> O will then be able to be unified with a non-throwing function type 
	iff the type of classFunc($0) unifies with a non-throwing function
	(iff input is a non-throwing function in the of Array.map)

Thus, all of the above uses should be legal, with the benefit of simpler unification.

My limited knowledge of compilers doesn’t doesn’t give me any reason to think that this isn’t possible, and my impression is that moving “rethrows” from a special annotation to a more general one would simplify the language.

What do you all think?

— Sasha

More information about the swift-evolution mailing list