A language is a notation system mutually intelligible to humans and computers. “Notation” = it has syntax; “intelligible” = it has meaning, aka semantics.
LOP lets us create little languages tailored to a specific set of problems, aka domain-specific languages, or DSLs.
DSLs are everywhere: Regular expressions, HTML & CSS, numerical expressions, SQL, PostScript, JSON, YAML, classic Unix commands, languages that compile to JavaScript, #lang racket, #lang brag, define-macro …
A language is an interface. An interface makes certain tasks easy.
What’s the difference between a language and function? (Warning: trick question.)
What’s the difference between a language and a library? (Same warning.)
Why Racket for LOP? Mostly, its hygienic macro system. Beyond that, libraries and tooling.
Why not string manipulation? Flat structure, no metadata, more housekeeping with variables, Greenspun’s Tenth Rule. + “Any sufficiently complicated program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Lisp.”
A Racket-implemented DSL is a source-to-source compiler. We can use everything in Racket, and pick the best tool for the job. We get everything in the Racket toolchain: libraries, distribution, runtime, etc.
LOP isn’t the right tool for every job. But Racket makes it plausible for more jobs, because LOP in Racket is easier and cheaper.