https://kotlinlang.org logo
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
language-evolution
  • k

    Ky Leggiero

    11/08/2019, 6:06 PM
    So basically if you don't have your own idea for how the language should change, or if your idea is not fully-formed, you can talk about it here without it being considered off-topic andor lost in #general
    👍 1
    :thread-please: 1
    e
    • 2
    • 1
  • p

    Pablichjenkov

    11/08/2019, 7:24 PM
    By the way I start warming up with a question: Any progress in private package or bringing Friend classes to the language? I feel like internal does not fill all my needs.
    ➕ 2
    m
    • 2
    • 5
  • h

    Hullaballoonatic

    11/09/2019, 8:03 PM
    so yeah, walrus operator?
    var next = stack.last
        get() {
            field = stack.pop()
            field
        }
    var next = stack.last
        get() = field := stack.pop()
    k
    q
    e
    • 4
    • 10
  • h

    Hullaballoonatic

    11/09/2019, 8:46 PM
    overloadable inverse operator?
    val i = 2
    -i // -2
    ~i // 0.5
    
    val M = Matrix.ofRows(vectorOf(4, 7), vectorOf(2, 6))
    // [ 4 7
    //   2 6 ]
    -M
    // [ -4 -7
    //   -2 -6 ]
    ~M
    // [  0.6 -0.7
    //   -0.2  0.4 ]
    👍 1
    k
    e
    k
    • 4
    • 13
  • j

    jimn

    11/21/2019, 10:09 AM
    on that note.. I hope I am not alone, but I would really like a "use wingnut-mode" language extension that puts kotlin into the category of overloading any operator to move kotlin from the "designated symbols" quadrant of https://en.wikipedia.org/wiki/Operator_overloading#Catalog to the top-right flexible quadrant.

    https://files.slack.com/files-pri/T09229ZC6-FP3NH4PCJ/image.png▾

    there are great reasons to protect a certain class of platform majorities from anti-patterns. but when you get into scientific and idiomatic equation solving you really want options to make your compiled context as transparent as possible without additional linker steps to add your ecosystem libraries to your type-safe efficiently compiled source code. I see less of this discussion than i would like to. I work routinely with graph notations and equation solvers, and also I deal with python constantly, and I would be more than happy to have such operators as foo[:] and foo[1:] in my own codex of my own equation solvers, and not have to think about what compiler extension i have to write personally to use these
    ➖ 1
    ➕ 1
    f
    k
    +2
    • 5
    • 45
  • b

    Burkhard

    11/24/2019, 9:36 AM
    How about a “generic nullable class”. My idea is that instead of nullable and not null, there is a third option “parameterized null” (
    <?>
    ). Than you could do something like this
    data class Test<?>(
        val foo: Foo<?>,   // nullable depending on class parameter
        val bar: Bar,      // never null
        val baz: Baz:?     // allways nullable
    )
    val test1 = Test<?>(getFooOrNull(), Bar(), null)
    val test2 = Test<!>(Foo(), Bar(), null)
    test1.foo?.doSomething()
    test2.foo.doSomething()
    This could be used to easily create Builder classes for data classes with immutable values.
    k
    k
    • 3
    • 8
  • s

    Samuel Michael

    11/26/2019, 12:16 AM
    just throwing it out how about list comprehensions in kotlin, i made a gem for Ruby support thinking of a Kotlin library for the same
    😱 1
    h
    • 2
    • 18
  • k

    Ky Leggiero

    12/01/2019, 3:52 AM
    @iex https://kotlinlang.slack.com/archives/C0B9K7EP2/p1515743921000044
    i
    d
    • 3
    • 5
  • h

    Hullaballoonatic

    12/01/2019, 3:56 AM
    Java allows default values for interface fields, so why does Kotlin not allow it? or at the very least delegation 😦
    d
    l
    • 3
    • 11
  • n

    napperley

    12/02/2019, 10:00 PM
    Came across a situation where it would be handy to create a value type that accepted multiple values. For instance Ncurses has the concept of colour pairs where each pair comprises of a id, background colour, and foreground colour. Currently Kotlin's experimental inline classes only allow a single value which limits where inline classes can be used 🙁. Would be nice to do something like this:
    inline class ColourPair(val id, val backgroundColour: Int, val foregroundColour: Int) {
        fun generatePairValue(): Int {
            // ...
        }
    }
    m
    d
    j
    • 4
    • 5
  • s

    stantronic

    12/04/2019, 12:48 PM
    Is there / could there be any way of enforcing named arguments in Kotlin? E.g. adding an annotation of “@UseNamedArgs” or similar would mean that the compiler would throw an error if that function was being called without using named arguments. Could help with code readability etc.
    m
    k
    q
    • 4
    • 9
  • j

    jimn

    12/05/2019, 7:06 AM
    object: myList :by x or object:FooType by x has been kind of the opposite of improvement over intellij "replace inheritance by delegation". my heart leapt high into the air when i learned of this but came down hard when i read the chosen implmentation.
    by
    should be considered something like
    extremelyvisibleaggregatememberVtable
    because you basically can only send a call through a one-way wormhole to the instance named unless you manually (and without intellij's help) "replace delegation by overrides" at the container level. there should be
    by
    , which does what is documented now, and a v2
    by
    by some other clever infix name which does delegation through the declarator's vtable of that interface.
    🤔 1
    • 1
    • 1
  • l

    Leon K

    12/05/2019, 4:17 PM
    I'd love to discuss true pattern-matching in Kotlin again. I know, the current stance of jetbrains is "No, no pattern matching, it's to complicated to implement and to complex syntactically to fit kotlins vision" But i'd still like to discuss it more. Do you think it would help Kotlin to have rust / scala-style pattern-matching and destructuring? if not, why not?
    👍 1
    s
    e
    +3
    • 6
    • 11
  • h

    Hullaballoonatic

    12/21/2019, 6:01 PM
    Awhile back I asked why kotlin did not add python-esque indexing of arrays/lists, e.g.
    val nums = listOf(1, 2, 3, 4, 5, 6)
    val firstThree = nums[..2]
    val lastThree = nums[-3..]
    val trimEndsByTwo = nums[2..-3]
    And the issue that I remember (note: not the only issue, perhaps) is that
    indexOf
    returns
    -1
    on an unfound element. so
    val elementsToSeven = nums[..indexOf(7)]
    would return the entirety of
    nums
    , an unexpected value C# 8.0 skirts around this issue by using
    ^
    instead of
    -
    as the end-orientation operator, and throws out of range for negative indices.
    val lastThree = nums[^3..]
    Would kotlin benefit from the same approach? I believe so. Especially given
    ^
    is not currently used at all
    j
    k
    • 3
    • 20
  • h

    Hullaballoonatic

    12/31/2019, 10:01 PM
    Man, I'd love it if keyboards were equipped with more math symbols. Ceiling and Floor brackets could not only serve as "Round up" and "Round down" the singular element contained respectively, but also return the max and min of multiple elements contained within.
    👍 2
    j
    • 2
    • 1
  • h

    Hullaballoonatic

    01/01/2020, 7:24 PM
    I often use inner classes in the following way (honestly don't know other uses for them):
    open class Line(open var from: Point, open var to: Point) {
        val reversed = Reversed
        inner class Reversed : Line(to, from) {
            override var from: Point
                get() = <mailto:this@Line.to|this@Line.to>
                set(v) {
                    <mailto:this@Line.to|this@Line.to> = v
                }
    
            override var to: Point ...
        }
    }
    Where every instance of Line has its own singular instance of Reversed, which only borrows its state from Line, and is otherwise stateless It is here that the idea of
    inner object
    comes to mind
    interface Line {
        var from: Point
        var to: Point
    
        inner object Reversed : Line {
            override var from: Point
                get() = <mailto:this@Line.to|this@Line.to>
                set(v) {
                    <mailto:this@Line.to|this@Line.to> = v
                }
    
            override var to: Point ...
        }
    }
    I'm not sure if this is the best nomenclature for this structure, though. Maybe
    satellite
    ? Could this be considered stateless in the same way that any getters/setters are? And thus usable in interfaces?
    👍 1
    r
    j
    • 3
    • 4
  • s

    stantronic

    01/10/2020, 10:14 AM
    Is there any way of making certain classes compile as data classes for some builds and normal classes for other builds? Thinking specifically of tests where you might want to use data-class style equals for assertions, but you dont need it in production
    🤔 1
    🇳🇴 1
    m
    e
    g
    • 4
    • 7
  • m

    max.cruz

    01/20/2020, 6:16 PM
    Hello everyone 👋🏽 with my team we were evaluating do some changes and base our error handling in the new Result class. I was taking a look at the fold implementation and I realize that the usual order from other languages and libraries is inverted, instead of left for errors and right for success is the other way. I was wondering and getting curious if this has some specific reason? Thanks in advance
    public inline fun <R, T> Result<T>.fold(
        onSuccess: (value: T) -> R,
        onFailure: (exception: Throwable) -> R
    ): R
    ➕ 3
    i
    k
    j
    • 4
    • 4
  • l

    Leon K

    01/24/2020, 4:46 PM
    I'm currently working with a lot of DSL and thus builder-classes, which currently are relatively cumbersome to implement when you want to otherwise work with immutable data-classes. I was thinking about how one could optimize this... serveral solutions come to mind. there is
    autoDSL
    , a library based on annotation processing that can automatically generate a dsl-style builder for your classes, which is simmilar to what i want, but is rather inelegant, and a library needing kapt - hurting compile-times What would you think about some kind of language-feature that allows for easier building of immutable (data)-classes, like some kind of
    buildable
    class modifier? I could imagine it being a way to specify that a data-class has some
    buildable
    fields, that are, as long as the class has not been built, mutable (and also might include
    building
    -functions, that are only present whilst the object hasn't been built. the modifier could then introduce a new method
    create
    which turns the buildable class-instance into the normal, immutable data-class instance that you would then use everywhere. this would, in a way, be a way of combining a builder class together with it's fully built, immutable version. for simple data-container-classes, this could be really practical any thoughts?
    👀 1
    h
    j
    r
    • 4
    • 8
  • d

    Derek Peirce

    02/10/2020, 2:25 AM
    The reflection is gone, and the properties are no longer adding performance or bytecode overhead, as they’re eliminated before the Kotlin is even compiled to Java. This would require the compiler to be able to make many more optimizations, but it would allow coders to write reflection-like code without deciding between the performance overhead of reflection or the engineering overhead of annotation processors. It could be used to write a custom
    equals
    or
    hashCode
    or
    toString
    implementation that uses fields based on their annotations or types, and to write easily understood serialization and deserialization formats. Another example. If properties are more aggressively inlined, it would also simplify existing code that uses properties. Consider this use of map delegation:
    class MapExample(
           map: Map<String, String>
    ) {
       val x by map
    }
    When the
    by
    is inlined, it becomes (effectively):
    val x: String get() = map.getOrImplicitDefault(MapExample::x.name)
    The decompiled class contains an entire
    KPropertyObject
    that is used only for its name. Suppose that this name access were inlined, because the compiler knows that the name of
    x
    is “x”:
    val x: String get() = map.getOrImplicitDefault("x")
    Now the overhead of involving properties is entirely eliminated. As I work on mobile code where reductions in bytecode size and execution time are top priorities, I would like to have property-inlining features like these to be able to use reflection-like features without their large overhead (We’ve eliminated many uses of
    by
    because of the unnecessary
    KProperty
    fields). Would these be feasible for the language, and how useful would they be to you?
    h
    • 2
    • 2
  • l

    Leon K

    02/23/2020, 1:01 PM
    Could anyone talk about the current state of the two "type-class"-like KEEP-proposals? (https://github.com/Kotlin/KEEP/pull/176 and https://github.com/Kotlin/KEEP/pull/87) What is their current status? Is there any indication that one of them will be implemented into the language in the "not-so-distant" future?
    r
    • 2
    • 36
  • g

    Gilberto Diaz

    03/18/2020, 3:06 PM
    where is the documentation to work with dates?
    e
    m
    • 3
    • 10
  • r

    rrader

    03/21/2020, 9:57 PM
    Is it possible to add smart cast for such cases?
    data class EmployeeDetailedDTO(val firstName: String)
    
    class EmployeesRepository {
    
        inline fun <reified T> findPage(isDeleted: Boolean = false): List<T> {
            return when(T::class) {
                EmployeeDetailedDTO::class -> listOf(EmployeeDetailedDTO("John")) as List<T>
                else -> TODO()
            }
        }
    }
    so, it will not be needed to add
    as List<T>
    ➕ 1
    m
    • 2
    • 1
  • d

    Derek Peirce

    04/05/2020, 4:16 AM
    Let’s talk a bit about Kotlin’s collection extension methods versus Java 8’s collection default methods, both designed to solve the issue of wanting to add more behaviors to existing collections, usually those that use lambdas, but in very different ways.
    list.forEach { println(it) }
    The Kotlin extension methods have an advantage in that, because they’re effectively static methods, they can be inlined, which makes this equivalent to:
    for (value in list) { println(value) }
    Meanwhile, the Java default methods have an advantage in that because it’s a default method, it can be specialized to the collection. For example, if
    list
    is an
    ArrayList
    , here’s how its
    forEach
    is implemented:
    public void forEach(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            final int expectedModCount = modCount;
            @SuppressWarnings("unchecked")
            final E[] elementData = (E[]) this.elementData;
            final int size = this.size;
            for (int i=0; modCount == expectedModCount && i < size; i++) {
                action.accept(elementData[i]);
            }
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
        }
    This is significantly more efficient than using its iterator, which requires creation and use of an iterator object as well as more frequent
    modCount
    checks. The cost is that action is no longer inlined, so a lambda object is created instead (either once or per
    forEach
    call, depending on what is in its scope), and there’s another level of indirection in executing it. Of course, this doesn’t consider additional performance improvements from JIT optimizations, but I would expect that inlining the lambda is much simpler than inlining the logic of an iterator object, and the resulting code would still be more efficient due to the
    modCount
    checks. However, we haven’t covered another advantage of specialized methods: they can operate significantly more efficiently on their collections. Take, for example, Kotlin’s
    getOrPut
    method versus Java 8’s
    computeIfAbsent.
    They are effectively the same in what they do. However,
    getOrPut
    requires a
    get
    call that may be followed by a
    put
    call. On a
    HashMap
    , this means hashing the object twice and finding the proper location in the proper hash bucket twice. On a
    TreeMap
    , this means traversing the tree twice. However, `HashMap`’s
    computeIfAbsent
    is specialized so that as soon as it’s determined that there’s no prior value at the correct hash bucket, the new value can be put in the correct place immediately, without rehashing or renavigating. (Strangely,
    TreeMap
    doesn’t have a similar specialized
    computeIfAbsent
    implementation, and I can’t tell why.) There’s also the issue that extension methods, being implementation-agnostic, can’t guarantee that a
    ConcurrentHashMap
    is operated on safely, while its specialized
    computeIfAbsent
    can. So where does that leave Kotlin? Are there plans to ever find some way that a more advanced or JIT compiler can benefit from both inlining and specialization, or are we doomed to create iterators over `ArrayList`s forever?
    m
    s
    +3
    • 6
    • 9
  • k

    Kroppeb

    05/10/2020, 1:18 PM
    There is a new KEEP that hopes to bring pattern matching and decomposition inside
    when
    conditions https://github.com/Kotlin/KEEP/pull/213
    ❤️ 10
    s
    • 2
    • 1
  • w

    wasyl

    06/04/2020, 2:55 PM
    I see Explicit API mode (https://github.com/Kotlin/KEEP/blob/master/proposals/explicit-api-mode.md) is included in 1.4-M2 such that
    public
    visibility modifier is required. So now all declarations will require either
    public
    modifier or
    private/internal
    . Is making
    internal
    visibility default in this mode on the table?
    i
    r
    e
    • 4
    • 5
  • c

    CraftSpider

    06/25/2020, 5:40 PM
    Hello. I have interest in K/N reflection. If I were interested in doing work to add support for it, what would be involved in that? Is it currently blocked by technical limitations, or would this kind of thing be practical?
    r
    • 2
    • 3
  • c

    CraftSpider

    06/25/2020, 7:40 PM
    (Please tell me if this is more suited for #kotlin-native, I'll gladly move it over)
    g
    • 2
    • 1
  • s

    Slackbot

    07/05/2020, 5:53 PM
    This message was deleted.
    d
    • 2
    • 1
  • a

    andrzej

    07/08/2020, 1:44 PM
    I'm very confused about a recent change in kotlin docs about usage of
    also
    scope function: https://github.com/JetBrains/kotlin-web-site/pull/1676/commits/c9d8e8fdb32ccf54da5b11459231e555a33eb597. It was already challenging to use scope functions properly (i.e. to not over- or mis-use them), this change made it harder... From previous clear usage advice of when to use
    also
    , now it is smth. like: "use
    also
    for a specific reason ("Use
    also
    for actions that need a reference rather to the object than to its properties and functions") unless there is
    this
    shadowing, all the usage guidance do not count, use it as
    apply
    . While reading code I need to analyse if
    also
    is put there because it was shadowing
    this
    or if it followed intended usage. Not to mention that all code bases that applied previous rule for years become messy after starting to apply new version of the rule... If really this change was needed, why not simplify it and just say: use it as apply, whenever
    it
    is more proper than
    this
    .
    i
    • 2
    • 2
Powered by Linen
Title
a

andrzej

07/08/2020, 1:44 PM
I'm very confused about a recent change in kotlin docs about usage of
also
scope function: https://github.com/JetBrains/kotlin-web-site/pull/1676/commits/c9d8e8fdb32ccf54da5b11459231e555a33eb597. It was already challenging to use scope functions properly (i.e. to not over- or mis-use them), this change made it harder... From previous clear usage advice of when to use
also
, now it is smth. like: "use
also
for a specific reason ("Use
also
for actions that need a reference rather to the object than to its properties and functions") unless there is
this
shadowing, all the usage guidance do not count, use it as
apply
. While reading code I need to analyse if
also
is put there because it was shadowing
this
or if it followed intended usage. Not to mention that all code bases that applied previous rule for years become messy after starting to apply new version of the rule... If really this change was needed, why not simplify it and just say: use it as apply, whenever
it
is more proper than
this
.
i

ilya.gorbunov

07/08/2020, 5:40 PM
Basically, "use 'also' as 'apply', whenever 
it
 is more proper than `this`" describes the essence of what we have tried to convey with this new wording, but then the request to clarify "when
it
is more proper" would inevitably come. So we expanded it with the situations when it is.
a

andrzej

07/08/2020, 9:48 PM
ok, I see, thank you for explanation. Then I have the following suggestions for docs improvement: 1. All examples of
also
on this page are about logging, it would be good to change that (I understand now there are many other valid cases, yet no single example of them) 2. Update section "Here is a short guide for choosing scope functions depending on the intended purpose:" and namely statements: "Object configuration:
apply
" and "Additional effects:
also
", now it should probably be a mix of both. 3. Still for me the following sentence: "Use
also
for actions that need a reference rather to the object than to its properties and functions" is a hint that using
also
in similar scenario as
apply
is discouraged and I if I understood you correctly, it is actually completely fine. Example: a mapping function as extension method - you would normally use
apply
but to avoid
this
shadowing you can use
also
(about which I have now some doubts because the docs say: "object rather than its properties")
View count: 4