• dev_null@lemmy.ml
    link
    fedilink
    arrow-up
    1
    ·
    edit-2
    1 day ago

    what if somewhere else in the code

    Then you’d need to do something else.

    the semantical and resourcewise equivalent would be a third variable

    So you are advocating for:

    data class Filters(
        val isAdmin: Boolean = false,
        val filterByAdmin: Boolean = false,
        val isConfirmed: Boolean = false,
        val filterByConfirmed: Boolean = false,
    )
    
    fun filterUsers(users: List<User>, filters: Filters): List<User> {
        return users
            .filter { !filters.filterByAdmin || it.isAdmin == filters.isAdmin }
            .filter { !filters.filterByConfirmed || it.isConfirmed == filters.isConfirmed }
    }
    
    fun getAdmins() {
        val users = getUsers()
        val filters = Filters(isAdmin = true, filterByAdmin = true)
        val admins = filterUsers(users, filters)
        println("Admins: $admins")
    }
    

    Over:

    data class Filters(
        val isAdmin: Boolean? = null,
        val isConfirmed: Boolean? = null,
    )
    
    fun filterUsers(users: List<User>, filters: Filters): List<User> {
        return users
            .filter { filters.isAdmin == null || it.isAdmin == filters.isAdmin }
            .filter { filters.isConfirmed == null || it.isConfirmed == filters.isConfirmed }
    }
    
    fun getAdmins() {
        val users = getUsers()
        val filters = Filters(isAdmin = true)
        val admins = filterUsers(users, filters)
        println("Admins: $admins")
    }
    

    To me, Filters(isAdmin = true) is a very easy to use API, where Filters(isAdmin = true, filterByAdmin = true), with the additional variable to avoid nullable booleans, is more verbose, for not much benefit and brings ambiguity. What if someone writes Filters(isAdmin = true), but forgets they need to set filterByAdmin = true for it to actually work? Easy mistake to make. We can prevent these mistakes by removing default values so they have to be specified on the call site, but then you need Filters(isAdmin = true, filterByAdmin = true, isConfirmed = false, filterByConfirmed = false), which is very verbose. Having two variables also allows your systems to get into invalid states:

    isAdmin = true, adminRightsHaveBeenValidated = false isAdmin = true, filterByAdmin = false

    What do these mean? It’s better for invalid states to be unrepresentable. Since these states are mutually exclusive, we should have only 3 states, not 4 which you get with 2 booleans. Which you could achieve with an enum True, False, None, but then you are just reinventing the wheel of nulls. You also get the issue that now you have to remember to always update both variables together.

    It all comes back to your point:

    it’d be idiomatic and reasonable to assume it to be false if we have no data

    You want to have ambiguous states, where a single value represents both “we have no data” and “we have the data, the answer is no”.

    • orgrinrt@lemmy.world
      link
      fedilink
      arrow-up
      1
      ·
      1 day ago

      Then you’d need to do something else.

      Precisely my point.

      And I’m not advocating for any of that. That’s just weird design, both of them, and as such a good example of something that warrants a bigger redesign in general.

      Just advocating for clear, sensible, self-documenting and most importantly, expandable and maintainable code.

      What’s idiomatic varies between languages and the conventions aren’t the same even then, when arguing across disciplines. This discussion seems to be more about different educations. I can get your point but from my personal experience in academia and working in the field it sounds undesired. But that’s just it. My, as in extremely limited, perspective. From your pov what you argue here is probably equally correct to what I think from mine is from my pov, it’s just a difference in the segment of the field we work in I suppose. Or plain old cultural differences.

      Whichever it is, I bet we both can find better use for our time. I’m thankful for the time and effort though, even if I wasn’t persuaded. Sorry to have prolonged it so.