Pablo's blog

A bit of this, a bit of that and a lot about computers

Archive for the tag “Java”

Refactoring: Consolidate Duplicate Conditional Fragments; in Java, Python and Ruby

I’m reading the book Refactoring and one of the refactorings it shows is called “Consolidate Duplicate Conditional Fragments” and it shows an example in Java:

if (isSpecialDeal()) {
  total = price * 0.95;
  send();
} else {
  total = price * 0.98;
  send();
}

is refactored into

if (isSpecialDeal()) {
  total = price * 0.95;
} else {
  total = price * 0.98;
}
send();

If you do it in Python it’s actually quite similar:

if isSpecialDeal():
  total = price * 0.95
  send()
else:
  total = price * 0.98
  send()

is refactored into

if isSpecialDeal():
  total = price * 0.95
else:
  total = price * 0.98
send()

But in Ruby it’s different. In Ruby, like in Lisp, everything is an expression, everything has a value (maybe there are exceptions, I haven’t found them). Let’s look at it in Ruby:

if isSpecialDeal()
  total = price * 0.95
  send()
else
  total = price * 0.98
  send()
end

is refactored into

total = if isSpecialDeal()
  price * 0.95
else
  price * 0.98
end
send()

Or if you want it indented in another way:

total = if isSpecialDeal()
              price * 0.95
            else
              price * 0.98
            end
send()

We can push it one step further:

total = price * if isSpecialDeal()
                          0.95
                        else
                          0.98
                        end
send()

Of these three languages, only Ruby can manage to have inside each branch of the if only what changes depending on the condition and nothing else. In this simple case you could use the ternary operator, :?, but if the case wasn’t simple, Ruby would be at an advantage.

I’m reading Refactoring: Ruby Edition next.

Are dynamic languages just a temporary workaround?

This can unleash so much hate mail, but here it goes, my inbox is ready!

Are dynamic languages just a temporary workaround? I’m not sure! I’m switching between the two types of languages all the time: Java, Python, C#, JavaScript. I’ll try to make the long story short.

Statically typed languages, like Java and C#, are nice because when you do

blah.bleh()

you know that blah’s class has a bleh method, at compile time. But better than that, when you typed “blah.” you get a list of methods, and you already know whether there’s a bleh method or not, and if you typed bleh and it doesn’t exist, the IDE lets you know, no need to wait for the compiler. Also you can do very deterministic refactoring, renaming all “bleh” for “bluh” for example.

Statically typed languages are not nice because they are very verbose and require a lot of boilerplate (if you’ve used Haskell, just bear with me for now please), so you end up with things like:

List[Car] cars = new List[Cars]();
foreach (Car car in cars) {
    car.Crash();
}

How many “cars” do you read there? And that’s a nice example. There are worse. So come dynamically typed languages and you can write:

cars = []
for car in cars:
    car.crash()

You have less cars, and less (no) lists. That means you are more productive. You start chunking out code faster without having to stop and think “What type of object will this or that method return?”. But crash() can crash your application instead of just the car because you can’t know if it exists until run-time. That might be OK or not, testing and whatnot.

Then comes C# 3.0 where you can do:

var cars = new List[Car]();
foreach (var car in cars) {
    car.crash();
}

And you can see that syntactically it got closer to Python, which is what gives you the productivity. Don’t know the type? type “var”. But semantically, it’s still statically typed, like the previous statically typed example. You know that car is going to be of some class that has a crash method. You can actually know car’s class at compile time, no need to run it.

That’s called type inference. You don’t have to specify the type where the compiler is capable of inferring it for you. C# type inference system is still very limited (but better than Java’s). Let’s see an example in another language

cars = []
map crash cars

That means, create a list called cars, call the function crash on each car. Would you say that that is a statically typed language? or a dynamic one? I’d say it is dynamic, but it is static. Very static. It’s Haskell. Haskell’s compiler will infer all the types for you. It’s amazing, you’ll write code as robust as with C#, but as terse as Python’s (Monads will then kill your productivity, but that’s another story).

In Python 3 you can define types for arguments. They are mostly useless, but it’s an interesting direction. I think the best it can do is that when a program crashes it’ll tell you: “function blah expected an int, but got a float, not sure if that was the problem, but you might want to look into that”.

Now, my question is, are dynamically typed languages just a temporary workaround? As our compilers get better, our computers faster, will statically typed languages keep giving us as many or more reassurances about our code and utilities while at the same time they become as simple and terse as dynamically typed languages? Or will dynamically typed languages start to gain types and over time be more static without the programmers that use them ever noticing?

My question is, will we in the future, 50 or 100 years, look back and said “Dynamically typed languages where a temporary workaround to statically languages being painful to use when human beings and their toy computers were so primitive?” in the same way we can say today that “non-lexical scope was a limitation we had and have due to the limitations of computer hardware 30 years ago”.

Reviewed by Daniel Magliola. Thank you!

NetBeans could make the Ruby on Rails experience great

NetBeans could make the Ruby on Rails experience great for the vast majority of developers who are using Windows, where installing Ruby, Rails, PHP, MySQL, Python, etc is always a pain and the end result is ugly. But it falls short in some important ways which turned my experience with it into a nightmare.

The reason I say “for developers using Windows” is because I believe that for everybody else, the experience is great already. Or as good as it can be and NetBeans can be an excellent IDE, but not improve the installation and managing experience.

This is my story, my rant.

I downloaded the latest NetBeans and installed it. When creating my first Ruby project, I encountered the first problem. Ruby chocked on my username, which was “J. Pablo Fernández”. You could say it was my fault. Windows 7 asked for my name and I typed it. I wasn’t aware it was asking for my username. Even then I would have typed the same, because Windows 7 doesn’t distinguish between usernames and names, and in the 21st century, computers should be able to deal with any character anywhere.

I know it’s not NetBeans’ fault, it’s Ruby’s. But! Can you imagine a Software Engineer telling Steve Jobs “oh, copying files in a Mac behaves weirdly because it uses rsync and that’s its behavior, you see, it makes sense because…”? Of course Steve would have interrupted: “You’ve failed me for the last time”. The next developer would have patched rsync, trying to get the patch upstream, or creating an alternate rsync or stop using rsync.

I’ve spent many hours creating another user, migrating to it, which in Windows is like 100 times harder than it should.

Hours later, as soon as I created a project I got a message saying that I should upgrade gem, Ruby’s package manager, because the current version was incompatible with the current Rails version. By then I had already played with NetBeans’ gem interface telling it to upgrade everything, it should have upgraded gem as well, not just the gems. Every single developer out there running NetBeans must be encountering this error, and indeed there are quite a few threads about it on forums.

Trying to upgrade gem with NetBeans was impossible. I think what they did to install and upgrade gems in NetBeans is excellent, but failing to upgrade gem itself was a huge drawback. This one was NetBeans’ fault. Neverfear, let’s do it from the command line.

When doing it from the command line I encountered another error:

\NetBeans was unexpected at this time.

Looking around it seems it’s because of the spaces in “Program Files (x86)”. That means that the command line environment for Ruby that NetBeans installs is broken for everybody. I repeat: everybody. The answer: install it somewhere else.

Well, I have two things to say about it: first, fix the freaking thing, Ruby, gem, whatever. Paths can have spaces and all kind of weirdness. It’s a big world full of people speaking languages that can’t be represented with ASCII and people that believe computers should do our bidding, instead of the other way around. “If I want spaces you better give me spaces, useless lump of metal and silicon”.

Second, if you know one of your dependencies is broken, try to avoid triggering the broken behavior or at least warn the user about it. “We see you picked C:\Program Files (x86)\ to install NetBeans, which is pretty standard, but you know, Ruby is broken and can’t work in there, not even JRuby, so if you plan to use those at all, please consider installing it somewhere else.”

I uninstalled NetBeans, or tried to. The uninstaller didn’t work. I deleted it and tried to install it on C:\ProgramFilesx86, which failed because some other directory created by NetBeans somewhere else existed from the previous installation, which halted the installation. I started a dance of run installer, remove dir, run installer, remove dir, run installer… until it worked.

Once I finished I found out that NetBeans installed in C:\ProgramFilesx86\Netbeans 6.7.1. Yes, that’s a space. Oh my…

As a bonus, NetBeans can’t automatically find Sun’s JDK in its default directory. I had to point to it by hand. Sun was, as usually, absolutely disrespectful of the platform conventions and installed its crap in C:\Sun. I would have picked another place but I thought “I’m sure some stupid program will want to pick that shit from there”. Silly me.

12 hours have passed and I still haven’t been able to write a single line of source code. I contemplated installing Ruby by hand, but it’s so ugly that I decided I’m not going to use Windows for this. I’m going to work on another platform where installing Ruby is trivial and where I would probably never touch NetBeans because I have other editors.

I know there’s a lot not really related to NetBeans here, for example, the fact that working with Python, or Ruby or MySQL in Windows is a pain; but it’s a great opportunity for NetBeans. There are developers wanting to use those languages and environments and if NetBeans makes it easy for them, they will pick NetBeans not because of its editor, but because of everything else (which is what I was hoping to get out of NetBeans).

Aside from doing some usability tests, the people working on NetBeans should learn from the people working on Ubuntu (not the people working on Evolution) and instead of asking me for debugging traces when I report a simple obvious bug and then tell me it’s not their fault, they should submit those bugs upstream, to Ruby, gem, or whatever. Whenever someone like me submits that bug to NetBeans they should mark it as duplicate of an existing open bug that points to the upstream bug. I would have followed that link and told the Ruby developers “wake up!”. As it is, I didn’t. It’s too much work for me.

Reviewed by Daniel Magliola. Thank you!

Printing the class-path in Clojure

Let’s compare how we print the class-path in Clojure and how we do it on Java.

In Clojure:

(println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))

In Java:

import java.net.URL;
import java.net.URLClassLoader;

public class PrintClasspath {
    public static void main(String[] args) {
        //Get the System Classloader
        ClassLoader sysClassLoader = ClassLoader.getSystemClassLoader();

        //Get the URLs
        URL[] urls = ((URLClassLoader)sysClassLoader).getURLs();

        for(int i=0; i< urls.length; i++)
        {
            System.out.println(urls[i].getFile());
        }
    }
}

To be fair, the output is not the same, but the effect is.

Hacking on the Clojure application

Being able to write, build and run a Clojure application, like I explained in a previous article, is not enough. You also want to hack on it, to iterative code on it, after all, you are using a Lisp.

What I mean by iterative coding is something not very few know or do, but it’s extremely common in Lisp. You have you REPL running all the time (that is, generally, the interpreter). You load the code into the REPL, run it, modify some part of the code and re-load it. You may not reload the whole file but only a function on it, and you may have background process running on the REPL, like a web server. It is very powerful. Read more…

How to create a Clojure application

Update: this is not my preferred way to create a Clojure application and shouldn’t be yours either, check out Leiningen

This is one of those posts that I publish partly for myself. And partly so people can criticize my way, which is also for myself, and only incidentally for others to learn from it.

It seems Maven is popular in the Clojure world. Clojure itself uses it, Webjure uses and its demo application uses it as well, there’s a branch for Compojure that uses too. So after building all those components using Maven I’ve decided to use it myself when building Clojure applications.
Read more…

Post Navigation

Follow

Get every new post delivered to your Inbox.

Join 329 other followers