hy

I stumbled upon a new programming language called hy. Basically it is for Python what Clojure is for Java; a LISP implementation. I have played around with it a bit, mainly for my Sandvalley project and at least so far I find it easier to use than Clojure. I think this probably is because Python standard library is much more familiar to me than Java’s.

If I have understood everything correctly, interfacing hy and Python is extremely simple. hy programs get turned into Python abstract syntax trees and the interpreter does not see any difference at all. There are some conventions how for example function names are mapped (some-function gets turned into some_function).

Hy seems to have quite active development community. What I lack currently is the documentation, but eventually that’ll pick up too.

(sorry, no code samples this time, still have to figure out how things mesh together :))

Status update

The past month has been extremely busy and I have not had time to take care of the blog properly. I am on the final stretch of my thesis and hopefully after finishing it I will have time to code again.

I managed to write some clojure code and get the very elemental ray tracer up and running. It does not do shadows or reflections yet, but those are just some details that I can add later.

I also converted pyherc and satin-python to 3.x version of Python and things are mostly working. For some reason style sheets fail to load, which is really bad problem. I have to find the reason behind this behaviour before adding more content.

Simple vector mathematics

I decided to start easy and just write some simple functions that I will eventually need in calculating ray traced images: dot product and cross product.

(ns cltrace.math)

(defn dot
  "Returns the value of dot product of the vectors v1 and v2"
  [v1 v2] (reduce + (map * v1 v2)))

(defn cross
  "Return the cross product of vectors v1 and v2"
  [v1 v2] [(- (* (v1 1) (v2 2)) (* (v1 2) (v2 1)))
   (- (* (v1 2) (v2 0)) (* (v1 0) (v2 2)))
   (- (* (v1 0) (v2 1)) (* (v1 1) (v2 0)))])

defn is a macro that is used to define a function. Here I’m defining two functions doc and cross for calculating dot and cross product respectively. First parameter is name of the function, second is optional string used for documentation, third one is a vector defining input parameters the function will accept and the last one is the actual function.

map function applies function to sequences, returning a sequence. For example (map * [1 2 3] [4 5 6]) will result [1*4 2*5 3*6], which equals to [4 10 18].

reduce function will apply function sequentially to elements of a sequence. For example (reduce + [4 10 18]) will perform [4 + 10 18] -> [14 + 18] -> 32.

Combine these two functions and you get a really pretty looking function to calculate dot product of two vectors that can be arbitrary long.

To test these two functions, I wrote some simple unit tests:

(ns cltrace.math-test
  (:use clojure.test
    cltrace.math))

(deftest test-dot-length-3
  (is (= 29 (dot [2 3 4] [2 3 4]))))

(deftest test-dot-lentgh-1
  (is (= 4 (dot [2] [2]))))

(deftest test-cross-simple
  (is (= [-1 2 -1] (cross [1 2 3] [2 3 4]))))

That’s not that many lines of code, but it’s a start. I can tell that it’s really different way of looking code and structuring a program. When I get more comfortable with the language, I should go and try writing a minimum viable product. That would basically be a program that can save a picture of unshaded, mono-coloured sphere into a file.

Learning something new

Learning new things can be useful and can often be helpful to see new aspects of old things. I have been working with Python code for 2 years or so now and wanted to try out something new: Clojure. I have known the language for a while already and even tried to dabble with it previously (with not that great success). Today I installed Leiningen and Light Table and decided to give it another try. I’m going to try and write a simple ray tracer with it. If I can get it to write png-files on hard drive with some shaded spheres and planes, I’m quite happy. I did something like that before with Python, so the problem domain is not new to me. Code is already available at GitHub of course, but it does not do much yet.

But the language and concept is totally new. I don’t know enough of basics to be productive with the language and even the simplest things take long time (first trying, then googling and then trying again). Light table helps lot though, since I see quickly what is happening and if all my tests are still passing.

I’m not going to abandon Herculeum. The project is in a spot that requires some mulling over design of the game and figuring out what kind of mechanics I would prefer the game to have.

Learning

It’s been busy week again and I have been cramming on information. I finished reading excellent How Google Tests Software and I must say that I’m impressed. It’s short, only a bit over 250 pages and full of interesting information not only about how they test the software, but also about how they ended up testing it like they do now.

I’m still slowly learning how to program in clojure and got a pile of links to get started with from a colleague:

https://github.com/functional-koans/clojure-koans
http://www.4clojure.com/
http://learn-clojure.com
http://clojure.org
http://clojuredocs.org

I haven’t touched anything else but the clojure-koans and 4clojure yet, but rest should be good too. Haven’t even had time to search for any books, since I still have pile on my nightstand to read first.

Interesting times and quite enlightening.

Achievement unlocked!

    
(defn mult_first [a b]
    (* (first a) (first b)))</code>

(defn mult_rest [a b]
    (if (= (count a) 1) (mult_first a b)
        (+ (mult_first a b) (mult_rest (rest a) (rest b)))))

(defn dot [a b]
    (mult_rest a b))

(dot [2 3 4] [2 3 4])

29

It probably could be a lot more elegant and I’m probably breaking who-knows-how-many conventions and guidelines, but it’s still the first clojure program I ever wrote (can be used to calculate dot product of two arbitrarily long vectors, as long as they are equally long).

edit:

Turns out I was right, the dot can be written in much simpler and cleaner way:

(defn dot 
    "Returns the value of dot product of the vectors v1 and v2"
    [v1 v2] (reduce + (map * v1 v2)))

(thanks Minilight in Clojure: Vectors)