• HiddenLayer555@lemmy.ml
    link
    fedilink
    English
    arrow-up
    1
    ·
    edit-2
    6 hours ago

    I mean, which one did you learn in math class? Not saying it’s better, but it’s way more common.

    • ☆ Yσɠƚԋσʂ ☆@lemmy.mlOP
      link
      fedilink
      arrow-up
      1
      ·
      5 hours ago

      If anything, I’d argue that superficial similarity to math notation is just more confusing when you’re learning imperative languages.

  • litchralee@sh.itjust.works
    link
    fedilink
    English
    arrow-up
    7
    ·
    edit-2
    14 hours ago

    I did indeed have a chuckle, but also, this shouldn’t be too foreign compared to other, more-popular languages. The construction of func param1 param2 can be found in POSIX shell, with Bash scripts regularly using that construction to pass arguments around. And although wrapping that call with parenthesis would create a subshell, it should still work and thus you could have a Lisp-like invocation in your sh script. Although if you want one of those parameters to be evaluated, then you’re forced to use the $() construction, which adds the dollar symbol.

    As for Lisp code that often looks like symbol soup, like (= 0 retcode), the equal-sign is just the name for the numerical equality function, which takes two numbers. The idea of using “=” as the function name should not be abnormal for Java or C++ programmers, because operator overload allows doing exactly that.

    So although it does look kinda wonky for anyone that hasn’t seen Lisp in school, sufficient exposure to popular codebases and languages should impart an intuition as to how Lisp code is written. And one doesn’t even need to use an RPN calculator, although that also aids understanding of Lisp.

    Addendum: perhaps in a century, contemporary programmers will find it bizarre that C used the equal-sign to mean assignment rather than equality, when the <= arrow would more accurately describe assignment, while also avoiding the common error of mixing up = and == in an if-conditional. What looks normal today will not necessarily be so obvious in hindsight.

    • porous_grey_matter@lemmy.ml
      link
      fedilink
      arrow-up
      3
      ·
      14 hours ago

      perhaps in a century, contemporary programmers will find it bizarre that C used the equal-sign to mean assignment rather than equality, when the <= arrow would more accurately describe assignment

      Maybe they’ll find a better symbol than the one we already use for less than or equal to.

  • davel [he/him]@lemmy.ml
    link
    fedilink
    English
    arrow-up
    5
    arrow-down
    3
    ·
    edit-2
    14 hours ago

    Notice that they have the same number of parenthesis. People say that lisps have a lot of parentheses, but they have the same number as any other language that uses parentheses to make function calls.

    • Oriel Jutty :hhHHHAAAH:@infosec.exchange
      link
      fedilink
      arrow-up
      9
      arrow-down
      2
      ·
      13 hours ago

      This is false. Lisp uses parentheses where other languages use (), [], {} or nothing at all. For example, in C I can write int i = 0, but the equivalent Lisp code involves three pairs of parentheses. Or take something like a[i] = f(i + 1) / 2 + p. The equivalent Lisp code is something like (setf (aref a i) (+ (/ (f (+ i 1)) 2) p)), and you can’t tell me that’s not a lot of parentheses.

      • ☆ Yσɠƚԋσʂ ☆@lemmy.mlOP
        link
        fedilink
        arrow-up
        2
        ·
        10 hours ago

        This is false, Lisp is a family of languages. Clojure is an example of a Lisp where you have different types of literals using () for lists, [] for vectors, {} for maps, and #{} for sets. Furthermore, there are plenty of libraries for doing infix syntax which can be trivially expressed using macros. For example, infix library in Clojure lets you write math using infix syntax. That said, it’s pretty rare that you’re actually writing a bunch of math expressions in regular code unless you’re working in a specific domain, so this hardly comes up in practice.

        • OK, my code snippets are Common Lisp. But note that none of them involve list/vector/set literals. I was thinking of [] for array indexing and {} for code blocks.

          As for infix macros, sure, that’s not hard to do, but it’s not built into the language and there being “plenty of libraries” is part of the problem: They’re all subtly different, none are standard, and I suspect most people don’t use them anyway. (Plus there’s fun little design issues like whether a*x + b should parse the same as a * x + b, and if it does, then how do you refer to a variable called a*x from an infix environment?)

          It doesn’t solve the main issue anyway. Take this snippet from the “infix” readme:

          (def hypot  (fn [x y]    (infix sqrt(x ** 2 + y ** 2))))
          

          It ends with a cluster of )))) (reinforcing the “lots of parentheses” impression) and all of those parentheses mean something different: From the outside in, we have the end of a symbol definition (def ...), the end of a function (fn ...), the end of a macro invocation (infix ...), and the end of a function call sqrt(...). It definitely isn’t just “the same number [of parentheses] as any other language that uses parentheses to make function calls”.

          Compare e.g. these versions written in Haskell:

          hypot = \x y -> sqrt (x ** 2 + y ** 2)
          

          … or Perl:

          sub hypot($x, $y) {    sqrt($x ** 2 + $y ** 2)}
          

          … or if you want to separate the function and symbol definition parts:

          *hypot = sub ($x, $y) { sqrt($x ** 2 + $y ** 2) };
          
          • ☆ Yσɠƚԋσʂ ☆@lemmy.mlOP
            link
            fedilink
            arrow-up
            1
            ·
            5 hours ago

            OK, my code snippets are Common Lisp. But note that none of them involve list/vector/set literals. I was thinking of [] for array indexing and {} for code blocks.

            Again, Clojure uses vectors for arguments, so you end up with syntax like this which provides the same visual information as any mainstream language.

            It doesn’t solve the main issue anyway. Take this snippet from the “infix” readme:

            Yes it does actually because you have syntax hints indicating the type of data structure you’re looking at. For example, in the snippet you highlight, the function arguments are in a vector.

            It ends with a cluster of )))) (reinforcing the “lots of parentheses” impression) and all of those parentheses mean something different

            First of all, you have exact same amount of parens as you would in a mainstream language like Java, C, or Js. Second, the parens do mean the same thing in that example. The big benefit with s-exps though is that you have structural editing, and you don’t actually manage parens by hand or even think about them. You treat expressions as building blocks that you manipulate and compose together. There’s nothing even remotely comparable to this available in languages like Haskell.

            However, here’s an example for you where you don’t have same parens.

            (defn foo [{:keys [x y]}]
              (let [z (str x " " y)]
                {:result z}))
            

            here you have different data structures manipulated, and you have different parens representing them.

            From the outside in, we have the end of a symbol definition (def …), the end of a function (fn …), the end of a macro invocation (infix …), and the end of a function call sqrt(…). It definitely isn’t just “the same number [of parentheses] as any other language that uses parentheses to make function calls”.

            It’s just broken down in the example. In practice you have defn and you just write:

            (defn hypot [x y]  (infix sqrt(x ** 2 + y ** 2)))
            

            The huge advantage over Haskell is that syntax is very simple and regular. You don’t have to think about it at all. Languages like Haskell and Perl introduce a lot of mental overhead because you have to memorize all the special cases and behaviors the syntax introduces. You can write really concise code, but there’s a cost to it. There’s a reason people refer to Perl as a write only language. On the other hand, Clojure hits the sweet spot of being very concise without needing a complex syntax.

            • I disagree with pretty much everything you write here, but especially this:

              First of all, you have exact same amount of parens as you would in a mainstream language like Java, C, or Js.

              My Perl example uses “mainstream language” syntax. Apparently that doesn’t count because it’s Perl (scary! mental overhead! write only!), so here’s exactly the same thing in JavaScript:

              function hypot(x, y) {    return Math.sqrt(x ** 2 + y ** 2);}
              

              … or

              const hypot = function (x, y) {    return Math.sqrt(x ** 2 + y ** 2);};
              

              … or

              const hypot = (x, y) => Math.sqrt(x ** 2 + y ** 2);
              

              Note how none of these involve four layers of nested parentheses.

    • ☆ Yσɠƚԋσʂ ☆@lemmy.mlOP
      link
      fedilink
      arrow-up
      7
      ·
      14 hours ago

      I find one huge advantage of Lisp syntax is that you can visually see relationships in code by following the nesting. It’s like having a diagram embedded for free once you get used to reading it.