This is the main reason Lisp has just never grown on me. I'm certain — and other responses demonstrate — that the readability can certainly be improved here. Yes, a programming language needs nothing more than parens. But dedicating a tastefully chosen set of sigils seems to make a lot of difference, in my opinion.
In the dialect called TXR Lisp, I have introduced precisely that: some tastefully chosen syntactic sugars which do not disturb the structure of the surrounding Lisp. I believe I made a wise choice by not targetting arithmetic. My syntactic inventions target areas like working with arrays, string processing, OOP and higher order functions.
Small taste:
1> (let ((x "abc") (y "def"))
(swap [x 0..2] [y 2..:])
(list x y))
("fc" "deab")
2> (mapcar (ret `@1-@2`) "abc" "def")
("a-d" "b-e" "c-f")
3> '#"lorem ipsum dolor sit"
("lorem" "ipsum" "dolor" "sit")
4> (let ((a "dolor")) ^#`lorem ipsum @,a sit`)
#`lorem ipsum dolor sit`
5> (eval *4)
("lorem" "ipsum" "dolor" "sit")
7> (defstruct (point x y) nil (x 0) (y 0))
#<struct-type point>
8> (new point)
#S(point x 0 y 0)
9> (new (point 1 2))
#S(point x 1 y 2)
10> (new point x 2 y 3)
#S(point x 2 y 3)
11> (let ((a (new (point 10 20))))
^(,a.x ,a.y))
(10 20)
12> (let ((a (new (point 10 20))))
`<@{a.x}, @{a.y}>`)
"<10, 20>"
13> (defmeth point distance (p) (sqrt (+ (* p.x p.x) (* p.y p.y))))
(meth point distance)
14> (new (point 3 4)).(distance)
5.0
15> (defmeth point distance-to (p q)
(let ((r (new (point (- q.x p.x)
(- q.y p.y)))))
r.(distance)))
(meth point distance-to)
16> (new (point 3 4)).(distance-to (new (point 20 30)))
31.0644491340181
19> (let ((pts (build (dotimes (i 10) (add (new (point (rand 10)
(rand 10))))))))
pts)
(#S(point x 5 y 6) #S(point x 1 y 1) #S(point x 1 y 3) #S(point x 5 y 7)
#S(point x 2 y 8) #S(point x 7 y 3) #S(point x 1 y 1) #S(point x 2 y 4)
#S(point x 5 y 6) #S(point x 5 y 3))
20> (mapcar .(distance) *19)
(7.81024967590665 1.4142135623731 3.16227766016838 8.60232526704263
8.24621125123532 7.61577310586391 1.4142135623731 4.47213595499958
7.81024967590665 5.8309518948453)
21> (mapcar (ret @1.(distance-to @2)) *19 (cdr *19))
(6.40312423743285 2.0 5.65685424949238 3.16227766016838 7.07106781186548
6.32455532033676 3.16227766016838 3.60555127546399 3.0)
I understand this point of view if most of your programs are just doing arithmetic, but once you start using functions and procedures the differences are pretty minimal.