Context - Parameters: lambda with arguments #5661
Open
+26
−7
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
UPDATE: I am not so bullish about the claim that this advances DCI that much. I began embracing contextOf and it avoids naming the variable at all which it is a very ceremonious process. I do think it would be more intuitive and make it sit right in within the Kotlin language, but I am not so bullish about this.
Dear @serras
I would like to make the case that adding extra context functions (that also add arguments to the block lambda) is a good idea that would make this feature feel more natural in the Kotlin language and reduce the ceremony and noise associated with trying to create context scoped context-parameters.
Possible now, Proposal enables: Ceremony, noise and path of least resistance
Let's take in consideration that the path of least resistance available is to leak the context, at least if you want to use it inside the lambda directly (without calling another function that requires and names the context).
With the changes proposed, even in this example with a single object, the option that requires less characters (and therefore could be considered the path of least resistance) becomes the one doing
contextObject ->. It is a clear winner with less character and ceremony and no function calls to contextOf. It feels and acts more integrated to the language.And while the second option in terms of character count is actually the one that leaks the context, if you were trying to scope the context and already went for the path of least resistance I would argue that at that point it is only natural to add the type safety in the lambda argument. So in this way I would consider
contextObject: ContextObject ->the next natural choice (despite higher char count to the leaky version).Ok, that was a very simple example to explain the notions of noise and ceremony and the practices it encourages (leaking objects outside of the scope).
DCI example with 2 parameters and an algorithm with 2 sequential contexts
This is a DCI (Data Context Interaction) example in Kotlin:
Right now we are limited to the noisiest option. Even with two objects, it is starting to add a lot of clutter. One way to avoid the contextOf calls and that noise, is to create additional functions for each stage.
However, we have lost the big picture, the clarity. We can not longer see the complete algorithm across multiple contexts:
I know perhaps there is a strict budget of how many functions we want to generate, and we may be tempted to implement the minimum and let library authors write layers on top. However, I truly think that the ability to name the context arguments in the lambda feels very natural and something that should truly be supported at a language level.
What do you think?
PS: The proposal is to add and not to replace existing functions because that would force functions that do not need these lambda arguments to declare them adding a tiny bit of ceremony but to those who don't really need any and already don't have any.
If the existing context calls were replaced by the proposal ones then _, _ -> becomes necessary for as many objects as you inject:
Also I don't know if that is even technically possible since the new generated functions with arguments rely on the argument-less to do their job.