1. 53
    1. 10

      Rust does something like this for structs. It’s fantastic. Definitely one of those quality-of-life things worth emulating.

      1. 1

        Yeah I was really envious of this feature coming from Rust! I’m so happy it made it into the language

      2. 10

        This is nice, kind of reminds me of JavaScript’s dict, in a different context:

        > var x = 42
        > var y = 0
        
        > var p = { x, y }  # you don't need {x: x, y: y}
        
        > console.log(p)
        { x: 42, y: 0 }
        
        

        Also works identically in YSH:

        ysh$ var x = 42
        ysh$ var y = 0
        
        ysh$ var p = { x, y }   # you don't need {x: x, y: y}
        
        ysh$ pp line (p)      # will become pp (x) in next release
        (Dict)  {x: 42, y: 0}
        
        
        1. 7

          I find JavaScript object destructuring and shorthands usage for arguments so elegant. There are no named arguments because you already have objects, so it’s free!

          1. 2

            Except for the heap allocated object 😉

            1. 2

              JS doesn’t guarantee that though. All literal cases could be optimised not to do that. I really hope JITs are clever enough.

              1. 1

                You can’t do this optimization on indirect calls

                1. 1

                  That’s what fallbacks / specialisation / tracing JIT is for. You always need the raw case accessible for eval() but that doesn’t stop the common paths from being optimised, even if the calls are indirect.

                  1. 1

                    All I’m claiming is that you can’t guarantee not allocating the intermediate object.

        2. 4

          I saw chatter last year on this coming to Python in some form this like

          x = 1
          y = 2
          result = foo(x=, y=)
          

          but I have a hard time determining whether it would be useful in practice. There hasn’t been any movement on it since January so maybe it’s been reconsidered.

          1. 6

            It’s useful for social reasons—it encourages the consistent use of longer and more descriptive names.

            As you say, it’s hard to see why foo(x=, y=) is better than foo(x=x, y=y), but it makes a lot more sense if the arguments were longer. For example, I have this type in a Rust program I maintain:

            pub struct HmrcExchangeRate {
                pub gbp: BigDecimal,
                pub start_date: NaiveDate,
                pub end_date: NaiveDate,
                pub currency: Currency,
            }
            

            You can immediately see how HmrcExchangeRate { gbp, start_date, end_date, currency } is an improvement over HmrcExchangeRate { gbp = gbp, start_date = start_date, end_date = end_date, currency = currency }. In particular, the compact form strongly encourages me to name start_date consistently throughout all my functions—otherwise, I don’t benefit from the shorthand. If I could only write out the longer constructor, I might just call the variable s instead and that would be less readable and less consistent.

          2. 3

            I agree this is a nice QoL improvement.

            While we’re talking about other languages which support this feature, Haskell supports it via (of course) the language extension NameFieldPuns. It also has RecordWildCards which lets you write Date{..} instead of Date{day, month, year} (both assume the variables day, month, and year are in scope). Some might argue that it is a little opaque (especially when used for constructing) but it can be really convenient too.

            1. 3

              OCaml has this too (no extensions needed though).

            2. 3

              This is a nice improvement, and yes it does remind of JavaScript’s nice object literal property shorthand.

              However, this paragraph stood out:

              Why didn’t I do it in the first place then? Short answer is I’m lazy and couldn’t be bothered writing the labels explicitly, and the labelled code doesn’t look particularly nice. “I don’t really need labels here, I know I’m passing arguments in the right order” are the last famous words.

              I don’t think the author is entirely to blame. This class of bug could have been prevented if argument labels were required, instead of just being available as an option to specify arguments out of order. Why is it up to every caller to be diligent about making call sites clear and readable? You could make that the job of the function writer. I do wonder if this would be impossible or ungainly due to interop with other BEAM languages.

              1. 1

                The bug would be prevented if dedicated types were used. And then the question is, are variable identifiers even needed anymore? :)

                1. 1

                  Would you mind showing what you mean in the context of this case?

                  1. 3

                    I mean that instead of the Date-constructor to expect two ints and a Month, it should expect a Year, a Month and a Day. So then string_to_int becomes string_to_day. And if doing so, the compiler would catch it, if year and day are being mixed up, because they are dedicated types.

              2. 2

                Gleam focus on simplicity and quality of life is so enjoyable !

                1. 1

                  Totally!! It’s such a fun and productive language, a breath of fresh air

                  1. 2

                    By the way I do enjoy your articles and your work on gleam a lot, thank you :)