Planet Erlang

Posted by Daniel Lyons Mon, 17 Sep 2007 19:50:00 GMT

Planet Erlang used to be in my list of aggregated sites. It’s not anymore, and because I don’t see a good place on the site to leave feedback, I’m leaving it here.

  • Planet Erlang is the only RSS feed that spams me. There’s no excuse. Planet Io doesn’t, Planet Haskell doesn’t, Planet Lisp doesn’t, Planet Erlang had better figure out how that’s happening and make it stop. Killing the item after it gets posted isn’t good enough if it still winds up in my RSS reader, which it does.
  • Planet Erlang’s RSS feed is one point shy of completely useless to begin with. The whole point of an RSS feed is to bring me the content without me having to ask. Planet Erlang brings me a one sentence description of the content—in the title and the body. Who thought this was a good idea?
  • Finally, when I do click on the title of the story, I wind up not at the story, but at Planet Erlang’s web page with Planet Erlang’s one-sentence summary of the story. Then I have to click again to get to the site.

Here’s a refresher on how RSS is supposed to work:

  1. I sit on my ass, reading news.

Here’s what actually happens with Planet Erlang:

  1. I sit on my ass, getting spam.
  2. Once in a while I see an interesting article’s title.
  3. I click on it to read it, because it isn’t already there in my news reader where it should be.
  4. I click on it again to get away from PE’s site and read it.

All this so I can see comments from someone about the site being linked to. Invariably, there are none for me to see. I’m invited to vote on the story. Invariably, the story has one vote.

I don’t know what you guys think running a Planet-style aggregator is all about, but you’re failing it, and you’re being an obstacle to the information I’m there to get.

Tags ,  | 7 comments

Three Little Letters

Posted by Daniel Lyons Fri, 14 Sep 2007 06:15:00 GMT

Someone on Reddit shared the most cogent summary of DHH’s philosophy. Love him or hate him, he deserves most of the credit for Rails (and indirectly much of the recent furor over DSLs), and understanding him will get you far in understanding those things. He’s also a Web 2.0 personality of no small importance.

It must be very gratifying to be David Heinemeier Hansson. After all, he’s entered that quite small group of people in the programming world who are known by their very own TLA. Designers and programmers of various stripes regard him very highly. Of course, this has only happened to three or four other geeks in all of time: ESR, RMS, DJB, and maybe EWD. In short, it only happens to blowhards.

DHH is a blowhard and you know it. 37signals’ products tend to be so “opinionated” as to be anti-user. Lots of people have walked away from Basecamp because part of having “vision” is apparently knowing and understanding your tool so well that no customer—no matter how much they use your tool—can possibly have a suggestion for you that you should even bother responding to with anything less than total contempt. Want some proof? There’s even a hilarious parody of 37signals’ blog.

Without a bunch of highlighter, let’s skip to the point: Lots of companies achieve success, make a blog, and rant about their awesome formula. Lots of fans arrive, read the blog, and start to copy the formula. You shouldn’t, though, because mixed in with “good” companies are bad companies with crap products. They’re just as successful. DHH believes that his formula is perfect and it’ll work for everyone, but he has no way to know which parts of his formula are brilliant and which parts are bullshit. If you start your company ready to say “fuck you” to the users, well, you might be successful, but you might not.

I’m really glad someone as surly as myself managed to start a company and get invited to talks to put up slides that say “fuck you” on them. Really. It makes me feel really good about myself. The cult behavior is what’s pissing me off. Hating users is not a road to success. It’s an obstacle to success that, in DHH’s case, was apparently not enough of one to stop it from happening.

37signals used to have a great page comparing the cost of Basecamp to their competitors. The competition, if they’re still around at all, was charging hundreds or thousands of dollars for comparable or less functionality with really bad UI. Basecamp showed up and for $20 you could use it and it was easy. Might the real take-away here be the oldie-but-goodie “find a niche and fill it?” Do I need to point out the utterly missing runaway success with their other programs, largely warmed-over versions of Basecamp with different UIs? Does anybody really use Backpack? I’m sure twenty people will show up to point out that they do, but it’s hardly the millions who are using Basecamp. Campfire? Writeboard? Please.

So let’s be serious. They’re a one-hit wonder and their success has everything to do with capitalism and nothing to do with their cult of personality. That may sound depressing, but it should be liberating. You don’t need to drink any kool-aid. You just need to find a niche and fill it. You can be the biggest asshole in the world, and you’ll still get stinking rich. If you play your cards right, you too can be reduced to just three little letters.

Just be sure to give DKL some the credit when that happens.

Edit: comments are closed. Please see my commenting policy, my response to another troll on Reddit, and think about why you wanted to waste your time insulting someone on their blog when you could just get one of your own. Thank you.

Tags , ,

G-d and Reasoning

Posted by Daniel Lyons Tue, 11 Sep 2007 05:38:00 GMT

One thing Michael and I often discuss theologically is G-d’s perspective of the world. I have a particular thought about His reasoning which seems unusually lucid right now, so I thought I’d put it down here.

Reason is accepted as a gift of G-d to man in the Catholic and I believe also my own Rabbinic traditions. That we live in a rational universe whose laws can be determined scientifically and which can, to some extent, be understood is also an important given. But does G-d reason as we do?

If we accept that G-d exists outside time then perhaps causality still exists, but without time to give it duration, the effect of reasoning would be instantaneous. Understanding reason as a gift to man, I do not see any reason to assume that G-d also employs reasoning the same way. Indeed, isn’t reasoning mainly the creation of useful abstractions that enable our feeble minds to make observations in general? Without time, but with causality, wouldn’t these derived relationships appear instantaneously to G-d? If G-d can perceive these relationships instantaneously and G-d’s omniscient mind can contain all of everything, then He hardly is in need of abstractions: He understands, instantly, everything. Logic would therefore seem to be a needless crutch to G-d, about as useful as a blind person’s cane to a man who can see.

And in that light, it seems that G-d would have no need to deal with us categorically. In fact He would by necessity deal with us individually, since there would be nothing to be gained by dealing with us categorically. He has no shortage of time or mental effort, and wastes none in performing the steps of a logical derivation.

All of which brings us back to the notion of a personal G-d, elemental to both Judaism and Christianity. It’s the only kind of G-d there could be. Why would a creator of the universe, outside of time and with no limit on “processing power” opt to be distant or deal with humanity in general instead?

This line of reasoning also helps explain why firm ethical rules are handed down to us to be implemented in practice, but which G-d bends in the biblical narrative. Reason is our tool to approach G-d, not G-d’s limitation to us.

Tags ,  | 2 comments

Object-Oriented Lisp and OCaml

Posted by Daniel Lyons Fri, 07 Sep 2007 19:12:00 GMT

I have a theory about the respective OO capabilities of Lisp and OCaml, but I’m not quite sure who to ask.

In Lisp, when you make some class and some methods, those methods look like regular functions. In fact, in a sense, they are regular functions which happen to have more than one definition depending on the types of their parameters. So functional-style programming isn’t hampered.

I’m wondering to what extent functional and OO programming styles intermingle in Lisp and OCaml. My suspicion is that OCaml suffers from a lower degree of functional/OO integration because it provides object#method syntax instead of method object syntax which would be analogous to its function call syntax and closer to Lisp’s (method object) syntax.

Tags , , , ,  | 1 comment

Knowing a Language

Posted by Daniel Lyons Fri, 07 Sep 2007 08:46:00 GMT

Apparently people are talking about what it means to know a language. The debate seems to be centered around whether or not knowing the language syntactically or in terms of the library is what really constitutes “knowing” it.

Even in natural language there is disagreement around this kind of thing. Some teachers prefer to focus on vocabulary, others on grammar. Many others prefer immersion to formal methods. I think this translates roughly to teaching programming in terms of idiomatic forms.

I’ve been exposed to all of those methods of learning a language in computer science. Lots of people buy, read and are devoted to “cookbooks.” I have found that, although they are often good, some are overly simplistic (O’reilly’s PHP Cookbook comes to mind), but neither is really a good substitute for reading actual code in the language. Immersion, if you will.

In Compiler Writing in college, we were required to implement a compiler for a language nobody knew which bore very little resemblance to other languages we knew (Tiger). In that class I got to exercise my skills at reading a BNF specification of a grammar, and I was able to write code that should have compiled pretty easily with just a little bit of studying. This doesn’t come up very often, because usually there is a body of code to learn from idiomatically. There are no idioms for Tiger, because nobody uses it enough to establish them and it’s designed to by syntactically troublesome without being particularly expressive in the first place. (I did once email the REALbasic developers to see if they would supply me with a BNF for the language, and I was told it didn’t exist). So the skill is nice to have but comes up very rarely.

The author above is, I believe, reaching for the same idea of idiomatic use in talking about max() in Python, because anyone who really understood Python would use it. At the same time, I have to say there’s more to it than that, because someone who really knew Python would know not only the idioms but also when not to use them. Lots of English speakers do not use “me” and “whom” correctly (including me, sometimes). True mastery includes that level of knowledge. For many languages, it probably includes a certain amount of knowledge about the implementation, or at least an intuition as to what equivalent constructs are going to perform faster, for example.

But taking this concept even further, I would say nobody is master of any programming language without knowing at least one other programming language. Linguistic myopia is a huge problem. Languages are primarily tools. If you think there are no better tools for any problems, you will find yourself writing unidiomatic code in your language to solve problems which are idiomatic in other languages. In the case where you’re forced to solve a problem in the wrong language, it may even be better sometimes to solve it in a way idiomatic to the more appropriate tool than heave and misapply your energy to an idiomatic but confusing solution. It certainly will be worth it for the affect on your brain.

Tags , ,  | 1 comment

Couch Painting

Posted by Daniel Lyons Thu, 06 Sep 2007 03:52:00 GMT

Recently I had a kind-of debate with a kind-of friend about programming. It came to basically one thing: do you value readability?

I certainly do. I think one of the things that makes programming interesting is that we’re trying to express something to a computer and another human being at the same time. All programming failures fall on one side or the other of that balancing act.

The argument for readability cannot be absolute though. A hundred lines of Python may be more readable than 20 lines of Haskell. So we have to ask ourselves some more questions besides pure readabilit. We have to ask ourselves if we are following the elements of style. Can we “omit needless words?”

  • Does this code communicate in 20 lines the same thing as 100 lines of Python?
  • Do we gain from the conciseness?
  • Does it take the same amount of time to understand?
  • Do we want to constrain all of our developers to the same standard?

The allure of functional programming is that it is both more rigorous and more concise. When you understand a fold, you are tempted to use it even in languages where its application will be awkward or difficult, such as Ruby. This template substitution probably has appeared on my blog before; normally this would be coded as an imperative loop, but I chose to use Array#inject which is basically a fold:

vars.inject(@template.clone) do |template, (region, value)|
  template.gsub(/%#{region}%/, value.to_s)
end

In OCaml this would probably have looked a lot more concise than it does in Ruby, and it would be considered more readable. So you have to consider your audience too. Haskell’s audience is smarter than Java’s, or at least thinking in a more high-level way. Though, really, you should try to learn Haskell, it’ll make you smarter. (Or if you’re really vindictive you’ll at least bring the average down.)

So my operative concept is not readability anymore. It’s conciseness. Concise not like Perl or APL, concise like “omit needless words.” It may take you longer to figure out than comparable 5x larger Python code, but it won’t take you 5x longer, and you won’t be falling asleep.

And why do you believe your code is so important anyway? I’d bet 99.9% of code in this world is couch paintings. It seems so important right now. In five years, is it going to be important? Or is it going to already have been rewritten by then? So much code is treated like an investment when it is written as so much slapdash cut-and-paste filler. Other code is written elegantly and perfectly and winds up forgotten because nobody knew how to treat it like an investment. The entities most qualified to treat code as an investment seem to have practices that encourage the quality being the lowest. Hiring lots of developers, outsourcing, having corporate policies about language choice and a complete lack of code reviews have a strong negative effect on code quality.

If we really wanted to treat code as an investment, wouldn’t we want to revel in it a bit more? Read it, really take the time to enjoy it, pass the tricks around the organization? Treat the code like a member of the company rather than a process or, worse, the result of some process like so much insect shit?

And while we’re on the subject, I no longer believe any project really needs more than three developers.

Tags  | no comments

Things I Hate

Posted by Daniel Lyons Thu, 06 Sep 2007 03:07:00 GMT

I don’t hate a lot of things, though the quantity and ardor seems to increase with every year. I want to share a few of those things with you now, so you can get to know me a little better than you already do.

The top three things I hate are:

  1. The wrong technology (MySQL and PHP)
  2. The wrong reasons (couch painting)
  3. Polyamory (more crap must be better)

Some technological equal-opportunists say things like “every technology has an appropriate use.” Guess what? Some technology doesn’t.

Let’s not beat around the bush. You shouldn’t be using MySQL or PHP. Not on this project, not on the next project, not now, not ever. I don’t care what monstrous shit they’ve stapled onto MySQL to try and make it look like a database or what monstrous object system they’ve stapled onto PHP to make it look like a real programming language. Neither of these things are real, they’re both charlatans and if you’re tempted to use them for a technological reason you don’t understand the problem and you should ask someone who does.

MySQL pretends to be a database. It is no such thing. It is an SQL front-end for a hair-removal tool. Dr. Codd’s Physical Data Independence says your view of the data should be independent of the physical representation of the data on disk. So which integer do you want, the 1-bit, 2-bit, 4-bit, 8-bit, 16-bit, 32-bit or 64-bit? Nevermind, let’s talk about the tables, those are pure relational entities, right? Oh wait, you wanted transactions? I guess you’d better use the InnoDB table type (what happens if you start a transaction and some of your tables are InnoDB and others aren’t?) Nevermind, let’s talk about SQL the standard. How would you like a TIMESTAMP column, that’s standard SQL? Oh wait, that one automagically changes when you update the row, you actually wanted a DATETIME. Want to concatenate some strings? Better remember that the concatenation operator is treated as logical OR in MySQL, or you’re going to see a bunch of 0’s where you expect strings (I know, instead I’ll use the handy CONCAT function!) Does this sound like hell yet? If not, MySQL is for you!

PHP is great, assuming you aren’t the slightest bit interested in consistent functionality across more than one server, like restating things over and over again, prefer your languages guess at what you meant when they can’t quite tell, and have configuration files. Off the top of your head, how many languages can you think of that have configuration files? Did you know PHP doesn’t ever free memory in the core, because it was never meant to be running longer than a fraction of a second? Or that you can define functions inside functions, but they’re actually defined in the enclosing scope (you like warnings, right?) Try accessing an array returned by a function without sticking it in a variable first sometime. And the joy of having dictionaries that are arrays at the same time never ends! What about SQL, PHP’s supposed to have that down, right? Of course there’s the PEAR DB module, which is deprecated, the MDB2 module, which doesn’t work properly on PHP 4, and ADODB, which everyone was using for years before PEAR existed. Oh, and let’s not forget that PHP will helpfully escape those strings on the way in, unless you’ve disabled that in the configuration, or locally with a .htacess, or at the top of the script with a setvariable function call. And my, what consistency in naming conventions! I hope you have a fast link to php.net.

Do not use this software for your own projects unless your husband or wife thinks you would be hotter bald, wrinkled and angry.

Oh, but you don’t have a choice about your deployment software, do you, because your son who’s good with computers already bought you hosting on a $5 a month shared plan, and whatever I write has to work on that thing. This is called the wrong reason. You didn’t call me when you were thinking about writing the app, you called me after you started. This is like calling your plumber with your toilet on the lawn and a kitchen sink on the floor in your bathroom where your toilet should be, and saying, “No, I already bought this sink, you have to make this work.”

Firstly: no, I don’t. This analogy is really much closer to Windows. You called me up and said, “Daniel, you’re good with computers; what kind of computer should I get?” And I said you should get a Mac. You gave me some excuses. I told you to get a Mac anyway. Instead, you bought this PC and now you’re on the phone with me. Why? Because you didn’t do what I said, when I told you what would happen if you got another PC, and you got one anyway, and lo and befucking hold, I was fucking right. What were your reasons again?

  • The price. $600 is too much? You can’t afford a computer. Nevermind the fact you spent $1500 on a PC. Doesn’t Apple tell you about their financing?
  • You can’t upgrade it. That’s bullshit on a stick. Did you ever upgrade that PC? Of course not. You didn’t do shit with it. You bought another stick of RAM two months before you decided it was toast. Nobody who upgrades their shit for real calls me up asking for help. You want to play upgrade-the-PC? Have a great time. Call me when it’s broken and it’s your peril.
  • “But I need compatibility with X!” Have you ever looked at a Mac? For $80 they come with programs that are fully compatible with X. Or for free, if you like NeoOffice. You know something else? Macs run Windows better than Windows computers do, with Parallels or VMWare or whatever. Try that, I dare you. In six months you’ll never run it and you won’t miss it.
  • “But what about emailing documents!” What is this, 1989?
  • “But my games!” Oh, that’s funny, I thought you had work to do. Because that’s what I was talking about. You want a video game system, buy one. I’m not here to help you get your fix.

There’s a reason all the artists and programmers are using Macs. We know quality when we see it. If you’re using Windows you’re making a statement to the world: I don’t deserve a real computer. Well, stop inflicting it on those of us that do, and get over your $600 sticker shock. Get a fucking Mac already.

Same thing goes for your database. If you need a database, chances are, you have data you want to keep and query. If you need a database, you need PostgreSQL. Not MySQL, not SQLite, a real G-ddamn database.

If you have a program to write, you need to pick the right tool for the job. Sometimes that’s Ruby, sometimes that’s Haskell. There are other languages, sure, but it’s never PHP and it’s never C++.

Would you let your car dealer determine what outfits you wear to work? Of course not. Then why do you let your ISP determine what you write your applications in? They’re your applications, not your ISP’s, for fuck’s sake. When you call up your ISP and ask about PostgreSQL you should hear one of two things:

  1. Oh, actually we recommend all our customers use PostgreSQL because it’s faster and doesn’t lose their data.
  2. It’s installed, have fun. We don’t give a damn what you’re up to.

If you instead hear one of these responses, get a new ISP:

  1. We recommend MySQL, because it’s [faster, better, more reliable, some other lie]
  2. We only support MySQL. (Who’s asking about support, asshole?)
  3. Let me transfer you to someone who can answer your question.

So you got the wrong ISP. So what? You dated the wrong people in high school. Now you know better. Quit trying to justify your stupidity by hand-waving, referencing other companies, or talking about popularity. Yeah, it’s true, doing things the right way is hard.

I don’t really have a good segue to polyamory but that’s a rant for another time anyhow.

Tags ,  | no comments

Feeling ACIDic

Posted by Daniel Lyons Thu, 06 Sep 2007 02:38:00 GMT

I have a number of rants in me that I haven’t had time to get out. But let’s talk about one of them for right now. Let’s talk about what it means to be ACID compliant.

ACID stands for Atomic, Consistent, Isolated and Durable. It refers to transaction support in some kind of data storage mechanism. According to my twisted view of open source databases, I think it became a big deal because for many years it was something PostgreSQL had that MySQL did not. Of course nowadays MySQL does have transactions and ACID compliance, assuming you put the correct non-SQL-92 conforming magic runes at the end of your table definitions, your copy of MySQL was compiled to support it, and you don’t mind losing the highly-touted screaming fast performance characteristics of MySQL’s stupider table “type.”

Each of these terms means something in particular referring to the way your system deals with transactions.

Atomic means that everything you do in your transaction either applies or it doesn’t. To the user, it means if part of what you’re doing fails, the whole thing fails. But it also means that if the whole thing succeeds and the database crashes, it either has all of the changes or none of them. All of the work in the transaction is one little bundle to the database, even if something goes wrong.

Consistent means, once you begin a transaction, your view of the data in the database will not change, even if other people are making changes at the same time. If you read the list of users at the beginning of the transaction, wait 900 years and read them again, you’ll see the same list of users, even if someone else has come along and deleted them, or the usual creation/deletion churning has occurred in the intervening time. Your view is completely static until you commit the transaction. Other people’s changes do not leak in.

Isolated means that your changes to the database cannot be perceived by other users until your whole transaction is complete. If you start a transaction and empty the users table, wait 900 years and then commit, in the intervening time, everybody else has still been able to log in and use their accounts. Your changes don’t leak out.

Durability means once you commit, your changes are permanent. Permanent in the sense of mortality. Permanent as in only a hardware failure can muddle them, and even then it cannot undo them.

There are a number of interesting things about ACID compliance. One that comes to mind is ACID compliance is not automatically inherited by systems built on ACID compliant systems. Suppose you have a database for keeping personnel data. Suppose Joe wants to give the programmers a raise and some extra vacation time. Suppose Joe goes down the list manually editing each programmer’s record in the payroll database. If the system is dumb, it will treat each change as its own transaction. If the check writing program comes along and starts running while Joe is going down the list of programmers, some of them will get checks with the raise and some will not. The check writing program is getting an inconsistent view of the data because the application wasn’t written to use the database in a way that guaranteed isolation.

Tags ,  | no comments

What Are Combinators?

Posted by Daniel Lyons Sun, 02 Sep 2007 22:51:00 GMT

This is my response to the question as asked on programming.reddit.com.

Depends on the kind. In terms of functional programming, I understand a combinator to be just a less frightening word for higher-order function. So a combinator is a function that combines the behavior of another function with its own. A good example is filter, which just removes certain items from a list. You make a short boolean function that tells you whether or not an item is worth keeping and combine it with filter and some list, and you get the list of items you wanted.

The effect is best illustrated in Haskell where you can call a function with fewer arguments than it requires. This is usually called currying. Supposing our function for determining whether or not an item is interesting is just called interesting, you can create a new function which just gives you back the list of interesting items in a list like this:

neatItems = filter interesting

For the sake of argument, suppose you consider every number one less than a number evenly divisible by three to be “interesting.”

interesting x = x `mod` 3 == 2

Try it out:

neatItems [1..10]   -- produces [2,5,8]

The fun doesn’t stop here! Functional languages provide functions with no name for those times when you need to pass something to a combinator but don’t want to bother making it a name. This is usually called an anonymous function or a lambda abstraction. This means you can make neatItems without going to the trouble of defining interesting first, if (for example) you would never use it except in this function anyway:

neatItems = filter (\x -> x `mod` 3 == 2)

Incidentally, whenever you define a function that takes one or more parameters without specifying their names by using combinators, as above, you’re using what’s called points-free style. To facilitate points-free style, you can switch between names and operators in Haskell quite easily by inserting parentheses and back-tics. Haskell lets you use any binary function in-line as an operator if you put back-tics around it, or an operator as a prefix function if you surround it with parentheses, such as (-).

If you want to “curry” an operator, such as to produce a function that multiplies by two, you just put the value inside the parentheses on the side you want. Thanks to basic arithmetic, (2*) and (*2) are the same, but the variable which is “curried” is different depending on the form (the first in the first, second in the second). A “curried” operator is called a section, and I have no idea why.

Another common combinator is (.), the dot operator. Dot lets you string together functions. Suppose you have a function which takes bread and makes toast, and another function which takes toast and butters it. You could glue these two functions together with (.) and arrive at a new function which takes bread and makes buttered toast:

butteredToast = butter . toast

We can now take the above example of filter to its logical extreme by defining our “interesting” test function with sections and the dot operator:

neatItems = filter ((==2) . (`mod`3))

Now there’s no points in that function at all. It’s not exactly a win for readability in this case, however. :) A slight improvement can be made by eliminating some of those parentheses with the ($) operator, which just takes everything on the right-hand side and slaps it into parentheses as an argument to the left-hand side:

neatItems = filter $ (==2) . (`mod`3)

Eh. Still not a lot better. I’d probably take the lambda abstraction over that unless I was feeling feisty.

Combinators come up more frequently in making libraries, much like dynamic method resolution in Ruby. A great example is Parsec, which is a parser combinator library. By introducing its own BNF-style operators, Parsec lets you define parsers in a BNF-reminiscent domain specific language. It’s also good for testing because you can separately test each constituent part’s parse directly rather than being stuck with parsing whole documents. It’s also quite fast. An example from Write Yourself a Scheme in 48 Hours:

parseNumber = liftM (Number . read) $ many1 digit
parseExpr = parseAtom <|> parseString <|> parseNumber

It looks like you’re just defining a kind of token. Actually you’re defining a function with a pretty rough specification, but that’s not your problem as the API’s user. All you have to know is how to use it to parse, which looks like this:

readExpr input = case parse parseExpr "lisp" input of
    Left err -> "No match: " ++ show err
    Right _ -> "Found value" 

I hope this answered your question!

Tags  | no comments

Haha... Ouch

Posted by Daniel Lyons Thu, 30 Aug 2007 09:34:00 GMT

Plan 9’s emacs(1) manual page.

Tags ,  | 1 comment

Older posts: 1 ... 3 4 5 6 7 ... 44