[HN Gopher] N-Params vs. Single Param
       ___________________________________________________________________
        
       N-Params vs. Single Param
        
       Author : carlos-menezes
       Score  : 31 points
       Date   : 2025-04-17 18:23 UTC (4 hours ago)
        
 (HTM) web link (www.carlos-menezes.com)
 (TXT) w3m dump (www.carlos-menezes.com)
        
       | disillusionist wrote:
       | I started using this pattern years ago and haven't looked back.
       | React components are defined using a single properties param and
       | it feels natural to extend the practice to other methods and
       | helper functions that I write.
       | 
       | One nice unexpected side effect is that I end up with more
       | consistency in variable naming when using a param object in order
       | to benefit from object definition shortcuts.
       | 
       | ie I will usually write something like                 const
       | firstName = getFirstName(); doTheThing({ firstName });
       | 
       | rather than                 const fName = getFirstName();
       | doTheThing({ firstName: fName });
        
         | carlos-menezes wrote:
         | Likewise. Even if the input object only has a single property,
         | I'll still use this pattern.
        
           | disillusionist wrote:
           | because i'm likely going to refactor this function "tomorrow"
           | with additional properties. :)
        
         | hyperhello wrote:
         | What bothers me a lot is that return values can't have a name.
         | Suppose I have a function
         | 
         | string combineName(string first, string last);
         | 
         | Okay, I _assume_ the result is the full name, but I don 't
         | really know that like I would if the return had a name in the
         | header. (The function can be getFullName, yes, but that's so
         | simple it doesn't matter).
        
           | geakstr wrote:
           | Some languages allow to define type alias, name of this type
           | can be self-explanatory:                 type FullName =
           | string;       function combineName(first: string, last:
           | string): FullName;
           | 
           | Also documentation comment for function is what specifically
           | solves this - describes what function does and returns.
        
             | hyperhello wrote:
             | Neither really addresses the issue. Making a type for a
             | single kind of string seems like an abuse of types just to
             | shoehorn the documentation in. Documentation can be used
             | directly of course, but that moots all of this -- just
             | document? Yeah, but naming the variable is super quick
             | compared to either.
        
           | disillusionist wrote:
           | you can do this rather easily by returning an object rather
           | than a primitive. if you're using a language like TypeScript,
           | destructuring the resulting returned object is rather trivial
           | and (in my opinion) delightful to read. eg
           | function combineNames({ first, last }) {         const
           | fullName = `${first} ${last}`;         return { fullName };
           | }       const { fullName } = combineNames({first: 'John',
           | last: 'Doe' });
        
       | 9d wrote:
       | > No guessing. No worrying about the order. Your code is self-
       | documenting. Plus, TypeScript gives you full autocompletion and
       | type safety.
       | 
       | 1. Most of the time, arguments are not the same type, so if
       | you're using TypeScript, you're already getting errors at this
       | point. In your example, only first/last names might get mixed up.
       | And if you still get those wrong while writing that code, you're
       | just phoning it in atp and maybe should take a day off.
       | 
       | 2. The same TypeScript that checks your types, also lets you see
       | the signature when hovering over the function.
       | 
       | In real world coding, this isn't an issue, and you'll probably
       | give up keeping this "rule" after a year or two. But good that
       | you're at least thinking about these kinds of things.
        
         | carlos-menezes wrote:
         | It's a preference grounded in long-term ergonomics that work
         | well for me. I've been using this "rule" for over two years now
         | and haven't found a reason to give it up.
        
       | hwpythonner wrote:
       | Not an expert in JS, but maybe this makes sense in JS where
       | everything is passed as objects anyway and having a single param
       | is often more readable there.
       | 
       | But in native languages like C/C++/etc, this pattern usually
       | hurts performance. Separate arguments go into registers (faster
       | but depends on number of arguments), while structs often involve
       | indirection, and sometimes alignment/padding issues. Also,
       | passing a const struct doesn't guarantee the fields inside are
       | truly const.
       | 
       | That said, it's context dependent. If you're passing stuff
       | through multiple layers or want a more stable function signature,
       | using a struct can be cleaner. Just not something I'd generalize
       | to any language or any use case.
        
         | taeric wrote:
         | I think the dream has long been that a compiler could optimize
         | away any inefficiencies that can be mechanically described. As
         | such, if there is a benefit to seeing the same structure in
         | many places, using a struct would be ideal.
         | 
         | I don't think we are near said dream, yet.
        
         | dicytea wrote:
         | Doesn't seem to be a problem, at least for Rust:
         | https://godbolt.org/z/fToxz3d7a.
         | 
         | Functions with plain arguments and a struct both produce
         | identical assembly output.
        
           | carlos-menezes wrote:
           | C++ for reference: https://godbolt.org/z/7G6qxK6T8
        
             | hwpythonner wrote:
             | Try compiling with optimizations. I think by default this
             | site doesn't add optimization flags.
             | 
             | Here what happens with optimizations:
             | https://godbolt.org/z/G18zd7chP
             | 
             | Look at the registers usages vs stack
        
               | carlos-menezes wrote:
               | Got it! Thanks for the link.
        
           | physicsguy wrote:
           | If you add a third argument you get different assembly
        
           | airstrike wrote:
           | Also worth noting clippy will warn about writing functions
           | with too many arguments for the same reason listed in TFA
           | 
           | https://rust-lang.github.io/rust-
           | clippy/master/index.html#to...
        
         | the_other wrote:
         | I've seen some evidence it hurts performance in JS, too. If
         | you're doing something "a lot", like media qstreaming, or
         | realtime updates, ordered params are likely faster.
         | 
         | I agree with others that the destructuring is a nice syntax to
         | read and write. Yet, I have started to feel it's an overused
         | pattern, deployed by habit rather than consideration (in my
         | code anyway). I can't put my finger on why. It's possibly a
         | gut-feel that my functions would be better taking feeer
         | arguments.
        
       | tantalor wrote:
       | "Avoid the Long Parameter List"
       | 
       | https://testing.googleblog.com/2024/05/avoid-long-parameter-...
        
       | joeyagreco wrote:
       | In my opinion, this is the _only_ way to handle n-param functions
       | in production code.
        
       | sixo wrote:
       | A little while ago I sketched some ideas for a programming
       | language [1], one of which was that I would like a language who
       | did not distinguish between these two cases. Obviously you can
       | always write a function with a single N-param argument, but it's
       | rather verbose, but would be nice to also be able to write the
       | param list normally and then refer directly to its parameter type
       | elsewhere. Although this would require that the "set of possible
       | parameter lists" were the same as "the set of possible object
       | type", which isn't the case in any language I know of.
       | 
       | [1]
       | https://samkrit.ch/2025/03/09/programming-1.html#anonymous-t...
        
         | feoren wrote:
         | Isn't C#'s named arguments basically what you want? You can
         | choose to use the names or not at the time of calling the
         | function. You can name some arguments but not others. Don't
         | many programming languages have this feature?
        
         | intrepidhero wrote:
         | I had a similar thought while designing my dream programming
         | language but I also wanted automatic currying and I couldn't
         | figure out an ergonomic way to have both.
         | 
         | Now I'm gonna go read your blog series.
        
       | krystofee wrote:
       | This is just because TS doesnt have keyword or keyword-only
       | arguments as Python for example has.
        
       | mx-bojangles wrote:
       | I agree that the example is easier to read with the single object
       | param. It might be even easier to read using a fluent interface
       | or a builder pattern. You should choose the best tool for the
       | job.
       | 
       | As a counter-example, I prefer                   setEnabled(item,
       | true);
       | 
       | to                   setEnabled({item: item, isEnabled: true});
        
         | janalsncm wrote:
         | If I have five parameters and they all need to be set
         | (otherwise the object is invalid), think of a constructor as a
         | sort of builder pattern that does all five at once and avoids
         | checking for invalid states (e.g. you only set 3 of the
         | variables) in other methods.
        
       ___________________________________________________________________
       (page generated 2025-04-17 23:00 UTC)