Generics, extensions, and where clauses: 😱

While trying to implement something completely different and unrelated to the code in this post, I found myself thinking really hard about the combination of Swift generics, protocols, and protocol extensions. But that is not the theme of this post.

But, usually one thing leads to another. At least, that’s what happens usually when I think hard about something: I end up figuring out something completely different. In this case, I’ve just noticed this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

finalclassSalmon{

funcbake(){

print("baking salmon")

}

}

finalclassBeef{

funcroast(){

print("roasting beef")

}

}

finalclassOven<T>{

letthingToCook:T

init(stuff:T){

thingToCook=stuff

}

}

extensionOven whereT: Salmon{

funccook(){

thingToCook.bake()

}

}

extensionOven whereT: Beef{

funcclean(){

print("Cleaning oven, only when cooking beef")

}

funccook(){

thingToCook.roast()

clean()

}

}

letsalmonOven=Oven<Salmon>(stuff:Salmon())

letbeefOven=Oven<Beef>(stuff:Beef())

// The compiler will say nononono to this

//salmonOven.clean()

salmonOven.cook()

beefOven.cook()

From a purely grammatical point of view, the code makes perfect sense, but I am not sure if there is a real use case for it, at least a use case than can not be solved applying traditional polymorphism (i.e. using interfaces/protocols the way your favourite deity meant them to be used), but well, there it is.