lundi 10 septembre 2012

Clojure for Java/Groovy developers: From GOTO to (recur)

Why this article?

I'm a developer for many years now. I started at 11 when my parents offered me my first computer: an Hector HRX (a French computer in the early 80's).
With it, I learned my first language: BASIC. The version with line numbers and the famous GOTO. A little memory ;)

10 PRINT "HELLO WORLD!"
20 GOTO 10

I learned deeply basic with my second computer, a MSX (I was afraid by the Z80 asm and now I suffer for never learn it). But the first big change occurred with my Atari ST and the GFA Basic. Even if the name of the language contains the 'basic' word, it was close to C. The syntax was very close, no line numbers and no goto. You wrote your functions and called them. And the performances of the GFA basic was good enough for different working. It was an introduction few years later for my C learning.

At the university, I studied the C and C++ languages. In these years, Java was new and the first versions was not very efficient.
With C, I liked to be close to the machine. I'm not afraid of pointers and it's fun to work with the memory.
When I learned the C++, I discovered the OO programming. At this time, I thought "Waaa, the object concepts make easier the programming".
Divide the implementation by objects exchanging messages is near to the formal mindset. I only found the C++ syntax was a little tricky and the multiple inheritance matters more than it solved problems. I don't think the multiple inheritance is bad, but how programmers use it is often not the best.
Thanks to C++ and C, I was ready to learn any other languages because they lay the basics for programming.

While my developer work life, I learned many languages: mainly Python and Java. I learned Java while the end of the Java 1.4 and the beginning of the 1.6 version. For me, the Java 1.6 was the good enough version. Its performances were good and the basics of this languages was fixed.

I discovered the Groovy languages for 3 years and I found it was a good compromise between Python and Java. For me, a language that rests on JVM is a good thing because it's more easy to push it in my company mentality. You generate a jar and all other developers can use your code in theirs. For me, I take less time to code.

Less time to code... It's the main point that did I wanted to take distance with Java. I think Java was a good language for programming. It was a corner stone, like the C, C++, and others. But the programming world keeps on to evolve and I doesn't want to become 'sclerotic' in my thoughts.
Coding in Java has became less and less fun: you write more code for less thing with all frameworks and the famous design patterns. The DP are good ideas but too many people follow them without thinking about them. And we retrieve code with a lot of classes that implement many interfaces with only one method. The code becomes more and more complex to find "what the program does". We lost the main goal of a program: make the job and be easy to maintain.
I repeat, I'm not against the DP. One big point they spread is the delegation over the inheritance.

Today, my main work is to develop server-side program. I don't work on GUI and my programs target data processing. So, I've never had to manage Java swing framework and other ones. My programs are stand-alone or web server applications. According to needs, I coded with C (for very specific needs), C++ (only for maintenance), Java (less and less) and Groovy (when I can).

For a few months, I have been interested for functional programming. I read different articles about this and I found the idea interesting. We go back to the target of a program: the functionality. A lot of articles talked about Haskell. A beautiful, pure functional language but... I wanted to stay in the JVM world to use all the already developed Java libraries. So, I chose to learn Clojure (http://clojure.org).

In this article, I don't detail the functional programming (wikipedia and a lot of others blogs explain the idea better than me). I'm writing about my first experiment with FP: A developer's journey in Clojure and the FP.

What this article is

In this article, there is no code. I give my feeling about Clojure and FP with my imperative mind. I try to share my experiment and, I hope, makes other developers to learn FP and Clojure. I won't talk about the benefits of Clojure in concurrency programming (for now but may be in the future). I chose to describe only the Clojure basics that are those used every day.

How do you code?

An important thing when you learn and use a language is the developing tools. For your knowledge, all main IDEs offer Clojure plug-in (Eclipse, Netbeans and IntelliJ). A lot of Clojure developers use emacs too, but I understand if you think it's too roots. My heart balances between IntelliJ and emacs. I tested the Eclipse plug-in, it works fine but I'm not a big fan of Eclipse. About IntelliJ, don't forget you can use the free community version.

First feeling

Syntax: The LISP way

All people who know *really* FP, please don't take the next sentence in the first degree :) I think Groovy let me to touch slightly the FP by closures. The fact to pass a function into method's arguments open the mind and offers a way to be more generic in objects. So, I want to go deeply into the FP and understand its paradigm.

The first thing, I understood is: learn a language like Clojure is very different than others. When you learn a new imperative language, the main work is a syntax translation. I know it's not limited to that, for some languages we need to understand some principles and the philosophy behind them. For example, when I learned Groovy, I had to move my mind in dynamic spirit and the famous closure logic. But the syntax and the language structure was close to Java.

One issue with a language like Clojure is you can do nothing without a minimal learning stage. The syntax of Clojure is based upon the LISP. It's very particular, all those parentheses. But, when I started learning this syntax, I understood that not regular doesn't mean not efficient. At the beginning, it's hard because we're used to languages based upon C syntax. You must open your mind. Once you did that, you find the Clojure syntax is concise, clear and efficient. And like with all languages, a bad programmer can make unreadable whatever source code :)

Hence, before write any lines of code, I had to read resources. I read the books "Learning Clojure" and "Practical Clojure". It takes a lot of time and it's frustrating. But it's necessary if you don't want to loose time after. So, the first weeks of my Clojure learning was: read books, take notes, test very little code chunks.

New abstractions

Indeed, the syntax is not the main new stuff to learn. You have to adopt new concepts and abstractions. For example, you want a for loop like in other languages. Huh, sorry it doesn't exist. You must ask yourself for what you want to do the loop. It's to compute a result then use the reduce function. It's to process each value in a list, then use map. And so on. It seems strange at the beginning but after some tests and code writing, you realize this kind of thoughts make your code more coherent. When you read again the code, or someone else, you understand *why* you did this code.

Another way in FP to replace loop is the recursion. You think your loops in term of recursion. When you worked for many years with imperative languages, you realize you didn't use the recursion very often. But in FP, and Clojure, you do, you must do. After a little time for lubricating your brain, the use of recursion becomes natural. Like other things, you must train yourself.

Another new abstraction to understand is data structures. As Clojure rests on JVM, you have the standard data structures like maps, lists (vectors in Clojure), set. You have sorted abstractions too for sets and maps. But some of the non-standard data structures are sequences and lazy-sequence. To make simply, sequence is like tuples in Python. Lazy-seq is a great stuff in Clojure. The items are computed while their evaluating. Thus, theoretically, you can have an infinite sequence.

Immutability

An important principle in Clojure (and in FP in general) is the immutability of data. This means you don't change the structure but you retrieve a new structure with the changes. When I read that the first time, I asked myself: "Huh, and the performances?". This vision is wrong because in Clojure, there isn't deep copy. The Clojure is well thought and it uses the structure sharing. It offers better performances even if data are immutable. The principles of the structure sharing is to manage the differences between 2 versions of one data structure. And here, we meet the pragmatic mind of Clojure. If you really need performances, you can switch temporally into mutable structures. You make the job on it and after you return the result in an immutable structure. But in practice, this kind of optimizations is very rare. And don't forget, nothing prevent you to make some code in Java. You'll can call this code easily because we work inside a JVM.

Another thing deriving from immutability, you don't have state. Indeed, each time you change a data structure you receive a new one. It's weird at the beginning but once again, when you start developing in Clojure, that becomes natural. And we'll see later we can manage state :) in some cases (and when it's really necessary).

Functions, functions, functionality

In Clojure (and in FP), all is function. There is no object, no method.
Even in another sort of language, you should avoid too long methods. In Clojure, you can't or it's so hard to write very long function that you don't. That forces you to split your implementation into chunks. What you should do in another languages, you do in Clojure.
And by this way, we come back to the target of programs: meet needs offering functionalities.

The functions are so everywhere you can use them like function result or pass them as argument to other functions. Return a function offers you to adapt your code while its running. Use a function as parameter gives you a way to be concentrated to the functionalities of your program. For example, you want to process fields from a record, we need meet 2 needs: read a CSV file and process data inside fields. First, you write a function that reads the file record by record. This function takes as argument an function that does the processing on the field. Thus, each function meets a precise need and you don't mix the functionality.

This possibility to divide the code offers you a really way for reusing. Because, in OO, we know that the re usability of code is a dreams. While coding, developers adds responsibilities to the objects and their boundaries become blurred. Or, to avoid the coupling, we develop a lot of classes that add the complexity and mask the code's target.

Summary

In this article, I yield only a superficial view of Clojure. I gave only some points that attract me to Clojure.
If you are tired of the Java heaviness and/or you like Groovy, Clojure is a good language to learn. But don't forget: you would have to take a lot of time for learning before appreciate that language. But it's worth.

In the future, I'll write articles about more accurate points in Clojure for Java and Groovy programmers (like how replace inheritance, objects). I'll talk about the concurrency programming too. And this time, there are source codes :)


vendredi 27 juillet 2012

Why I quit Apple OS X

Hi all folks, in this post I'm talking about my progressive stop using Apple OS X.


Remarks: The content below talks about my personal experience. A software developer spends time to develop, write Bash script. I'm not a gamer (except games like Zork or MSX games), not a designer. Now, I program in JVM languages (Groovy, Clojure) and make Web development (PHP, Grails, CSS3, HTML). 

EDIT: I edit my text to be accurate about my memory management problem. It seems it wonders some people, I met the problem with my iMac with 3GB. The problem was less obvious with my laptop has 4GB.


The Happy Days

First, there a summary of my "Apple" life. All began like a dreams for me, I was a Linux user (since the end of my studies in 1998). I'm a developer and my favorite tools are the command-line, emacs and more and more good IDE like IntelliJ (before Eclipse and Netbeans).  
But I was bored by a lot of configuration problems. The biggest problem was to be able to use a DSL modem. I spent a too many times to configure module, kernel, edit configuration files. I'm not a system hacker system, only a good developer and I like programming, not configuration for programming.
So, in 2003 I saw an ad about OS X Panther and I said "Yes!". It seems a simple OS with bash shell (very important for me), with a lot of open source products inside.
Thus, I bought my first iBook G4 laptop with OS X Panther. I was very happy, the printer worked directly, no problem with DSL modem and I could spend all my time to program. The happiness. The sole exception was Java, on a Power PC architecture, the Java implementation was very slow. But, at this moment, I developed in Python, C and I discovered Objective-C and Cocoa (an excellent framework).
Later, in 2006, I ordered my iMac and a white MacBook laptop (currently, I'm writing with this iMac and I use regularly the same laptop :)). Both was on Tiger, again the OS was fine, responsive and this time the Java implementation was good enough (thanks the Intel choice).

The Disillusion

When Leopard was out, I bought it and it didn't seem so great. I felt my computers made heavy. And I noticed the memory of my computers started being limited. So, I upgraded my iMac with 3Gb (the max memory capacity for it) and 4Gb for my laptop. But I continued boasting OS X to my friends and some of them bought Apple computers.
I bought an iPhone and an iPad and I was happy by the simplicity of their interactions with OS X. 
But Apple started "forcing" user to adopt frequently updates. I know the term "forcing" is a little strong because you don't have knife against your neck. But, I was developer, more and more in Java for my job and I wanted to have the last release, I had to update my OS. 
When I installed Snow Leopard on my iMac, I was really disappointed. My hard disk frequently swapped and I spent more time to look at the color wheel and wait for my computer. With whatever IDE, I had these issues and I had no more pleasure to code with OS X. I talked about the problems on forums, bringing up the memory manager problem and each time, people respond me "The memory manger of Apple is the best. Upgrade your memory. You can't, so change your computer with the latest". But I was at max on my computers! And since when, I need 8Gb to develop programs ? And if I wrote again the Apple's memory manager was bad, I was shutdown in flames. No criticizing the master! 
I told to myself: "God, why with 3Gb or 4Gb on an Intel core 2 duo computer, I can't continue developing like before". Even my friends, who bought Apple computers thanks to me, was became full Apple compliant in their computers, phones and thoughts too. They didn't understand why I wouldn't to buy new computers. How can I say ? ... They cost some money and my current computer works pretty well. Ah, it's not enough?! 

Back Home

I forgot Linux for my personal use (I used and using again it for my job inside a virtual machine on Windows). I don't know why, may be I wouldn't spend time again for configuration. But I was happy no more with OS X (and sorry, but I can't use Windows. I'm too Unix lover for that). 
And one day (last year, 2011), I was watching the Big Bang Theory TV show and Sheldon talked about Ubuntu. It was like a hammer hit on my head. "Yeah, why don't try install Ubuntu on my macs?".
I downloaded the ISO file, burn the CD and .... go! No problem with the installation, the WiFi works well. Some adjustments was needed on my laptop (only configure settings for the touch pad, but I found quickly and easily it). My printer (a WiFi Epson PX720WD) works perfectly after downloading and installing the drivers. 
And the most important, for me, my computers are fast, responsive and I develop with intelliJ in Clojure, Groovy, C with pleasure. I can have the latest JVM version without change OS or computer :)
Futhermore, I can use my iPhone and iPad easily. I put my video and podcast on them directly from Ubuntu. 

Nowadays

I rarely return on OS X with my computers. The last time was to update the OS of my iPhone and iPad.
And I'm not in a hurry to use the last version of OS X when I read to use iCloud, you must update to Lion (and if you computer can't, then change it), by default (now, by what in the future?), you must install application from the MacAppStore, the application auto-termination, the new file system with Mountain Lion, the SSD use masks the memory management problem. Apple wants to transform your computer into a big iPad. I can't be happy, me a simple developer, with this logic. 

Now, I feel fine again :) Free, quiet, making development, discover new languages, new programming and software architecture concepts with old computers that work pretty well :). And when your computer isn't the fastest, you optimize and you are surprised when you see your program run on a server with the latest technologies.

I don't say Linux (or Ubuntu) is better than OS X. All operating system have pros and cons. It's a way-of-life choice, I don't want to buy new things just to have new things. And, the most important, I don't want my choices are controlled by a company.




mardi 15 novembre 2011

Idea to manage methods' result and exceptions

I ofen had to think about how I could manage well methods' result as well as exceptions.
To be honest, I'm not a big fan of exceptions. I think exceptions and their management put a lot of noise in the code. With exceptions, we have our try / catch blocks (sometimes those blocks are nested) and we must deal with variable declarations to be sure they are in the good scope.

Then, I've begun to think about a way to manage errors and results of my methods. First, I thought to add an error param in each method. This way is often used in C programming. But now, I develop in Groovy and for me. this way is a kind of anachronism. Anothier way was to return null for error and the result when method is successull. But in this case, we don't have granularity to manage different errors. And sometimes, null is the good result.

After pieces of time, I said to myself: "Why don't use some computing principles as current as HTTP and login framework like log4j ?". Thus, yesterday I began to write a class may be used to return information from method calls.

I'm explaining my thoughts. First, I take from log4J the notion of result's level. For a method, I consider those levels:
  • OK (method is successfull and the caller can trust in the result)
  • WARNING (a result has been given but something were weird)
  • ERROR (method has failed)
  • FATAL (big problem with the method, like an exception)
To retrieve the status level of my method call, I want to use some getters like isOk(), isWarning(), ...

From HTTP, I take the result code number and a message. The result code is an integer and the message is a string. It's simple and efficient. The developer saves into these properties information about result. The message could even be a code used by a i18n message bundle for instance.

After, I have to get the result. This can be a non-type property (I'm into Groovy mind) named value.

And last, I want to use insance of my class like the real method's result. So, I must to catch calls to my class and delegate them to the result object.

Here, a Groovy code showing my idea:

class Response implements GroovyInterceptable {
    public final static NL = 0
    public final static OK = 100
    public final static WR = 200
    public final static ER = 300
    public final static FT = 400
    
    Integer status = NL
    String message
    Integer returnCode
    def value
    
    
    Boolean isResponse() { true }
    
    Boolean isOk() { status == OK }
    Boolean isWarning() { status == WR }
    Boolean isError() { status == ER }
    Boolean isFatal() { status == FT }    
    
    def invokeMethod(String name, args) {
        def result
        if (name in ['isOk', 'isWarning', 'isError', 'isFatal']) {
            def metaMethod = metaClass.getMetaMethod(name, args)
            result = metaMethod.invoke(this, args)
        } else {
            def metaMethod = value.metaClass.getMetaMethod(name, args)
            result = metaMethod.invoke(value, args)
       }
       
        return result
    }
} 
 
// A method to test my result class
def add(x, y) {
    new Response(status: Response.OK, message: "$x plus $y", returnCode: 0, value: x + y)
} 
 
// Some tests
def result = add(12, 8)
assert result.isOk()
assert result == 20
assert result + 5 == 25
println result.message
println result.status


With the Groovy code above,  I can manage all the cases which can happen from method calls.

What do you think about that ? I wait for any feedbacks and other ideas to improve my method result class. If you want, you can write implementation into other languages.