Wednesday, February 28, 2007

Python: Creating Instance Methods

Why didn't I know about the "instancemethod" function of the "new" module? It allows you to create new instance methods on the fly.

PyCon: Some More Random Comments

I got a chance to speak at length with Adele Goldberg, co-author of Smalltalk. We were discussing the subject of Women in IT. Apparently, she found my comments about harnessing sexual energy quite entertaining. During our talk, she mentioned The Girls' Middle School. There are many things we can do to improve the situation and help more women make it into IT.

During the lighting talks, there was a guy who was the world record holder for solving Rubik's Cube blindfolded. He said that you should learn how a Rubik's Cube works if you wish to solve it. There are 8 corner pieces and 12 side pieces. The middle pieces are basically fixed. In order to memorize the state of the cube, he assigned numbers to each of the corners and separately to each of the sides. Hence, you have a list of 8 corners and a list of 12 sides. Once you have the two lists memorized, it's really just a matter of sorting the list. He advised solving the corners first, and then solving the sides.

Ian Bicking gave a lighting talk in which he gave a screen cast about a new "more intelligent" Web framework. It was a spoof. It was hilarious! I really hope he blogs it!

PyCon: Weaving Together Women and IT

This talk was given by Anna Martelli Ravenscroft, co-author of the "Python Cookbook".
  • Computer science is taught either too high or too low.
  • Programming should not be complex!
  • There are very influential women in computer science.
  • The ratio of women to men in IT has actually gone down. The problem is very complex. No one knows for certain exactly why it has gone down.
  • In general, "weeder classes" conflict with the low self efficacy of many women to make the problem worse. They are extremely and needlessly harmful.
  • Programming is a bit of a "priesthood", and that's a turnoff for many women.
  • Programming in school is generally not a social activity, which is also a turn off for women.
I asked why women were generally turned off by the "priesthood" of programming, especially since they're dying to get into the Catholic priesthood ;) When I first discovered programming as a junior in college, you could barely tear me away from the thing.

We discussed it a bit. We actually came to the novel conclusion that men have an excess of sexual energy that drives us into the programming priesthood. While we are busy being rejected by women, we tunnel our energy into our programming efforts. This matched what I had heard about Sir Isaac Newton. He never married and purposely chose to "channel" his energy into his studies in order to distract himself from his sexual needs. It also matches my own experience during high school.

PyCon: Software Development with Trac

  • The Trac talk was held in the large conference room, and still, over the half the audience professed to using it.
  • The beauty of Trac is that it brings together a bug tracker, your version control system, a source code browser, and a wiki. You can use one wiki syntax everywhere, and links between things (such as from a Subversion commit messages to a bug) just work.
  • Trac also provides a unified timeline for all of these things.
  • It has a great plugin infrastructure.
  • They're currently working on a plugin to provide enhanced workflow management.
  • "Bitten" is a plugin to tie into PyBot. This integrates Trac with continuous integration. It was written by the same guy who wrote Genshi :)

PyCon: Twill, Scotch, and Figleaf -- Tools for Testing

This was a talk on testing tools by Dr. C. Titus Brown. Please see my summary of his earlier tutorial. This talk was really a demo for those who didn't come to the tutorial. Here are some new things I picked up:
  • Twill can take care of running Tidy.
  • Scotch lets you replay HTTP interactions. Hence, you can use it to mock a server providing some service so that you can test a consumer (presumably, some other server) of that service.
  • Setting up Twill so that it talks directly to the code being tested using WSGI rather than actually making an HTTP request can simplify the number of silly things that can go wrong. However, it's still nice to be able to do either with the same test.

PyCon: The Essentials of Stackless Python

This was a talk on Stackless Python by Christian Tismer. Unfortunately, Christian recently suffered from a stroke, so his speech was quiet and slurred. Let's hope he recovers quickly! The difficult subject matter, a strong accent, his slurred speech, and his tendency to talk about minor technical details rather than what he was trying to accomplish compounded to make the talk nearly impenetrable. I understood what he was saying most of the time, as did most of the stackless people, probably. However, as evidenced by the lack of questions, I doubt very many other people did.

One thing I did grasp, however, was that PyPy makes implementing stackless easier.

PyCon: The Wonderful World of Widgets for the Web

This was a talk on Tosca Widgets by Kevin Dangoor, the leader of TurboGears. Overall, Kevin's a pretty charismatic guy, and the talk was well received.
  • These days, users require nicer, more featureful forms. Things like WYSIWYG widgets, date picker widgets, and autocompletion are becoming ubiquitous.
  • The goal of Tosca Widgets is to provide a way to encapsulate the HTML, CSS, and JavaScript necessary for things such as a WYSIWYG widget into a convenient package.
  • A Tosca Widget knows how to output HTML to link in the CSS and JavaScript.
  • Conceptually, this is part of the view layer (i.e. the V in MVC).
  • You are responsible for passing a value into the widget.
  • They are using FormEncode for validation.
  • The library knows how to aggregate individual widgets into a form.
  • Because the HTML, CSS, and JavaScript are packaged together, it's easy to add Ajax behavior to the widget.
  • However, they don't yet have built in JavaScript validation. JavaScript validation routines built on top of FormEncode would be a natural progression.
  • It's easy to package a widget into a Python egg. The widgets installed are discoverable because they provide a setuptools entry point.
  • Unlike Dojo widgets, the emphasis is on packaging things together from the server's point of view. (I'm a little unclear about the correct overlap between these two projects. I get the feeling that he was hand waving a bit. However, it's clear that packaging widgets into Python eggs is helpful.)
  • They're using a templating engine (Kid?) for the HTML, but they're thinking of getting rid of that, per Ben Bangert.
  • There is a Tosca Widgets browser that lets you play around with all of the widgets you have installed.

Tuesday, February 27, 2007

PyCon: Write Less Code with XRC for wxPython

Here are some random comments:
  • His approach simplifies layout.
  • There are multiple ways to do layout.
  • Use sizers!
  • This project lets you load widgets from an XML document.
  • There are many ways to generate the XRC document.
  • The XRCed program comes by default with wxPython, and it's quite nice.
  • It doesn't work with wx.Grid or custom widgets.

PyCon: Developing with IronPython and Windows Forms

Here are some random comments:
  • One of the IronPython guys was a "reformed" Ruby on Rails guy ;)
  • One of the guys didn't even like Windows, but admitted, "Windows Forms is nice."
  • C# doesn't have first class functions.
  • The ability to use Windows Forms and IronPython together is a great boon for .NET developers.
  • If you're going to use this stuff, buy the full version of Visual Studio instead of relying on the free version.

PyCon: Keynote: Robert M. Lefkowitz

This was by far the strangest and perhaps thought provoking of the talks. The speaker admitted he hadn't come to provide answers, but only to ask questions. His resume clearly implies he's a brilliant guy. I can only attempt to convey some of the ideas he put forth:
  • Code should be treated as a communication medium.
  • If source code is written literature meant primarily for human consumption, it makes sense to internationalize it. It's easy to internationalize the keywords. It might take more work to internationalize the functions and variable names.
  • It makes sense to create a way to verbalize source code.
  • The study of rhetoric should be applied to programming.
  • He thought that the separation of code into multiple modules was a compiler-only requirement that detracted from readability. I personally disagree.
There was much, much more, but it is beyond my abilities to provide a full summary.

PyCon: Some Random Comments

Here are some random comments:
  • Unfortunately, many of the speakers who had some trouble getting their presentations setup were Ubuntu users using
  • Adele Goldberg told me that normative evaluation, like they do at UC Santa Cruz, is helpful for girls.
  • Someone gave a big plug for Pyro, which is an RMI system for Python.
  • Robert M. Lefkowitz mentioned that Saint Isidore, the Bishop of Seville, is the saint of programmers and the Internet.
  • This is obvious, but the best talks at PyCon were the ones that integrated the audience.

PyCon: Interactive Parallel and Distributed Computing with IPython

This was my favorite talk, aside from the OLPC keynote.
  • CPUs are getting more parallel these days, they aren't getting necessarily faster.
  • The free ride of relying on Moore's law to solve your performance problems isn't working anymore.
  • We need to embrace parallelism, but it's hard.
  • The IPython physicists have problems that simply can't be solved in a reasonable amount of time using a single CPU.
  • They wanted an interactive, Mathematica-like environment to do parallel computing.
  • They have been able to implement multiple paradigms on their foundation, including MPI, tuple spaces, MapReduce, etc.
  • They're using Twisted.
  • It's like coding in multiple Python shells on a bunch of computers at the same time.
  • Each machine returns the value of the current statement, and they are aggregated into a list.
  • You can also specify which machines should execute the current statement.
  • You can move data to and from the other machines.
  • They implemented something like deferreds (aka "promises") so that you can immediately start using a value in an expression even while it's busy being calculated in the background.
  • They've tested their system on 128 machines.
  • The system can automatically distribute a script that you want to execute.
  • The system knows how to automatically partition and distribute the data to work on using the "scatter" and "gather" commands.
  • It knows how to do load balancing and tasking farming.
  • Their overhead is very low. It's appropriate for tasks that take as little as 0.1 seconds. (This is a big contradiction to Hadoop.)
  • You can "talk to" currently running, distributed tasks.
  • It also works non-interactively.
  • All of this stuff is currently on the "saw" branch of IPython.

PyCon: IPython: Getting the Most out of Working Interactively in Python

IPython is an amazing replacement for the standard Python shell. As a result of this talk, I've already switched.
  • It's embeddable so that you can add a shell into your existing applications.
  • You can even use it as a replacement for your UNIX shell because it's so easy to interact with UNIX command line utilities.
  • He mentioned "ipython -p tutorial", but I can't figure out what it does.
  • It has better introspection, tab completion, color, syntax highlighting, and debugger integration.
  • It was inspired by Mathematica.
  • It has macros.
  • It takes care of moving content to and from your editor so you don't have to cut and paste and remove the ">>>" at the beginning of each line.
  • It can trivially lookup code definitions and docs while you're working on something.
  • It has a better version of the "dir" function.
  • It has various, useful "magic" commands.
  • Doing things like "!ls" lets you talk to the shell. In this way, it's easy to do some UNIX shell scripting.
  • It has support for timing and profiling.
  • It has a nicer version of pdb called ipdb.
  • In stack traces, it can show the syntax highlighted code as well as all the data.
  • You can use ipython to dynamically code GUIs that have event loops that would block the normal interpreter.
  • In general, ipython knows how to work with the event loops of many different libraries.

PyCon: Embedding Little Languages in Python

Little languages embedded in Python can improve the readability of code by allowing the coder to specify what he's trying to do (declarative) rather than how to do it (imperative). First you dream up a syntax for what you're trying to convey by typing some pretend code, and then you try to get Python to conform to something similar to your ideal syntax. The author did not cover using a parser, but instead misused (in a good way) Python syntax. He suggested the following tricks:
  • Make use of function parameter lists, including keywords, *args, and **kargs.
  • Use Python classes to represent states. Use methods for transitions.
  • Use reflection tricks.
  • Put domain specific syntax in docstrings.
  • Use operator overloading by doing things like implementing the __add__ method.
All in all, his tricks were all pretty simple. I'm sure all the RoR coders out there are yawning. However, it was a fun talk anyway. Unfortunately, I got so carried away, I missed two talks while talking with some guy about parsers and various other things.

PyCon: Keynote: Python 3000

The goal is to correct early design mistakes. It's also to reduce cognitive load on newbies. It is not a total rewrite like Perl 6.

I'm not going to cover the details because I think everyone should just read his slides whenever they come out.

Personally, I'm excited about the str vs. unicode unification as well as the stackable I/O library (a la Java). Finally, the csv module will no longer require explicit encoding and decoding.

Also, Guido is adding a "nonlocal" keyword to fix the scoping problem I've mentioned before.

PyCon: IronPython: Present and Futures

Jim Hugunin's talks are always spectacular, and this was no exception.

He implemented generics for Python. Python doesn't really need these. However, it's necessary to interact with some .NET libraries.

He gave this great demo of the XNA game framework for .NET that targets both Windows and the XBox. Naturally, it runs the code in a sandbox. Because of this, Microsoft is allowing anyone to write code for the XBox. He wrote Python code for the framework. It was a really impressive 3D application with spectacular performance. Unfortunately, IronPython can't yet run on XBox or Windows mobile because that version of .NET doesn't support generating byte codes on the fly.

Apparently the guys from Microsoft Robotics Studio came to him to ensure they could program robots in Python. They wanted to embrace it from the very beginning. He gave a really great robot demo where a robot fetched a ball using software written in Python.

PyCon: Scaling Python for High-load Web Sites

  • The speakers were smart, but their content was pretty standard.
  • To avoid the global interpreter lock, run two instances of CherryPy.
  • They were using Nginx for load balancing. It can "spoon feed" clients. It can talk to memcached.
  • Of course, a missing index in the database can destroy everything.
  • They automated deployment to new servers.
  • Their "dirty little secret" was that they used ZXTM Zeus server for caching, load balancing, and SSL accelaration.
  • If users repeated hit the reload button because of a slow page load, they will compound the situation until they eventually bring down the server. You may want time limits. You may need maximum client connection limits.
  • You may want to disable swap to avoid thrashing.
The funny thing was that they used a demo application called "Flikr Killer" as the basis for their talk. Apparently, they hadn't read Cal Henderson's book "Building Scalable Web Sites." The great irony is that Cal is an engineering manager for Flikr, and in his book, he covers exactly the same things they did, and more. We all had a good chuckle, and one of them promised to read the book ;)

OLPC: Downloadable Version of Wikipedia for Kids

I've been thinking about One Laptop Per Child (OLPC). I was thinking that if the laptop is going to be the child's way to learn about the world, it would be very helpful to have a downloadable version of Wikipedia written for kids.

It might also be helpful to "tag" various portions of the content so that the content varied slightly depending on the child's age.

Monday, February 26, 2007

PyCon: Keynote: Adele Goldberg

  • One Laptop Per Child is going to change the world.
  • The US schooling system is in crisis.
  • The Internet is very free, but schools are very rigid.
  • Schools aren't succeeding.
  • She mentioned The Education Program for Gifted Youth (EPGY) at Stanford University
  • Social interaction has a positive impact on eLearning.
  • "Teaching to the test" is destroying education.
  • is amazingly educational.
  • Constructivist teaching is great, but it's hard.
  • Programming is one of the most beneficial eLearning activities.
  • Not enough time is given in schools to eLearning; it doesn't matter because they're too constrictive anyway.
  • Let kids learn at their own pace.
  • Inquiry-based, project-based, group-based learning is good.
  • Lecture-oriented classrooms are bad.
  • The best learning is the type kids do when they aren't in school.
Adele was very passionate, but she didn't elicit the same passionate response that Ivan Krstic did in his One Laptop Per Child talk. I felt like she was saying, "I'm working hard to change the world, why aren't you?" instead of, "We're going to change the world, and you can help!" However, since I have children of my own, I hope she continues to forge ahead and that she meets with success.

PyCon: Creating Games with Pygame on the GP2X

This is a nice, little handheld computer. It's a "hacker's machine." It can run Linux. It's fun emulating old games. It's fun to write Pygames for it.

PyCon: Pyweek: Making Games in 7 Days

The contest resulted in lots of small, fun, innovative games. A week gives enough time to finish something interesting, yet still live life. Make it simple, creative, and polished. This is a fun way to learn how to make games in Python.

PyCon: Good-bye Hello World: Rethinking Teaching with Python

  • Python should be the first language; think of "Hello World" in Java.
  • Problem: Python can still be taught boring; many students still hated the programming class.
  • Be example driven.
  • Drop the boring lectures.
  • Create simple, fun, graphical programs.
  • Get them engaged.
I asked if coding was an intrinsic talent that you either have or don't have. He said that there are a few "born coders". They're going to succeed in even the most boring class, so just get out of their way. There are also a few students who won't ever get it. There is just nothing you can do. The vast majority of students are in the middle.

PyCon: Web Frameworks Panel

  • pyjamas is JavaScript written in Python like the Google Web Toolkit.
  • "Reinventing the wheel is a great way to learn more about wheels."
  • The various frameworks are targetting different niches. There was consensus among the audience that the variety can be a strength.
  • There wasn't anything really new, and there were no major conclusions.

PyCon: Towards and Beyond PyPy 1.0

I came in late and it was hard for me to hear and understand everything, but this was one of the coolest talks.

This is Python written in Python running in a virtual machine. They had runtime modifiable grammar working; they added "do while" on the fly! They have proxies that claim to be actual instances of another class; they showed a demo where a "list" was actually proxying to a database. Somehow they showed a demo where they were embedding a shell in a browser; they were using emacs in the shell in the browser to play emacs' Tetris! I think they have a "@lazy" function decorator for lazy evaluation. They've created new technology in their JIT. Their funding runs out in March, so that will slow them down. They support multiple backends, including LLVM. Extension modules are problematic for them. They're thinking of multiple frontend languages.

Hmm, if they're moving toward multiple frontend languages, and they already support runtime modifiable syntax. It sounds like they'll have a working version of Perl 6 ;)

PyCon: Using Stackless

Write asynchronous code that looks like (more simple) blocking code.

These are the things that were new or surprising to me:
  • Exceptions don't unwind all the way to the original tasklet creator.
  • It sounds like each tasklet has its own contiguous stack on the heap.
  • They can monkeypatch the socket module to make urllib2 asynchronous!!!
  • They don't really know where they're going.
  • However, it's working in production.

PyCon: Parsing Revisited: A Grammar Transformation Approach to Parsing

He handwaved a bit as to why he had to write his own parser. He used grammar transformations to use a simpler parsing algorithm. In this way, he was able to support more complicated grammars. Otherwise, this was a pretty basic talk.

PyCon: Python, Unicode, and I18N

Instead of checking for str and unicode separately, use:
 >>> from types import StringTypes
>>> isinstance("", StringTypes)
Otherwise, this was an extremely basic talk.

Update: Use:
 >>> isinstance("", basestring)
Thanks, Bob Ippolito!

PyCon: Keynote: One Laptop Per Child

Here's an outline of his talk on the One Laptop Per Child (OLPC) project:
  • Formal education is bad unless you have great teachers.
  • There are a billion school age children in third world countries.
  • They created a next generation LCD screen. Monochrome at high resolution. Color at lower resolution. Sunlight viewable.
  • Laptop has very, very low power consumption: 1 watt.
  • 20 hours of battery life.
  • Automatic mesh networking.
  • Automatic routing for other laptops.
  • They had to get rid of the crank because it was fatiguing the laptop.
  • Many ways to power it including a separate pull chord.
  • All sorts of incredible innovations.
  • No moving parts.
  • Custom filesystem for the flash drive.
  • Wireless range is 2km.
  • Based on Fedora Linux.
  • Completely new user interface paradigms.
  • Great paradox of open source: it's too hard to figure out how to hack on it.
  • Hence, they added a "view source" button and coded almost everything in Python. This is my dream come true!
  • Help them out at
  • $100 price range, but you can't buy one yet.
  • They're planning on rolling out 1-10 million units next year.
  • I tried it out, and it's amazingly cool!
  • OLPC is looking for volunteers, especially to write apps.
  • Contribute significantly, and they'll give you a laptop.
  • "Ideas are dangerous."
  • Get an emulator at

PyCon: Testing Tools in Python

I went to a two hour tutorial on testing. It was everything I hoped for. It was given by Grig Gheorghiu and Dr. C. Titus Brown. Here's an outline:
  • Unit tests:
    • Make sure your code works in isolation.
    • It's not a full code path.
    • He's purposely ignoring unit tests.
    • He encourages the confusion between unit tests and functional tests.
  • Functional tests:
    • Make sure your code works properly.
    • Use mock or live resources.
  • GUI tests:
    • Use a tool to record your interactions with an app and then play it back.
    • These are fragile.
  • Regression tests:
    • Making sure things don't get worse.
  • Acceptance tests:
    • "Unit tests ensure that you write the code right.
    • Acceptances tests ensure that you write the right code."
  • Mock testing:
    • Use "fake" resources so as to test your code with fewer dependencies.
    • Use mocking at the I/O boundaries.
  • nose:
    • You don't need to use the unittest API.
    • It's trivial. Write a module with a test_foo function. Run nose.
    • Unifies all the different test APIs.
    • Supports test fixtures via setup and teardown functions.
    • To test multiple apps: nosetests -w package0 -w package1 ...
    • If you have a lot of code, he recommends using nose from a Python script, not from the CLI.
    • The plugins are great.
  • Selenium:
    • This is GUI testing.
    • Test your AJAX.
    • Limited to a single Web site.
    • Really slick way to run tests in your browser.
    • You can script tests in Python.
    • Writing the scripts can be tedious, and they are fragile.
    • Useable for cross browser testing: Firefox, IE, Safari, Opera, etc.
    • Avoid it unless you're using AJAX.
  • My question: my tests pass, but I get bugs for cases I didn't consider:
    • You'll never:
      • Have complete code coverage.
      • Have tests for every situation.
      • Get away from the need for exploratory testing.
    • Automated tests free you up to do more exploratory testing.
    • When you find a bug, write test cases to try to flush out nearby bugs.
  • twill:
    • Speaker wrote it, and he likes it.
    • It's just a simple layer on top of other libraries.
    • Code in Python or "twill script".
    • In a sense, it is a scriptable browser, but it doesn't support JavaScript.
    • Run twill from within nose.
    • Can talk to WSGI directly.
    • It's lower level than Paste Fixture:
      • Unlike Paste Fixture, trivially toggle between direct WSGI or a live server.
  • figleaf:
    • A code coverage tool that's not restricted to just the CLI.
    • Code coverage is necessary, but not sufficient.
  • Continuous integration:
    • Continuous integration and buildbot are tremendously useful.
    • Distribute your building and testing across multiple platforms.
    • Tinderbox guys switched to buildbot.
    • For C and C++, he gave a plug for cmake.
    • You need to test in a cleanroom environment, on multiple platforms, in a developer neutral way.
    • Use a Subversion post commit hook to launch it.
  • Most important recommendations:
    • Start with some unit tests, some functional tests, and buildbot.
    • Build test fixtures as you need them, instead of ahead of time.
    • He's not a fan of test driven development.
      • This blew me away since he's foremost in the Python testing community.

PyCon: Introduction

I just got back from PyCon 2007. It was awesome! :-D

I'm going to post summaries of the talks I went to. I'll post them one at a time so as not to overwhelm the reader. Some talks weren't that interesting, but I'll post something brief anyway, just for completeness.

The trip home from Texas to California has taken nine hours so far. It's almost 4 AM, and I'm stuck in the airport until puplic transit starts running in a few hours. On the plane, there was a medical emergency as well as a mechanical malfunction, so the plane had to return to the gate twice! Well, now's a great time to do some blogging!

Here are some brief comments. There were just shy of 600 attendees. The laptops were pretty evenly split between Windows, Mac, and Linux. This was due to a huge increase in the number of Ubuntu Linux users. The next PyCon will be in Chicago.

Update: I got home at 8:30 AM after thirteen and a half hours. I knew I was having problems when I asked the traffic guy where the "BART to bus" was--twice. Since I was at SFO, that statement made no sense in at least two ways!

Thursday, February 15, 2007

Haskell: Syntax

Learning Haskell is hard. Those who disagree with this basic premise should stop reading now; they're obviously far more talented and intelligent than I am. However, wrapping your mind around the concepts is just one part of the difficulty. I believe that the syntax itself contributes to the difficulty of reading and understanding Haskell. I think that there are some parts of Haskell's syntax that are meant to be clever and flexible; however, this same flexibility leads them to be difficult to decipher.

Unfortunately, I fear the only ones who are going to read this post are the ones most likely to disagree with it, but I'm going to try anyway ;)

Function application

I think "f(a, b)" more clearly portrays function application than "f a b" does. Consider "map myFunc a". It'd be a lot visually clearer which function was getting called and which function was being passed if it were written "map(myFunc, a)".

The syntax for currying

I think the currying syntax is terrible. Consider "unwords . map showVal". This is a curry because map takes two arguments. Now consider "unwords . spam showVal". Is this a curry? Who knows? Unless you understand the type signature for "spam", you don't know.

I think it's important for the syntax of a language to help you decipher code even if you aren't familiar all the libraries being used. For instance, Haskell does this by forcing you to use upper case names for types, and I think this was an improvement over C. I think you should have to *work* to make a curry happen, and it should be obvious to the reader what is happening. Perhaps "unwords . curry(map, showVal)" would be clearer.

Function type declarations

Similarly, the syntax "f :: a -> b -> c" places the burden of currying on you when it's often the case that you aren't even thinking about currying. It'd be a lot clearer to just say "f :: (a, b) -> c". This doesn't stop you from using currying; it just frees you from having to think about it when you're not actually using it yet.

If you actually are writing a function that returns another function, say that! For instance, "f :: (a) -> ((b) -> c)". Now the reader will know that you plan on actually returning a function without the issue of currying getting in the way.

Point free style

Point free style can be elegant. For instance, consider "h = f . g". This says that "h" is "f of g", and it's more elegant than "h x = (f . g) x".

However, consider "main = getArgs >>= putStrLn . (!! 0)". When point free style is used in the middle of a larger expression, perhaps with a curry (or in this case a section), a ">>=", and function composition, things can get out of control. I think it's often clearer to use an explicit argument so that the reader doesn't have to figure out where the invisible argument is being consumed. Even though the following is one line longer, it's much easier to read:
main = do args <- getArgs
putStrLn (args !! 0)
Point free style is even more inscrutible if no type declaration is given. In such cases, the reader is forced to hunt down the right number and type of arguments.

The $ operator

"$" is function application. Consider "putStrLn $ args !! 0". This is the same as "putStrLn (args !! 0)", but you don't need the parenthesis. Aside from the fact that you're left wondering which has higher precedence, "$" or "!!", this is an improvement. However, if you have a very long line with a mix of "." and "$", things can get confusing. Worse, you end up reading the code from right to left. It seems strange to have to look at the operators in order to figure out whether to read from left to right or right to left. Sometimes, you're left reading from the inside outward. It's trivial to write a function application operator that has its arguments in reverse, and I think it improves readability. After all, that's exactly how UNIX pipes work, for instance, "cat a | b | c". Furthermore, that's how ">>=" works for monads. My earlier comment about excessive use of point free style still stands, though. If you get too many "invisible" variables, it may be better to use a "let" or a "where".

Record member access

I think C's "a.b" is clearer than "b a", especially when you have multiple levels. Consider, "a.b.c" vs. "(c . b) a".

Mixing monads

For new programmers, OOP can be mildly difficult to understand, but it's powerful. Monads are even harder to understand, and they're even more powerful. If you consider "obj.getHouse().getDoor().ringDoorbell()", playing with multiple objects at the same time seems to have linear mental complexity. However, playing with multiple monads at the same time seems to have exponential mental complexity, especially since you can only use the "do" syntax with one monad at a time. If you mix the State monad (for state) with an Either (for error handling), a Maybe (for NULL encapsulation), IO, etc., things get tricky. Hand waving a bit, if it were trivial to mix and match monads, there wouldn't be a need to put IORef in the library--the user could just mix IO and State on the fly.


In general, I really like Haskell, so please have *some* mercy on me when you flame me to death for stating these opinions ;)

Haskell: Write Yourself a Scheme in 48 Hours

I just finished Write Yourself a Scheme in 48 Hours. It's awesome! It took me a few weeks to finish it while riding the train.

One piece of advice, though. Don't do the exercises inline. You might be able to do them once you've finished the tutorial, but if you're able to do them all as they come, you probably didn't need to read the tutorial.

Wednesday, February 14, 2007

Vim: Soft Wrap

Here's another Vim tip, which I'm surprised it took me so long to find out. To make Vim "soft wrap" text, like Microsoft Word does, use ":set wrap linebreak textwidth=0".

Vim: Simple Autocompletion

Just in case I'm not the only one who didn't know this, using Vim, type the following into a file named
def really_difficult_name(a, b):
return a + b
Now, type "really" and hit ^n. It'll autocomplete the function name.

I saw a talk by Bram Moolenaar, the author of Vim, at Google last night. I really like that guy. He reminded me that sometimes it's better to be practical than idealistic. Having his voice inside my head is soothing, especially since the little Stallman voice in my head is often so damn demanding ;)

Friday, February 09, 2007

HTML: Making HTML Validation Easier

Creating pedantically, well-formed HTML is a nice thing to do to increase your karma as a Web developer ;) However, it can also be a tedious waste of time. Fortunately, there are a couple tricks to make it easier.

For instance, which DTD should you use per today's best practices? Apparently, this is a religious argument. I suspect no fewer than two comments below will be on this topic. I've spent way too much time looking at the various arguments, but I was finally persuaded by this long discussion: I've chosen:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
Wait! Before you disagree with me, let me tell you my secret!

Although 4.01 Transition is the least hacky thing per today's standards (per the discussion linked to above), my actual HTML source is in XHTML! Genshi, my templating engine, lets me choose whether to output HTML or XHTML. Hence, I get the best of both worlds, and I can change my mind later!

The next question is how to catch silly HTML mistakes. For instance, I didn't know that you must specify an action on form tags, even if you're just going to set it to "". As wicked cool as Firebug is, I don't think it provides HTML validation. Furthermore, using the W3C's validator can be painful if you're working on an application that requires form based logins and is not publicly accessible. Copy and pasting the HTML source gets old quickly!

The Firefox plugin Html Validator solves this need quite well. It shows me a little icon to tell me how the page is validating. At anytime, I can "View Page Source" to see the warnings and errors. Html Validator works by embedding Tidy in the extension. Although the work flow isn't nearly as streamlined, I also like Offline Page Validator. It's a plugin that simply loads the W3C validator with the source of the current page. This is nice because it uses the W3C validator, but it takes work to right click and select "Validate Page". Nonetheless, it has the additional benefit that it's a rather simple plugin, whereas Html Validator actually has a compiled copy of Tidy in it.

In summary, Genshi lets me switch between HTML and XHTML with a simple configuration change, and Html Validator lets me see if the page is validating correctly just by looking at an icon.

Happy validating!