Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't use lisp languages, but one basic difference this has from other lisps is that functions accept multiple expressions, e.g.:

    (defn greet [firstname lastname]
      (def fullname (string firstname " " lastname))
      (string "Hello, " fullname))
In other lisps, you'd have the last expression nested inside a `let` block:

    (defn greet [firstname lastname]
      (let [fullname (string firstname " " lastname)]
        (string "Hello, " fullname)))
which makes the code hard to read and edit IMO. Languages like Haskell and OCaml suffer from a similar problem too.


> which makes the code hard to read and edit IMO. Languages like Haskell and OCaml suffer from a similar problem too.

That's interesting, I've always really loved the "return last expression in a block" syntax. (Ruby and Rust can be added to your list as well.) That syntax just reads really naturally to me.


I like that too, but both Rust and Ruby allow multiple expressions/statements before the last expression. In Haskell and OCaml IIUC you need to use things like `let x = ... in <expr>` or `<expr> where x = ...`, so you still have a single expression in function bodies.


Common Lisp:

    (defun greet (firstname lastname &aux fullname)
      (setf fullname (format nil "~a ~a" firstname lastname))
      (format nil "Hello, ~a" fullname))


In common lisp `defun` does not require using `let`.


There are two things at play here (1) the implicit body and (2) being able to add new bindings in an existing scope with "def".

CL has an implicit body, but does not allow defining new bindings outside of some dedicated forms (let, etc.). I really prefer having to write "let" forms instead of having new variables added inside the body.


in Racket you can do it either way, and perhaps these sorts of issues should just be solved with an auto code formatter?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: