TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Toying with Kotlin's Context Receivers

48 pointsby nfrankelabout 3 years ago

10 comments

haroldadminabout 3 years ago
While I really like Kotlin in general, I&#x27;m not a fan of this feature. It feels like unnecessary syntax sugar for functions that accept multiple parameters.<p>Replacing a function call `foo(bar, baz)` with just `foo()` by bringing `bar` and `baz` into context is not meaningfully better in any way. I&#x27;d even argue it reduces the readability of the code due to implicit receivers.
评论 #31394639 未加载
评论 #31396605 未加载
derrizabout 3 years ago
I&#x27;m really not a fan of implicit context being passed around like this. I hated Scala&#x27;s implicit feature although I&#x27;m not familiar with the recent apparent improvements referenced in the article.<p>In a larger &#x27;with&#x27; block, you cannot tell which invocations will interact with or change the state of a context object without looking at site of the definition of the function.<p>For me, when reading others&#x27; code, being able to construct a mental model of what the effects of a line of code in isolation is a vital property for code to be readable&#x2F;comprehensible. Without implicits, you can mentally constrain what effects a line like &quot;x.y(z)&quot; will have on the state of the program.<p>One issue I had with the Scala feature was how it made refactoring is more fraught - as it&#x27;s not clear which pieces of code in the &#x27;with&#x27; block can be moved elsewhere from just reading the code.<p>Context objects behave like a form of global variable except their use can be even more confusing as Foo@this will refer to different things depending on the runtime call stack. And similarly, it bakes in a singleton aspect to the context objects. The example model from the article should allow functions to operate on multiple Transaction or AccountRepo instances, for example.
评论 #31395275 未加载
评论 #31394704 未加载
ohgodplsnoabout 3 years ago
Context receivers are also being considered as a poor man&#x27;s DI&#x2F;insane man&#x27;s DI, depending on how you see it. Probably both. After all, if you have a class that requires A, B and C to do its work, marking it as needing those three in context make it super easy to just always have to provide them.<p>Unfortunately (fortunately? Because I know the evil, disgusting things I would do if it was easier), right now you have to nest with(x) or x.apply { } blocks to have everything in scope. A with(a, b, c) { } syntax would be very welcome, but I don&#x27;t think functions of type (A, B, C).() -&gt; Unit are going to exist any time soon.
评论 #31395015 未加载
评论 #31394225 未加载
captainmuonabout 3 years ago
It seems really confusing that the context object becomes an implicit `this`. It is already hard enough to understand what scope a name will be looked up in. Many languages suffer from this when they have a kind of `with` block. Ironically, VB6 gets it right. There you have to qualify members with a leading dot, if they are to be looked up in the context, e.g.:<p><pre><code> &#x27; Haven&#x27;t written this in 20 years so maybe it is not 100% correct :-) With myForm .Title = &quot;Hello World&quot; .Maximize() End With </code></pre> When I heard &quot;context receivers&quot;, I thought something completely different and got excited: Sometimes you need to pass a parameter to a function that only gets called several levels deep. It is ugly to add that parameter to every intermediate function. But it is even worse to add a global variable. The OOP solution would be to put all the functions as methods on an object, and pass the data via a field on the object. But what if you could pass the parameter like this (pseudocode):<p><pre><code> function outer() { use-extra-context(logcolor=&quot;RED&quot;) { foo(); } } function foo() { bar(); } function bar() { baz(); } function inner() takes-extra-context(logcolor) { print(&quot;Something&quot;, color=logcolor); } </code></pre> Basically something like dynamical scope, or thread local storage. (Or reading from the other comments, maybe this proposal does just that and I missed something?)
throwaway234322about 3 years ago
Seems the examples are contrived.<p>* Transactions are first-class in most RDMBS, performing I&#x2F;O in between each one, and then sending a commit or rollback seems bizarre when you can send off one, not to mention implementing it in the host language is unnecessary.<p>* It seems to be using blocking I&#x2F;O when most platforms have evolved to concurrent I&#x2F;O.<p>* If the host language does indeed expose high level start&#x2F;commit&#x2F;rollback, it should be exposed minimally with a RAII-safe callback routine, something like `runTransaction`. You wouldn&#x27;t want to see the former in the wild.<p>* It seems to argue for the use of context &#x2F; implicit parameters, where I think you really don&#x27;t want to use it in this case. Implicits or Context seems better for something like executors or React Context.<p>* Are they really using floats for monetary value?
fiddlerwoaroofabout 3 years ago
A lot of these sorts of language features feel to me like workarounds for a lack of methods with multiple dispatch: methods like the transfer method seem to belong to a collection of classes but typical OO languages force you to pick a single class to attach them to.
评论 #31394158 未加载
评论 #31395008 未加载
jatinsabout 3 years ago
Useful for things like React Context when using Kotlin&#x2F;JS.<p>The other way to look at this is this lets you model your functions dependencies into two different groups: 1&#x2F; &quot;Data&quot; your functions is working with - passed as good ol&#x27; arguments 2&#x2F; &quot;Services&quot; your function needs to do certain operations - passed as context<p>I guess it&#x27;s slightly nicer when thought that way, though good luck getting a team of 200 developers on the same page regarding how to use these advanced features.<p>Code review:<p><pre><code> A: &quot;Why are you passing that data as context?&quot; B: &quot;makes it cleaner&quot; </code></pre> Cleanliness lies in the eyes of beholder, so how do you argue with that?
评论 #31395420 未加载
评论 #31395369 未加载
Daishimanabout 3 years ago
Can someone provide a decent, frequent example that merits adding all this overhead to a language? I&#x27;m having a very difficult time thinking why use this instead of plain interfaces and extension methods. Heck is just doing `Service.transfer(trx, args)` really such an abomination that needs correction?
whoisthemachineabout 3 years ago
Is this private class fields with a different syntax?
SemanticStrenghabout 3 years ago
I&#x27;d appreciate a comparison with Scala 3 given&#x2F;using or the previous implicits