In the area of arithmetic, although the basic operators are functions invoked using (f arg ...), we give them short names like +, -, * and /. Why? The obvious reason is that we would find it irksome to be writing (add ...) and (mul ...).
Lisp can have notations, and they can be had without disturbing the Lisp syntax. Notations that are related to major program organization have payoff.
In TXR Lisp there is relatively small set of new notations, which all have correspondence to S-exp forms, the same way that 'X corresponds to (quote x).
;; slot access
obj.x.y.z --> (qref x y z)
Of course, people are going to prefer this to something like: (slot-value (slot-value x 'y) 'z)
Then: ;; unbound slot access
.x.y.z --> (uref x y z)
;; method call
obj.x.(f a b) --> (qref x (f a b))
;; x.f(blah).g(foo).xyzzy(x, y) pattern:
x.(f blah).(g foo).(xyzzy x y) ;; looks like this
;; sequence indexing, function calls (the "DWIM" operator)
[array i] --> (dwim array i)
[f x y] --> (dwim f x y)
;; ranges:
a..b --> (rcons a b)
;; slice
[str 0..3] --> [dwim str (rcons 0 3)]
;; Python-like negative indexing:
[str -4..:] --> [dwim str (rcons -4 :)] ;; : means "default value: one index past end sequence (its length)".
;; quasistrings -- recently appeared JavaScript in strikingly similar form!
`@a @b ...` --> (sys:quasi @a " " @b) --> (sys:quasi (sys:var a) " " (sys:var b))
;; word list literals
#"a b c" --> ("a" "b" "c")
;; quasi word list literals
#`a @b c` --> (sys:quasilist `a` `@b` `c`)
Some Lisp syntax is streamlined: (lambda (a b c : x y . r) ...) ;; a b c required, x y optional, r rest
Dot notation allowed without preceding atom: (. x) -> x
Improper lists can be function calls: ;; TXR: verbosity-free wrapping of a function.
(defun wrapper (. args)
(wrapped . args))
;; CL:
(defun wrapper (&rest args)
(apply #'wrapped args))
This works even if the thing in the dot position is a symbol macro expanding to a compound form. The reason is that the code walker/expander will recognize and transform (func ... . rest) into (sys:apply (fun func) ... rest) first, and then expand macros. (I.e. we can't work this into existing Lisps like CL implementations without going down to that level.) ;; the : symbol -- symbol named "" in keyword package:
;; used as a "third boolean" in various places
(func 1 2 : 4) ;; use default value for optional arg, pass 4 for the next one
;; diminishes need for keyword args
;; built-in regex syntax
#/a.*b/
;; C-like character escapes
"\t blah \x1F3 ... \e[32a"
;; multi-line strings with leading whitespace control:
"Four sc \
ore
\ and seven years ago" -> "Four score and seven years ago"
;; Simple commenting-out of object with #;
#; (this is
commented out)
Also, there is no programmable reader in TXR Lisp; no reader macros. I'm not a big fan of reader macros. They are only useful for winning "I can have any damn syntax in my language" arguments. Problem is, the whole territory of "any damn syntax" is a wasteland of bad syntax, nt to mention mutually incompatible syntax.