Last active
July 24, 2020 03:49
-
-
Save GeekAndDad/967972d329b354b7fa5fe241895c596d to your computer and use it in GitHub Desktop.
Computed properties don't call specialized version of functions? Work fine when you call the specialized functions directly but not when those functions are used within a getter or setter it seems… ???
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// macOS playground source | |
// swift 5.3, Xcode 12b2 | |
import Cocoa | |
struct Foo<A> { | |
var subVal: Any? | |
let defaultValue: A | |
init(defaultValue: A) { | |
self.defaultValue = defaultValue | |
} | |
var value: A { | |
get { | |
return map(value: subVal) ?? defaultValue | |
} | |
set { | |
subVal = map(value: newValue) | |
print("subVal: \(String(describing: subVal))") | |
} | |
} | |
func map(value: A) -> Any? { | |
print("map A -> Any?") | |
return value | |
} | |
func map(value: Any?) -> A? { | |
print("map Any? -> A") | |
return value as? A | |
} | |
} | |
// make a specialization for Strings identical to the above | |
// except change the print to use "EXT" instead of "map" | |
// so we can see when the internal generic one is called | |
// and when the restricted one is called | |
extension Foo where A == String { | |
func map(value: A) -> Any? { | |
print("EXT A->Any?") | |
return value | |
} | |
func map(value: Any?) -> A? { | |
print("EXT Any?->A") | |
return value as? A | |
} | |
} | |
print("\nUse an Foo<Int> so the specialization shouldn't get involved either directly or via the computed property\n") | |
var f = Foo(defaultValue: 42) | |
print("via computed property:\n") | |
print(f.value) | |
f.value = 43 | |
print(f.value) | |
print("\ncalling functions directly") | |
print(String(describing: f.map(value: 43))) | |
print(String(describing: f.map(value: "hello")), "(nil expected)") // should print nil because we are a Foo<Int> | |
print("\n\n*** Now use Foo<String> so the specializations should be involved calling directly OR via computed property\n") | |
var g = Foo(defaultValue: "hello world") | |
print("via computed property: \n") | |
print("> should see 'EXT' instead of 'map' in next print but won't 0") | |
print(g.value) | |
print("\n> should see 'EXT' instead of 'map' in next print but won't 1") | |
g.value = "zip!" | |
print("\n> should see 'EXT' instead of 'map' in next print but won't 2") | |
print(g.value) | |
print("\n> WILL see expected 'EXT' instead of 'map' in next two prints which call `map` directly\n") | |
print(String(describing: g.map(value: "hello"))) | |
print(String(describing: g.map(value: 42)), "(nil expected)") // should be nil as we are a Foo<String> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
hello? | |
Use an Foo<Int> so the specialization shouldn't get involved either directly or via the computed property | |
via computed property: | |
map Any? -> A | |
42 | |
map A -> Any? | |
subVal: Optional(43) | |
map Any? -> A | |
43 | |
calling functions directly | |
map A -> Any? | |
Optional(43) | |
map Any? -> A | |
nil (nil expected) | |
*** Now use Foo<String> so the specializations should be involved calling directly OR via computed property | |
via computed property: | |
> should see 'EXT' instead of 'map' in next print but won't 0 | |
map Any? -> A | |
hello world | |
> should see 'EXT' instead of 'map' in next print but won't 1 | |
map A -> Any? | |
subVal: Optional("zip!") | |
> should see 'EXT' instead of 'map' in next print but won't 2 | |
map Any? -> A | |
zip! | |
> WILL see expected 'EXT' instead of 'map' in next two prints which call `map` directly | |
EXT A->Any? | |
Optional("hello") | |
EXT Any?->A | |
nil (nil expected) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Simpler version of this on the Swift forms:
https://forums.swift.org/t/computed-property-getter-and-setter-in-generic-struct-not-dispatching-function-calls-to-specialized-implementations/38712