For a "language's awareness of code", there's no better I've seen than Lisp and its macro facility -- specifically, Common Lisp. But the trade there is that most of the time an object's type is not known at compile time or macroexpansion time. For literals, the types are known, so you can find examples of aggressive macros that test to see if an object is a literal and, if so, treat it one way -- maybe based on its type -- and otherwise prepare the detected variable for run-time type inspection.
Here's an example I adapted from the CLLIB library (part of the CLOCC library) several years ago. The goal is to provide functions that will chop a prefix string off of some other string with a matching prefix. The prefix may be known at macroexpansion time or it may not. If it is, we can an optimization: compute the prefix's length first and embed it as a literal, so that it's not recomputed on each call to the generated function. The macro is daunting at first, but the actual generated code is small.
(defmacro after-prefix-core (comparison-op prefix string &optional length)
"Similar to cllib:string-beg-with-cs."
(flet ((chop (prefix prefix-length string string-length)
`(when (and (>= ,string-length ,prefix-length)
(,comparison-op ,prefix ,string :end2 ,prefix-length))
(subseq ,string ,prefix-length ,string-length))))
(let* ((gstring (gensym "STRING-"))
(gstring-length (gensym "STRING-LENGTH-")))
`(let* ((,gstring ,string)
(,gstring-length ,(or length `(length ,gstring))))
,(if (stringp prefix)
;; Constant -- length known at expansion time.
(let ((prefix-length (length prefix)))
(chop prefix prefix-length gstring gstring-length))
;; Other form -- length not known at expansion time.
(let ((gprefix (gensym "PREFIX-"))
(gprefix-length (gensym "PREFIX-LENGTH-")))
`(let* ((,gprefix ,prefix)
(,gprefix-length (length ,gprefix)))
,(chop gprefix gprefix-length gstring gstring-length))))))))
(defmacro after-prefix (prefix string &optional length)
"Similar to cllib:string-beg-with."
`(after-prefix-core string-equal ,prefix ,string ,length))
(defmacro after-prefix-cs (prefix string &optional length)
"Similar to cllib:string-beg-with-cs."
`(after-prefix-core string= ,prefix ,string ,length))
See the form
(if (stringp prefix)
in the middle? That's inspecting the first argument at macroexpansion time and, depending on whether the argument is a literal or symbol, its type may or may not be known. If the type is a symbol, we assume that we should wait until run time to reconsider it as a variable pointing to some other value.
Here's the expansion for the form (after-prefix foo bar)
:
(LET* ((#:STRING-5340 BAR) (#:STRING-LENGTH-5341 (LENGTH #:STRING-5340)))
(LET* ((#:PREFIX-5342 FOO) (#:PREFIX-LENGTH-5343 (LENGTH #:PREFIX-5342)))
(WHEN
(AND (>= #:STRING-LENGTH-5341 #:PREFIX-LENGTH-5343)
(STRING-EQUAL #:PREFIX-5342 #:STRING-5340 :END2 #:PREFIX-LENGTH-5343))
(SUBSEQ #:STRING-5340 #:PREFIX-LENGTH-5343 #:STRING-LENGTH-5341))))
Note that the variable #:PREFIX-LENGTH-5343
is bound to the computed length of FOO
, bound here to variable #:PREFIX-5342
.
Now look at the expansion for the form (after-prefix "foo" bar)
, where the prefix is now a string literal:
(LET* ((#:STRING-5463 BAR) (#:STRING-LENGTH-5464 (LENGTH #:STRING-5463)))
(WHEN (AND (>= #:STRING-LENGTH-5464 3) (STRING-EQUAL "foo" #:STRING-5463 :END2 3))
(SUBSEQ #:STRING-5463 3 #:STRING-LENGTH-5464)))
Now there's no computing the length of "foo"; it's inlined as 3.
It may seem like too much work in this example, but being able to do such things is a good power to have, as your question opines.