2025-03-12 14:47:00
rigsomelight.com
Inline evaluation has been around for a long time, but not every
programmer has had the chance to use it. If you haven’t, this is an
opportunity to try it.
To this end I’ve coded up a simple editor with some code examples. The
following examples are all editable and executable, however no run
button exists to execute them. You’ll use Control-r
to
RUN/EVALUATE pieces of code that you select from inside the editor
panes below.
To see it in action, place your cursor immediately after the
expression you want to evaluate in the editor below. Then, press
Control-r
(hold the Control
key down while pressing the r
key). For example, if you want to evaluate (+ 1 2 3)
, position the
cursor after the closing parenthesis )
and then press
Control-r
. For brevity, we’ll be using ^r
as shorthand for
Control-r
from now on.
1 ;`-- Place cursor after 1 then hit ^r "Gremlins are cuties!" ; `-- Place cursor after " then hit ^r (+ 1 2 3) ; `-- Place cursor after 1 then hit ^r (+ 1 2 3) ; `-- Place cursor after the ')' then hit ^r (+ 1 (/ 8 2) (* 2 3) ) ; `-------`-` Place cursor after each ')' and then hit ^r (+ 1 (/ 8 2) (* 2 3)) ; `-- Place cursor after ')' and then hit ^r ;`-- Place cursor above this line and hit ^r
When you pressed ^r
, the editor found the closest preceding complete
expression and sent it it to a runtime session (REPL) for
evaluation. The result then appeared right next to your code, exactly
where you were already looking. No context change needed to see the
code run.
You may have noticed that you can evaluate smaller parts of an
expression, like (/ 8 2)
, just as easily as a full expression. You
can also evaluate expressions that span multiple lines.
Lisp languages make it simple to write editor tools that can do
this. It is trivial to write an editor plugin to detect an
expression delimited by parenthesis.
Sometimes, when I’m uncertain about function names or behavior,
instead of searching for them, I simply try evaluating them inline to
see if they exist and if they behave the way I expect them to.
For example, I know I created a function that renders HTML into a
div
above the editor, but I can’t remember if it’s called
show-html
or display-html
. Let’s evaluate both of the expressions
below to see which one works:
;; was it show-html or display-html?? (show-html "") ;; `-- ^r eval here (display-html "") ;; `-- ^r eval here
With inline evaluation, I can quickly discover which function is
defined and if it does what I expect, all without leaving the
editor or breaking my flow.
In the next example, let’s apply this same approach to discover what
the look
, move
and reset
functions do.
In all examples that follow, try evaluating each expression with
^r
to see the results.
(look) (move :east) (reset)
Notice how the look
function returns data describing your location
in a text adventure game, while the move
function lets you navigate
through this virtual world.
This provides an opportunity to demonstrate how inline evaluation
helps us build and refine code incrementally.
Evaluating (look)
and (move :east)
could work as a spartan interface to the
game, but it would definitely be better to display this data using our
display-html
function. Right? Right??
Now if we examine the data that the look
function returns we can
see that it’s returning a hash map of some sort, with the keys
:desc
, :seen
, :exit
and so on. Each of these keys map to
string descriptions of the state of the game.
Let’s work on formatting the data returned by look
into some HTML
that we can display.
;; First lets see what data is returned (look) ;; I see a :desc key that holds a description (get (look) :desc) ;; OK we have a description let's put that into an HTML string (str "" (get (look) :desc) "
") ;; Now let's display that HTML (display-html (str "" (get (look) :desc) "
"))
Let’s improve our code by breaking out that paragraph tag into its own
function:
;; Evaluate this to define the paragraph function (defn p [content] (str "" content "
")) ;; now let's see how it works (p "Hello") (display-html (p (get (look) :desc)))
OK, now we are getting somewhere. But we also have to format the
things that are :seen
in the room:
(look) ;; Let's extract the :seen items (get (look) :seen) ;; Add some context to the raw data (str "You see: " (get (look) :seen)) ;; put it in a paragraph (p (str "You see: " (get (look) :seen))) ;; let's add the :desc and the :seen together (str (p (get (look) :desc)) (p (str "You see: " (get (look) :seen)))) ;; then display it (display-html (str (p (get (look) :desc)) (p (str "You see: " (get (look) :seen)))))
So we’re building up some code to format the the data returned from the
look
function as HTML.
So let’s put this code in a function and start working on the function
instead of just composing expressions.
;; so here's our initial format function (defn look-html [data] (str (p (get data :desc)) (p (str "You see: " (get data :seen))))) ;; let's see if it's working (look-html (look)) ;; and finally (display-html (look-html (look)))
OK now we have a look-html
function which we can re-use, but there
is definitely room for improvement. If we look at the data that’s
returned by the look
function you can see that there is also an
:img-path
. Let’s use that to add more visual interest to our game
display.
;; let's build up an expression to format the :img-path as ;; an img tag (get (look) :img-path) (str "") ;; let's insert the image tag into our look-html function (defn look-html [data] (str ;; v-- added img here --v (str "
") (p (get data :desc)) (p (str "You see: " (get data :seen))))) ;; let's see if it's working (look-html (look)) ;; and let's take a look! (display-html (look-html (look)))
Not bad at all. OK, now we only have one more piece of information
left to add to our look-html
function. When you evaluate the
(look)
function you will notice an :exits
entry which gives the
player clues about which directions they can move from their current
location.
I think we are at the point where you can add the :exits
info to the
look-html
function.
;; here's the :exits data (get (look) :exits) ;; Add the exits data to the function below: (defn look-html [data] (str (str "") (p (get data :desc)) (p (str "You see: " (get data :seen))) (p (str "Exits: " )))) ;; test it out here to see if it's working (look-html (look)) ;; and finally take a look! (display-html (look-html (look)))
Do you want to play a game?
Now that we’ve built our look-html
function, let’s use inline
evaluation to explore the text adventure.
Below are several game interaction functions. Using the inline
evaluation, evaluate each one to discover its purpose and effect on
the game state. This demonstrates how inline evaluation serves as both
a development and exploration tool.
(display-html (look-html (look))) (move :east) (stack) (push :picture) (peek) (pop) (unlock-function :_something?_) (reset)
Don’t be afraid to enhance the UI. Here are some suggestions:
- Create a
looki
function that combines ourdisplay-html
andlook-html
functions:(display-html (look-html (look)))
- Develop a
movi
function that callsmove
and thenlooki
to show the new location - Extend your
look-html
function to display the(stack)
information - your own images, there’s nothing stopping you from creating your own
images and using those in the game
And end?
Thanks for taking the time to experience inline evaluation.
As programmers, we often fall into cognitive ruts that constrain
our expectations of what the programming process can be. These mental
ruts, in turn, limit the potential of what we create. I have observed
decisions by language designers, programming architecture advocates,
and tool builders that directly ignore or impede this type of
interactivity—a situation I find genuinely unfortunate.
It’s hard to get people to try things outside their experience. It’s
natural to resist unfamiliar ideas and dismiss them. Many who read
this will likely respond by arguing that this kind of interactivity
isn’t necessary or useful. However, in my humble opinion, that simply
isn’t true.
Yes, these may be toy examples inside a toy editor, but this level of
interactivity is very real. Clojure programmers—and others who use
similar evaluation capabilities—apply this technique daily in
professional settings, from data pipelines powering major retailers to
the video streaming services you likely use yourself.
My argument isn’t that Clojure or Lisp is inherently superior to other
languages, but that inline evaluation is incredibly valuable and
deserves wider adoption across programming environments.
By experiencing it firsthand, you might be inspired to expect more
from your programming languages and tools—or even create your own.
Keep your files stored safely and securely with the SanDisk 2TB Extreme Portable SSD. With over 69,505 ratings and an impressive 4.6 out of 5 stars, this product has been purchased over 8K+ times in the past month. At only $129.99, this Amazon’s Choice product is a must-have for secure file storage.
Help keep private content private with the included password protection featuring 256-bit AES hardware encryption. Order now for just $129.99 on Amazon!
Help Power Techcratic’s Future – Scan To Support
If Techcratic’s content and insights have helped you, consider giving back by supporting the platform with crypto. Every contribution makes a difference, whether it’s for high-quality content, server maintenance, or future updates. Techcratic is constantly evolving, and your support helps drive that progress.
As a solo operator who wears all the hats, creating content, managing the tech, and running the site, your support allows me to stay focused on delivering valuable resources. Your support keeps everything running smoothly and enables me to continue creating the content you love. I’m deeply grateful for your support, it truly means the world to me! Thank you!
BITCOIN bc1qlszw7elx2qahjwvaryh0tkgg8y68enw30gpvge Scan the QR code with your crypto wallet app |
DOGECOIN D64GwvvYQxFXYyan3oQCrmWfidf6T3JpBA Scan the QR code with your crypto wallet app |
ETHEREUM 0xe9BC980DF3d985730dA827996B43E4A62CCBAA7a Scan the QR code with your crypto wallet app |
Please read the Privacy and Security Disclaimer on how Techcratic handles your support.
Disclaimer: As an Amazon Associate, Techcratic may earn from qualifying purchases.