January 2018

S M T W T F S
  123456
78910111213
14151617181920
21222324252627
28293031   

Style Credit

Expand Cut Tags

No cut tags
pozorvlak: (polar bear)
Tuesday, February 12th, 2008 10:26 am
I'm going to make what should be an uncontroversial statement: if you don't understand and use monads, you are at best a quarter of a Haskell programmer. A corollary of this is that, since using monad transformers is the only (or at least the approved) way to use two or more monads together, if you don't understand and use monad transformers you are at best half a Haskell programmer.

[Another corollary is that I am, at best, about an eighth of a Haskell programmer: though I understand monads well on a theoretical level, I invariably emerge defeated from any attempt to bend them to my will.]

But we'll come back to that later.

Something I've been thinking about for a while is this whole business of designing languages to make programs shorter. )

1 There really ought to be a word that means "would never use a twopenny word when a half-crown word would do", but I can't think of one. English grads? Edit: sesquipedalian! Of course! Thanks, [livejournal.com profile] fanf! (Originally, I used "prolix")
2 I actually came up with this list by thinking about languages whose users were the most passionate. But they're also extremely concise, which I think is a large part of the reason for the passion. If I were focusing purely on concision, I should probably consider Forth, but I don't know enough about it.
3 J has "boxed arrays" too, which are something like two-dimensional s-expressions, but let's leave those aside for now.
4 You might want to raise this objection against Smalltalk, too: objects are members of classes, which are something like types. Now, I've hardly used Smalltalk, so I'm probably talking out of my elbow, but: since everything is an object, and the language has powerful reflection features and duck typing, we can in fact write generic operators that work for objects of many or all classes. But maybe I'm entirely wrong about Smalltalk programming: in which case, please delete all references to the language from my argument.
5 Do you find yourself wanting to go out and strangle small fluffy animals every time you have to type out an instance declaration that would be entirely unnecessary in a duck-typed language? I do. Particularly when it doesn't work and spits out some ludicrous error message at me, telling me that I've encountered another stupid corner case of the typeclass system.
6 I learned to my surprise the other day that I'm a member of the Geometry and Topology research group, and not the algebra research group as I'd always assumed - apparently universal algebra is now considered a branch of geometry!
pozorvlak: (babylon)
Thursday, December 13th, 2007 05:33 pm
I'm in the middle of writing up a research proposal for a postdoc position I'm applying for. I've had enough of categorification for a while, and it struck me that doing formal semantics for a simple language in the APL family (J, K, A+, Matlab...) could be both Fun and Interesting. Some poking around on Google and MathSciNet suggests that nobody's done anything in this vein before - I've downloaded all the relevant looking papers (all three or four of them), and intend to read them this evening after climbing :-)

The trouble is that I've never written anything like this before. Some of you, I know, have: does this look remotely sane? Does the topic sound interesting? The second section, you'll be pleased to hear, is very much a zeroth draft at this stage :-)
pozorvlak: (babylon)
Saturday, September 29th, 2007 12:58 am
While trying to do one of the exercises from SICP, I wanted to apply and to a list. Now, I could have used fold, but it seemed a bit of a waste given that Scheme's and is variadic: what I needed was an equivalent of Perl's func(@list_of_args) idiom, or Python and Ruby's func(*list). So, inspired by the syntax for variadic function definitions, I tried
(and . list)
for various values of list, and it worked! Rather elegant, I thought: no special syntax, just an application of Lisp's usual list-construction and argument-passing rules (like the Perl idiom, in fact). But when I tried it with + instead of and, no dice - instead, I get a "Combination must be a proper list" error. Obviously something to do (I realise, belatedly) with the fact that and is a special form and not an ordinary function. Maybe Larry Wall was onto something with his idea that different things should look different :-) But why doesn't it work for ordinary functions? Isn't (func . args) equal to (func arg1 arg2 arg3...)?

[You can get the effect I was originally after by using (apply func list).]


One of the especially nice things about my shiny new Ubuntu installation is that I now have a working Java system, so I can run J in all its graphical glory. So today I worked through one of the J labs: specifically, the one about the Catalan numbers (I can't find the lab online, alas - you'll just have to download J and try it for yourselves :-) ). The standard formula for the Catalan numbers involves factorials, so both the nth Catalan number itself and the time needed to calculate it grows very quickly with n. You can improve the run-time by rearranging the formula to use binomial coefficients (J has a built-in function for calculating nCr in a non-stupid way), and this makes calculation of Catalan numbers up to the 10,000th or so almost instant. But when I tried to use this code to find the 100,000th Catalan number, my computer locked solid. Response became glacial, the hard drive paged constantly, and I had to kill J and restart the lab.

Fortunately, there was a better way. The rest of the lab showed how you could use the prime decomposition of 2n! and n! to find a much quicker way of calculating Catalan numbers. With this code, the calculation again became instant - a salutory reminder of the power of a good algorithm :-) I'm still finding J a bit hard to read, though: code like
+/ <. n % p ^ >: i. <. p ^. n
or worse,
cat1=: (! +:) % >:
makes my eyes cross :-(

[As any fule can see, the first line calculates the exponent of each prime p in n!, and the second is the naive formula for calculating the Catalan numbers.]

While writing this post, I came across this link, which is rather fun: Culture Shock.
pozorvlak: (Default)
Monday, September 10th, 2007 12:39 pm
Current status on some of my long-term projects:

Thesis: Up to 36 pages )

Birdshot!: I had some good ideas for this )

Moving in with [livejournal.com profile] wormwood_pearl: Nominally moved in at the beginning of August. )

Learning Haskell: I'm going to officially give up on this one for now. )

Diet: This is going really well. )

Munro-bagging: up to 61 out of 284 )

Becoming a l33t martial artist: I've been doing some capoeira. )

Learning to juggle 5 balls: I'm getting 8 catches pretty consistently. )

Reading Ulysses: Haven't looked at it since I reached page 500. ) I seem to have so many other things competing for my attention :-)
pozorvlak: (gasmask)
Tuesday, June 26th, 2007 02:29 pm
The APL Lesson: If all your problems can be solved with short programs, it doesn't matter how hard it is to write or maintain long ones.

Smith's (First) Law: Any sufficiently large test suite for a program written in a dynamic language will contain an ad-hoc, informally-specified, bug-ridden, slow, patchy implementation of half of the Haskell type system.

Yegge's Axiom of Size: Large systems suck. This rule is 100% transitive. If you build one, you suck.
pozorvlak: (pozorvlak)
Tuesday, June 26th, 2007 01:27 pm
I've fixed the J Mandelbrot set program. Needless to say, the fix took precisely three characters :-)

[By the way, did anyone read that post? Does anyone else think J is interesting? Or did you just see a wall of punctuation and get scared off?]

The gory details )

Now here's the interesting bit: the Haskell version seems only to work because of what I can only assume is a bug in GHC's handling of IEEE 754 special values. The Haskell version behaves exactly like the J version until it gets to the stage of taking the magnitude of NaN + i NaN, at which point (in Hugs) it dies with an "arithmetic overflow!" error (grrrr: that's what Infinity and NaN are for), or (in GHC) it returns Infinity (which is greater than 2, of course). G'huh? How does Infinity make sense here? It's not a number, it doesn't have a magnitude, much less an infinite one. Even more weirdly, sqrt (nan*nan + (nan*nan)) returns NaN as expected.

Yet again, I suffer pain because someone didn't read IEEE 754 properly. Which is the IEEE's fault for charging heavily for their standard documents, rather than making them freely available like they would have done if they actually cared about wide dissemination and interoperability. Grrrrr.
pozorvlak: (Default)
Saturday, June 9th, 2007 11:04 pm
I've been learning the programming language J recently, and in the course of my studies came across this example program by Ewart Shaw, to draw an ASCII-graphics Mandelbrot set:
{&'#.' @ (2:<|) @ ((+*:)^:400 0:) (18 %~ i:_20) j.~/ 28 %~ _59+i.75
It embodies so many J features and techniques that I'm going to analyse it here as an introduction to the language. )
pozorvlak: (Default)
Wednesday, May 16th, 2007 09:32 am
The relationship between human languages and programming languages is interesting to me. In general, programming languages are a lot simpler (which is great, because it makes it easier to learn lots of them): they also have rather less vocabulary (but that's OK, because you're actively encouraged to make up your own). We talk about programming "idiomatically": while it's often possible to use one language's idioms in another, they can look almost as odd as, say, Japanese idioms used in English. In the evolution of programming languages, you can see a super-compressed version of the evolution of human languages: ideas, grammatical forms, and vocabulary transfer from one language to another where there's contact between the two communities, and languages split into mutually-unintelligible descendants when the communities fracture. There's at least one example of creolization that I'm aware of: the programming language Perl can be considered a creole of C, shell, sed and awk (and has since absorbed features from many other languages). Perl's also been heavily influenced by that other notable creole, English, and incorporates several features from human languages (like topicalization). It's no coincidence that Larry Wall, the original creator of Perl, studied linguistics at graduate school. In the opposite direction, you'll sometimes hear hackers describing human languages in terms derived from programming languages: Japanese is sometimes said to use reverse Polish notation.

But as I said, programming languages tend to be a lot simpler than human languages. In fact, so-called object-oriented languages (like, say, Java) have been described (perhaps "derided" is a better term) as languages in which everything is a noun: dually, so-called functional languages (like Haskell) could be described as languages in which everything is a verb. Actually, verbs and nouns cover pretty much everything in most programming languages. Perl has pronouns and conjunctions, and pronouns can be added to Lisp with sufficient cleverness; a couple of languages have something vaguely resembling adverbs.

So you can imagine my pleasure at learning yesterday that the language called J has gerunds :-)

*downloads J interpreter*


Fig. 1: The gerund attacks some peaceful pronouns (image courtesy n. molesworth)