Scheme 7: Macros video

Series: Feel the cool, Basics, Closures, Recursion, Quotation, Lambda, Macros.

Continuing the series on Scheme, this video explains the ultimate alternative – when nothing else is flexible enough, we can create our own bits of lanugage using macros.

Slides for Scheme 7: Macros

Goodness in programming languages, part 2 – getting your code running

Posts in this series: Syntax, Deployment, Metaprogramming, Ownership

The fancy word for what I’m talking about here is Deployment. How easy is it, once you’ve written your code, to get it running on someone else’s computer? What barriers are there to someone else using your program?

Examples of potential barriers include:

  • Having to download some other program first, e.g. a runtime or some kind of dependency.
  • The actual program being a huge download.
  • Something mysteriously not working because of different versions of something on the person’s computer.
  • The program simply not working on the operating system or machine architecture of the computer.

Anything that can be done to remove these barriers makes my life as the supporter of the program easier, and makes it more likely people will use it.

Here are some things I like:

  • Java’s ability to run almost anywhere. Once you have the runtime, Java code is relatively easy to get running on many different operating systems and architectures, using almost-identical code. Other runtime-based languages are also strong here.
  • Java and Python’s large built-in libraries. Both Java and Python include large amounts of functionality in their standard libraries, reducing the need to depend on third-party components.
  • Python and Perl’s ability to work out of the box on most Linux systems. If you are developing for Linux, you can pretty much guarantee that an up-to-date runtime will be available, meaning no dependencies at all are needed.
  • Many languages’ easy integration with Linux packaging. Most of the above barriers disappear if you can install dependencies using your operating system’s built-in package manager.
  • Quickly‘s easy way to build your program into the packaging system. Things really become easy if your program itself is integrated into the packaging system.
  • C and C++’s lack of dependencies. It is possible to write C and C++ programs that depend on nothing except standard runtime libraries, which are almost guaranteed to exist on most machines.

One way to handle dependencies is to package them together with your code. This is what most corporate Java software does – the specific Java runtime that is known to work is packaged with the program itself. This makes for big downloads, and defeats the concept of providing a single package for all platforms, but it does work. It also makes for huge headaches to do with licensing, and is often impossible for software producers who don’t employ legions of lawyers. It also feels bad and wrong.

When packaging and deploying software, I subscribe to the philosophy of “Find the dependencies – and eliminate them“. Until someone can click a single button and have your software running, you haven’t finished.

Goodness in programming languages, part 1 – syntax and layout

In this series I will comment on what I like in some of the languages I use. I will cover things that I find convenient, things that might lead me to write correct code, things that tend to make my code more readable, and possibly other things that I just like for no clearly-articulated reason. The purpose of this series is to help me think about what features I would put in a language if I created my own.

Posts in this series: Syntax, Deployment, Metaprogramming, Ownership

What aspects of syntax and layout – how the code appears in your text editor – do I like? This is entirely irrelevant to the computer that is running the code, and an implementation detail of the language compiler or interpreter, but is extremely important to me.

  • Python and Scheme’s low-symbol approach. Python and Scheme tend towards the use of English words, rather than symbols to express concepts. This makes code easier to read for someone unfamiliar with the language, and also for me.
  • Python’s unambiguous block structure. Python uses indentation to express block structure (e.g. for variable scope, namespaces and logic structures). Programmers in most languages (notably C-like and Lisp-like ones) tend to use indentation to help humans understand the block structure of their code, but the computer uses different symbols to understand the same thing. This can lead to ambiguity where a human may mis-read the real block structure of some code because the indentation is inconsistent with the symbols. Python avoids the problem by making indentation the syntax understood by the compiler. [Go avoids the same problem by stating that code with inconsistent indenting (as defined by the gofmt program) is invalid.]
  • Scheme’s simplicity. Scheme (like other Lisp dialects) has very simple rules to describe its syntax. This means you need to learn very little before you can understand the structure of Scheme programs, and it is unlikely you will be confused by rare structures.

Of course, there are trade-offs in all these points. Using fewer symbols can make programs verbose (although I find Python feels very concise). The lack of an end-of-block symbol makes short Python snippets look clean, but can make longer sections hard to understand (perhaps better editor support would help with this?). Scheme’s use of brackets for everything means there are a lot of brackets, so working out which does what job can be difficult.

Nevertheless, the goals of reducing the number of symbols with special meaning, allowing humans and computers to use the same ways of understanding code, and being as simple as possible are good goals to have.

My Address Book 1.9.0 – rewritten from scratch

Ordinarily, my motivations for doing open source work are clear: peer recognition and the satisfaction of knowing people are using my work.

However, I’ve been distracted from that stuff recently because of my desire to scratch my own itch, by re-writing My Address Book from scratch to allow sharing the same address book between the web interface and the various email programs I use on different computers.

The only way to make it work with those email programs is to store the data in an LDAP server, instead of the custom MySQL database I had used in the original version (which is still available, of course: My Address Book version 1).

While I was doing it, I took the opportunity (or made the mistake) of re-writing in my favourite language, Python. Joel would not approve, but that’s the fun of open source: I can do whatever I like, no matter how unwise.

I learned a lot of things on the way:

  1. I like web.py. It is a simple, and helpful library in the Python tradition of being concise but powerful.
  2. Setting up Python running as FastCGI on either Apache or lighttpd is much harder than creating a page of PHP. However, once it’s done, it’s done. (The results of my research are shown at the bottom of the Install Guide.)
  3. Setting up an LDAP server to act as a little address book is unbelievably complicated. See the Install Guide for how to do it. One day, I or someone else will turn all those instructions into the preinstall step of a .deb, and no-one will ever have to worry about it again. Volunteers, please.
  4. Templetor, web.py’s templating system is fine, but too slow for large pages. I had to reimplement the main address list rendering in plain Python, which made me sad.
  5. I am compulsive about getting my work out into the world.

It has been a struggle to write all the documentation and think through the installation procedure and all the other stuff that comes with making a public release, but I have been unable to move on to other things until I have got it done. I hope I’ve done an ok job – the installation procedure is far too complex and should be automated, but if the volume of documentation is any indicator of how helpful it is, it should be reasonable.

I think I found it more difficult than normal because, unlike normal, getting it out to other people was not my main motivation for doing the project. I’m glad I’ve worked through it though, and I really hope some people get interested enough to help me make it much easier to use.

I think this project is a good example of how it can be much better to live in the open source world than the proprietory one. If I want to create a small address book for my family in the open source world, I end up with an industrial-strength LDAP server providing it, meaning that so long as someone does the work to make it simple to use for my simple use case, it can scale to solve pretty much any problem I might have in the future. So if I start a small business that eventually grows and needs to track millions of addresses, I can keep using the same LDAP server, on the same hardware, as my original address book.

Of course, My Address Book would have broken long before that. It doesn’t even do paging, and the home page lists all your addresses in one page.

I must write a rant one day about how I hate paging.