I’ll soon be starting a new permanent job, and in preparation I’m making it clear what is my prior intellectual property. In this case, it’s not so I can make “oodles of money” in the future, but it’s actually so I can release it as Open Source.
So what I’ll be explaining here is not something I’ve finished, but an idea which I’ve actually been playing around with for a year or so, but never gotten around to fully implementing. This will also help bring together my thinking on this and hopefully inspire me to really get going on this project :-)
What is funcjure?
funcjure is a “functional syntax wrapper” around Clojure. What do I mean by that? Well, Clojure is a great language, especially if you’re either used to or prepared to adapt to prefix notation. ie instead of typing 1+1, you type (+ 1 1) which although relatively easy to understand, can get a bit harder as things get more complex, like 9+5*7/4+62/6 which would translate as (+ 9 (*5 7) (/ 62 6) etc…
The logical question is Why? (do I have to type prefix notation) The Clojure and Lisp people will say “well, that’s the way it is, so just get used to it”, which I’m fine with as I wrote my first Lisp program over 3 decades go. Even still, I would prefer to use infix notation (which is what we’re taught for maths) and see no reason why we shouldn’t as computers are great at doing the sort of rote translation required to convert infix to prefix notations.
Clojure is a great language, which also has a fantastic ecosystem and community, and is written in Java which has a HUGE ecosystem. Furthermore, Clojure can call Java code, which has helped tremendously by giving Clojure “out of the box” access to so many libraries and products. Finally, because Clojure is a Lisp, its strong point is Symbolic Manipulation which is exactly what is required for translating infix to prefix structures in order to implement funcjure!
What would this look like? Let’s take some typical Clojure and then show what it would look like in funcjure:
"Hello World!" ; Minimal "Hello World!"
; "Hello World!"
(println "Hello World!" ) ; Standard "Hello World!"
; println("Hello World!)
; Clojure((println "Hello World")) ; Execute some Clojure code
(def a "test") ; Define a variable
(def mylist '(1 2 4 5 6)) ; Define a variable list
; mylist='(1 2 3 4 5 6)
(println a mylist) ; Print our variables
; println(a mylist)
(first (rest '(1 2 3 ))) ; Get the 2nd element of the list
; first(rest('(1 2 3)))
(.println System/out "Hello World from Java!")
; System.out.println("Hello World from Java!")
; or Java(System.out.println("Hello World from Java!"))
(defn factorial ; Now let's do the classic Factorial function
([n] ; when only one argument is passed in
(factorial n 1))
([n acc] ; when two arguments are passed in, with recursion
(if (= n 0) acc
(recur (dec n) (* acc n)))))
(factorial 6) ; And test it
; factorial(n) = factorial(n 1)
; factorial(n, acc) = if((n==0), acc, recur(dec(n), n*acc))
The overall purpose is to make code much more accessible and ‘natural’ to write as we’re essentially taught infix notation as our “second language” when we study even the most basic mathematics. None of this is really new – in the beginning, things look like our old friend BASIC, with direct assignment and loose typing, which easily map to Clojure. You’ll also notice that access to Clojure and Java is provided by the respective functions. Speaking of functions, these are written similar to Prolog and other languages (eg Erlang) which allow for “pattern matching” in function definitions. In the beginning, the capabilities would be mapped directly to Clojure (as shown above), but eventually it would be nice to go to a full Prolog style, so the factorial function could be written like
factorial(0) = 1 ; The base termination case
factorial(n) = n*factorial(n-1) ; Iteration by recursion
which I think is way more elegant.
That’s about it for this post, as this really contains the base concepts for what I’d like to do. There’s obviously a lot more scope and subtlety to this, some of which I’m aware of and probably a lot more which I’m not, but I personally would much prefer to use a language like this and have access to Clojure and Java when needed for efficiency or easy code porting.
What do you think? All comments / suggestions / critiques would be gratefully accepted as I haven’t really done much more work than this, other than having a 1/2 working translator for this syntax which I’m going to (hopefully) get to work on in the next few weeks before I start my job.