Graphical code exploration
clj-tiles is a website for visual programming I created in 2021. It makes specific choices for representing code as graphics. The following is a side-by-side comparison with another site of this kind, BlockPy.
I compare loops and function definitions and show that clj-tiles can be used to represent both Clojure as well as Python code.
The Loop
Two versions of the same for
loop:
A First Analysis
Usually, visual tools are seen as a means to teach coding. A beginner assembles simple Python programs and the graphical blocks are meant to help learning the syntax.
I see graphical blocks in a different way. They are meant to convey ideas, to show essential code snippets to an audience.
I made my choice of graphical representation to be as clean as possible with that presentation use-case in mind.
Python and Clojure Code
The graphics on top is generated from the following Python code:
(pow(x, 4) for x in (1, 2, 3))
The second graphic is generated by clj-tiles out of the following text, which also happens to be valid Clojure syntax:
(->> (pow x 4) (for [x [1 2 3]]))
I deliberately chose this for
example because in this case, the Python and Clojure syntax are basically the same. Admittedly, in the text representations the parentheses are distributed differently, but the graphical clj-tiles representation (shown above) does not involve parentheses at all.
I see this lack of parentheses in the graphics as a crucial advantage. I think that because in graphics the blocks take over the role of partitioning code, the parentheses mostly become superfluous .
The Function
Above, BlockPy (in cyan) and clj-tiles are shown next to each other. The clj-tiles graphics was generated using the following text:
(define myfunction
(parameters x
base)
(return (log x base)))
Any Clojurian will protest as this is not valid Clojure code. Indeed I do not recommend this form either, the text was only chosen to show that clj-tiles can be made to resemble BlockPy. Be that as it may, with suitable Clojure-macros this text can be made executable code. Remember that the for
of the first example is also a Clojure macro, albeit a standard one.
clj-tiles for Python
The above cyan-coloured BlockPy graphics represents the following Python code for a function definition:
def myfunction(x, base):
return log(x, base)
I do not know why the BlockPy creators were choosing to change def
into define
. In any case, I find the following clj-tiles graphics much more suitable for this Python code:
Naturally, the according text is basically Python (with the usual parentheses caveat which, as stressed, only pertains to the text and not to the graphics):
(def (myfunction x base)
(return (log x base)))
So my claim is that for some simple Python cases, clj-tiles graphics are more suitable for Python than BlockPy. The reason is that BlockPy, being a learning tool, needs to cover all Python constructs. In the examples shown up to now, clj-tiles, on the other hand, uses only two types of blocks, the list and the vector:
.
clj-tiles does not aspire to cover every syntax construct. It is rather meant to present selected code snippets, it is a tool to present ideas.
Purely Web-based
clj-tiles graphics can be executed as Clojure programs within the clj-tiles website. Anyone can use clj-tiles out of the box, the website can read source code text from any given web address. After the code is processed, all further graphical manipulations are reflected in subsequent executions. Below is an example featuring the Emmy library.
The textual representations of the above graphics is shown below. The screenshot is taken from a simple website that serves as an online notebook.
Because everything is purely web-based and thus without active server backend, clj-tiles graphics need not be restricted to its website. Any environment that supports JavaScript can be used. Here, the Python Jupyter environment is especially interesting.
A Jupyter Example
Throughout the following, we study one single well known math function: the logarithm. We will code this study in two syntax styles: one resembles Clojure (using Clojure-macros), the other is Python. We show that both languages can be represented (and executed) within Jupyter using the same clj-tiles graphics. Let’s start.
The log of sixty-four is close to four.
We differentiate log. As a result we get the derivative, which is one over x. With this, we verify that the function named log is indeed the natural logarithm which has e as its base.
We’d like to change the logarithm’s base. For this we define our own logarithm function. We make one and the same mathematical definition in two different syntax styles. More precisely, we distribute the parentheses of Python differently to get Clojure style code. There is no naming conflict, the first definition is for SymPy in a Python environment, the second is for Emmy in the browser. Nonetheless, there is only one Jupyter notebook.
Note that one single graphic represents both textual definitions faithfully.
Indeed, both functions return the number two as the result of log-base-eight sixty-four.
Note that the graphics represents both versions faithfully.
We are not happy that eight and sixty-four are on an equal footing here. Whereas eight is a parameter that is more or less part of the function-name, it is the number sixty-four that we want to crunch. So we define the higher-order function log_base.
We are relieved to also get for our new function the number two as a result. But we like the new graphics much better, it clearly distinguishes between the parameter b and the variable x.
For calculating the derivative of log_base, there are now two possibilities. The Python way is to first calculate the expression log of x and then take the derivative of this expression:
The Emmy way ist to directly take the derivative of log and then calculate the resulting expression.
This concludes our log example.
Special Topics
In a first read, jump to “Summary and Outlook” by omitting this section.
Another Jupyter
A Clojure to Python compiler like Hissp can be used to execute the textual definition of clj-tiles graphics ()not with JavaScript) but within a Python environment.
Higher order functions
The Python code
this_returns_a_function("three=")(3)
renders neatly in BlockPy
For the respective Clojure code
((this-returns-a-function "three=") 3)
we actually had to introduce a third type of block showing the pipe symbol |
so that confusions with vectors are avoided:
We think this is neat too, also because of the unique beige colour.
Let blocks and maps in Clojure
Because the standard (let [x 2 y (pow x 3)] y)
does not look great in graphics (left side), I’d suggest to introduce some macro, call it let-p
, which reads as (let-p (x 2) (y (pow x 3)) y)
. We think that the respective graphics on the right hand side indeed looks nice.
Concerning hash-maps, there certainly can be found one solution or another. One could maybe think along the lines of the presented solution for higher order functions, another one can be found hidden in the clj-tiles pages. The question here is if one really wants to do keyword destructuring within blocks. My answer is that this should be avoided. Unless having a really good reason, using a list starting with hash-map
should be sufficient.
Remark
I would go as far as to say: if the graphical representation of a program cannot be held clean, it has no practical purpose and one should either simplify the code snipped to be presented or switch language altogether. Thus I suggest to avoid striving for completeness of syntax coverage but keep the block representation of Clojure as simple as presented with all in all just three types of blocks.
Clojurists Together Application
What project are you applying for?
clj-tiles - https://github.com/kloimhardt/clj-tiles
Who is applying? How are you related to the project?
Markus “Agwin” Kloimwieder, project creator
What are you wanting to achieve with this funding?
clj-tiles is a website for visual programming in Clojure. At its core, clj-tiles parses Clojure code and transforms it into XML for Google-Blockly, the graphics engine. Since 2021, the codebase and tutorials have grown so that I now consider it feature complete. I’d like to extract the parser and make it easily accessible for everyone to use. The motivation is detailed in the post https://kloimhardt.github.io/blog/software/2025/03/30/py-clj-tiles.html
Why is this project important to the Clojure community?
The clj-tiles website is not used by anyone at all. But I still think that Clojure has an edge here. An open clj-tiles API would empower any Clojurian to experience and show that Clojure has an edge when it comes to visual programming.
Do you receive any other funding to work on this project?
No.
Summary and Outlook
For some simple Python cases, clj-tiles is more suitable for Python than BlockPy. In general, with clj-tiles, code snippets written in different languages can be presented in a uniform graphical manner. Thus, with and within such a presentation, an eventual transition from Python to Clojure can be facilitated by clj-tiles.