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.

Advertisements

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!

Formating strings in C#, like in Python

I like Python’s way to format strings because you can use it everywhere, it’s part of the strings. You can do

print("Welcome %s!" % user.name)

as you can do

Console.Writeln("Welcome {0}!", user.Name)

But then in Python you can also do

randomMethodThatTakesAString("Welcome %s!" % user.name)

In C# it gets trickier, because the call to Console.Writeln takes extra arguments for the string arguments, while RandomMethodThatTakesAString doesn’t. It just takes a string. So the only way to go is

RandomMethodThatTakesAString(String.Format("Welcome {0}!", user.Name))

which is ugly.

Thanfully C# 3.0 has extension methods, so I quickly wrote this method:

blah blah

and now I can write:

RandomMethodThatTakesAString("Welcome {0}".Args(user.Name))

which is more verbose that Python’s version, but equally nice in my eyes.

If you can understand why allowing the language to be extendable in one aspect was a win here, then you can understand why so many, me included, love Lisp that is extendable in every possible way.

Reviewed by Daniel Magliola. Thank you!

Update 2009-09-17: For those complaining that I didn’t show how I did it, here is the Args method:

public static class StringExtensions {
    public static string Args(this string str, params object[] args) {
        return String.Format(str, args);
    }
}

Printing emails in Django

When developing applications in Django, it may be nice to print emails instead of sending them. If you send them you have to be careful which addresses you use. Just being on the safe side and always using @example.{com,org,net} is not enough, you have to use an address you can actually retrieve emails for. And you have to configure your development environment to actually deliver mails. And then wait for the whole thing in each code-try iteration.

So, basing myself on the testing code, I’ve added this to settings.py and mails are now printed:

if DEBUG:
 from utils import BogusSMTPConnection
 from django.core import mail
 mail.SMTPConnection = BogusSMTPConnection

Of course you’ll also need the BogusSMTPConnection class, I’ve defined it as following:

from textwrap import wrap
class BogusSMTPConnection(object):
  """Instead of sending emails, print them to the console."""

  def __init__(*args, **kwargs):
    print("Initialized bogus SMTP connection")

  def open(self):
    print("Open bogus SMTP connection")

  def close(self):
    print("Close bogus SMTP connection")

  def send_messages(self, messages):
    print("Sending through bogus SMTP connection:")
    for message in messages:
      print("tFrom: %s" % message.from_email)
      print("tTo: %s" % ", ".join(message.to))
      print("tSubject: %s" % message.subject)
      print("t%s" % "nt".join(wrap(message.body)))
      print(messages)
      return len(messages)

And that’s it.

Pylons or Django?

I am trying to decide whether to use Pylons or Django. Both are frameworks for building Python web applications, but with opposing philosophies.

Django tries to be everything. It comes with its own ORM, its own template engine, its own everything. That gives you a nice developing experience because everything fits together and because very nice applications can be built on top of all those components, like the admin tool, which is amazing. Continue reading