50 lines
2.4 KiB
Plaintext
50 lines
2.4 KiB
Plaintext
;;;; builtin/name: the spelling that always reaches the builtin.
|
|
;;;;
|
|
;;;; Shadowing a builtin is legal and program-wide within the file that does
|
|
;;;; it (shadow-builtin.flan is that rule on its own). What it used to cost
|
|
;;;; was the builtin itself: a (defn length ...) had given up the builtin
|
|
;;;; length for
|
|
;;;; the whole file, so a definition that meant to *wrap* the builtin was
|
|
;;;; unbounded recursion instead, and stack-overflowed at run time with
|
|
;;;; nothing for the compiler to object to.
|
|
;;;;
|
|
;;;; builtin/length is the way out, and it is the package qualifier's own
|
|
;;;; spelling: rl/draw-fps is draw-fps from the package imported as rl, and
|
|
;;;; builtin/length is length from the compiler. builtin is a reserved
|
|
;;;; qualifier —
|
|
;;;; an import may not take it as an alias — so the two can never be confused
|
|
;;;; about which one a name means.
|
|
;;;;
|
|
;;;; Five lines, and between them the whole feature. In order:
|
|
;;;;
|
|
;;;; - 9: (builtin/max 3 9) with nothing in this program named max. The
|
|
;;;; qualifier is legal whether or not anything is shadowed; a spelling that
|
|
;;;; only compiled while some other declaration existed would be a spelling
|
|
;;;; nobody could write down in advance.
|
|
;;;; - 5: this file's own length, which is a real wrapper — it is "1 + the
|
|
;;;; builtin length", and the inner call reaches the builtin rather than
|
|
;;;; itself. This is the program the earlier lane could not write.
|
|
;;;; - 4: builtin/length in the same file, beside the bare name that means the
|
|
;;;; definition. Both spellings, one program, different answers.
|
|
;;;; - 99: the shadowed operator, unchanged. An operator is a builtin like any
|
|
;;;; other and shadows like any other.
|
|
;;;; - 3: builtin/+ — the reader takes builtin/+ as one symbol, because '/'
|
|
;;;; and '+' are both ordinary symbol characters and the token does not
|
|
;;;; begin with a digit or a sign, so an operator needs no exception here.
|
|
|
|
;;; The wrapper, written the way the dead end said could not be written: the
|
|
;;; inner builtin/length is the compiler's length, and the outer name is this
|
|
;;; one.
|
|
;;; Both additions are qualified too, since + is shadowed below and this
|
|
;;; function wants the arithmetic and not the 99.
|
|
(defn length [s str] i32 (builtin/+ 1 (builtin/length s)))
|
|
|
|
(defn + [a i32 b i32] i32 99)
|
|
|
|
(defn main [] ()
|
|
(println (builtin/max 3 9))
|
|
(println (length "abcd"))
|
|
(println (builtin/length "abcd"))
|
|
(println (+ 1 2))
|
|
(println (builtin/+ 1 2)))
|