• 0 posts
  • 66 comments
Joined 2 years ago
Cake day: January 7th, 2024
  • Compared to what’s going on on Windows these are such non issues, and yet people are so dramatic about it. I installed Kubuntu almost 15 years ago and I’m on the same install still (going through several PCs with the same disk/image). Disabling snap took me 5 minutes many years ago and was never an issue, another 2 minutes for disabling the Ubuntu Pro message.

    Would it be better if these didn’t exist? Of course. But when comparing distros, this wouldn’t even be worth putting on a list of pros and cons. Is another distro better for your needs? Great. Is Ubuntu better for your needs? Also great, and surely if it is, then it taking 7 minutes longer to setup is not even a factor worth considering?

    If a friend had needs that I know Ubuntu fits best, I wouldn’t “not let them do it” for some ideological reasons, I’d just tell them to disable snap if they are not aware of it.

    This is the silly distro infighting that makes people avoid Linux.

    “Friends don’t let friends install hyped flavor of the week distros like CachyOS, popOS and Bazzite that will be out of the vogue in 3 years, instead of something that just works” is what I could’ve said just as well, but how about let people use what they want?

  • You should tell that to Linus Torvalds, he’s developing the Linux kernel without using GitHub at all. I’m sure he will appreciate being told git is insuffient to develop a good product and write good code, the best practice is to use a Microsoft service in a particular way and nothing else can work.

    Tell me, when I work on a project alone, who am I exactly requesting to pull my code and why do I need to use a feature of some git hosting website instead of reviewing, checking, debugging, merging, and reverting if necessary my change locally and using my CI/CD?

  • A high quality VR store where I can actually physically browse the isles would be superior to trying to browse a 2D website. And being able to pick up a product, with a realistic 3D model, look at it from any angle and visually compare packaging sizes across brands - like I can in a real store but can’t on a website - would be nice.

    I can’t tell you how many times I accidentally ordered a too small or too big version of something, because product photos on websites are always the same size (just fill the frame).

    Of course, this will never happen. If a store had a budget to make this, they could use that budget to make their online shopping website 10x better instead.

  • I have an Index, no, it’s far from “obviously compatible”. Yes you can get it working, but with many tradeoffs, performance issues, crashes, many VR games not working anyway even if the headset does, missing features outside the core functionality. And getting even to that state of not so easy unless you are on the correct distro with correct display manager.

    I wish you could do VR on Linux with an experience at least somewhat close to Windows. But that’s just not the case, so I need a Windows 10 VM to play VR.

  • 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”.

  • It is not more accurate nor less wasteful. If you default it to false and you have 100 admin requests in the session where that variable is stored, you would have to check with the database 100 times. Because you are conflating false to mean two things: “the user is not an admin” and “we don’t know if the user is an admin”. Where if you set it to true or false the first time we need the information, then subsequent requests don’t need to check anymore.

    does not have to worry about nulls

    I am used to null safe languages where there is no such thing as worrying about nulls, because not checking for null on a nullable type is a compile error, and so it’s impossible to forget about the null case. Maybe it’s why I don’t see any issue with using them.

  • Let’s say you have a website receiving 1 million requests per day. 0.01% of those are admin requests that need to know if your are an admin to execute them. It would be wasteful to check with the database if you are an admin for every request, when only a tiny minority of then needs to know that. So for 999.900 of the requests isAdmin will be null. We don’t know if the user is an admin and we don’t need to know.

  • Depends on your requirements.

    If the admin status needs to be checked in a database, but most actions don’t require authentication at all, it’s pointless to waste resources checking and it would be left null until the first action that needs the information checks it and fills it in as true or false.

  • So in a language with nullable types, are you against a boolean ever being nullable? Null means “empty, missing info”. Let’s say we have role variable with a enum type of possible roles. It could still reasonably be nullable, because in some scenarios you don’t know the role yet, like before log in.

    In any use case where we need to store some boolean, it’s a common occurrence that we don’t have the data and it’s null. It would be overkill to use an enum with True, False, NoData for these cases, where there is already a language feature made just for that, nullable values.

    I’ve never used TypeScript, just writing from experience in other languages.