Dictionaries as functions?

I'm filing this under discussion because I don't have a concrete pitch to make, but am interested in starting a conversation that could lead to a pitch.

I've been bumping into use cases lately where I have a generic algorithm that could easily be written to accept an optional-returning function, but where the most frequently expected use cases involve call sites where the user has a dictionary.

It's easy enough to write myGenericAlgorithm { myDictionary[$0] } but it would be much nicer in this common use case to just say myGenericAlgorithm(myDictionary). Currently this is possible, but requires overloads.

I'm wondering if we could build on SE-0253 to support implicit conversion from callable types to corresponding function types. If we did that, then a callAsFunction method could be added to Dictionary and everything would just work as desired.

Note: doing this would also allow us to remove the special case introduced by SE-0249 by adding callAsFunction to KeyPath.

2 Likes

I would want to use subscript as a function instead: myGenericAlgorithm(myDictionary.subscript(_:)). Rather, accessors in general.

10 Likes

:+1:
myGenericAlgorithm(myDictionary) vs. myGenericAlgorithm(myDictionary.subscript(_:))

your way is much better because it's very clear what's going on, better than all the "implicit short hand" notations we are getting now, too much obfuscation to my taste, causing too much cognitive overload :frowning: easy for the compiler is very hard to human!

While I (sometimes) miss this from Scala I'm not sure it fits Swift so well..

So the reason why it works well in scala is that it's not "just" sugar but it really means that a Map (dict) IS-A Function:

res2: scala.collection.immutable.Map[String,String] = Map("" -> "")

scala> Map("" -> "").isInstanceOf[String => String]
res3: Boolean = true

So one could pass it around as such, which comes in handy if someone wanted to prepare some mock data quickly etc. Merely adopting callAsFunction without the typing relationship seems to me like it'd not achieve the "i can pass it around like a function" :thinking:

It somehow feels like a ship that has sailed though with Swift (though it's not like I have much information about what ships have sailed or not :slight_smile:).

Right, that is why I mentioned supporting implicit conversion from callable types to the corresponding function type. Wouldn’t that do what you are looking for?

I'm not an authoritative compiler person but generally the more implicit conversions a language has the weirder it gets and those could be seen as weird edge cases...

So if we wanted to pull this off I'd rather see it inherit from a function type representing Key -> Value, but we can't do this in Swift AFAIK...

Anyway, just some thoughts :slight_smile:

This was discussed during SE-0253 and listed as a possible future direction. The purpose of this thread is to discuss a specific potential use case for the feature.

I see, I have missed that part -- thx for the pointer :slight_smile: