Part 4 — A complete beginner’s guide to Computer Programming with Clojure: Maths.

Harvey Ellams
7 min readDec 31, 2020
Photo by Jeswin Thomas on Unsplash

Polish notation

We discussed Polish Notation in Part 1. Polish Notation means the operator is prefixed before the operands. We are more used to the infix method, whereby the operator sits in between the operands. So, to understand Clojure’s Polish Notation, take the operator e.g. the plus sign +, and move it to in between the numbers. So, (+ 15 10) is actually evaluated as 15 + 10.

Let’s begin with a new REPL session. Recall from Part 3, Ctrl + T will open a terminal and lein repl will start a new REPL session.

In the REPL, try the following code below. Also, try with different numbers. (Note the double semicolons ;;. The ;; indicate a comment will follow. This is very useful when writing code as everything after the ;; is ignored by Clojure. This allows you to write your own comments and explanations about the code that precedes the ;;)

Type the following — as already explained, you don’t need to type the ;; or anything immediately after, as these are just comments.

(+ 5 5) ;; addition, 5 + 5.=> 10
(- 20 10)
;; subtraction, 20 -10.
=> 10
(* 5 2) ;; multiplication, 5 x 2.=> 10
(/ 50 5) ;; division, 50 divided by 5.=> 10
(mod 24 14)
;; modulo, 24 mod 14.
=> 10
(inc 9) ;; increment, 9 + 1.=> 10
(dec 11) ;; decrement, 11 -1.
=> 10
(Math/pow 2 4)
;; 2 to the power of 4, 2 x 2 x 2 x 2.
=> 16.0
(Math/sqrt 100)
;; Square root of 100.
=> 10
(Math/cbrt 1000)
;; Cube root of 1000.
=> 10
(Math/hypot 6 8) ;; Hypotenuse for a right angled triangle
=> 10

Notice the (Math/ . . .) function. This is inbuilt and didn’t need to be imported. This function allowed us to use specialist functions such as sqrt and hypot for Square root and Hypotenuse respectfully. There are many more math functions attributed to (Math/ . . .).

Square Root Calculator App

We will expand upon what we have learned thus far and combine it with our understanding of the javax.swing from Part 3. The following code in Listing 1. will produce an App designed to take a number as input and, after pressing a GUI (graphical user interface) button, display the square root of the number. Think of it as a calculator App with only one function, provide the square root.

Type Listing 1. into the REPL:

Listing 1.

(import ‘(javax.swing JFrame JLabel JTextField JButton)‘(java.awt.event ActionListener)‘(java.awt GridLayout))((let [frame (JFrame. “Square Root Calculator”)input-text (JTextField.)inputNo-label (JLabel. “Input Number”)square-button (JButton. “Find Sqr Root”)result-label (JLabel. “result”)](. square-button(addActionListener(proxy [ActionListener] [ ](actionPerformed [evt](let [i (Double/parseDouble (. input-text (getText)))](. result-label(setText (str (Math/sqrt i) “ is the square root”))))))))(doto frame(.setLayout (new GridLayout 2 2 3 3))(.add input-text)(.add inputNo-label)(.add square-button)(.add result-label)(.setSize 400 100)(.setVisible true))))

You should see something similar to the image below:

To test everything works as it should, we will use some test data. In this case, I have used 10000 (ten thousand) as I know the square root of 10000 is 100.

On a side note, you may see the REPL reporting some errors. For now, you can ignore these errors.

Following are two sections to help you understand the code contained in Listing 1. In other words, I have broken this down into two explanations. The first explanation is a high-level overview of the code. The second goes into greater depth and attempts to help your understanding further. Nevertheless, at this stage of your coding journey, you are not expected to understand everything.

Listing 1. High-Level Overview

(import ‘(javax.swing JFrame JLabel JTextField JButton)

‘(java.awt.event ActionListener)

‘(java.awt GridLayout))

Import the necessary library functions to create Java UI components and their associated functionality. Once imported into the current REPL session, you can write other code snippets to take advantage of these javax.swing GUI components. In other words, if you decided to write another function or code snippet that required another component, you would need to import it into the current REPL session.

((let [frame (JFrame. “Square Root Calculator”)

input-text (JTextField.)

inputNo-label (JLabel. “Input Number”)

square-button (JButton. “Find Sqr Root”)

result-label (JLabel. “result”)]

Assign variable names to the components. For instance, ‘input-text’ will be used to capture numbers input by the User into the Java UI (User Interface) component, JTextField. ‘inputNo-label’ will hold the JLabel UI component assigned the text, “input Number’. This continues until all the variables are duly assigned.

(. square-button

(addActionListener

(proxy [ActionListener] [ ]

(actionPerformed [evt]

(let [i (Double/parseDouble (. input-text (getText)))]

(. result-label

(setText (str (Math/sqrt i) “ is the square root”))))))))

This is where the action happens i.e. when you press the button. Our variable ‘square-button’ is given a ‘listener’. In other words, it waits until the User inputs a number. When a number is input, it processes the input e.g. ‘getText’, and stores it in the variable i. Then changes the value of i by applying the square root function e.g. (Math/sqrt i). It then takes this result and stores it as ‘setText’. Next, it places the result before the string, “ is the square root”

(doto frame

(.setLayout (new GridLayout 2 2 3 3))

(.add input-text)

(.add inputNo-label)

(.add square-button)

(.add result-label)

(.setSize 400 100)

(.setVisible true))))

So, you have the library components, you associated variable names to each component, and you have created the specific functionality. Now, you need to layout the App. The first two numbers (2 2) relate to the grid. The first number is the X value and the second number relates the Y value. In other words, the large X defines two columns and the large Y defines two rows below the JFrame title bar.

The other two numbers (3 3) relate to the spaces in between the grid. So, small x and y define a 3-pixel gap. The ‘.add’ directive places the components. This is done in order from left to right, and then from the top down. The ‘.setSize’ dictates the overall size of the frame and ‘.setVisible’ lets you set it.

Listing 1. In-depth explanation

Listing 1. starts with an import statement to bring in a number of functions to assist in the layout.

JFrame and JLabel are already known to us.

JTextField — this function creates an input-field to capture text or numbers.

JButton — this creates a button.

java.awt.event ActionListener — this function recognizes change. In this case, it recognizes a change in state for the button. To explain, consider the following line:

square-button (JButton. “Find Sqr Root”)

Here, we create a button with the text “Find Sqr Root”. We then assign it a name to use throughout the rest of the program. In this case, the name is ‘square-button’.

The next time we see ‘square-button’ is in a function beginning

(. square-button

(addActionListener — The ActionListener is added to the button.

proxy [ActionListener] [ ] — This actually connects the action listener to the button.

actionPerformed [evt] — When the action (event) is performed, i.e. the button is pressed, it is then ready to process the following function:

(let [i (Double/parseDouble (. input-text (getText)))]

(. result-label

(setText (str (Math/sqrt i) “ is the square root”))))))))

Reading from left to right, let the letter i hold our number. To. explain, Double/parseDouble creates a space in the computer's memory to hold up to 64 bits. This space will be named input-text and getText is the action which actually grabs the number typed.

In reality, the innermost part is evaluated first. So, getText grabs the text (our number) and names it input-text which is then held in a chunk of computer memory and assigned to the letter i to be used later in the program.

result-label — is declared near the beginning of the program. It uses the JLabel function and assigns it with the text “result”. However, this text will change!

(. result-label

(setText (str (Math/sqrt i) “ is the square root”))))))))

Reading from the inside, i (our number typed in earlier) is converted to its square root. This result is then placed at the beginning of the sentence ‘is the square root’. Next, the function setText will update i.e. change the value of result-label to show or square root number result, followed by the text ‘is the square root’.

SUMMARY

The best way to understand the code in this chapter is to view it like Boilerplate code. Listing 1 is the essence of computer programming. Listing 1 produces an App that takes in a value and computes the result. To really understand Listing 1, try and re-write it so that it calculates the cube root instead. Experiment with changing the values in the (doto frame . . .) section. Also, try changing the order. Only when you experiment with code will you begin to understand it. As already mentioned, this code can become your boilerplate code for future projects. It has three significant elements, an area to take input, a button to effect processing, and an area to display the result. See if you can memorize this code.

To reiterate, the import statement at the beginning only needs to be run once in an active REPL. After, just run the code from the section beginning ((let …

Previous

Part 5 — Text Processing

--

--