Working with Clojure and Racket

Written by Dominik Joe Pantůček on 4 dubna, 2019.

As you might have noticed, we are working with rather interesting technologies here at Trustica. Developing and manufacturing cryptographic USB device brought us to play with various hardware pieces and gave us a chance to work with interesting software development platforms, languages, operating systems and libraries.

For those following Cryptoucan™ development since the beginning of the last year, you are already familiar with the scheme-based programming language Racket[1] in which we develop all the software for Cryptoucan™ testing, stocks management and manufacturing control. However, in the past, we have also considered a different language. Clojure[2]. And because right now I am teaching the Algorithms and Data Structure introductory course at local university[3][4] and the students are supposed to learn Clojure basics during the semester, it is probably the right time to compare Clojure and Racket – as they have much in common.

Racket can – in principle – run on top of any sufficiently advanced Scheme[5] platform. It comes with its own byte-code compiler and virtual machine, but there is an ongoing (and quite successful) effort to make it run on top of Chez Scheme[6]. Clojure – quite contrary – is tightly bound to the Java[7] world as it runs on top of Java Virtual Machine[8] (JVM) and uses many components from various Java libraries.

Picture 1: Clojure logo

As both languages are Scheme-based, they share the common LISP[9]-inherited syntax of S-expressions[10] (symbolic expressions) which are evaluated as the program is being run. However, in case of Clojure, the Scheme inheritance is not so strict. Many primitive data types (atoms) are implemented using appropriate Java equivalents. Although this simplifies connecting Clojure code with existing Java libraries, it removes parts of the Scheme clean design. And in a lot of cases, you need to use specific data types although you are creating something relatively generic. A simple array of integers has a special type brought in from Java world for example – and any other data type working with integers has worse efficiency in Clojure.

But for the brighter side, if you dig through the layers of Java-related stuff and can write a decent code in Clojure, you will find it useful for certain Artificial Intelligence[11] and machine learning[12] related tasks, where this language and Java platform are both used extensively.

When strictly following the functional paradigm, Clojure can actually be quite nice acquaintance after an afternoon or two. The downside comes when you need to implement algorithms that require side effects. That is variable mutation. You need to use explicit references to encapsulate values in mutable boxes or you need to use specific local bindings to emulate local mutable variables. Actually the latter is implemented in terms of the former and looking at the source code – the implementation is far from nice and clean. Compared to Racket features for side effects, Clojure can sometimes feel like a joke. Racket goes as far as mutable pairs and lists – should you need them!

Picture 2: Racket logo

All that said, it is an excellent learning experience for the students. First year university students typically lack any experience in – usually even any knowledge about – functional languages from the LISP family. This means none of them has any advantage over any other – maybe actually those without any programming experience have often slight advantage as they did not learn any bad programming habits yet. And although Clojure is definitely not entirely nice and clean, it can serve as a tool for teaching programming from its mathematical foundations.

The main difference for newcomers can be the platform support. Racket works out of box on all major platforms: Linux, Mac and even Windows. Clojure requires quite some effort if you want to set up your development environment on Windows. And also – for Racket, there is the excellent DrRacket[13] integrated development environment. Clojure relies on third-party editors and environment integration – for example through Leiningen[14].

 

 

Enough of academic talk for today, I think you all understand why we stick to Racket here! See you next week with Cryptoucan™ news again.


References

1. https://racket-lang.org/

2. https://clojure.org/

3. https://www.praguecollege.cz/

4. http://tees.ac.uk/

5. Wikipedia contributors. (2019, March 30). Scheme (programming language). In Wikipedia, The Free Encyclopedia. Retrieved 14:59, April 3, 2019, from https://en.wikipedia.org/w/index.php?title=Scheme_(programming_language)&oldid=890221901

6. https://www.scheme.com/

7. https://www.java.com/en/

8. Wikipedia contributors. (2019, March 20). Java virtual machine. In Wikipedia, The Free Encyclopedia. Retrieved 15:01, April 3, 2019, from https://en.wikipedia.org/w/index.php?title=Java_virtual_machine&oldid=888674840

9. Wikipedia contributors. (2019, April 1). Lisp (programming language). In Wikipedia, The Free Encyclopedia. Retrieved 15:01, April 3, 2019, from https://en.wikipedia.org/w/index.php?title=Lisp_(programming_language)&oldid=890445060

10. Wikipedia contributors. (2019, January 20). S-expression. In Wikipedia, The Free Encyclopedia. Retrieved 15:01, April 3, 2019, from https://en.wikipedia.org/w/index.php?title=S-expression&oldid=879283089

11. Wikipedia contributors. (2019, April 3). Artificial intelligence. In Wikipedia, The Free Encyclopedia. Retrieved 15:02, April 3, 2019, from https://en.wikipedia.org/w/index.php?title=Artificial_intelligence&oldid=890782419

12. Wikipedia contributors. (2019, April 3). Machine learning. In Wikipedia, The Free Encyclopedia. Retrieved 15:02, April 3, 2019, from https://en.wikipedia.org/w/index.php?title=Machine_learning&oldid=890697907

13. https://docs.racket-lang.org/drracket/index.html

14. https://leiningen.org/