An Introduction to Clojure REPL and Evaluating Code Inline
The REPL is an essential element of a Lisper's toolkit. In this chapter, we'll solidify our grasp of the REPL and editor integration. We'll also learn about some problems that come with the REPL.
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
Lesson Transcript
[00:00 - 00:07] According to the official Flosure Docs, their PEL is a user interface to your program. Closure is a hosted language.
[00:08 - 00:16] In our case, Closure script is hosted on JavaScript. This means that a given moment of time, there are two sets of code available.
[00:17 - 00:29] CLJS code that we wrote and JS code that the Bell tool produced. To test our code, we need the JS version to run, but modifications are made to the CLJS version.
[00:30 - 00:41] The Repel provides a bidirectional bridge between these two realms. It lets you control execution of code in JavaScript realm without leaving the closure script realm.
[00:42 - 00:50] Inline evaluation is a niche concept. Instead of building the concept bottoms up, let's see the final product and tear it top down.
[00:51 - 00:59] This is how we evaluate the code inline. Inline evaluation leverages the end Repel to execute code inline.
[01:00 - 01:07] This lets us develop and debug functions without leaving the editor. Inline eval is not limited to core functions.
[01:08 - 01:20] In the demo, we also defined a new function using the defen macro and called it inline. You can also evaluate third party libraries referred to inline docs and a lot more.
[01:21 - 01:37] Something like React's hot reload compiles your code each time you save so the newer version is available in your browser. Inline evaluation lets you completely bypass the browser or your runtime and lets you evaluate your code right in your editor.
[01:38 - 01:48] Our first project was configured to run as a node script so the inline execution of the code happens in node environment. And the Repel serves as a bridge.
[01:49 - 01:56] In this chapter we will connect the Repel to your editor. We have introduced multiple tools in our process so far.
[01:57 - 02:03] Let's see how everything fits in the big picture. At step 0 you write closure script code in your text editor.
[02:04 - 02:11] We already have the source for first project. ShadowWatch converts your CLJS code to valid JavaScript.
[02:12 - 02:25] You can execute a command that will run JS code in node environment as we did earlier. In the node runtime executes the code and doesn't exit while shadow is in watch mode.
[02:26 - 02:36] The node script did not exit because the Repel needs this runtime for inline evaluation. The Repel is the bridge between CLJS source and the runtime.
[02:37 - 02:54] When Shadow converts your code to be ready for the runtime the Repel can initiate the execution, update the functionality without full rebuilds and get the output from the runtime back to the editor. This is why the Repel is a user interface for your program.
[02:55 - 03:05] If you followed the steps in the last section you would have your source open in your editor. ShadowWatch in a terminal and node script running in another terminal.
[03:06 - 03:17] We have configured an Repel to run on port 9000 so let's connect our editor to it. We will talk about multiple editors but you only need to follow the selection that applies to you.
[03:18 - 03:34] In VS code we first need to open the project folder and on the bottom left corner you should see a button for N-Repel which status disconnected. If you don't see this button refer to the getting started section and ensure that your editor is set up correctly.
[03:35 - 03:49] Click on the N-Repel button and click connect to running Repel server in project. You can also type control shift P or command shift P and then search for Calva connect to running Repel server in project.
[03:50 - 04:02] In the choice of Repel's choose shadow CLGS Repel you will be asked for a host and a port. Most probably Calva will read your config and auto fill this information.
[04:03 - 04:13] If that doesn't happen enter local host 9000. We configured this port for Repel and shadow config and in the choice of Bells choose script.
[04:14 - 04:26] You should see a Calva window with the message Repel connected. The N-Repel status on the bottom left of your editor will also turn golden yellow indicating the connection was successful.
[04:27 - 04:48] To verify the connection open first project.code namespace and type a simple expression say product 45. Now bring your cursor at the end of this expression and press control shift P or command shift P. In the command menu search for Calva evaluate current form and hit enter.
[04:49 - 04:57] You should see the result flash at the end of your cursor. Next try and print a message to your runtime i.e. the node script running in the terminal.
[04:58 - 05:01] Evaluate print line high. They should flash nil in your editor.
[05:02 - 05:11] But if you go and check your terminal you would see the keyword high printed. Calling inline eval with the command menu each time might be tedious.
[05:12 - 05:24] We recommend that you assign the shortcut control Xe or command Xe to run this command. Emax need an extra dependency in your project in order for the CIDR integration to work.
[05:25 - 05:34] Add the CIDR and Repel dependency to your shadow config as follows. You will need to restart shadow watch after saving changes to the config.
[05:35 - 05:48] You will also need to restart the node process running in the other terminal. To connect to the end repel we can call meta-exciter-connect and in the prompt enter localhost 9000.
[05:49 - 06:01] A CIDR buffer should open up with some information about CIDR and end repel. In the prompt user we can shift to the script repel using shadows repel function.
[06:02 - 06:15] After your repel is connected we can go back to firstproject.core and enable C IDR mode using meta-exciter mode. And to verify the connection we can execute an expression say product 5.4.
[06:16 - 06:27] To evaluate an expression inline we can bring the cursor to the end of the form and use the shortcut CXE. Let's try executing another expression printline high.
[06:28 - 06:41] This should flash nil in your editor but if you go back to the terminal running the node script you would see the keyword high printed on your console. When you evaluate a form your editor passes it to the repel.
[06:42 - 06:51] The repel figures out the relevant JavaScript code that should be run and executes it in the connected runtime. In our case that runtime is node.
[06:52 - 07:02] The code is executed and any returned values are flashed inline in the editor. When we printed a message our output went to stdout that is our terminal.
[07:03 - 07:12] The inline eval flashed nil because printline does not return anything. The repel provides an excellent feedback loop but can also lead to some problems.
[07:13 - 07:19] It's a tool to aid your development process. It's not a substitute for your development process.
[07:20 - 07:27] One of the problems that the repel leads to is hanging code. We entered some arbitrary code in first project.code namespace.
[07:28 - 07:37] It's fine right now but imagine you ship this code to production. The program will evaluate the multiplication and the print function each time this namespace loads.
[07:38 - 07:53] To avoid this hanging code problem it's always a good idea to use the comment macro for code that we intend to run only in derpel. The comment function is an alternate to the literate form of comments i.e. the ones that start with semicolon.
[07:54 - 08:08] This type of comment that holds code to be run exclusively at development time is also known as a rich comment. You can make progress in the repel but at the end of the day your program needs to run somewhere else.
[08:09 - 08:15] Getting something working in the repel is not the same as being production ready. Think of the repel as an inspection tool.
[08:16 - 08:25] It really shines when you are working with pure functions. As we progress in this course and start writing more code we will understand how to best leverage derpel.
[08:26 - 08:35] You should also make it a habit of saving your files. With the repel you can define functions in the namespace and run them without actually saving the file.
[08:36 - 08:46] This means when your repel restarts the function might not be available and your code might break. You might have noticed the slow startup time and the added burden of connecting to end repel.
[08:47 - 08:55] It's a common practice in closure world to never kill the watch process and the repel session. This way whenever you sit down to work your toolkit will be ready.
[08:56 - 09:05] In this chapter we learnt about the repel and how to evaluate code in line. We built a mental model for repel and studied some of its advantages and shortcomings.
This lesson preview is part of the Tinycanva: Clojure for React Developers course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Tinycanva: Clojure for React Developers, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
![Thumbnail for the \newline course Tinycanva: Clojure for React Developers](/_next/image?url=https%3A%2F%2Fs3.amazonaws.com%2Fassets.fullstack.io%2Fn%2F20211025023718656_CoverImage_Tinycanva%2520%25281%2529.png&w=3840&q=75)