1. 37
  1. 23

    The really interesting thing here is that the creator (betaveros) is using this specific language in the Advent of Code contest where he is currently number one on the leaderboard: https://github.com/betaveros/advent-of-code-2022

    Which is an interesting take on the concept of domain specific language.

    1. 10

      Operator precedence is customizable

      Okay.

      and resolved at runtime.

      What?

      noulith> f := \-> 2 + 5 * 3
      noulith> f()
      17
      noulith> swap +, *
      noulith> f() # (2 times 5) plus 3
      13
      noulith> swap +["precedence"], *["precedence"]
      noulith> f() # 2 times (5 plus 3)
      16
      noulith> swap +, *
      noulith> f() # (2 plus 5) times 3
      21
      

      … I will not use this language.

      1. 3

        I will not use this language.

        I think you’re missing the spirit of the language. It’s a language for fun, for puzzling, for golfing – a collection of the author’s favorite toys and his very own recliner, perfectly molded to his butt.

        It’s not for production code at work.

        1. 2

          Actually most of the language looks sensible/reasonable: a relatively small, functional-inspired, dynamically-typed scripting language. Just this feature that strikes me as completely unreasonable – in particular, destroying any hope of having a compiled implementation with good performance and without unfathomable complexity.

        2. 2

          Most of the lisp/scheme derivatives support rebinding functions, because they need worry no precedence, and the symbols are resolved at runtime anyway. I guess re-parsing the expression at runtime would be the natural next step, though the justification for doing that escapes my comprehension.

          1. 2

            If you can scope the changes to specific blocks then I can think of a million uses for this. I wouldn’t run any batch programs or scripts I’d share with other people, but as a supercalculator it’d be divine.

            1. 1

              I’m curious, what are the use-cases you have in mind for dynamically changing the precedence of infix operators?

              1. 1

                I was thinking more the swapping definitions thing, which should be useful to change functions externally. The only use I can think of swapping precedence off the top of my head is testing if two operators are associative with each other. I’d be curious to know what motivated his decision with this!

          2. 7

            Ever wanted to write x max= y while searching for some maximum value in some complicated loop? You can do that here. You can do it with literally any function.

            Oh my gosh I love this.

            We don’t have that problem because we don’t distinguish sets and dictionaries.

            I don’t love this as much.

            1. 4

              Ever wanted to write x max= y while searching for some maximum value in some complicated loop? You can do that here. You can do it with literally any function

              I do not understand what x max= y is supposed to do. Care to explain, maybe with an example?

              1. 8

                x=max(x,y)

                1. 6

                  Thanks for this! I now understand that max= is being understood the same way += is. Neat.

              2. 2

                I don’t love this as much.

                Why not? That’s how at least a few languages implement sets: hashtables/dictionaries with dummy values. Python, in particular, comes to mind.

                1. 3

                  This may have been true in the past, but I don’t think that python does this currently. Python’s dict implementation now guarantees order, but the set definitely does not.

                  1. 3

                    While they don’t share the same implementation (anymore?), Python sets are absolutely still implemented using a hashtable: https://github.com/python/cpython/blob/main/Objects/setobject.c

                  2. 1

                    What’s the union/intersection/difference of two dictionaries?

                    1. 2

                      What’s the union/intersection/difference of two dictionaries?

                      A dictionary containing union/intersection/difference of the keys of those two dictionaries?

                2. 2

                  I like this, both the content and the non-pretentious style. I do have questions/opinions, though:

                  particularly when I’m not on a dev computer

                  I didn’t see anything in the design about catering to this specific scenario. Is it just not there yet? I’m curious about design decisions around this, since my bread and butter language, Python, sucks sooo much in this aspect.

                  List concatenation is ++. String concatenation is $.

                  Hmmmmm, I don’t know. In one hand, I feel like Python got it so right by making addition and string and list concatenation look the same. On the other hand, the numpy/pandas ecosystem uses + to do element-wise addition, and I wonder if that isn’t actually more natural. I would suggest that maybe the first is better for glue code, and the second for numeric/data sciency code, but maybe I’m wrong.

                  For loops use left arrows: for (x <- xs) …. Use a double-headed arrow for index-value or key-value pairs: for (i, x <<- xs) ….

                  This is dope. Subtle, but smart, feels obvious once you learn it, and I feel that it’s a bit of syntax that would stick very easy, i.e., you learn it once and don’t get surprised by it anymore.

                  To close, one more question: what’s the \ for? I saw it in some expressions, waited for an explanation but didn’t find one.

                  1. 4

                    The \ starts a lambda, see

                    Lambdas look like \x, y -> x + y.

                    There are some good ideas in there. I wouldn’t have expected going all in in infix operators to turn out this readable

                    1. 1

                      Ah, cool, thanks!

                    2. 2

                      If anything, string concatentation should be the same as multiplication, since that’s how it’s written in mathematics. (Julia does it that way.)

                      1. 2

                        I’ve never heard of this, what should I Google?

                        1. 3

                          You can read Stefan Karpinski’s comments here for why it is how it is in Julia at least.

                          https://groups.google.com/g/julia-users/c/nQg_d_n0t1Q

                          I think Haskell et al got it right by using a non-arothmetic operator, personally, tho it’s not of huge consequence.