[swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

Magnus Ahltorp map at kth.se
Tue Dec 5 19:06:30 CST 2017


> 6 Dec. 2017 04:13 Thorsten Seitz <tseitz42 at icloud.com> wrote:
> 
> I just wanted to add that the single purpose of a static type system is to ensure that the methods being called on a receiver are present at runtime and take arguments of the types known at compile time. Of course the type system does not guarantee that those calls to not fail. Even in Haskell there is no guarantee that a function call does not fail as it allows partial patterns (therefore `head []` crashes). Or a function call might enter an infinite loop. But, to repeat, the type system guarantees that the method or member itself will be present.
> 
> Therefore I cannot follow the argument that it follows from the possible failure of a Swift method or member access that it is ok or even a comparable type of failure if the method or member itself is not present. This would imply that Swift’s static type system is unnecessary. Why check for the presence of a method or member if calling it or accessing it might fail anyway? No, I do not buy that argument. And I do not think that I have to provide examples where a static type system is of help.

SOURCE MUSIC: "Soothe me"

Program crashes.

		PROGRAMMER
	What? What did I do?

		RUNTIME
	You failed to call a method correctly.

		PROGRAMMER
	The method was present, sir.


By your reasoning, this code would be ok:

class Example {
	var a: Int { return values["a"]! }
	var b: Int { return values["b"]! }
	var c: Int { return values["c"]! }
	var d: Int { return values["d"]! }
	…
}

(which I believe is more or less equivalent to what has been suggested by some, but by enumerating all the dynamic members that seem to exist)

but not

class Example: DynamicMemberLookupProtocol {
   subscript(dynamicMember: String) -> Int {
	return values[dynamicMember]!
   }
}

> The remaining question therefore is whether it is ok to remove the static type system for certain isolated use cases and that might be the case. But I like others would prefer if those use cases would be isolated somehow visually. Someone proposed to require `dynamic` before expressions containing dynamic member lookups similar to `try`, with the additional option to enclose a whole block into `dynamic { … }` to express the same as prefixing each expression with `dynamic`. I still think this has merit:
> 
> ````
> let result = dynamic x.foo.bar  // will crash if foo or bar are not present
> 
> let result = dynamic? x.foo.bar // will return nil if foo or bar are not present
> 
> // will crash if foo or bar are not present
> let result = dynamic {
> 	let y = x.foo.bar
> 	let z = y.baz(42)
> 	return z.zork()
> }
> 
> // will return nil if foo or bar are not present
> let result = dynamic? {
> 	let y = x.foo.bar
> 	let z = y.baz(42)
> 	return z.zork()
> } 
> ````

Which is already possible with the proposal, using the existing "throw" mechanism in Swift.

/Magnus



More information about the swift-evolution mailing list