TXR Lisp has this notation, combined with Lisp parethesis placement.
Tather than obj.f(a, b). we have obj.(f a b).
1> (defstruct dog ()
(:method bark (self) (put-line "Woof!")))
#<struct-type dog>
2> (let ((d (new dog)))
d.(bark))
Woof!
t
The dot notation is more restricted than in mainstream languages, and has a strict correspondence to underlying Lisp syntax, with read-print consistency.
3> '(qref a b c (d) e f)
a.b.c.(d).e.f
Cannot have a number in there; that won't go to dot notation:
4> '(qref a b 3 (d) e f)
(qref a b 3 (d)
e f)
Chains of dot method calls work, by the way:
1> (defstruct circular ()
val
(:method next (self) self))
#<struct-type circular>
2> (new circular val 42)
#S(circular val 42)
3> *2.(next).(next).(next).(next).val
42
There must not be whitespace around the dot, though; you simply canot split this across lines. In other words:
*2.(next)
.(next) ;; nope!
.(next) ;; what did I say?
The "null safe" dot is .? The following check obj for nil; if so, they yield nil rather than trying to access the object or call a method: