• 2 Posts
  • 31 Comments
Joined 2 years ago
cake
Cake day: June 19th, 2023

help-circle




  • I mean if you like something you gotta be able to critique it. Especially when you can see things taking a turn for the worst.

    Also I was using Apple stuff very stuff actively my last phone just wasn’t an iPhone. I still have my iPad, Apple Watch, … .

    Also I think I’m not just a hater. As I said, stock iOS Apps have made massive progress and run circles around Googles Stock Apps not to mention that the XS despite being 5,5 years old still is fast and feels quite modern hardware wise.










  • Unpopular opinion perhaps, but I rather have a language that allows me to implement hacky solutions than one that requires me to completely scrap and rearchitect everything.

    I for example once had to overwrite a dozen or so of prototype methods in a JS class because the library a we were using just fell apart when doing certain things inside a Shadow DOM - it was a library that was released long before that feature. And completely rewriting huge chunks of code that interacted with that library would have wasted 100s of hours and the end result might have been really akward as well since many other systems are architected around how that one library worked. So instead it was a matter of patching in a few checks and workarounds for shadow dom elements.

    And since its extremely well documented why we decided to to that, what these hacks do I don’t see an issue with that. Obviously this shouldn’t be the modus operandi everytime but its always good to have the option i.m.o. to dig yourself out of a hole.



  • for me the biggest thing was the whole strict enforment of nullability - doesn’t always play nice with existing java code, builders (essentiay abusing the anonymous function syntax) and delegations.

    Its just very odd when you see some code from someone else who really goes to town with these things.

    Also just in general its very different approach from Java where you have to do everything with very basic but easy to understand tools while Kotlin gives you a giant toolbox to play with, but where many tools have a certain learning curve.

    But in that toolbox there are some gems. My favorites being extension methods null safe calls and pattern matching with when.


  • I’d personally go for a native App in Java with the older android.view and android.widget UI library which I not only find more intuitive for beginners but which also have a neat drag and drop UI designer built into Android Studio. Also once you are comfortable in Java you can easily add Kotlin into your existing project but for the start I’d start with Java since Kotlin throws lots of new stuff and rules at you in the beginning.

    These are just my opinions but I’d generally stay away from multiplatform frameworks like flutter, react native, maui, … if you don’t need the multiplatform aspect. They generally make it more difficult to work with lots of low level APIs (like the step counter, fitness data, …). Also all of them suffer from my experience from being harder to debug and “cryptic error messages syndrome” (especially Maui).

    Also the new Jetpack and Compose stuff in Android I personally find quite hard to get going with. But thats maybe just me being more used to the old stuff.





  • Essentially a function that doesn’t produce side effects, like modifying variables outside of its scope or modifying the function parameters. This something you should always try to incorporate into your code as it makes it much easier to test and makes the function’s use less risky since you don’t relay on external unrelated values.

    To give you an example in JavaScript, here are two ways to replace certain numbers from an other list of numbers with the number 0

    first a way to do it with a non pure function :

    let bannedNumbers = [4,6]

    const nums = [0,1,2,3,4,5,6,7,8,9]

    function replaceWithZero(nums){
        for (let i = 0 ; i < nums.length; i++){
            if (bannedNumbers.includes(nums[i])){
                nums[i] = 0
            }
        }
    }
    replaceWithZero(nums)
    console.log("numbers are : ", nums)
    

    here the function replaceWithZero does two things that make it impure. First it modifies its parameter. This can lead to issues, for example if you have Second it uses a non-constant variable outside of its scope (bannedNumbers). Which is bad because if somewhere else in the code someone changes bannedNumbers the behavior of the function changes.

    A proper pure implementation could look something like this :

    const nums = [0,1,2,3,4,5,6,7,8,9]
    function repalceWithZero(nums){
        const  bannedNumbers = [4,6]
        const result = []
        for(const num of nums){
            result.push(bannedNumbers.includes(num) ? 0 : num)
        }
        return result
    }
    const replaced = replaceWithZero(nums)
    console.log("numbers are : ", replaced)
    

    Here we are not modifying anything outside of the function’s scope or its parameters. This means that no matter where, when and how often we call this function it will always behave the same when given the same inputs! This is the whole goal of pure functions.

    Obviously in practice can’t make everything 100% pure, for example when making a HTTP request you are always dependent on external factors. But you can try to minimize external factors by making the HTTP request, and the running the result only through pure functions.


  • For new code I’m writing I’m using mostly JsDoc function headers on public methods of classes and exported functions. With one or two sentences explaining what function does.

    Also try to explain what to expect in edge cases, like when you pass am empty string, null, … stuff of that nature - for which I then create unit tests.

    I also always mention if a function is pure or not or if a method changes the state of its object. On a sidenote I find it odd that almost no language has a keyword for pure functions or readonly methods.

    If I add a big new chunk of code that spans multiple files but is somewhat closed off, I create a md file explaining the big picture. For example I recently added my own closed off library to my angular frontend that handles websocket stuff like subscribing, unsubscribing, buffering, pausing,… for which a created a md file explaining it.