summaryrefslogtreecommitdiff
path: root/html
diff options
context:
space:
mode:
authorTaylan Kammer <taylan.kammer@gmail.com>2025-02-18 22:48:57 +0100
committerTaylan Kammer <taylan.kammer@gmail.com>2025-02-18 22:48:57 +0100
commit4d0db1a1065f18d879b3ff90da6ecb14e9e1ae31 (patch)
tree7c5c275e7f3dae7bf96377560269b5a1bfa1fb99 /html
parent2384a31c42f480c961785bcf0520bb0688b8e028 (diff)
update
Diffstat (limited to 'html')
-rw-r--r--html/notes/symbols.md49
1 files changed, 49 insertions, 0 deletions
diff --git a/html/notes/symbols.md b/html/notes/symbols.md
index 8aa666f..aa3c448 100644
--- a/html/notes/symbols.md
+++ b/html/notes/symbols.md
@@ -17,3 +17,52 @@ and bare symbols will just be reader syntax for a string constant.
Instead of `string->symbol` we will have `string-intern` which
basically does the same thing. Dynamically generated strings that
aren't passed to this function will be uninterned.
+
+## But but but
+
+(Late addition because I didn't even notice this problem at first.
+How embarrassing!)
+
+But if symbols and strings are the same thing at the reader level,
+then how on earth would you have a string literal in source code,
+without it being evaluated as a variable?
+
+ (display "bar") ;should this look up the variable 'bar'?!
+ (display bar) ;should this display the string 'bar'?!
+
+There's actually a simple solution.
+
+The syntax `"string"`, with double-quotes and nothing else, becomes
+reader syntax akin to the apostrophe, and expands to:
+
+ (quote #"string")
+
+And `#"string"` is the real syntax for string literals, which are
+always treated as identifiers by the evaluator.
+
+Bare identifiers like `foo` instead directly become `#"foo"`, without
+the wrapping `(quote ...)`, and are thus evaluated.
+
+This also means that manually writing `#"string"` in your source code
+allows that to be used as an identifier regardless of whether it has
+illegal characters in it, essentially doing what `|string|` does in
+R7RS-small.
+
+Let's sum it up; here's the reader transformations:
+
+ foo -> #"foo"
+ "foo" -> (quote #"foo")
+ "foo bar" -> (quote #"foo bar")
+ #"foo bar" -> #"foo bar"
+
+Some pseudo-code based on Scheme:
+
+ (let ((#"all your" "base ")
+ (#"are belong" "to us"))
+ (display
+ (string-append #"all your" #"are belong")))
+
+That prints: "base to us"
+
+I'm not married to the syntax `#"string"` and may end up using the
+simpler `|foo|` in the end. It doesn't really matter.