There's been a lot said about using Java in Clojure code. However, the circumstance may arise when you need to write Clojure code to run in Java. It is a little more roundabout and a little less clean, but it is possible. I'll be going over the gen class option available for the interop to take place.
Let's look at a simple example.
What we have available now is a package test with class Speak. We can instantiate an instance of speak. We can call hello("my name") on our instance and I'm sure you can guess what happens. One caveat to notice is that we must prepend our function names with '-' and we must declare our function's in the top gen-class block. We can then get a little fancier. Here's the same example with a global variable.
Now we can set the name on our instance before we call the speak function. Notice the :state declaration in the top block. We can only have one state variable, so use it wisely. Here, I intend to only use it to hold the name to say hello to. A good pattern is to use the state option to store a map of all the variables one might need since we are limited to one state variable.
Monday, January 30, 2012
Day In Review
I was on the Hosemonster project again today. We were able to finish the graphing framework and completed fitting curves to a set of data points. It felt good to have a finished product that we will then plug into the application.
The second half of the day was dedicated to refactoring. The new, edit, and view pages for our models were all basic and contained many repeating portions. In order to stay DRY and to help keep the system simple we started refactoring to collapse the new, edit, and view pages of our models into one page that then tweaks itself dependent on a parameter corresponding to a action which is passed down. I liked this refactoring since it meant we had a pattern to follow as more and more models are introduced to the system.
Another refactoring we had was to collapse the Interactor's update and create functions into one save function. Again, these two functions contained a lot of the same lines and in order to stay DRY we collapsed them upon each other. This change was fairly simple since we need to create if the model does not have an id and update if it does. This was the only different in the two functions.
The second half of the day was dedicated to refactoring. The new, edit, and view pages for our models were all basic and contained many repeating portions. In order to stay DRY and to help keep the system simple we started refactoring to collapse the new, edit, and view pages of our models into one page that then tweaks itself dependent on a parameter corresponding to a action which is passed down. I liked this refactoring since it meant we had a pattern to follow as more and more models are introduced to the system.
Another refactoring we had was to collapse the Interactor's update and create functions into one save function. Again, these two functions contained a lot of the same lines and in order to stay DRY we collapsed them upon each other. This change was fairly simple since we need to create if the model does not have an id and update if it does. This was the only different in the two functions.
Sunday, January 29, 2012
Using External Dependencies For Specific Use Cases
I am going to recount a recent learning experience I encountered while working on a Rails Project. The ideas I came away with are not Rails specific, however, and are applicable to all software. The learning experienced involved me leaning on third party libraries. This lean later turned into a fall and I realized that third party libraries are to be used for a specific case and only for that case. Dependencies are for what you yourself can not do on your own in a reasonable time period. I learned that we must be careful with the libraries we make use of since their behavior is outside of our control even if we believe to have them pinned down in test.
ActionMailer is a gem most Rails programmers are familiar with. For a story I was completing I needed to email notifications and I knew I was not going to implement a mailing system in a reasonable time period. I then introduced ActionMailer and wrapped the functionality. I had the system under test and I felt pretty confident with what I was using ActionMailer for. My tests were green. The code then went live and I quickly learned that I had made a big mistake. I started receiving ActionMailer generated exceptions. What had happend? I was green when I had committed!
Well, I was green and it was a false positive. ActionMailer has a different set of rules for test and for production. In my case I leaned on ActionMailer and got burnt. I took an array of email addresses and joined them by commas to produce a string to be used as the recipient list of my generated mail. When there were no array entries this produced an empty string. When I sent an empty string to ActionMailer in test it essentially disregards it. Great, I thought, ActionMailer handles my empty email list case! WRONG!
In production an empty string as a recipient list with ActionMailer produces an exception. When the operation is fairly common it produces a lot of exceptions. It was my fault for not narrowing my usage of ActionMailer to the specific cases in which it was actually needed. I instead used it for my empty string case. The moral of story, external dependencies are for specific use cases and nothing more.
ActionMailer is a gem most Rails programmers are familiar with. For a story I was completing I needed to email notifications and I knew I was not going to implement a mailing system in a reasonable time period. I then introduced ActionMailer and wrapped the functionality. I had the system under test and I felt pretty confident with what I was using ActionMailer for. My tests were green. The code then went live and I quickly learned that I had made a big mistake. I started receiving ActionMailer generated exceptions. What had happend? I was green when I had committed!
Well, I was green and it was a false positive. ActionMailer has a different set of rules for test and for production. In my case I leaned on ActionMailer and got burnt. I took an array of email addresses and joined them by commas to produce a string to be used as the recipient list of my generated mail. When there were no array entries this produced an empty string. When I sent an empty string to ActionMailer in test it essentially disregards it. Great, I thought, ActionMailer handles my empty email list case! WRONG!
In production an empty string as a recipient list with ActionMailer produces an exception. When the operation is fairly common it produces a lot of exceptions. It was my fault for not narrowing my usage of ActionMailer to the specific cases in which it was actually needed. I instead used it for my empty string case. The moral of story, external dependencies are for specific use cases and nothing more.
Friday, January 27, 2012
Day In Review
Yesterday, I worked on Artisan for the entire day. I paired with Myles for the whole day, since Myles is new to Artisan and unfamiliar with the code base. This was a good experience for the both of us, since Myles was introduced to the code base, and for me since I had to articulate the components of the system. It's always a good idea to articulate, at a high level, what each component of a system does. It forces you to think about your system at a high level and the missing abstractions seem to bubble up when you talk about a system in this way.
Specifically, Myles and I were able to have the iteration new/edit form working as a modal. This keeps the workflow contained on the storyboard page, which was the goal of our work. The changes actually pointed us towards a missing abstraction and implementing the abstraction for iteration presentation felt good. It made the change feel painless and allowed the existing code to stay largely in tact.
The second half of the day we revisited the storyboard column sorting bug. We fixed the bug, however we introduced redundant behavior (sorting when it is unnecessary) and are having trouble cutting this behavior out.
Specifically, Myles and I were able to have the iteration new/edit form working as a modal. This keeps the workflow contained on the storyboard page, which was the goal of our work. The changes actually pointed us towards a missing abstraction and implementing the abstraction for iteration presentation felt good. It made the change feel painless and allowed the existing code to stay largely in tact.
The second half of the day we revisited the storyboard column sorting bug. We fixed the bug, however we introduced redundant behavior (sorting when it is unnecessary) and are having trouble cutting this behavior out.
Wednesday, January 25, 2012
Day In Review
I started the day off working on the storyboard sorting bug. This is a tricky bug to get rid of because of the way the behavior works. Sortable, the jquery-ui widget, allows callback functions for an update in a single column and a receive event from another column. What is happening is a column drag for a single story will trigger an update event in the original column, an update event in the new column, and a receive event in the new column. This is fine and dandy, however, we trigger a frivolous update event in the original column and it's wasteful. I've been trying to find a way to avoid the update event, however, it's hard to define the behavior in such a way to do the event in one column and not in the other. This process is ongoing and I plan on revisiting it tomorrow.
The second half of the day I dedicated to hosemonster and the graphing functionality. I have been spiking out ways to generate curve fitting functions given a set of data points. In the morning I, out of curiosity, entered a sin function and got a jagged heart-monitor looking output. I hypothesized that calculating more points would smooth the line and it did, I had a continuous sin function. This is when I got really excited, what a cool thing to have happen.
The next problem was figuring out how to calculate the form fitting function. The solution involves creating an arbitrary length polynomial whose degree is determined by the number of points supplied. To create the polynomial involves the use of Gaussian Elimination to solve for the coefficients of the function. Wai Lee and I were able to get a polynomial class under test, use the test data provided, plug in the polynomial generator, and create form fitting curves for data points.
The second half of the day I dedicated to hosemonster and the graphing functionality. I have been spiking out ways to generate curve fitting functions given a set of data points. In the morning I, out of curiosity, entered a sin function and got a jagged heart-monitor looking output. I hypothesized that calculating more points would smooth the line and it did, I had a continuous sin function. This is when I got really excited, what a cool thing to have happen.
The next problem was figuring out how to calculate the form fitting function. The solution involves creating an arbitrary length polynomial whose degree is determined by the number of points supplied. To create the polynomial involves the use of Gaussian Elimination to solve for the coefficients of the function. Wai Lee and I were able to get a polynomial class under test, use the test data provided, plug in the polynomial generator, and create form fitting curves for data points.
Tuesday, January 24, 2012
Clojure Map to Ruby Hash Kata
I performed the Clojure Map to Ruby Hash Kata and have the video available. Unfortunately, I wasn't able to include audio to introduce the kata and walk through some of the steps. That being said, you should be able to follow along. Enjoy.
Saturday, January 21, 2012
Day In Review
After completing some stories for Artisan, I needed to go back and review the work I had done. Unfortunately, there were some items that needed work. This was helpful to review, since it's part of the learning process. One big mistake I had made is probably a common one among Rails developers, I had missed a key abstraction and placed behavioral code in my controller.
I had gone from the highest level, an incoming HTTP request to the lowest level, talking to the database, all in one controller method. Instead of doing this, I pulled the behavioral code into an interactor that mapped to an existing model. This turned out to be great for the codebase because when the interactor first came together I began to notice responsibilities that lived hodge-podge in the system that ought to be shifted to this new abstraction. It was like taking a weight off the shoulders of many system components and helped reduce code duplication, which is always a win.
I had gone from the highest level, an incoming HTTP request to the lowest level, talking to the database, all in one controller method. Instead of doing this, I pulled the behavioral code into an interactor that mapped to an existing model. This turned out to be great for the codebase because when the interactor first came together I began to notice responsibilities that lived hodge-podge in the system that ought to be shifted to this new abstraction. It was like taking a weight off the shoulders of many system components and helped reduce code duplication, which is always a win.
Tuesday, January 17, 2012
Clojure records, types, and protocols
Clojure offers a way to structure data in the form of records, types, and protocols. Even more interesting, functions (behavior) can be added to these structures. If you are coming from an object-oriented background this probably sounds familiar, but there are differences that are both small and large worth noting.
Protocols, in clojure, are roughly equivalent to an interface in Java. A clojure protocol, like a java interface, defines a contract that an implementer agrees to when implementing a protocol. Simple enough right? Not so fast, what might strike someone as strange (and can be a potential pitfall) is that concrete implementations of a protocol are not required to implement all of the methods defined on the protocol. That means that when using a protocol there are not guarantees that a function in the contract of the protocol is implemented on the concrete record or type. So, when receiving or dealing with a protocol, as an abstract contract of available functions, the record or type behind the protocol might not be living up to its end of the contract. This is something to watch for when using protocols.
Records are a way to structure a persistent map. When defining a record the user can define all of the fields they wish to hold within the map. These fields become the keys and the values are populated during creation of an instance of a record. What is different from object-oriented programming is that the values of the fields never change after the record is instantiated, the data is immutable. When will a record be useful? When we want to define a set of fields that is commonly repeated and then provide a common way to populate the fields and refer to the map. Now that we understand the data side, how does the behavior side fit in? The only way to place functions within the record is to implement a protocol. Once a record makes use of a protocol it is then able to implement as many (or as few) of the protocol's abstract functions as it needs. Remember, however, that the data is immutable and the functions can not manipulate the stored data.
Types are very similar to plain old java objects (POJOs). Where a record is a map, a type encapsulates its data using the dot-notation, as one would use in most any object-oriented language. As with records, types must implement a protocol to have functions and is limited to the functions available on the protocol. Also, as with records, types do not need to implement all of the functions of a protocol.
After reading the high level overview it would probably be nice to look at some code:
Monday, January 16, 2012
Day In Review
Today was dedicated to the hosemonster project. The models on the project keep expanding and that has been keeping myself and my pair busy. I really like the view / model / interactor separation that we have implemented. The views push information down the interactor which encapsulates the models. In return the interactor will push information back to the UI. This keeps a nice separation and I enjoy the implementing the idea of tell, don't ask in the the workflow.
Sunday, January 15, 2012
Day In Review
On Friday I can continued working on the hosemonster project. I paired on adding fields and validations (lots of fields an validations) to our existing models. We had received a new specification for some models and this was the first step in implementing the specification. At lunch, Dave gave a great talk on building web sites in Clojure. I enjoyed how it was given in a framework agnostic point of view and described the commonality between all Clojure web frameworks. For Waza, I paired on Metis with Myles and Wei-Lee and discussed what methods should be on the interface for the Data Store. In the end we decided on simplicity in only offering create, update, save (update and if not available, create), find-all (attribute matched), find-first, find-by-id, delete-all, delete-first, delete-by-id. We avoided the ActiveRecord-esque temptation to use macros and offer more methods since we wanted a simple interface for all types of data stores to inherent. We then begin implementing the in-memory data store. We didn't finish and left the in-memory data store as a work in progress.
Thursday, January 12, 2012
Namespace Your Javascript
Imagine, if you will, any small non-trivial program, whether it's in an OOP, functional, or procedural language. To make this post easy to follow, think of Tic-Tac-Toe. What are you imagining? Maybe some kind of board data structure probably abstracted away in a container, some kind of game logic container, and so forth. This is good, this is the kind of separation that we ought to strive for when building a Tic-Tac-Toe application. Now think about the last web app you worked on. Think about your javascript file(s). Did they have the same kind of separation? If so, then stop reading. However, it is very likely that it did not have the proper level of separation. Did you have a single applicaton.js? Were you sending it for every single page load? Yikes! Did it make use of other libraries that you needed to send over on every page load? Double yikes! Maybe it looked something like this:
What we can see here is two very different responsibilities. One, we want to hide and show some_div depending on certain button clicks. Two, we want to sum a column as feedback for a form submit. Instead of namespacing these two concerns, we've cluttered the global namespace and gave functionality to every div with id some_div, every button with id some_button/some_other_button, and trigger a call back on every form submit. Furthermore we make event bindings in document ready. What happens when the specifications change and now afer totalling the column we must trigger extra events depending on the total? We'll just throw another function on there right? WRONG!
We're going to namespace. For this blog post we'll just work this simple example, and therefore, we will namespace simply. For more complex applications with many seperate files take a look at this namespace function. So, we refactor and now we have a namespace for each seperate concern.
Now, our global namespace contains only Visibility and ColumnReporter. We've moved our bindings out of document ready which means we can put them under test! The code looks cleaner, it's organized with a purpose. Furtheremore, we can separate the code into two files and send over each file only when necessary. Of course, there's more refactoring to be done, but we're on our way to clean javascript without a cluttered, bloated global namespace.
Day In Review
I began yesterday by working on the hosemonster project, but soon after stand up Micah had a task for me to complete. Micah asked for a Clojure Map to Ruby Hash converter. It was to be written in clojure, take a map as a parameter, and then return a string representation of a ruby hash. The source is found here. It was a good learning experience since I went through a few refactorings. It was also good to practice recursively iterating through a map since this is the natural way of iterating in Clojure.
The second part of the day Micah wanted the converter to be plugged into his code sparring app in order to allow more languages to participate. Ultimately, I failed to to have it return ruby hashes from the app, but I plan on giving it another go soon.
Tuesday, January 10, 2012
Day In Review
Working with Clojure is a paradigm shift and a new route to explore on my software journey. I am enjoying taking on a language that differs from Ruby in many ways and offers a change of pace. Decoupling functions from data encapsulation has advantages that I'm starting to see. Although Clojure can have side effects, I like the emphasis on side effect free functions. On the flip side, it offers different challenges and requires a different perspective to accomplish tasks in code. The constant nesting of functions can be dizzying at first, but by the end of the day it started feeling more natural. I must give a big shout out to my pairs for the day since they were patient with me while taking in the new code base. I'm looking forward to continuing down the Clojure path as I feel that there are many interesting ideas to explore through Clojure and functional programming as a whole.
After the work day ended, Uncle Bob gave a talk on Professionalism in Software. He spoke at length about the "inverted the pay structure" of software development, emphasizing that software's details are only fleshed out in source code. Uncle Bob spoke about using professional methodologies that accept this fact. Afterwards, I was able to speak to some attendees who work at non-Agile shops. Their experiences were interesting to hear about and I took away some understand of what it means to not follow the methodologies I have been following in my very short time in industry. Moving forward I will take these lessons into account as I try to discipline myself to work more and more professionally.
Monday, January 9, 2012
Day In Review
Today, I began by picking up a three point Artisan story. I like the abstractions between input and presentation that we are building in Artisan. The current story asks for emails to be sent to a configurable list of people depending on certain events happening. I was able to place email handlers into the classes that process these change events and it felt very painless, which is great. The email handler themselves are passed high level objects and pulls out the necessary data for email presentation, which removes that responsible from other locations in the code. Moving forward, I want to make this email presenter class easily extensible so that developers in the future can easy manage mass emails in the same way.
The second portion of the day I spent working on the Clojure Koans. Thankfully, I have had the opportunity to pair briefly with Myles on Metis, an ORM for Clojure. Unfortunately, event after pairing, Clojure still feels a bit weird to me. I'm purposefully moving slowly and constantly referencing the documentation to try and get a good feel for Clojure.
The second portion of the day I spent working on the Clojure Koans. Thankfully, I have had the opportunity to pair briefly with Myles on Metis, an ORM for Clojure. Unfortunately, event after pairing, Clojure still feels a bit weird to me. I'm purposefully moving slowly and constantly referencing the documentation to try and get a good feel for Clojure.
Subscribe to:
Posts (Atom)