pozorvlak: (pozorvlak)
2007-09-24 12:49 pm

SICP

I got back from Wales on Tuesday, to find my copy of Structure and Interpretation of Computer Programs (sometimes known as the Wizard book, or SICP, or "sickup", as I've taken to calling it) waiting for me. It's the first-year computer science textbook used at MIT, and early signs are that it's going to be worth its weight in rather good coffee.

Chapter summary )

I've been working through the exercises, and I'm up to about page 70 (most of the way through Chapter 1). So far, there hasn't been anything really difficult, though a couple of the exercises require you to do Actual Experiments on a computer, and since, what with one thing and another, I don't have a working one at the moment (I'm typing this on [livejournal.com profile] wormwood_pearl's laptop), I haven't been able to do these. Some of the algorithms are new to me, and I've particularly enjoyed doing some programming with loop invariants (but how do you find them in the first place? Presumably there are techniques...), but it's hard to shake off the feeling that a lot of it is old hat; I've been programming computers for nearly twenty years, I'm no longer surprised by the concept of a data structure :-) I've enjoyed the philosophical and historical asides - if an algorithm dates back to ancient Egypt, they'll tell you which papyrus fragment it was found on - and the generally thoughtful and informed tone of the book. The progression from procedural to data-driven to metalinguistic programming reminds me of Eric Raymond's The Art of Unix Programming, but this is surely not coincidence - like many expert Unix hackers, Eric was a Lisper first. [livejournal.com profile] totherme may be amused to learn that his old tutor, Joe Stoy, is a frequently-cited contributor :-)

1Including some probabilistic algorithms - the ease with which one can roll a die in Lisp is not such a trivial matter :-)
2Plus ways of making change from a dollar or pound - I was amused to note that they haven't updated it to reflect the disappearance of the halfpenny :-)
3They're quite fond of the prefix "meta": for instance, they call an interpreter for language X written in language X a "metacircular interpreter", rather than just a circular one, for reasons which I can't quite fathom.
pozorvlak: (Default)
2007-09-20 04:09 pm

Fun combinatorial problem

This morning, I got an email from (of all things) a pianist, which had been relayed to the department at large by the Head of Department. He was trying to develop a more rigorous warm-up routine for pianists. Specifically:
One of my exercises involves fingers 1-2-3-4. To succeed in playing smoothly at the piano, and to produce equality in the fingers, the following rules must be observed (each 'rule' has a direct technical application at the piano):

each combination must be 6 digits long ; the same number can be used more than once, but never consecutively ; all 4 numbers must be used at least once ; and the combination must not end on 1 or 2.

I have tried my best to work out the possibilities (I have around 30 so far), but I know there must be an equation for this. I just can't see it!
You may like to have a go at this yourself: once you've done that, here's the email I sent him back )

For maximum points, provide a combinatorial argument establishing the number of such sequences, and an algorithm to enumerate them all. Bonus points if your algorithm traverses the space of warmup sequences in a manner that can be used by the pianist without resort to memorising vast numbers of sequences :-)
pozorvlak: (Default)
2007-09-12 09:25 am

Operads in Ruby

Short version: I'm going to write a mildly cool and somewhat useful utility in Ruby which shows off Ruby's reflection capabilities and has something to do with my PhD thesis.

OK, first some (not really necessary) mathematical background )

OK, that's the maths out of the way, on to the code. The ability to do categorical composition of functions is useful, so maybe the multicategorical kind would be useful too? Ideally, we'd like a compose function which took a function f and a list of functions g1, g2, ... gn, and returned the function f.(g1,...gn) which takes (x11, ... xnmn) to
f(g1(x11 ... x1m1) ... g1(xn1 ... xnmn))
Unpleasant multiple sequences seem to be an unfortunate fact of life when dealing with this stuff. Anyway, here's an implementation in Ruby )

I'm sure this code can be improved, and I'd love to hear how. I don't think it's possible to write a function like this in vanilla Haskell, and writing one in Template Haskell is beyond my template-fu. It would be possible in Perl, but because of Perl's eccentric argument-passing conventions, you'd have to manually pass the arities in. This also uglifies the code somewhat.
pozorvlak: (gasmask)
2007-09-11 07:47 pm

Everything in Ruby is an object, is it?

irb(main):001:0> def fred(x); x + 1; end
nil
irb(main):002:0> fred.methods
ArgumentError: wrong # of arguments(0 for 1)
        from (irb):2:in `fred'
        from (irb):2
irb(main):003:0> 1.+.methods
ArgumentError: wrong # of arguments(0 for 1)
        from (irb):3:in `+'
        from (irb):3
irb(main):004:0> {|x| x+1}.methods
SyntaxError: compile error
(irb):4: parse error
{|x| x+1}.methods
  ^
(irb):4: parse error
{|x| x+1}.methods
         ^
        from (irb):4
irb(main):005:0> lambda {|x| x+1}.methods
["call", "==", "[]", "arity", "to_s", "dup", "eql?", "protected_methods",
 "frozen?", "===", "respond_to?", "class", "kind_of?", "__send__", "nil?",
 "instance_eval", "public_methods", "untaint", "__id__", "display",
 "inspect", "taint", "hash", "=~", "private_methods", "to_a", "is_a?",
 "clone", "equal?", "singleton_methods", "freeze", "type", "instance_of?",
 "send", "methods", "method", "tainted?", "instance_variables", "id",
 "extend"]
In unrelated news, Happy birthday [livejournal.com profile] stronae!

And does anyone if there's a portable way of finding the arity of a function in Scheme?
pozorvlak: (Default)
2007-09-10 12:39 pm

Long-term project SITREP

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: (kittin)
2007-09-03 12:41 am

Chasing your tail

I have a question for the CS types out there: what exactly is the point of tail-call elimination?

Before you go into great detail about stack overflows, rest assured that I understand that bit. But why is tail-recursive code considered such a good thing? I mean, you write your code in a non-obvious way so that the optimiser can turn it into the loop that you meant to write in the first place. Why not just write the loop yourself? It has the same effect, expresses your intent more clearly, and doesn't require the mental gymnastics to make your code tail-recursive, or to decode it when reading.

I can see why you need it if you're determined to make your language stateless (though actually, that's a related question: how is recursive code with accumulators any safer than iterative code with local state?), but why is it needed in languages like Lisp, which already have perfectly good looping constructs?

Don't get me wrong: recursion is clearly a Good Thing. But all the really interesting uses of recursion, it seems to me, are things like recursion on trees or other data structures, which are not in general tail-recursive.

In other hacking news, I spent much of my evening making a set of spice racks out of chopsticks, duct tape and strawberry boxes. My kitchen is now a fraction tidier.
pozorvlak: (Default)
2007-08-19 12:09 am

Type warnings

Here's something that occurred to me the other day: consider duck-typed languages like Python )

OK, so far so standard. Now, most duck-typed languages are dynamic, which means that we only try to determine if bar has a spoffle method at runtime, and die with an error message when it doesn't (possibly after trying some error recovery, e.g. by calling an AUTOLOAD method or similar). But it occurred to me that in simple cases (which is to say, the majority), we could work out most of this stuff statically. For each function definition, see what methods are called on its arguments. Recurse into functions called from that function. Now, each time a function is called, try to work out what methods the arguments will support, and see if that includes the interface required by the function. Issue an error if not. Thus we get the code reuse benefits of duck typing, and the correctness benefits of static checking. If the static checking is slowing down your development cycle too much, drop back to fully dynamic checking, and only run the static checks on your nightly builds or something.

This also cleared up something else I'd been vaguely wondering about. In his splendid Drunken Blog Rant Rich Programmer Food, Steve Yegge says
Another problem is that they believe any type "error", no matter how insignificant it might be to the operation of your personal program at this particular moment, should be treated as a news item worthy of the Wall Street Journal front page. Everyone should throw down their ploughshares and stop working until it's fixed. The concept of a type "warning" never enters the discussion.
I'd wondered at the time what a type warning would mean. When is a type error mild enough to only warrant a warning? Here's one idea: a type warning should be issued when it cannot be proved that an argument to a function implements the interface that function needs; a type error should be issued when it can be proved that it doesn't.

This all seemed very interesting, and struck me as potentially a fun and reasonably easy hacking project, at least to get something workable going. But if it's occurred to me, it has probably occurred to someone else, so I asked the Mythical Perfect Haskell Programmer if he was aware of any work that had been done on static duck-typed languages. "Oh yes," he said, "O'Caml's one." Buhuh? Really? Well, that's O'Caml moved a couple of rungs up my "cool languages to learn" stack...
pozorvlak: (Default)
2007-07-25 03:55 pm

Internal and external martial arts

One of the more useful ways of classifying martial arts is into external and internal, sometimes known as hard and soft. External martial arts (like karate and taekwondo) emphasize the actual mechanics of punching and kicking (or blocking, or throwing, or grappling), whereas internal martial arts (like aikido and tai chi) are more abstract, focusing on things like listening, blending, and the flow of energy (chi, or ki, or ache, or ... if it helps, remember that this isn't energy in the physicist's sense, but something else with the same name. Like the physicist's energy, it's an abstract, derived concept, but that doesn't mean it isn't useful). I'll quote [livejournal.com profile] totherme here:
Of course tai chi is a martial art - the energy abstraction exists to facilitate martial application - but we learn it for its own sake - like learning to add numbers rather than learning to add apples. Apples are a great example, but they miss the point - if you add numbers then you can add bananas too :)
I've studied just enough martial arts to be extremely wary of making broad generalisations, so I'll hedge a bit and say that the ultimate aim of most established martial arts is to produce internal martial artists, which is to say those who intuitively understand the concepts taught by the internal styles (or possibly the deeper concepts behind them - the Tao that can be named is not the true Tao, of course). The difference is in the approach, and the stations you pass through on the way. Hard styles present you with a series of examples of correct technique, and leave you to deduce the underlying principles yourself; soft styles try to teach you the principles, and leave you to work out many of the fine details. Both approaches can produce both internal martial artists, and extremely effective fighters - believe it or not, tai chi can be very dangerous in experienced hands! It's notable that many arts seem to evolve towards internality as they age - karate's thought of as an external style, but it's much more internal now than it used to be. This progression is clearest in the history of aikido, which developed towards being an internal style as its founder progressed towards being an internal martial artist.

This distinction can be useful to bear in mind as an analogy. You sometimes hear mathematicians talk about "hard" and "soft" geometry, which strike me as similar in some ways to hard and soft martial arts - hard geometry has lots of coordinates, lots of differential forms, lots of linear algebra, whereas soft geometry is more abstract and topological. [livejournal.com profile] totherme and I were discussing our respective ways of thinking about programming a while ago, and found this helpful in reaching some understanding: whereas the training I've received has all been about how to do specific things, his CS degree has taught him more explicit versions of what I (sometimes, unreliably) do in my head - things like proof of code correctness by invariants. Internal versus external, in other words - the Oxford CS course attempts to do the Tai Chi thing to hacking.

This is also one way of looking at category theory (I think this makes Attempt To Explain My Thesis No. 3...). An awful lot of modern pure mathematics is implicitly categorical, but this can be hard to see because the details get in the way. Category theory attempts to extract the deeper principles from a large variety of techniques, and make it explicit, so it becomes easier to learn them (or work them out on-the-fly). Actually, this is how mathematics works in general: by identifying the implicit principles that underly things and making them explicit so you can think about them in their own right, thus (hopefully) making the original problem easier.
pozorvlak: (kittin)
2007-07-12 12:47 pm

Fantasy Curriculum

Several of my fellow PhD students here have to do a substantial amount of programming as part of their PhDs: unfortunately, most of them haven't done any programming before. The usual procedure, alas, is to hand them a Fortran compiler and tell them to get on with it, often hacking on a large mass of code written by someone else who was "taught" the same way. I try to do what I can to help, but there's a limit to the amount of time I can devote to someone else's project (and a limit to the amount of time they'd want me to devote, I suspect). But still, I see some horror stories: yesterday, for instance, an office-mate finally tracked down a bug due to a magic number which had been bothering her for longer than she cared to say, and which had been seriously undermining her confidence in her actual model. Not using magic numbers is basic programming practice, but nobody had told her this.

So I've been thinking about an introductory course on programming aimed at maths/science grad students. The emphasis would be on writing maintainable code and modern programming practices: modularity, use of libraries wherever possible, test-first programming, use of debuggers, source control systems and profilers, optimising later (if you have to at all), use of high-level languages, documentation, and so on. My real aim would be to break the cycle of abuse whereby each new generation of grad students is told to write 1000-line-to-a-function, opaque, untested, rape-and-paste Fortran by their supervisors, because it was good enough for their supervisors, and on and on...

Here's a first cut at a course catalogue entry for this fantasy course: I'd be very interested to hear everyone's comments.

Practical Computer Programming for Scientists )
pozorvlak: (gasmask)
2007-06-26 02:29 pm

Starting points for thought

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)
2007-06-26 01:27 pm

J two - ohhh...

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)
2007-06-11 06:04 pm
Entry tags:

Learning Perl

The other day, [livejournal.com profile] stronglight was asking for some tips on learning Perl. Here's what I told her:
All assistance short of actual help )
Did I miss anything? I think she's wanting Perl for bio stuff, but I'm not familiar with any of the various Perl for Bioinformatics books. It's also her first programming language, if that helps.
pozorvlak: (Default)
2007-06-09 11:04 pm

J as she is spoke

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)
2007-05-16 09:32 am

The private life of the gerund

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)
pozorvlak: (babylon)
2007-04-26 03:51 pm

Some fun problems

I've encountered some interesting-looking mathematical puzzles recently, and thought I'd pass them along:

1) Consider functions from the set {1,2,...n} to the natural numbers {0,1,2,...} with the following property: the sum of the images of any two distinct subsets are distinct. So f(1) + f(3) + f(4) != f(1) + f(2) + f(7) + f(9), say. There's at least one such map for any n, given by f(i) = 2^i. The question is, can we do better than this? What, for a given n, is the smallest maximum value of a function with this property?

We can make some simplifications: for instance, we can assume that the function is increasing, so we're asking for f(n). I've written some Haskell code to investigate this, which indicates that sequences which do better than 2^n are extremely common for n>4, and that the first such sequence one encounters is [3,5,6,7], but so far provides little insight. I can post the code if someone wants to see it. Merely getting the damn thing to compile was so challenging that I have little confidence in its correctness, however :-)

2) Consider a set of n circles in the plane, labelled 1..n. Construct a matrix whose (i,j)th entry is the area of the intersection of circle i with circle j. The resulting matrix is (apparently) positive definite: prove this.

The guy who told me problem this claims it took him ten years...

3) The "Chinese university entrance exam" question from this story. My Euclidean geometry is a bit rusty, so I'm currently only on part (ii). (i) is pretty easy.

Thanks to Dr. Richard Vale, Prof. Oleg Chalykh, and the Royal Society of Chemistry...
pozorvlak: (Default)
2007-04-17 01:31 pm

Originality considered difficult

About a month ago, [livejournal.com profile] wormwood_pearl and I went to see the fantastic stand-up comedian Daniel Kitson (who you should all go and see if the slightest opportunity presents itself). One thing that he said really struck me:
If you ever think you've had an original thought, put it in quotation marks and type it into Google. Now that's a humbling experience.
So I really shouldn't have been surprised when I found out that someone else had already gone ahead with my idea to extend TeX with OCaml. You can get OCamlTeX here. Somewhat to my surprise, it's based on PerlTeX, which allows you to extend TeX using Perl, writing the bodies of your macros in Perl code. For example, \perlnewcommand{\reversewords}[1]{join " ", reverse split " ", $_[0]} defines a macro that reverses the words in its arguments (not at all easy in raw TeX). I'm not entirely sure (the Perl's less than entirely clear, and the TeX is completely beyond me), but it seems to work by setting up intermediate files to communicate between a perl process and a latex process: latex writes out requests to one file, perl reads them, writes the results out to another file, which latex reads and incorporates in the document. Thus there's no need to reimplement the hairy TeX lexer or macro-expander (as there would be with a preprocessor-based approach) or to rewrite the whole of TeX in Perl/OCaml (as I originally envisaged - but come on, it could be fun :-) ).

Another one for the originality-is-hard file is this article, which says a lot of the things I've been thinking about the differences between static typing and unit testing, and how they each influence development methodology. Only the author, mwh, said it back in 2004 :-(. Mwh mentions some things I hadn't thought of, like unit testing tending to make your designs more loosely coupled (because it's such a pain setting up dozens of helper objects for each test). I was particularly struck by this paragraph:
As to which "side" is better, well, I'm not going to attempt an answer to that question :-) One thing to consider, though, is the side benefits of a given methodology such as the unit testing driving loose coupling. There are probably side benefits to the powerful static type system approach, too. I will notice that for sub-genius programmers, the unit test approach is probably just plain easier.
This resonated with something else that I've been thinking. Kevin Barnes draws a distinction between "freedom languages" and "safety languages" - freedom languages are languages like Lisp or Perl or C, which strive to give you as much freedom as possible. The rationale for this was expressed wonderfully by chromatic: bad programmers will shoot themselves in the foot anyway, and good programmers will use the features to do things that would otherwise be impossible. Safety languages are languages that go to the opposite extreme, and make it very hard to do unsafe things, like Java or Ada. The rationale being roughly a) fewer bugs (even good programmers make mistakes), b) better automated tools. Compare this with the distinction drawn here between Languages for the Masses and Languages for Smart People. At first I thought he was talking about the same thing, but then it struck me: Haskell (and ML, etc), are Languages for Smart People that are also Safety Languages. Which makes them interesting, as most other LFSPs are Freedom Languages. This suggests the question: are there any LFMs that are Freedom Languages? Possibly Python: it's certainly an LFM (it's closely entwined with a project called Computer Programming for Everybody, will be the main programming language used on the One Laptop Per Child laptops, etc - note that I'm not saying that being an LFM is a bad thing!), and yet you can (if you're prepared to ignore the scary DEPRECATED! warnings) do most of the run-time metaprogramming and dark hackery that are more common in Ruby, Perl etc.

Re-reading the LFSP article, I notice that he's mainly concerned with abstractive power: maybe this is the distinction. Safety Languages for Smart People employ powerful abstractions, but restrict dark hackery; Freedom Languages for Smart People allow for both. Maybe the distinction is only visible above a certain level of power, like the weak and electromagnetic forces are only distinct at certain energies...

Of course, if all my "thoughts" are formed by stitching together things I read on the web, it's hardly surprising that they're not original :-)
pozorvlak: (Default)
2007-04-05 01:50 pm

Opus 200

Haskell continues to bitch my sh*t )

I notice that this is my 200th post to this blog, which has been running for around 16 months: that's a remarkable amount of effort given all the other things I should probably be doing instead. (And some of those posts were quite long). I was originally planning to write a list of links to my favourite posts, but I did one of those as recently as September, and since then it's been more of the same: more (interesting|important) ideas that everyone should know about, including a few on antipatterns which seemed quite popular (and to reiterate, the idea was to get some other people to blog about their interesting ideas: what is the conceptual toolkit with which you understand the universe?), more arguments with libertarians, a bit about maths, including a nice metaphor for what I do for my day job phrased in terms of bridges and islands and stuff, some daft scripts and sketches, (plus occasional updates on the Forties spy thriller I'm writing for Edinburgh next year), and rather a lot about computers. I'm currently learning the programming language Haskell, you see, and while learning a new language is normally not such a big deal, Haskell is based on radically different assumptions about programming to the ones I've hitherto held (linked post is allegorical, so you've got a fighting chance of understanding it), and this is forcing me to re-examine many of my cherished beliefs. Which is a good thing (I have to keep reminding myself). There are basically two reasons to learn a new language: to get useful stuff done, or to extend the range of thoughts that you're capable of thinking, in a Sapir-Whorfish way. In fact, I'm increasingly convinced that Haskell embodies an approach to programming which I've never seen or heard about before, and for which I've been using the term "guarantee-oriented programming": I've got various drafts of a post to that effect lying around my hard drive, waiting to be kicked into shape.

Anyway, I'm not going to talk about that. What I am going to do is ask you, my loyal and valued readers and friends, what you'd like to see in the future. Would you like to see more Interesting Ideas, or should I just give up on them? Is there too much computer stuff? I've been tagging not-for-general-audience posts with beware the geek, with the initial plan that they'd be few and far between, but having given myself that license, I seem to have been writing more and more posts like that. I don't think custom filters would work, because I'd like to keep it world-visible, but I could post all the techie stuff to another journal, like [livejournal.com profile] neoanjou does with [livejournal.com profile] neoscientia. Conversely, would you like to see more maths and/or computing? Would you like to see more daftness on the lines of Jeeves versus Predator or the Expressionist Thoughts of Edvard Munchton? More politics? Or would you like to see something else entirely? I could have a go at Gothic poetry, I suppose...

Then again, maybe I'm getting my hopes up. If I've learned anything in the last year and a half, it's that posts written too near to the weekend tend not to garner many comments :-)
pozorvlak: (Default)
2007-03-29 03:19 pm

What I was trying to say

chromatic, in a conversation about domain-specific languages in Perl 6, put something I've been trying to say for a while into the correct words that would never quite come for me.
I can decipher and fix bad Ruby code, for example, because I know the underlying language.

You know Ruby's syntax maybe, but who says you know the domain of the business problem the code attempts to solve?

I maintain that that is much more important than syntax--and if you have undisciplined, barely-competent monkeys who cannot or will not write maintainable code, then your biggest risk is not that they might use powerful language features to do bad things that are hard to unravel.

Your biggest risk is that they will do anything. It doesn't matter what they do, if they have access to your source code. They may never know about symbol tables or run-time code evaluation or method aliasing or macros or code generation or monkey patching, but you can be sure that they'll pull a stupid trick such as writing files and reading them in line by line because they don't know how to use arrays.

They're barely competent! They're undisciplined! They're monkeys! Want to fix your coding problems? Start by getting rid of monkeys, not by complaining about powerful tools that competent developers might be able to use productively.
From what I've seen, all the safety features in the world will not prevent monkeys from shooting themselves and others in the foot. Paw. Whatever. Whereas good, disciplined programmers will be able to get great mileage out of supposedly dangerous features, by using them correctly (note that "using them correctly" includes not using them in cases where it's not a good idea). I might, of course, be wrong, but this has been my experience thus far, and this is why I'm finding it such a big adjustment to come to a language community that seems to believe the opposite.

[Remember that crack I made a while ago about how, in the limit case, the "guarantees over expressivity" philosophy would lead to preferring guaranteed termination over Turing-completeness? It seems someone actually does believe that. Disclaimer: I've only skimmed the paper.]

By the way, I came across chromatic's post from Piers Cawley's post DSLs, Fluent Interfaces, and how to tell the difference, which says something I've long suspected: that this whole (embedded) DSL business is mostly just a buzzword slapped on a lot of fairly straightforward and common practices.
pozorvlak: (Default)
2007-03-22 11:33 am

Let them have the waltz, they cannot have the calculus

[Non-geeks: sorry for the recent rash of beware-the-geek posts: this stuff has been much on my mind lately. Normal service to be resumed shortly.]

Is this the kind of thing people mean when they talk about embedded domain-specific languages in Haskell?

Code listing )

There's a long tradition of writing symbolic differentiators in epsilon lines of Lisp, so this seemed like a reasonable exercise. It could be straightforwardly extended to deal with other variables, partial differentiation, standard functions like sin and cos, etc, though it would quickly get unwieldy. I'm not too happy with the simplifier - can anyone see how to make it tidier? Basically, I'm applying rules until no more apply (this is how Mathematica works internally, btw): maybe an explicit rules database would help? Expressing the rules as Haskell functions allows me to use pattern-matching, which helps, but less than I'd hoped.

Edit: on reflection, this probably shouldn't qualify as a DSL. What could really use DSLifying, however, is the simplification rules. (Slot 1 + Slot 2) + Slot 3 --> Slot 1 + (Slot 2 + Slot 3), or something, or better yet, associative op = (Slot 1 `op` Slot 2) `op` Slot 3 --> Slot 1 `op` (Slot 2 `op` Slot 3); associative (+); associative (*). Now, how to implement that? :-)