Posts Tagged ‘Python’

Why learning Haskell/Python makes you a worse programmer?

Thursday, August 2nd, 2007

Recently, I’ve been having a lot of conversations with a friend of mine about meta-programming, partly due to some development we are working on, and partly due to our coming PhD. Some of the time we incur in largely (perhaps irrelevant) philosophical ruminations about programming languages.

But today, he found a rather peculiar blog-post, where the author teases the readers arguing “Why learning Haskell/Python makes you a worse programmer”.

Why learning Haskell/Python makes you a worse programmer?

The author presents two claims to defend his thesis: a) Demotivation and b) Code Obfuscation. Considering demotivation, he states that he “(…) constantly find (himself) wanting to use idioms from these languages, or noticing how much less code (he would) be able to write if (he) was using one of these languages (…)”. Further, it notes that it finds “(…) C# code very ugly compared to both Python and Haskell (…)”. The conclusion, he remarks, “is to make me very depressed and demoralised. I feel like a human compiler, translating the Haskell or Python in my head into a language which is a whole level lower.”

In what comes to code obfuscation, the author believes that because “C# has begun to get some features that are more friendly to functional style programming”, the programmer “when faced with a very common situation” tends to try a “functional solution”. Adapting this “functional solution” to a language like C#, results in “writing such complex code — using such advanced features as anonymous delegates — when a simple loop would have sufficed”. The overall conclusion is “don’t bother improving yourself, unless you have the freedom to improve your environment accordingly.”

While I tend to sympathize with the author frustrations, I believe this to be a classic example of misunderstanding about programming paradigms and languages. In fact I’ll try to summarize my arguments on “Why learning Haskell/Python makes you a *better* programmer”.

The difference between Paradigm and Syntax

First and foremost one must understand the difference between paradigm and syntax. Each different paradigm usually results in a different algorithm. Though, the same algorithm can be expressed in different syntaxes, which depends on the language one’s using to implement. The fact that a certain syntax is less ugly to a programmer implementing a certain algorithm designed in a certain paradigm qualifies the expressiveness of a language. This expressiveness is dependent on the domain’s problem and the paradigm of the solution, so different algorithms (that solve the same problem) can make the same language seem very beautiful or very ugly.

Expressiveness in Programming Languages

A common metric used to quantify the expressiveness of a language is the number of code lines needed to implement a certain algorithm. It is very common to find advocates of every language, using as arguments single-liners to convince that her/his language is the best: “just compare this one-line quick-sort implementation in X to this 30 line implementation in Y”. This makes the reader believe that X is more expressive than Y, while not noticing that the algorithm paradigm used for X is the same as the native paradigm of X, while the opposite isn’t always true (e.g. see [1] [2] and [3]).

The “other side”

It’s also amusing to see many people learning functional languages, believing they are the other side, and putting C and C# (or Java) in the same bag. Why this happens? Because people tend to learn syntaxes and not paradigms. If a language has a syntax very close to another (like C, C++ and C#), they tend to believe that the paradigm is the same. Even worse, because they find that a certain syntax in a certain language produces expressive code, they incur in the pitfall of trying to apply the same paradigm in a different language (and, surprise! that language wasn’t designed to be expressive in that paradigm). I’ve seen this problem occur over and over, especially in people that already have some programming experience; how many times I’ve seen code written in Java which is plain old C in another syntax?… These authors don’t have a clue what Object-Oriented is all about, and I doubt they also have a clue what Functional Programming or Logic Programming is about too (somehow, Prolog and the Logic Paradigm tends to be forgotten).

Which is the best?

What is the solution? In portuguese we say “Cada macaco no seu galho”, which losely translates to “To each its own”. One must understand that there are several forces to be taken account when choosing a certain language to implement a desired solution. Most of the time this are related to infrastructure features (like available frameworks and tools). But an important force (most of the time marginalized) is related to the problem’s domain; I would argue that functional languages are very expressive in what comes to mathematical defined algorithms and that I would definitely choose C to implement a device-driver (don’t confuse the choice of expressiveness with performance) and SQL to define relational queries.

The author’s mistake, in my point of view, is trying to force-fit a solution in a paradigm that is not natural to the language in question (for the author’s sake, I know that he knows this, but not everyone understand this). Just because a language has the infrastructure to deal with certain paradigms (like C# 2.0 new functional-oriented features), this doesn’t mean the necessary syntax is there to make it expressive in that same paradigm; “while in Rome be Roman”.

What can we do?

One solution for the problem of expressiveness are Domain Specific Languages (DSL). DSLs try to solve this by extending/redefining the original syntax and semantic of a language to better express solutions designed for paradigms more closely related to the problem’s domain (consider LINQ and mathematical sets) while maintaining the concepts horizontal between syntaxes (which differ from scripting or embedded interpreters). DSLs aren’t just syntactic sugar (I will argue about this on a different post).

Why learning Haskell/Python makes you a better programmer?

So why does learning other languages (especially languages that implement other paradigms) makes you a better programmer? a) Because it teaches you different points of view and b) because it gives you the best syntax and semantic for a certain domain. Learning different languages don’t necessarily make you better in other languages. It makes you better in understanding and designing new algorithms, though. But most important, it should make you feel more decoupled from implementation details and more detached from syntax.

There is an analogy that I like to apply when people ask “Is it worth it?”. Scott Ambler, in his book The Object Primer, talks about the difference between the Specialist and the Generalist. He argues that while a specialist is a “Jack-of-all-trades and a master of none”, good developers should try to be generalists, as in a “Jack-of-all-trades and a master of few”.

How I miss Python…

Wednesday, August 1st, 2007

Dear ECMA Technical Committee, please add list comprehension to C#. Here’s a simple snip in python:

', '.join([c.name for c in columns])

And the equivalent in C# (2.0):

public static string FieldList<T>(IEnumerable<T> columns) where T: Column {
    List<string> fields = new List<string>();
    foreach(T c in columns)
        fields.Add(c.name);
    return string.Join(", ", fields.ToArray());
}

Now try to translate the following python snip:

x = [(c.m(y) for (c, y) in zip(columns, ys) where c in primarykey])

Windows Inter-process Synchronization in Python

Tuesday, December 5th, 2006

Suppose you have two processes that need to sync information between them. If you were using Linux, a SIGHUP signal would do the trick. But Windows don’t have signals…

Fear no more… We have Named Events to the rescue… I’ve found the need to use these for inter-process synchronization when I was confronted with the problem of having an external application reacting to database triggers. Of course, the RDBMS we are talking about is PostgreSQL, and the external application is made in Python.

Anyway, the trick consists of setting a well-known named Event in the external application (server), and then Pulsing this event inside a ‘plpython’ function in postgreSQL. So, the server would be something like:

import win32event
event = win32event.CreateEvent(None, 0, 0, ‘Global\EventXPTO’)
win32event.WaitForSingleObject(event, win32event.INFINITE)
print ‘Received event…’

But there’s a catch… If PostgreSQL is not running as the same user as the script, it will give an ‘Access is Denied’ error when trying to open the Event. Thus, we need to change the PySECURITY_ATTRIBUTES (first parameter of CreateEvent) from None to something that allows the world to access it. Here’s how:

import pywintypes
import ntsecuritycon

def createEventSecurityObject():

sa = pywintypes.SECURITY_ATTRIBUTES()
sidEveryone = pywintypes.SID()
sidEveryone.Initialize(ntsecuritycon.SECURITY_WORLD_SID_AUTHORITY,1)
sidEveryone.SetSubAuthority(0, ntsecuritycon.SECURITY_WORLD_RID)
sidCreator = pywintypes.SID()
sidCreator.Initialize(ntsecuritycon.SECURITY_CREATOR_SID_AUTHORITY,1)
sidCreator.SetSubAuthority(0, ntsecuritycon.SECURITY_CREATOR_OWNER_RID)acl = pywintypes.ACL()
acl.AddAccessAllowedAce(win32event.EVENT_MODIFY_STATE, sidEveryone)
acl.AddAccessAllowedAce(ntsecuritycon.FILE_ALL_ACCESS, sidCreator)

sa.SetSecurityDescriptorDacl(1, acl, 0)
return sa

Of course, change the event setup to:

event = win32event.CreateEvent(createEventSecurityObject(), 0, 0, ‘Global\EventXPTO’)

And the client:

import win32event
event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, ‘EventXPTO’)
win32event.PulseEvent(event)

You can certainly figure the rest on your own ;) It would be advisable though to read this MSDN article if you want to know more about inter-process synchronization in Windows.

P.S. Don’t forget to check win32api.GetLastError() when creating or opening events.

Boost, Python and Dijkstra

Thursday, November 30th, 2006

Boost “provides free peer-reviewed portable C++ source libraries.” It also provides some very good Graph manipulation functions, one of which is a very fast Dijkstra shortest-path implementation that I wanted to use from within Python.

Bear in mind that for this project I need to host Python in a Windows 2003 Server machine. First thing to do is to get the Python bindings for the Boost Graph Library. Problem is, it isn’t very clear how do you install it… After trying a while, I copied the contents of bgl-python-0.9/python/boost/graph to $python$/lib/site-packages/boost/… it worked :)

Second problem is to understand all this C++ templating world. If you try to invoke a binded function from within Python you can get something really cryptic (try writting boost.dijkstra_shortest_paths() in the interpreter).

After trying to read the documentation, looking at the usage example of BGL, and banging my head into a wall several times, I finally found how to make it work… I leave a simple example here for anyone who’s interested.