3

I am fascinated to Lisp as it is simple yet powerful. I am just a beginner and I know there have been lots of discussions on removing parentheses from Lisp and its dialects. Yet I request Lisp ninja's to take few minutes answering this.

Will there be any side effects in Lisp/Clojure if they had followed 2 conventions below:

;; function declaration
defn function-name param-1 .... param-n
  ...
  function-body ;; not (function-body)
  ...

;; function call
function-name param-1 ... param-n ;; not (function-name param-1 ... param-n)

While still using () or [] for inline and nested expressions.

(println "hello, ") (println "world !!!") ;; inline    
= a (- 2 3) ;; nested
4
  • 2
    parsing would be more complicated, and you'd have the tab vs. space war happening Jan 17, 2014 at 11:36
  • will it have any problem implementing macros and other stuff?
    – user115126
    Jan 17, 2014 at 11:39
  • 9
    Not to discourage the question, because you will get interesting answers that will help you. But FWIW, my advice is this: Don't bother. Lisp's simple, no-nonsense, use-everywhere, data=code syntax is your friend. Just get to know it better and you won't want or need to filter it through your previous glasses. Let it improve you; don't bother trying to improve it.
    – Drew
    Jan 17, 2014 at 17:01
  • 1
    @user115126 Btw, that's Drew Adams, an extremely prolific (Emacs) Lisp developer. I hope this info gives his comment some more credence, because I think it's very good advice.
    – nanny
    Aug 20, 2015 at 13:15

3 Answers 3

9

You can do that, and much more, using sweet-expressions. There is already a working implementation of sweet-expressions for Scheme, which I encourage you to study. The basic idea is that you replace the standard S-expression reader with a sweet-expression reader; everything else stays the same, and you retain homoiconicity and the ability to use macros.

The question is how to implement sweet-expressions in Clojure, since curly braces are already used as a notation for maps, sets, and metadata.

2
  • David Wheeler explains how to handle maps at (permalink.gmane.org/gmane.lisp.readable-lisp/131) by creating them with the "map" function, and keeping {} for sweet-expressions. I don't know how you could handle sets and metadata, but maybe the approach of having literal "unprexided brackets" mentioned for the [] vectors could work as well.
    – TuringTest
    Jun 15, 2015 at 16:22
  • Sweet-expressions hide the structure of the code: go explain people what `\\` is for.
    – coredump
    Aug 20, 2015 at 13:55
4

Lisps are very unique in how they are defined. Lisps are not defined in terms of text but in terms of Lisp data structures. E.g. in Python a function definition is defined like this:

the letter d followed by the letter e followed by the letter f followed by whitespace followed by an identifier denoting the name followed by the character ( followed by …

Whereas in a Lisp a function definition is defined like this:

a list with three elements, the first of which is the string "def", the second of which is a list of strings denoting the names of the parameters, and the third is the code of the function also represented as a list

Likewise, a function call is a list whose first element is a string denoting the name of the function to be called and the other elements are the arguments to the function.

How you write down those lists and strings is irrelevant. You could use the traditional Lisp syntax, you could use JSON, YAML, XML or whatever. The important thing is that code is just a data structure. How that data structure is represented is irrelevant.

1
  • Note: in reality, the identifiers would be symbols, not strings, I just wanted to avoid introducing a data type that not everybody is intimately familiar with. Jan 17, 2014 at 16:49
0

As mentioned by Chris, sweet expressions are what you are looking for.

with respect to Clojure, you can write indented code with a plugin called indent-clj. You'd end up with something like this:

defn factorial [n]
  if (<= n 1)
    1
    (* n (factorial (- n 1)))

Sweet expressions also mention infix, discussed here for Clojure Clojure has yet to use the #[...] reader form, so it is possible to use #[n <= 1] for infix expressions. This would never get support, but here it is anyway:

defn factorial [n]
  if #[n <= 1]
    1
    #[n * (factorial #[n - 1])]

A fully supported way to implement infix today is to use a macro of course, or even Clojure's tagged literal facility to create a custom infix tag, say #nfx (...). It's a bit verbose, so I don't see any benefit over the normal way:

defn factorial [n]
  if #nfx (n <= 1)
    1
    #nfx (n * (factorial #nfx (n - 1)))

Sweet expressions also introduce "neoteric" expressions, that is the traditional function call syntax f(...). This seems impossible in Clojure, since spaces around collection delimiters are optional (e.g. (a(b)) is a valid list).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.