• TomasEkeli@programming.dev
    link
    fedilink
    arrow-up
    2
    ·
    6 hours ago

    Opinion: if the method takes a boolean it should be split to two methods. If it takes two bools it’s four methods in a trench-coat.

  • JakenVeina@midwest.social
    link
    fedilink
    arrow-up
    6
    arrow-down
    1
    ·
    17 hours ago

    Yup, I’ve taken to doing this exact same thing in TS/JS. That is, defining functions to take an options object instead of multiple parameters.

    It’d be much nicer if TS/JS could support named parameter binding, like many other lanaguages, cause that’s what I do as a nearly universal rule, in every language that supports it.

    No, having an IDE inject paramter names in the editor is not a solution. Not only does it always look like shit, because none of them have any concept of formatting for readability, it also means the code then becomes unreadable outside of an IDE (and user configuration) with that feature.

  • jtrek@startrek.website
    link
    fedilink
    arrow-up
    47
    arrow-down
    1
    ·
    1 day ago

    I use keyword arguments in Python to minimize this pain. Instead of

    
    create_user("Bob", True, False)
    

    it’s

    
    create_user(name="Bob", admin=True, send_email=False)
    

    JavaScript makes that more cumbersome with the object thing , but it’s better than nothing.

    • Eager Eagle@lemmy.world
      link
      fedilink
      English
      arrow-up
      20
      ·
      edit-2
      1 day ago

      This! There’s also a longstanding open issue on rust to allow a similar way to pass keyword/named arguments. IMO every modern language should have something like this. Makes all the difference when reading code.

      Inlay hints from your editor are a good help, but this should be built into the language.

      • calcopiritus@lemmy.world
        link
        fedilink
        arrow-up
        7
        ·
        9 hours ago

        Not saying that named parameters are bad, but the builder pattern serves the same purpose and imo it’s more ergonomic.

        TrainBuilder::new()
          .with_electric_motor(true)
          .with_width(1.0)
          .build()
        

        I don’t care about the color of the train or the amount of wheels, I just want the default train with a few changed parameters.

        If you do named parameters in rust, you would need to set every parameter. The only way to not set every parameter is to give a special meaning to the Default trait. But that is uncommon to happen in rust. And many structs that could easily derive Default don’t.

        • Eager Eagle@lemmy.world
          link
          fedilink
          English
          arrow-up
          1
          ·
          2 hours ago

          If you do named parameters in rust, you would need to set every parameter.

          If that’s the condition, yeah, it’s bad. The good thing about how Python handles it is that they can still be mandatory or optional. And that makes it a more flexible option than the builder pattern because it applies to any function or method.

      • FizzyOrange@programming.dev
        link
        fedilink
        arrow-up
        10
        arrow-down
        1
        ·
        22 hours ago

        Rust doesn’t need this as much because it has enums so you can just do create_user(user, Role::Admin, Notify::None).

        • Eager Eagle@lemmy.world
          link
          fedilink
          English
          arrow-up
          9
          ·
          21 hours ago

          you can have a better data structure in any language, but rarely someone will bother doing that for booleans

          • FizzyOrange@programming.dev
            link
            fedilink
            arrow-up
            1
            ·
            42 minutes ago

            Yeah I do wonder if we need an easier way to declare these things because programmers are lazy and even in Rust I wouldn’t always bother.

            You can kind of do it in Typescript with strings:

            function create_user(role: "admin" | "normal")
            

            But of course the downside is they are strings at runtime. I’m sure it’s possible though.

          • Traister101@lemmy.today
            link
            fedilink
            arrow-up
            3
            ·
            18 hours ago

            Right cause the boolean isn’t a named type. If you have two possible states that can be represented with a boolean, or an enum of the two possible states which embeds more info into the callsite

    • ugo@feddit.it
      link
      fedilink
      arrow-up
      5
      ·
      24 hours ago

      zig uses anonymous structs for the same effect

      doWork(.{
          .flurbify = true,
          .flurbification_intensity = 1001,
      });
      
    • Riskable@programming.dev
      link
      fedilink
      English
      arrow-up
      3
      ·
      1 day ago

      Thank you for posting this comment. I came here to write the exact same thing and now I don’t have to!

      👍

  • samc@feddit.uk
    link
    fedilink
    English
    arrow-up
    5
    arrow-down
    1
    ·
    19 hours ago

    Agree with several people here that named parameters are a good solution, they add minimal overhead at the call site and function declaration and look very natural.

    Another option for languages that want function arguments to have fixed size is bitmasks. I wonder if it could be a useful language feature to infer the flag names from the function declaration. Something like

    def my_function(arg1, arg2, [FLAG1, FLAG2]) {
        if (FLAG1) {
            do thing
        } 
       ...
    }
    
    my_function(val1, val2, FLAG1 | FLAG2)
    
  • CodexArcanum@lemmy.dbzer0.com
    link
    fedilink
    English
    arrow-up
    14
    arrow-down
    4
    ·
    1 day ago

    Good IDEs have multiple ways of showing you this info, and many languages have named parameters that fix this. Also, just putting a comment on them is not a crime, it just won’t update when you change the function but then your IDE can often only do so much at call sites, so you often need to update the calls (and the comments) manually. I’m sure LLM agents can change both as well.

    Or, in JavaScript like these examples were, yeah, just pass in an object. Passing in an object should be standard in JS when you have more than like 2 params anyway because it solves several issues with parameter identification, optional parsms, method overloading, and so on. And JS passes everything by reference so you aren’t losing performance.

      • draco_aeneus@mander.xyz
        link
        fedilink
        English
        arrow-up
        2
        ·
        17 hours ago

        Indeed. There will be lots of times when you’ll be reading code without a while IDE attached. When doing code reviews in the browser, when looking at patch files or git diffs in the command line, when browsing code files on some git host, or when you’ve gone to a confrence and you left your laptop in the hotel room because Steve from accounting assured you it would just be a meet-and-greet with clients, but then some production bug hit and every odd-numbered request is returning a 401 for some reason, so you need to borrow Steve’s laptop to fix this.

  • schnurrito@discuss.tchncs.de
    link
    fedilink
    arrow-up
    9
    arrow-down
    1
    ·
    1 day ago

    That’s why IntelliJ shows you, in these kinds of cases, the names of the parameters where the function is called…

    There are also languages, like Scala and Swift, with named parameters, which also solve this problem.

    • qprimed@lemmy.ml
      link
      fedilink
      English
      arrow-up
      20
      arrow-down
      1
      ·
      1 day ago

      but isn’t that just using tooling to de-obfuscate code that should be clear to begin with?

      passing structs, dicts, whatever keeps the code clear, expressive and extensible. if I can bake-in flexibility and clarity without being overly focused on performance, I am choosing the former every time.

    • nous@programming.dev
      link
      fedilink
      English
      arrow-up
      13
      ·
      1 day ago

      You shouldn’t need tooling to fix an issue. Better for a design that does not require extra tooling.

    • brianpeiris@lemmy.ca
      link
      fedilink
      English
      arrow-up
      2
      arrow-down
      1
      ·
      18 hours ago

      IntelliJ doesn’t help when you’re doing a code review, or just reading through hundreds of lines of code, I don’t want to move my mouse or cursor over every line to see the parameter names.

      • draco_aeneus@mander.xyz
        link
        fedilink
        English
        arrow-up
        3
        ·
        17 hours ago

        I agree with you. However, I think you’ve misunderstood what inlay hints look like. Here’s an example.

        IntelliJ inlay hint example

      • Traister101@lemmy.today
        link
        fedilink
        arrow-up
        2
        ·
        18 hours ago

        By default inlay hints are enabled so you wouldn’t have to do that. But yeah it’s tied to using the editor which makes it a non solution

    • Riskable@programming.dev
      link
      fedilink
      English
      arrow-up
      2
      arrow-down
      3
      ·
      24 hours ago

      If your language requires an IDE to show you WTF is going on in the code, it’s a bad language.

      Given, there’s ways to write poor code in any language, but some are much, much worse than others. Java and JavaScript being the kings of that kind of thing.

      Some day, AI assisted coding will become so intelligent that it will look at your average “enterprise” Java code and ask the user, “WTF were they even trying to do here?” Which is the only correct response a lot of the time.

      • sbeak@sopuli.xyz
        link
        fedilink
        English
        arrow-up
        1
        ·
        7 hours ago

        Conversely, most software developers look at LLM-gen (LLMs are not proper artificial intelligence since they don’t understand what you’re feeding it) code and say “WTF were they even trying to do here?”

        Indeed, AI (not LLMs, mind you, but AI) does have its use cases. For instance, in science, there are many fields where mass processing of data by conventional means is unfeasible. And in programming, using AI to help detect bugs so that an experienced developer, knowing how to troubleshoot and with context of the project’s aims and scope, can fix the issue more easily.

        LLM-gen code is very fragile and filled with loads of bugs, not to mention how the code it writes does not credit the original authors, as it ignores licensing and attribution requirements of projects that were scraped for its data set. And half the time, people producing LLM-gen code do not understand what it has produced and does not bother to review it before trying to push it to a large project, leaving the burden of filtering it out for those maintaining the project (when that effort could be directed at adding new features, fixing bugs, or doing anything else really)

  • kibiz0r@midwest.social
    link
    fedilink
    English
    arrow-up
    5
    arrow-down
    1
    ·
    1 day ago

    TypeScript doesn’t really save this

    TypeScript tells me the values are booleans. That’s not really the problem.

    The types are technically correct. I still have to remember what the arguments mean.

    You could use branded/tagged types. Probably not useful in these narrow, one-off occurrences. But if you have a concept that applies across your whole domain, they can be useful.