<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>Col</title>
  <link>https://cjwatson.dreamwidth.org/</link>
  <description>Col - Dreamwidth Studios</description>
  <lastBuildDate>Wed, 28 Dec 2016 15:34:51 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>cjwatson</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <image>
    <url>https://v2.dreamwidth.org/171109/185940</url>
    <title>Col</title>
    <link>https://cjwatson.dreamwidth.org/</link>
    <width>100</width>
    <height>95</height>
  </image>

<item>
  <guid isPermaLink='true'>https://cjwatson.dreamwidth.org/21454.html</guid>
  <pubDate>Wed, 28 Dec 2016 15:34:51 GMT</pubDate>
  <title>Small data hack: bin day calendar</title>
  <link>https://cjwatson.dreamwidth.org/21454.html</link>
  <description>I&apos;m very lazy.  Rather than having to keep track of Cambridge bin collection days manually, especially around holidays, I wrote a thing to convert it into an &lt;a href=&quot;https://en.wikipedia.org/wiki/ICalendar&quot;&gt;iCalendar file&lt;/a&gt; for me so that I could import it into Google Calendar.  Here it is in case it&apos;s useful to anyone else:&lt;br /&gt;&lt;pre&gt;
#! /usr/bin/python3

from argparse import ArgumentParser
from datetime import datetime
import os.path
import re

from bs4 import BeautifulSoup
import dateutil.parser
from icalendar import (
    Calendar,
    Event,
    )
import requests


parser = ArgumentParser(
    description=&quot;Generate iCalendar file for Cambridge bin collection days.&quot;)
parser.add_argument(
    &quot;id&quot;,
    help=(
        &quot;Unique identifier for this calendar, normally your host name.  Make &quot;
        &quot;sure that this does not collide with any other calendars.&quot;))
parser.add_argument(&quot;address&quot;, help=&quot;Your street address in Cambridge.&quot;)
parser.add_argument(&quot;postcode&quot;, help=&quot;Your postcode.&quot;)
args = parser.parse_args()

now = datetime.now()
req = requests.get(
    &quot;http://bins.cambridge.gov.uk/bins.php&quot;,
    params={&quot;address&quot;: args.address, &quot;postcode&quot;: args.postcode})
soup = BeautifulSoup(req.text)
cal = Calendar()
cal.add(&quot;prodid&quot;, &quot;-//riva.pelham.vpn.ucam.org//bin-days//EN&quot;)
cal.add(&quot;version&quot;, &quot;2.0&quot;)
cal.add(&quot;calscale&quot;, &quot;GREGORIAN&quot;)
cal.add(&quot;x-wr-calname&quot;, &quot;Bin days&quot;)
cal.add(&quot;x-wr-timezone&quot;, &quot;Europe/London&quot;)
for div in soup.find_all(&quot;div&quot;, style=re.compile(r&quot;^text-align:center&quot;)):
    desc = div.contents[0]
    when = dateutil.parser.parse(div.b.get_text(&quot; &quot;).rstrip(&quot;*&quot;))
    while when &amp;lt; now:
        when = when.replace(year=when.year + 1)
    event = Event()
    event.add(&quot;uid&quot;, &quot;bin-days/{:%Y%m%d}@{}&quot;.format(when, args.id))
    event.add(&quot;dtstart&quot;, when.date())
    event.add(&quot;summary&quot;, desc.capitalize())
    event.add(&quot;transp&quot;, &quot;TRANSPARENT&quot;)
    cal.add_component(event)
with open(os.path.expanduser(&quot;~/public_html/bin-days.ics&quot;), &quot;wb&quot;) as out:
    out.write(cal.to_ical())&lt;/pre&gt;On Debian, this requires the python3-bs4, python3-dateutil, python3-icalendar, and python3-requests packages.  You&apos;ll probably want to change the output path to somewhere that your calendar software can see (so if it&apos;s a web service such as Google Calendar then it needs to be something that corresponds to an accessible URL).  The web-scraping is pretty gross, but it&apos;s the best I can do given the council&apos;s published data.  Ideally this would itself be a web service that could generate calendars on demand for a given address and postcode, but like I say I&apos;m lazy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=cjwatson&amp;ditemid=21454&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://cjwatson.dreamwidth.org/21454.html</comments>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://cjwatson.dreamwidth.org/15047.html</guid>
  <pubDate>Fri, 26 Dec 2014 16:21:56 GMT</pubDate>
  <title>December days: Programming language improvements</title>
  <link>https://cjwatson.dreamwidth.org/15047.html</link>
  <description>As a follow-up to my post about my &lt;a href=&quot;http://cjwatson.dreamwidth.org/11623.html&quot;&gt;personal history of programming languages&lt;/a&gt;, &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://cartesiandaemon.livejournal.com/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/external/lj-userinfo.gif&apos; alt=&apos;[livejournal.com profile] &apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; width=&apos;17&apos; height=&apos;17&apos;/&gt;&lt;/a&gt;&lt;a href=&apos;http://cartesiandaemon.livejournal.com/&apos;&gt;&lt;b&gt;cartesiandaemon&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; asked me to expand on &quot;which language(s) do you use most now (C and Python?) and what improvements would you like to see in them?&quot;&lt;br /&gt;&lt;br /&gt;&lt;a name=&quot;cutid1&quot;&gt;&lt;/a&gt;Mostly I do indeed use C and Python these days.  I&apos;m still comfortable enough in Perl and often reach for it particularly for shorter text-processing kinds of jobs (some of which &lt;a href=&quot;http://anonscm.debian.org/cgit/users/cjwatson/madison-lite.git/tree/madison-lite&quot;&gt;grow a bit more than I&apos;d intended&lt;/a&gt;), but I really haven&apos;t kept up with work on the core language much since about Perl 5.10, so I&apos;m not desperately qualified to talk about things I&apos;d like to see improved.  The trends I&apos;ve seen there seem to be towards making it easier and more natural for people to use modern and safer techniques rather than perl4isms, things like &lt;a href=&quot;http://search.cpan.org/perldoc?Modern::Perl&quot;&gt;Modern::Perl&lt;/a&gt; and &lt;a href=&quot;http://search.cpan.org/perldoc?Moose&quot;&gt;Moose&lt;/a&gt;, and these seem like good things but I don&apos;t have a lot of experience to share there.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;C&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;C is in many ways an awful language for the sorts of things it&apos;s often used for: manual memory management, no bounds checking, a standard library with a host of peculiar warts, support for closures that could be described as poor if you were feeling generous, and so on.  (C++ fixes some of these at the cost of &lt;a href=&quot;http://yosefk.com/c++fqa/&quot;&gt;truly insane programmer-facing complexity&lt;/a&gt;.)  Huge numbers of security vulnerabilities can be ascribed to defects in the design of C.  On the other hand, it underpins so many other things, especially on Unix, that it isn&apos;t really possible or reasonable to avoid entirely, and it&apos;s pretty much the greatest common denominator for library interfaces that want to be usable from more than one language environment.  (You can sometimes make C++ libraries usable from C, but you have to be pretty careful.)&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://developer.gnome.org/glib/&quot;&gt;GLib&lt;/a&gt; (and its object system add-on, GObject) is pretty pervasive these days, including in various things that otherwise have nothing to do with GNOME, and it&apos;s not at all a bad general supplemental library: better-designed and more comprehensive than much of the C standard library, and, sure, it may be a megabyte or so but you almost certainly had it installed anyway.  I think for a new C project these days I would probably turn to it, unless it were particularly small or needed to function in particularly minimal environments.  Its main flaw is verbosity, particularly where callbacks are involved.  For this I think it&apos;s possible to do an excellent job with domain-specific languages that provide a thin wrapper over C.  I converted performance-critical parts of a project at work recently from Python to &lt;a href=&quot;https://wiki.gnome.org/Projects/Vala&quot;&gt;Vala&lt;/a&gt; recently, and was very impressed: it made it actively enjoyable to program using GObject, which wasn&apos;t something I could really say before, and it was still possible to inspect and roughly understand the generated C code.  GObject also provides very close to automatic binding generation for various other languages by way of &lt;a href=&quot;https://wiki.gnome.org/Projects/GObjectIntrospection&quot;&gt;gobject-introspection&lt;/a&gt;, which is extremely powerful for being able to use the right tool for individual jobs without having to commit to it for your whole project.  I think that this kind of thing is probably the right path for many C projects.&lt;br /&gt;&lt;br /&gt;For things that need to stick with plain C, it&apos;s certainly possible to incrementally evolve the facilities they&apos;re using to make things safer and easier.  &lt;a href=&quot;http://valgrind.org/&quot;&gt;valgrind&lt;/a&gt; made quite a few waves when it was introduced a little over ten years ago: in C you often find that your memory management mistakes are only reported as a crash in some entirely different part of your program much later, and this is excruciatingly difficult to debug directly, so valgrind keeps track of absolutely everything you do with memory and tells you if it looks invalid.  Compiler developers have been doing all kinds of interesting things recently such as &lt;a href=&quot;https://code.google.com/p/address-sanitizer/wiki/AddressSanitizer&quot;&gt;AddressSanitizer&lt;/a&gt; and &lt;a href=&quot;http://developerblog.redhat.com/2014/10/16/gcc-undefined-behavior-sanitizer-ubsan/&quot;&gt;Undefined Behaviour Sanitizer&lt;/a&gt; which promise to make it easier to spot problems early, and there are all sorts of proactive hardening techniques one can use to stop bugs escaping into the rest of your system as exploits.&lt;br /&gt;&lt;br /&gt;Library-wise, there&apos;s always more to be done.  I made my own small contribution to this with &lt;a href=&quot;http://libpipeline.nongnu.org/&quot;&gt;libpipeline&lt;/a&gt;, which I&apos;d like to see used by more C projects that invoke other programs, since it&apos;s very easy to get this kind of thing wrong.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The Python world spent a long time collecting all the things that were hard to improve in the core language without breaking compatibility in some way, and batched up a lot of these into Python 3.  Unfortunately the transition to Python 3 has been an extremely painful and protracted one.  Despite considerable work on migration strategies such as 2to3, the changes were substantial enough that it&apos;s taken quite some time for many projects to be ported, and you can only start using Python 3 once all your dependencies have been ported and are available anywhere you might want your code to run.  (In particular, the Unicode string changes are I think a significant net improvement - they&apos;re not without problems, but Python 2 was even worse for anything that might care about internationalisation - but porting to them requires going through your program and for each string-like variable in it determining whether its essential nature is to contain binary data or text.  Easy enough to get right from scratch, but painful to retrofit.)  The right answer for many projects is to write &quot;bilingual&quot; code for a while that works in both Python 2 and Python 3, which is largely possible with libraries like &lt;a href=&quot;http://pythonhosted.org/six/&quot;&gt;six&lt;/a&gt; to help, but this is a bit of extra cognitive load on programmers and of course not everyone cares.  So I think if I got one wish here it would be for all the remaining stragglers to be magically ported to Python 3 so that we could stop caring about the old stuff and simplify things, but that&apos;s not likely to happen any time soon.&lt;br /&gt;&lt;br /&gt;I guess the main general improvement I can think of for Python, short of &quot;please be faster&quot; and various standard library warts, would be some form of partial static typing so that I don&apos;t have to rely quite so completely on test suites to defend me against my own foolishness.  I hear that something like this &lt;a href=&quot;http://thread.gmane.org/gmane.comp.python.ideas/30432&quot;&gt;may be underway&lt;/a&gt; for Python 3.5, which will be interesting.&lt;br /&gt;&lt;br /&gt;This post is part of my &lt;a href=&quot;http://cjwatson.dreamwidth.org/7469.html&quot;&gt;December days&lt;/a&gt; series.  Please prompt me!&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=cjwatson&amp;ditemid=15047&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://cjwatson.dreamwidth.org/15047.html</comments>
  <category>december days</category>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://cjwatson.dreamwidth.org/13584.html</guid>
  <pubDate>Sun, 21 Dec 2014 16:49:27 GMT</pubDate>
  <title>December days: Teaching children programming</title>
  <link>https://cjwatson.dreamwidth.org/13584.html</link>
  <description>As a follow-up to my post about &lt;a href=&quot;http://cjwatson.dreamwidth.org/11623.html&quot;&gt;programming languages&lt;/a&gt;, &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;https://liv.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/silk/identity/user.png&apos; alt=&apos;[personal profile] &apos; width=&apos;17&apos; height=&apos;17&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;https://liv.dreamwidth.org/&apos;&gt;&lt;b&gt;liv&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; asked me: &quot;can you talk about whether you&apos;re planning to teach your children programming, and if so how?&quot;&lt;br /&gt;&lt;br /&gt;I&apos;d very much like to teach my children programming, yes, for a variety of reasons.  One is that it&apos;s a thing I&apos;m personally enthusiastic about that I want to share with them.  Another is that it&apos;s an increasingly useful secondary skill in all kinds of other academic disciplines, whether that&apos;s for data analysis or driving complex machinery or whatever, and I&apos;d like them to have that be accessible to them if at all possible.  And of course I think it&apos;s a worthwhile skill in its own right, as computers become more and more a part of everyday life.&lt;br /&gt;&lt;br /&gt;On the other hand, I don&apos;t want to teach them just single bespoke skills, such as just one programming language: what I really want to impart is the mental discipline of ordering your thoughts in order to instruct a computer accurately in how to do them, which I think is an aptitude that transfers itself well to all kinds of other things, even though doing that clearly involves learning the nuts and bolts of programming (preferably in more than one languages) and especially for children it needs to involve having fun along the way.  There&apos;s no point trying to teach programming to children if they find it boring, or if it&apos;s too early in their development.  (I tried to teach B how to program some years ago, but honestly I hadn&apos;t prepared well enough, it fell rather flat, and by the time we revisited it he wasn&apos;t really interested, so I definitely want to prepare better this time round.)&lt;br /&gt;&lt;br /&gt;&lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://ghoti.livejournal.com/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/external/lj-userinfo.gif&apos; alt=&apos;[livejournal.com profile] &apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; width=&apos;17&apos; height=&apos;17&apos;/&gt;&lt;/a&gt;&lt;a href=&apos;http://ghoti.livejournal.com/&apos;&gt;&lt;b&gt;ghoti&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; has been planning to start with a plan she&apos;d previously started on while TAing at primary level, namely to start with &lt;a href=&quot;http://scratch.mit.edu/&quot;&gt;Scratch&lt;/a&gt; (hmm, appropriately the top featured project there is currently a dreidel game) and move on to &lt;a href=&quot;https://github.com/livewires/python&quot;&gt;Rhodri James&apos;s Python course&lt;/a&gt;.  I&apos;ve generally been of the opinion that it will work better if we wait until J&apos;s reading is a fair bit more fluent, and so to be honest I hadn&apos;t yet thought much about the details yet; Scratch is more visual than a lot of languages but it still has a very significant textual component.&lt;br /&gt;&lt;br /&gt;I think this is still an area where I very much don&apos;t think I have the answers and am listening for suggestions.  My criteria are that I want them to be able to progress quickly to doing things that will interest them, I don&apos;t want them to get bogged down in syntactic vinegar, but I also want them to be using (if not necessarily as the very first step) a language that isn&apos;t a toy and that they can write real non-trivial programs in, and preferably one that won&apos;t get them stuck in particularly bad habits.  Python seems like a pretty good thing to aim for with the support of some decent code libraries and teaching materials, so &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://ghoti.livejournal.com/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/external/lj-userinfo.gif&apos; alt=&apos;[livejournal.com profile] &apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; width=&apos;17&apos; height=&apos;17&apos;/&gt;&lt;/a&gt;&lt;a href=&apos;http://ghoti.livejournal.com/&apos;&gt;&lt;b&gt;ghoti&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&apos;s plan generally seems sound here, but I sort of feel the need to work through it ourselves first to make sure we aren&apos;t caught by surprise along the way.&lt;br /&gt;&lt;br /&gt;Does anyone else reading this have experience with teaching children (other than themselves!) to program?  I&apos;d be interested in hearing about what you did.&lt;br /&gt;&lt;br /&gt;This post is part of my &lt;a href=&quot;http://cjwatson.dreamwidth.org/7469.html&quot;&gt;December days&lt;/a&gt; series.  Please prompt me!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=cjwatson&amp;ditemid=13584&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://cjwatson.dreamwidth.org/13584.html</comments>
  <category>december days</category>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>6</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://cjwatson.dreamwidth.org/11623.html</guid>
  <pubDate>Sat, 13 Dec 2014 16:12:53 GMT</pubDate>
  <title>December days: Programming languages</title>
  <link>https://cjwatson.dreamwidth.org/11623.html</link>
  <description>&lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://ewx.livejournal.com/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/external/lj-userinfo.gif&apos; alt=&apos;[livejournal.com profile] &apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; width=&apos;17&apos; height=&apos;17&apos;/&gt;&lt;/a&gt;&lt;a href=&apos;http://ewx.livejournal.com/&apos;&gt;&lt;b&gt;ewx&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; prompted me to write about programming languages, and said &quot;be as specific or general as feels appropriate&quot;.&lt;br /&gt;&lt;br /&gt;&lt;a name=&quot;cutid1&quot;&gt;&lt;/a&gt;Answering prompts with a personal-history kind of framing seems to be working quite well this month, so I&apos;ll stick with that for this one.  I started programming when I was seven; that was on a ZX Spectrum+ which was a lovely piece of hardware for the time, so the language available was Sinclair BASIC.  This wasn&apos;t a bad BASIC dialect, and I remember its PRINT command having some useful gadgets.  The limited memory and the very odd encoding (numbers were always five bytes; reserved tokens were always one byte) meant that it was sometimes worthwhile to go through some ridiculous circumlocutions which have stuck in my head: INT PI was two bytes in memory against five bytes for 3 (ditto SGN PI for 1 and NOT PI for 0).  At any rate this kept me going until I was 11, at which point we got an 8086-based PC.&lt;br /&gt;&lt;br /&gt;There was a dark stage for about a year here where I didn&apos;t have any programming language worth mentioning, because MS-DOS 3.3 (I think it was) didn&apos;t ship with one.  Batch files were sort of barely functional for a few things, and if you were really determined it was possible to do things like write a minimal calculator in them, but it wasn&apos;t exactly pleasant.  Out of a mix of desperation and curiosity I resorted to teaching myself assembly language via DEBUG.COM; I haven&apos;t used that experience much since, but it was probably worth having done at least for a while.&lt;br /&gt;&lt;br /&gt;When I was about 12 we upgraded to MS-DOS 5.0, which shipped with QBasic, so I had a more or less familiar language available again with slightly different quirks.  Not having to number lines manually was a bit of a revelation, and I seem to remember subroutines being noticeably better.  Some things were more annoying, and I seem to remember putting in some effort to add some of the facilities that the Spectrum&apos;s PRINT command had.  I stuck with this until I was about 16 or so, including going to the All-Ireland Schools&apos; Programming Competition (which I think is now the &lt;a href=&quot;http://aipo.computing.dcu.ie/&quot;&gt;All-Ireland Programming Olympiad&lt;/a&gt;); I placed respectably enough but not particularly close to the medals, and reckoned that some of that was due to trying to use BASIC, which was just a bit too clunky for the job.&lt;br /&gt;&lt;br /&gt;That summer I went on a residential course in Dublin where I learned Pascal, and that made a big difference, though part of that was probably just due to the mental flexibility involved in having learned a second language.  The next year I went back to the same competition and felt I&apos;d done much better.  I sat through the awards ceremony, of course presented in reverse order, figured I&apos;d just missed out on the medals and might try again next year, and almost fell over when they announced I&apos;d come first.  This of course did a lot for my confidence and meant I got to go to the international competition, which was mainly useful in that it was the first time I&apos;d really hung out with other serious programmers.&lt;br /&gt;&lt;br /&gt;I learned C at some point before going to university.  If memory serves it was initially a dialect called Pacific C, although I haven&apos;t retained any of its idiosyncrasies.  I think I then used Visual C++ for a bit, until I switched to Linux-based systems in 1998ish and taught myself GNU C, which even at the time was much closer to the standard.  (It wasn&apos;t until a year or two later that I got hold of a copy of &lt;a href=&quot;https://en.wikipedia.org/wiki/The_C_Programming_Language&quot;&gt;K&amp;amp;R II&lt;/a&gt;, at which point things started making a lot more sense than whatever I&apos;d picked up through osmosis.)&lt;br /&gt;&lt;br /&gt;At university they taught us ML (on the reasonable basis that virtually nobody knew it already so it levelled the playing field) and Java.  ML was excellent at broadening the mind but I never kept it up.  I used Java for a while, but eventually I decided that it just felt too clunky for me and I was running into its limits a lot in terms of what systems programming was reasonable at the time, and I&apos;ve avoided it since.&lt;br /&gt;&lt;br /&gt;Once I was using Linux, the scripting facilities were a lot more powerful and it often made sense to use them for things where I&apos;d previously have used full-fledged programming languages.  I used a lot of bash, sed, awk, and such around this point.  In 1999 or so I taught myself Perl, and that was another big step up in terms of how quickly I could get things done.  Perl is often criticised for being a write-only language, and I admit that I&apos;ve occasionally &lt;a href=&quot;http://www.chiark.greenend.org.uk/~cjwatson/tmp/beerglass.pl&quot;&gt;contributed&lt;/a&gt; to this, but I think my normal style is rather more readable and it&apos;s mostly fine if you refrain from playing silly buggers too much.  It remained my language of choice for some years, including lots of work on the Debian bug tracking system which is written in Perl.&lt;br /&gt;&lt;br /&gt;When I started working for Canonical, Python was the preferred language there, so I taught myself that.  That was just as well since I soon found myself being handed stuff like &lt;a href=&quot;http://bazaar.launchpad.net/~cjwatson/germinate/trunk/view/30/germinate.py&quot;&gt;Germinate&lt;/a&gt; to maintain (nowadays it looks more like &lt;a href=&quot;http://bazaar.launchpad.net/~cjwatson/germinate/trunk/view/head:/germinate/germinator.py&quot;&gt;this&lt;/a&gt;, which is a bit more tractable).  Nowadays I&apos;m very comfortable in Python, either 2.x or 3.x, and my &lt;a href=&quot;http://cjwatson.dreamwidth.org/5840.html&quot;&gt;new job&lt;/a&gt; will involve even more of it.  It&apos;s a reasonably nice general-purpose language with generally excellent library facilities; it&apos;s maybe not the fastest thing in the world with the standard implementation but it&apos;s not terrible, and I feel pretty comfortable with its quirks.&lt;br /&gt;&lt;br /&gt;Apart from the time spent learning ML at university, all of these fall into the general category of procedural/imperative languages, and I have to admit I really haven&apos;t done much outside that sphere.  A number of people I respect are big fans of functional languages, and I suspect that at some point I will end up teaching myself Haskell.  I&apos;ve done &lt;a href=&quot;http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/2014-04-15-porting-ghc-a-tale-of-two-architectures.html&quot;&gt;some work related to that&lt;/a&gt; before in a rather strange way, but I never really taught myself more than a minimal amount of the language as a result.  (On the other hand, it did cause some local Haskell developers to buy me drinks, so that was a win.)  Once I have more energy for free-time experimentation again then this might be reasonably high up my list.&lt;br /&gt;&lt;br /&gt;Virtually all of this has been self-taught.  I did have some formal programming education (A-level computing, which in this area at least mostly covered ground I already knew, and university), but it&apos;s mostly been driven by what I needed at any given point rather than learning new languages for the sake of it.  That said, if you&apos;re learning to program I strongly recommend learning more than one language once you&apos;re over the initial hump, just so that you have a better idea of what&apos;s intrinsic to the field in general and what&apos;s just a quirk of the language you learned first.&lt;br /&gt;&lt;br /&gt;This post is part of my &lt;a href=&quot;http://cjwatson.dreamwidth.org/7469.html&quot;&gt;December days&lt;/a&gt; series.   Please prompt me!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=cjwatson&amp;ditemid=11623&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://cjwatson.dreamwidth.org/11623.html</comments>
  <category>programming</category>
  <category>december days</category>
  <lj:security>public</lj:security>
  <lj:reply-count>5</lj:reply-count>
</item>
</channel>
</rss>
