Tuesday, January 1, 2013

Some of the guys participated in the Ludum Dare #24 game contest. It was a lot of fun.

Here's the art assets that I was proud of, the rest I did, didn't come out to well. It takes me a long time to produce decent art and rushing definitely doesn't help me. Anyhow, I put the assets up on my share for anyone to use.

Friday, September 14, 2012

So the start of the 3rd day of digging in Clojure's source, I'm scanning through the code looking for something that I want to dig further into. I'm finding my self relatively happy with the progress I've made so far. Looking over the various functions, I'm noticing that it looks a lot less foreign now.

(cast) calls java's cast, passing in a class and a class name to cast to. (to-array) calls clojure's java wrapper to toArray(), (vector) has a bunch of overloads to constructing a vetor, and so on. Much of those and the one's like (nil?), (false?), (not), and such are really straight forward, many of which just call the java code underneath. All of these become just needing to read up on whats available for our use.

For the most part, I'm scanning the code and all is well. Then I get to the functions for (if-let) and (when-let) and I'm taken back again.

I'm reading them a few times, and although I can follow the code, I'm not really sure what they are doing. I also notice that I'm not as comfortable with (let) as I want to be either. So I'm going to look at (let) in more detail first.

I read over the docs and some other info else where like this. I get a better feel for it. I just needed to work through some examples. I won't bore you with to many. The idea with (let) is you create a local scope that you can manipulate your data with.

As I'm digging through let I also run into the (->) function. That one apparently runs through a group of functions in order that you give them. I won't go to much into details about this one here as this post will get really long with every derail, but I figured I'd mention it in passing as I'm about to use it, and I myself didn't know what it was until just now.

That local declaration/logic peers into the future, a decade less than a century from now, to tell me how old I will be. Here's something else I noticed while looking at the examples. I really don't like it for these examples, but I'm sure there's use for it else where.

These two are the same call, however the second one uses a complex vector. where it maps the first values together and the second values together. In these simple cases I like the first version much beter. When I run into a reason to use the second one, I'll share.

The first thing I see that I don't know what it is, is the (assert-args) call. I can make some guesses, but I have a few so I figure its a good one to look up to make sure. After hitting the google, I quickly find out that it's a private function and not an openly accessible one, I won't be calling it with my code. But it's still good to understand for the sake of this exercise. Looking at the source for this one, I see that is runs through the arguments of the function and makes sure that the correct number of arguments were passed in based on what the function want. Seeing that I feel silly as the function was named pretty well and that could have just been implied.

([bindings then]
`(if-let ~bindings ~then nil))

The next part I start looking at is the one above this. Having no idea what's going on here with the ` and the ~ symbols, I do some searching online. It turns out that this is a macro and the ~ symbol is replacing those values with the values being passed in. Lets look at this example:

With my surface understanding of what's going on here, is we are creating a function that we can run at a later point. Seeing as how macros are a big chapter in a book I'm about to get back to, I'm not going to dig in past the surface for now. However our chunk of code in the if-let that we are looking at, creates a macro to call itself again putting the 'bindings' and the 'then' into place with a nil value. Which turns out is the overload call in this function, so we'll move on to that.

We see some heavy use of (let) which is ok, we know it's just setting stuff up locally for the function. then we see this guy: [form (bindings 0) tst (bindings 1)]. I do some searching online and read over the function some more then I realize how silly I was. In this function, bindings is being asserted that it's a vector (array), and you can get the value of a vector at an index by calling the vector as a function. So: ([99, 200] 1) returns 200. I attribute my lack of reading this one to the syntax highlighting. In the source, "bindings" and "assert-args" were the same color, making them stand out. "assert-args" was a private function doing stuff under the hood, I assumed "bindings" was also.

After that last puzzle piece, the whole thing becomes readable to me. Call if-let, pass in some bindings and then a then function and let it rip. As long as all the checks pass, it will bind the values and then call the 'then' function passed in.

Technically I had the right idea, but I was missing part of the idea of what if-let does. The "if-let" function allows us to streamline a "let" block and a nested "if" statement into one cleaner call. So although my code worked, you really want to pass in the actual "then" statement.

The last few calls, I just wanted to see the exceptions we were looking at if we didn't pass in the correct number of arguments for the vector to be formed from. The author of the code went through the trouble to put them in, may as well get some use out of them. :)

Summary

We looked at the (if-let) code, gaining a better understanding of (let) in the process (which makes sense as I was missing the whole point of (if-let) in the first place), touched the surface of macros, gained a passing understanding of the (->) function, saw a way of writing more complex vectors (which I'm not a fan of yet), and found that there is such a thing as private functions in Clojure.

Just playing around with recur more. I really didn't like the example they had online. After digging around some, I got the idea behind recur, it recalls the function it directly sits under. Mostly I see it used in loops in the examples online, however the = function we were looking at yesterday didn't. It was just calling the normal function it was in.

Quick warning, the first couple of examples won't have a way to stop them. I'm running them in repl, and CTRL+C to stop them. I felt that this best explains what recur is doing.