Code and Data are One

Posted by Daniel Lyons Mon, 05 May 2008 12:09:00 GMT

There is a general desire to keep code and data separate, but they are indivisible.

We use migrations in Rails to manage changes to the database, but some data is invariably essential to the proper working of the application. The database schema itself is data. As your understanding of the dataset of the application changes so does the database schema; data affecting data.

The code itself is utterly meaningless except as transformations to the data. Even esoteric languages like Haskell, J and Forth which do their best to avoid naming the data work only by computing with it. Nothing else happens other than examining and modifying data. Thus, much data is inline in the code: initial values, special values, error values.

Sometimes it feels like there is a hard distinction between data and code, but even then, it is an illusion. On the processor, there are just bytes; there’s no difference between moving bytes from your code into the registers to examine them or moving data from a file into registers to execute them. It’s all just bytes moving from point A to point B.

The source code itself is probably the most obsessively well-managed data on the planet. Nobody uses version control for anything else.

Consider TeX. Is it a document (data) or a transformation (program)? Both. Restricting your output to DVI or PDF is no different from restricting your output to plain text. You can perform arbitrary computation with TeX. And this is of course necessary to make a well-crafted document: code is needed to compute how to style the data properly.

On the web we try very hard to maintain a separation of “content” and “presentation,” but the CSS is served by the same web server that sends out the HTML. More and more people are using the same template systems to generate their CSS as to generate their HTML: CSS isn’t enough on its own. Of course it isn’t, no amount of built-in functionality can ever replace arbitrary code (until you become Turing-complete or close to it). Even then, you use inline styles and generate not particularly flexible HTML interfaces.

There is no real distinction between content and presentation either. These things are all the same. Data. Or code.

Be aware of the illusion you operate under for the sake of good style.

Tags ,  | 1 comment

Magic and True Names

Posted by Daniel Lyons Sat, 19 Jan 2008 04:44:00 GMT

I somehow find myself participating in a game design group called “Etherware.” I’m not quite sure how, but at any rate, we’re discussing how to implement magic in a video game. Most video games implement magic as a list of pre-defined spells. This is very constricting.

My first reaction was, of course, that to make it better is to make it a language, and now we’re actually talking about making a programming language designed around a particular task and trying to find a compelling UI for it that doesn’t resemble programming.

We’ve identified so far four different “languages”: wand waving, rune cutting, verbal incantations and potion crafting. I haven’t read Harry Potter all the way through so I’m probably omitting several.

Jesse mentioned that he always prized the “true name” concept from various magic systems: that once you know someone or something’s true name, you have power over it.

A “true name” is just a string that can be used as an address. There are a number of ways to deal with this, probably the easiest one is just to make a hash and use that. It occurred to me that the number of objects in any game will be prohibitively large, and anyway, what do you do if the gamer creates new objects?

An easy solution to this problem is to use the memory address encoded in hex. But that’s not very user-friendly, or very pronounceable. Plus they tend to be quite large. On the other hand, you have encodings like base-64 which use the alphabet. Base-64 isn’t very pronounceable either, though. You could take the alphabet as-is and use it to encode numbers under base 26.

On the other hand, there are other types of orthographies, such as a syllabary, in which every possible syllable is enumerated. It wouldn’t work with English because of the vast quantity of dipthongs and consonant combinations, but it works quite well for Japanese, which has two syllabaries, katakana and hiragana. There happen to be around 115 distinct symbols in katakana. So, you can encode any number in Romanized katakana by removing any duplicate sounds, assigning an order to the orthographs, and converting the number to base 115. If you do, you’ll get something like this:

>> 12983.to_name
=> "ryavu" 
>> 6.to_name
=> "ki" 
>> 12983923239823.to_name
=> "megomeagyubika"

Converting back is easy if you’ve ever implemented atoi() in C:

>> "ryakujani".name_value
=> 33155983
>> "kyu".name_value
=> 53
>> "aeiouaeiou".name_value
=> 7158386439867648320

The latter example there is to illustrate the point that, just because it always works, doesn’t mean it always makes something that would be a word. I haven’t computed the probability, but it’s roughly the probability of a number showing up all 9’s. I expect it to be particularly rare because base 115 can represent numbers with a pretty high compression ratio. The set of three syllable words is 1,520,875 in size. There are 5 vowels out of 115, which means there are 60 ways to choose three vowels in a row, so 60 / 1,520,875 = 0.00395%, AKA not very likely. But still can happen.

Of course, there is already a swell system built into every language and every program of uniquely identifying an object. The memory address! And it happens to be a number. In Ruby, you can get at it with Object#object_id and convert back to the object with the please-don’t-use-me method ObjectSpace#_id2ref. Which means you could also have this:

>> h = {:this => "that", :name => 48}
=> {:this=>"that", :name=>48}
>> h.magic_name
=> "vachugyuku" 
>> "vachugyuku".object
=> {:this=>"that", :name=>48}

Works with everything in Ruby, for free. Oh, is that a class?

>> Numeric.magic_name
=> "weseke" 
>> "weseke".object
=> Numeric

Yeah, I think it is!

I’m pretty proud of the code. It’s BSD-licensed, so feel free to borrow it. Feedback appreciated!

Tags , , ,  | no comments

Fizzbuzz in SNOBOL4

Posted by Daniel Lyons Mon, 31 Dec 2007 18:06:00 GMT


**  FizzBuzz in SNOBOL4
**
**  Daniel Lyons <fusion@storytotell.org>
**
**  Yes, I am insane, before you ask.
**
**

        I = 1
LOOP    FIZZBUZZ = "" 
        EQ(REMDR(I, 3), 0)              :F(TRY_5)
        FIZZBUZZ = FIZZBUZZ "FIZZ" 
TRY_5   EQ(REMDR(I, 5), 0)              :F(DO_NUM)
        FIZZBUZZ = FIZZBUZZ "BUZZ"      
DO_NUM  IDENT(FIZZBUZZ, "")             :F(SHOW)
        FIZZBUZZ = I
SHOW    OUTPUT = FIZZBUZZ
        I = I + 1
        LE(I, 100)                      :S(LOOP)
END

Tags , ,  | 1 comment

Simplicity and the GWT

Posted by Daniel Lyons Sat, 08 Dec 2007 23:48:00 GMT

“GWT 1.5, due in the first quarter of 2008, will produce “better” JavaScript code than manual programming by the industry’s best and brightest – in terms of speed, size and manageability of code. GWT 1.5 is also expected to improve compilation of Java code.” —Google’s next web toolkit thinks it’s better than you

Let’s try that claim again with some different technologies. “gcc will produce ‘better’ assembly code than manual programming by the industry’s best and brightest—in terms of speed, size and manageability of code.” The claim sounds pretty unlikely, don’t you think? How are you going to do better than manual human intelligence on all three fronts that matter? But something is missing. What language are we compiling from and to?

GWT is in the somewhat ironic position of compiling Java to JavaScript. By analogy, this is like saying you can compile from C to Lisp and produce better Lisp than experts could—in terms of speed, size and manageability. Does that seem likely? Then how, pray tell, could someone compile from a language that lacks full closures and prototyping OO to one that does, improving all three of those things at the same time? For that matter, when has compiled code ever been smaller than manually written code?

I don’t know anyone using GWT, because the only people who would use it would already be using Java and I don’t know anyone doing serious web development in Java. Web development is hard in a way that precludes clunky languages (but not stupid ones like PHP).

It reminds me of the other night when my room mate David Baird and I were talking about simplicity. To some idiots, MySQL is simpler than PostgreSQL. This claim is bizarre to me, since MySQL’s source is 10 MB larger compressed, MySQL deviates intentionally and insanely from the SQL standard, and MySQL includes a variety of obnoxious features that no true database would provide. Yet it is considered simple and “industry standard.”

Half of it is from The Rise of Worse is Better, MySQL chooses to make the implementation simpler than the interface, whereas PostgreSQL prizes the interface more. Why else would MySQL’s SQL syntax change with every release, while PostgreSQL’s remains the same? But this doesn’t explain the absurd notion of table types, which only MySQL has.

There is another dichotomy here, between differing conceptions of simplicity. Which of these is simpler?

sum = foldr (+) 0

Or:

int sum(list_t list) {
  sum = 0;
  for (cur = list; cur != NULL; cur = cur->next)
    sum += cur->value;
  return sum;
}

There are at least three different ways of looking at this:

  1. “You’re comparing apples to oranges! Unfair!”
  2. “The C version is simpler because it’s closer to what’s really happening.”
  3. “The Haskell version is simpler because it’s closest to the concept.”

People who fall under category one are the kind of people who say things like “it doesn’t matter what language you choose to implement something in, because they’re all Turing-complete.” It only doesn’t matter if the time it takes to write, the experience of writing it, the quantity and severity of the bugs introduced while writing it and the human resources required to write it don’t matter. I think a lot of people say this because they don’t want to get into a religious war about language—it’s a cop-out.

What I’m really interested in is what happens to people to make them fall under category 2 or 3. I think this quote from Alan G. Carter’s Why No-One’s Noticed This Before may be the essence of it:

“We don’t miss what we haven’t got, and this can lead to seeing things in profoundly different ways. A person who frequently does juxtapositional thinking is aware of the importance of self-consistency in their thinking. If something doesn’t “hang together”, they know they have made an error. Often they use self-consistency as the basis of their thinking, deducing that something must be missing, and then being able to find it. A person who is rarely if ever in a position to do juxtapositional thinking, will not consider or expect self-consistency in this way. Their view of reality is therefore fragmented. If they don’t require their understanding to hang together, they develop the idea of “mere facts”. What are facts? What do they prove? Nothing! Instead they use their focussed attention to concentrate on compliance with a proceduralism, and they don’t let mere facts get in the way. They certainly don’t trust their own good senses.”

Look again at PostgreSQL. It assumes that the database is there to alleviate certain burdens. It provides you with SQL. At that point, the database’s job is complete and it is up to you to learn SQL. Learning SQL may imply learning the theory of relational databases. PostgreSQL isn’t there to hold your hand and help you do this. If it takes you 30 minutes to write an SQL statement, well, that’s how long it takes you to write it. People in category 3 don’t mind, because they’d rather have one comprehensive solution for their data situation that hangs together.

Look at MySQL again. Table types aren’t part of data management, they’re a leaky abstraction, an exposure of low-level details. MySQL’s query planner also sucks compared to PostgreSQL’s. Perhaps most damningly, MySQL doesn’t support two of the three fundamental set operations (INTERSECT and MINUS/EXCEPT). If you were modeling a relational database on set theory, you probably would have started there.

Yet MySQL is full of tiny details meant to “helpfully simplify” some aspect of databases. Such as the TIMESTAMP type. There is no other type in MySQL which is defined as equivalent to some other type plus some behavior. There is no other type in MySQL defined so, nor in all of PostgreSQL, defined in terms of behavior (when you UPDATE a row with a TIMESTAMP column, the TIMESTAMP column receives the current time even if you didn’t specify that it should be modified). However, I haven’t ever seen someone intentionally use the TIMESTAMP feature for what it’s there for, just people stumbling onto it and realizing that a whole bunch of data they thought they had has actually been obliterated. It doesn’t hang together.

David and I concluded that there is a kind of simplicity which requires learning and a kind of simplicity which attempts to avoid it. Some people find the thought of recursion and higher-order functions a lot less simple than for loops. And yet, for loops become more sophisticated in mundane languages with each successive one.

There are people who find the REPL a horribly frightening place. Look at the complete lack of “noise” in the Haskell code. It’s nothing but you, G-d and the problem. There is no public static void main. There is a desire to be typing while programming, and in plenty of languages you have to push this edifice of text around before you can begin to get anything done. There is a sensation of programming when really you’re doing nothing. You can reason operationally and have the appearance of getting things done. Somebody wrote an API for making new table types in MySQL. I have no doubt this is far simpler than improving the query planner. Someone else contributed a BerkDB table type for MySQL. I have no doubt this was fairly simple. But why would you? This is problem avoidance, but adds so many megabytes to the source code, which nobody even actually uses. There is a digital artifact to this lack of interest in actually getting anything done.

People use ActiveRecord to avoid learning SQL and relational database theory. Yet, I know plenty of people who have not studied relational database theory but who understand it anyway. A lot of people start out making tables that aren’t normalized. After a while they start to use joins. Eventually they acquire the insights, usually after not very long, say a year or two, and then they are as good as someone who has studied it. After a while they begin to be annoyed with MySQL. ActiveRecord is there to make dealing with the database more like dealing with Ruby. As long as everything is in one language, it should hang together better. But of course, ActiveRecord is built for MySQL primarily, but with an eye to portability. The advanced database users grow annoyed at it because it also represents problem avoidance.

The GWT is a lot like ActiveRecord. It wants to mitigate some problem which isn’t, in reality, a problem. It’s a nightlight. When you look at my Rails code, you see a lot of me manually executing SQL. This practice is encouraged by the books and DHH and many other Rails users do this. However, it ties you to a particular database—PostgreSQL in my case. Is your database a problem, or a solved problem? GWT is saying JavaScript is a problem, do you think JavaScript is a problem?

I can certainly look at Ruby and SQL and say, both of these things are great. I have some trouble looking at JavaScript and turning in revulsion, asking for Java to come and mitigate the pain.

Tags , , , , , , ,  | 5 comments

Lisp Tumblog: A Couple More Gross Insights

Posted by Daniel Lyons Tue, 27 Nov 2007 15:15:00 GMT

I have implemented paging using the SERIES macros, but now I have no idea how to implement the actual next/previous links. Well, the next link is really the one I’m worried about. :)

I rewrote the HTML template portion and so 2/5ths of the pages are now generated in a reasonably nice way. I would say there are now maybe a hundred or 150 lines of code I like in the program. I may have made a (possibly false) observation about the Lisp/Haskell dichotomy:

When you program Haskell, the program starts out beautiful and gets uglier and uglier as gets closer to completion. When you program Lisp, the program starts out ugly and gets more and more beautiful as you factor it into correctness.

We’ll see if it pans out as I finish implementing the tumblog.

Tags ,  | no comments

Weekend Program: Lisp Tumblog

Posted by Daniel Lyons Mon, 26 Nov 2007 18:16:00 GMT

Yesterday, I wrote a 250 line Lisp program to run my new tumblog. I have a few notes here I wanted to share about it. The next version will probably be open source; right now I can hardly stand to look at the code.

  1. Hunchentoot is very cool. The prefix and regex dispatcher functions are very handy. It was actually very easy to use, so easy it was almost counter-intuitive. I wonder why it took me so long to start actually building this program, since I’ve been thinking about it for so long.

    However, it doesn’t help you build an abstraction atop it. That’s your problem. So my URL handling is very ad-hoc and slimy, which is one reason pagination doesn’t work right now.

  2. CL-WHO is a mixed bag. On the one hand, it seems to be very efficient. On the other hand, it’s a bit hard to figure out how to build a template with it. It also can’t handle XML namespaces, which means my Atom feeds won’t validate due to missing XML namespace declarations and whatnot. I also don’t know how to make it emit an XML DOCTYPE or the XML processing instruction which indicates the encoding. Once I figure out how to do a reasonable templating system with CL-WHO my line count will probably go down by 50 lines or so.
  3. cl-prevalence was a pretty serious win in the storage backend department. I just make a list of instances and as long as I go through the transaction mechanism they’re saved to disk and reappear when I restart the app. Very simple and elegant. I wish I hadn’t had to go by the really old documentation to figure it out though.

    There is one bug with cl-prevalence though, which is that it doesn’t handle the clock—or at least it doesn’t seem to based on what I could find. This is a problem because my instances save their instantiation time as their creation time. I worked around it by making a snapshot immediately after adding an instance to the list. I have mixed feelings about that. In any case, it shouldn’t be very hard to fix this in the library by providing a special variable with the time when the transaction started and telling people to use that instead of (get-universal-time).

  4. I included the Parenscript library but never used it. So it’s Ajax-free for right now.
  5. Initially I was very worried about what format to put the date in. Then I decided, fuck it, nobody really cares what time you post something, they only care whether or not the site is abandoned or if they’ve missed something. So I put the last-updated date at the bottom and my design is even more minimal than Steve Dekorte’s. Top that! :) (There’s no way it could be related to my being a shitty designer.)
  6. Developing with Slime and sshfs was pretty good, but sshfs was definitely the worst part of it. I realized last night I could have just had the code checked out via Mercurial locally and be sending that to the remote Lisp, and then eventually check it in and back out on the server so that startup would work. Kind of a “duh” moment.
  7. There was a general lack of refactoring. I have a to do list with about 5 simple refactorings I should have done during development. Once a little bit of your code is scuzzy, it’s pretty easy to let the rest of it turn scuzzy apparently. I guess programming is no different than any other aspect of life.
  8. Weirdly, when I call read-from-string in Slime, it comes back in the tumblog: namespace, but when my code for processing the form calls it, the atoms come back in the common-lisp-user: namespace. It’s moderately annoying because I’m having to use #'string-equal to compare atoms instead of #'eq.

So there you have it. A short feature review: I can post through the web (but not edit), it understands markdown for my commentary, you can filter by tag, it has Atom feeds overall and by tag, and that’s it. I will hopefully rewrite it soon to be less scuzzy, or perhaps to add pagination, after all I only have 4 more entries to post before I need it. I plan on using tags to point out items of particular interest to some of my friends and family, so if you see your name on an item, that’s why.

Tags ,  | 2 comments

Programming: The Desperate Losing Battle

Posted by Daniel Lyons Sat, 27 Oct 2007 22:53:00 GMT

Jonathan Edwards refused to participate in the much-vaunted Beautiful Code essay collection, saying on his blog:

“Telling an inspiring story about a beautiful design feels disingenuous. Yes, we all strive for beautiful code. But that is not what a talented young programmer needs to hear. I wish someone had instead warned me that programming is a desperate losing battle against the unconquerable complexity of code, and the treachery of requirements.”

You’ve probably never heard of this guy, but he is responsible for the most interesting development in programming languages in the past thirty years, Subtext. Subtext seems destined to be whispered about for decades before emerging as a powerful yet obscure influence on some future technology.

All good programming languages are based on an interesting principle or theory of computation. The best are those that obliterate an unnecessary barrier, usually between the language and the compiler and the resulting code. In the middle of the second Subtext video, Edwards reveals that Subtext is actually about directly manipulating the run-time structure of the code.

This is quite a departure. In fact, isn’t this the problem most people have with recursion? Visualizing and understanding the run-time structure of the code, namely the call stack?

Of course there are a plethora of other interesting benefits to Subtext; editing a run-time graph enables a lot more code sharing and less duplication. In the second video, you can see incredible simplification of refactoring. I’m also surprised at the excellent details of the GUI and how it all hangs together so well. It has all the hallmarks of being created by a great programmer philosopher. An underground hit.

It will be interesting to see what comes of this in the coming years.

Tags ,  | 4 comments

Functional/Object Oriented Evolution

Posted by Daniel Lyons Thu, 04 Oct 2007 02:27:00 GMT

I noticed something interesting the other day about the functional and object-oriented languages.

Consider Python, where you can write functions like:

def foo(first, second=0, *rest, **kwargs):
  return first + second / len(rest) * kwargs['multiple']

Compare to a functional language like Haskell, where you can’t do that, but you can create types like:

data MyThing = YourThing Integer 
             | AnotherThing (Int, Char, Float)
             | NoThing

Weird that in Haskell, a functional language, you don’t get keyword arguments or arbitrary numbers of arguments, but you do in Python, whereas in Python, you’re confined to a rather small set of built-in types or full-on objects.

Of course in Lisp, you get really ornate functions and the ability to make new types through OOP. But you don’t get strong typing. ;)

Tags , , ,  | 2 comments

One More on Haskell

Posted by Daniel Lyons Fri, 28 Sep 2007 09:11:00 GMT

My faith in Haskell has wavered somewhat lately, and all because of Reddit. Essentially, three things:

  1. Haskell’s fixed-point combinator, y f = f (y f).
  2. The ramifications of Haskell’s purity on abstraction.
  3. Haskell’s epidemic academia.

The first is really two problems. One is that the usual definition of the Y-combinator is not itself recursive. Obnoxious. The second problem is that, though it’s beautiful, there are a number of problems that you can’t express in Haskell using the above combinator which you could in an untyped language. This isn’t, apparently, news to anyone but me. I can’t see how to use the above Y-combinator. This is an incredibly academic problem, like most Haskell problems, but it bugs me a little.

The second was elucidated by Peter Van Roy on Lambda the Ultimate’s forum:

“True state lets information pass “underground” between two interfaces, i.e., the information passes without any apparent connection between them. This is because the connection is the shared state, which is shared by the two interfaces yet hidden from the outside. The shared state is a kind of covert information channel: it lets a module pass information to other modules (or to itself in the future) without anybody else seeing it.”

His point has to do with the fact that Haskell’s purity means that in order to get data from some point A to some point B through a number of other modules, each of the intermediate modules will have to carry the information around, even if it doesn’t do anything with it.

I would like to hate that, really, I would. But I can’t, because I programmed Voltaire in a very functional and abstract way in PHP partly because I could count on a handful of global variables passing some state around “underground” between modules that were loosely connected. In particular, Voltaire creates a region context and a template context in which each script is evaluated. The database connection is also shared clandestinely like this. If I were using Haskell, every function in the system would have to take an extra four parameters to get the current region, template, path and database connection, even if it wasn’t going to use it or pass it directly to a child.

It’s easy to denounce. At the same time I feel blameless for having done it, because while the state is “available” to anything beneath, nothing should be changing these variables outside the core. It’s available in a read-only way. Later on I wrote a plugin for rendering templates programmatically, and that involved understanding the inner state, and another plugin for producing lists which also involved understanding the inner state. But languages like Lisp provide interesting semantics for those times when you would want to change the behavior of a global variable safely.

Which brings me back around to Lisp, the language I have paid the least attention to of the four or so that I decided were “safe” so long ago when I started to force myself to use functional programming. And, truly, there are things about Lisp which are hard to love. The principle advantage of Lisp is that it permits you syntactic innovation. It’s certainly the only language that provides it meaningfully (let us not quibble about Lisp/Scheme differences or bizarre languages like Pliant). But doesn’t this seem like the fundamental abstraction of programming languages?

Aren’t we always starting with some problem and selecting a language based on its syntactic abstraction of some part of the problem domain? I mean, I pick Lisp because I want the ability to create my own structures. That comes in handy against every problem domain. But if I want to write a blog, well, Rails makes it a lot easier up front. Maybe I don’t get linguistic abstraction, but the starting abstraction is quite close. Michael chooses REALbasic for application development, I choose Cocoa. Both of us are making certain sacrifices in the name of abstraction. I lose defmacro. He loses the most recent Cocoa innovations. If I pick Lisp for my blog, then I’m sacrificing the fast start. The laziness of later syntactic abstraction had better pay off. The up-front cost is higher. For any given reasonable language, there is going to be a situation in which its abstraction is an up-front benefit that beats the up-front cost of using Lisp.

You see, these languages are compression algorithms. They compress your explanation of how to solve a problem. Like any compression algorithm, there are problems for each language that compress so badly you wind up writing a different language inside the language. This is Greenspun’s law all over again. Lisp wins frequently because it makes it easy to create a sublanguage for a subproblem that compresses it better. Ruby wins frequently because it encompasses most problem domains.

And Haskell wins frequently in academia because academia is interested in representative subproblems rather than complete problems. My experience on the ICFP this past year was that when you give Haskell a pure math problem, it will beat nearly anything else hands-down for both readability and speed. Now sprinkle some I/O on the problem. How about a non-local return? Perhaps a bit of, dare I say it, destructive state? Suddenly you find yourself looking up “monad transformer,” wondering what the hell you got yourself into.

And Justin, G-d bless him, is a Haskell wizard. I can sort of read the code he wrote. My contribution to that code was negligible. I wasn’t much help debugging it. But at the end, we had a performant Haskell version using prominent Haskell performance themes. But it was also 300 lines of code. I remain convinced against any of that pesky proof stuff that an OCaml implementation would have been half the length, more understandable, maintainable and debuggable. I believe Justin came away from the contest with the opposite conclusion: proof, solid proof, that Haskell can be made to attack the kinds of domains that other languages are generally selected for. In other words, his success with Haskell encourages him to use it more, whereas it filled me with doubt.

And today I see on Reddit a link to the paper introducing Haskell Server Pages. Not to the code itself, or the documentation talking about it, or to a page talking about it or some examples, but to an academic paper about it. I write on Reddit that “I have to admit I’m getting a bit tired of seeing things that should be cool Haskell libraries show up as academic papers. It’s as though the whole industry has turned its gaze to Haskell, exasperatedly asking to see something practical, and instead of turning out practical things, the Haskell world turns out academic papers about practical things. “Proof” that Haskell can be used practically is not the same as people using Haskell practically, nor the same as people practically deciding to use Haskell.”

Let’s face it. I really enjoy Haskell in part because of its snobbery, but that’s really a part of what it is. And the posturing about how mind-expanding it is. Haskell is addicted to academia. You’re much more likely to see a paper about some neat library than a neat library. When you go look at the code, it’s untested, only works on one platform, is broken or partially implemented. Academics are not rewarded for having good, useful code. They’re rewarded for writing papers.

Look at the Wash page and tell me who’s going to use this framework. Look at the first four links. Notice these PDFs and PS files are all LaTeX output. What kind of web people would do this? Academic web people.

So here we are. I suppose every language has its vices. I’m particularly drawn to languages that do a lot of posturing, apparently. Beyond that I’m not sure what to conclude. Every language that isn’t pure offal (Java) seems to have a place in the world. It would be better not to get too worked up about it, but it’s probably impossible.

Tags , , , ,  | 1 comment

The Ultimate Act of Hubris?

Posted by Daniel Lyons Fri, 28 Sep 2007 08:59:00 GMT

In a sense, isn’t writing a language in itself the supremely audacious act of intellectual hubris?

“Behold, my language. You want my language so badly, you’re already going to have my language around to compile it in. My language is best for a variety of tasks—for example, see how well it works for that most important and complex of tasks, implementing my language? Don’t you want to use my language for your next project? Especially considering how much effort and hard work I donated to the world, making my language and then implementing it? Bearing in mind as you decide that my language is better than any predecessor language, because it builds on their strengths without their weaknesses? Did I mention my language is a mathematical formalism? Yeah, it is.”

Tags , ,  | 1 comment

Older posts: 1 2 3 ... 6