👾 Game Player 🎲 Dice Jailor 💻 Functional Typer 📹 Content Creator 🎧 Air Wiggler 🏹 Arrow Shooter ⛔️ Out of Charac

dneaves.com

  • 0 Posts
  • 7 Comments
Joined 2 years ago
cake
Cake day: July 10th, 2023

help-circle
  • Functional language developers are obsessed with side effects but I rarely ever see problems with it in real code. Like I can remember once in maybe 10 years setting a developer write a “get” method that also wrote to a file. Caught during code review, rewritten easily.

    While, sure, get methods writing files could happen in side-effectful code, the side-effect concern is less about that and more of expectations. With OOP languages, class methods can create a dichotomy of expected returns: Using a list reversal as an example, will a list.reverse(some_list) function reverse the list in-place, or return a copy of the reversed list and leave the original in-tact? To know the answer, you have to check the docs or the type signature (which, yes, is easy, but the answer isn’t obvious). Which, the main concern is trying to debug things “magically changing”, since nested function calls and inherited function calls can modify something from layers upon layers of abstraction away.

    FP languages tend to not have this dichotomy, with very few exceptions like IO in Haskell, ports in Elm and Gren, external functions in Gleam, or FFI in Haskell, to name some ways from languages I know, all of which usually move the control of the program outside the language’s “default area”, anyway. Outside the exceptions, to reverse a list a reverse function needs to be given that list explicitly, and it also will be returning a copy of the list reversed, only and always





  • When the enum reaches your JSON, it will have to be a string (as JSON does not have a dedicated “enum” type). But it at least ensures that languages parsing your JSON will should have a consistent set of strings to read.

    Consider this small bit of Elm code (which you may not be an Elm dev, and thats okay, but it’s the concept that you should look to get):

    -- A Directions "enum" type with four options:
    -- North, East, South, West
    type Directions
        = North
        | East
        | South
        | West
    
    -- How to turn each Directions into a String
    -- Which can then be encoded in JSON
    directionsToString : Directions -> String
    directionsToString direction =
        case direction of
            North -> "north"
            East  -> "east"
            South -> "south"
            West  -> "west"
    
    -- "Maybe Directions" since not all strings can be parsed as a Directions.
    -- The return will be "Just <something>" or "Nothing"
    directionsFromString : String -> Maybe Directions
    directionsFromString dirString =
        case dirString of
            "north" -> Just North
            "east"  -> Just East
            "south" -> Just South
            "west"  -> Just West
            _       -> Nothing
    

    The two functions (directionsFromString and directionsToString) are ready to be used as part of JSON handling, to read a String from a key and turn it into a Directions enum member, or to turn a Directions to a String and insert the string to a key’s value

    But all that aside, for your restructuring, and keeping with the license plate example, both type and license number could be contained in a small object. For example:

    {
        ...
        "licensePlate": {
            "type": "government"    <- an enum in the language parsing this
                                       but a string in JSON
            "plateNumber": "ABC123"
            ...
        }
        ...
    }
    

  • If its something that represents mutually exclusive states, like the license plates examples (Gov’t, Embassy, Learner), an enum like 4wd mentioned is a better idea than many boolean keys. This would also be the switch/case question you posed. For a “regular case”, I would include that in the enum, but if you create an enum that only contains “special cases”, you can always set it to null.

    On the case of booleans, I would suggest avoiding them unless it is necessary, and truly a binary (as in, two-option, not binary numbers), self-contained-in-one-key thing (obligatory anti-boolean video). If the use case is to say what a different key’s object represents, you don’t need it (see: enums. You’ll thank yourself later if you add a third option). If the use case for using it is saying another key contains value(s), you don’t need it. Many languages can handle the idea of “data is present, or not present” (either with “truthy/falsey” behavior interpreting “data-or-null”, or “Maybe/Option” types), so often “data-or-null” can suffice instead of booleans.

    I would suggest trying to always include all keys of a present object, even if it’s value is null or not applicable. It will prevent headaches later when code might try to access that key, but it isn’t present. This approach might also help you decide to reduce the quantity of keys, if they could be consolidated (as in taking booleans and converting to a state-like enum, as mentioned above), or removed (if unused and/or deprecated).


  • Essentially, there is a massive pixel-divided canvas. It starts out pure-white.

    You are allowed to place one single pixel of a certain subset of colors every x minutes (I don’t remember how often, somewhere between 5 minutes to an hour).

    Your pixel(s) can be overridden by any other user who places their pixel on your space after you place yours.

    Some people come together to form collaborative art, messages, etc. (As seen here).

    In the past, there have been countries’ flags, a giant spreading black void, hidden Among Us beans, and many fandom-specific and subreddit-specific images.