I used to program in a LISP (the language predates Lisp) derivative called "Boot". (It booted a computer algebra system.) It added two rules to LISP: unparenthesized expressions bind "to the function call", using dynamic lookup to determine arity, and failing if the binding wasn't unambiguous; and, ';' to delimit expressions. It's been a decade since I used the language, but it would look something like this:
define (hello)
displayln "Hello, World!";
hello;
The boot 'compiler' only did name resolution and parenthesization, then it kicked everything back to an underlying LISP. (In this case, SBCL, which rocked!)
The second level language built on Boot was Spad, which used a slightly friendlier syntactic top-form:
e : t = x
With compact forms:
e := x
e = x
e : t
e
Which lets you uniformly parse packages, modules, domains, categories, functions, annotations, etc. etc. For instance, we had a Spad-lite syntax:
The second level language built on Boot was Spad, which used a slightly friendlier syntactic top-form:
With compact forms: Which lets you uniformly parse packages, modules, domains, categories, functions, annotations, etc. etc. For instance, we had a Spad-lite syntax: Then you could assert membership: An implementation would be: