We can answer on question what is VPS? and what is cheap dedicated servers?

October 2007

Prism

I’ve seen talk of MS Silverlight and Adobe AIR. People talk them up like the future of web applications or something. I don’t know much about them, but I almost completely certain I don’t want anything to do with them.

Here’s a general rule I have: I don’t accept anything made by people who hate the web. If you hate the web and you want to improve the web, I don’t want anything to do with you. If you think the web is some kind of implementation detail then I probably don’t care what you are doing. If you still think the web is a fad, then you are just nuts; if all you can think of is reasons why the web is stupid and awkward, and you think it’s some giant step backward (from what?), then you haven’t thought very deeply about what’s happened in the world of technology and why.

To me Silverlight and AIR reek of a distaste for the web.

So it is with great delight that I read the announcement of Mozilla Prism: a bridge between the desktop and the web, written by people who don’t hate the web.

The premise of Prism from what I can tell is this: to make a web application into a desktop application, you just give the browser a shallowly separate identity. It lives in its own window, has its own icon, it’s own launcher. Maybe runs in its own process for reliability. You take away the chrome (URL bars, back button, etc). Unlike previous ideas for Mozilla (like xulrunner) you don’t add chrome back in with XUL, you just write all the controls with HTML and Javascript.

All the things that Prism isn’t is what makes it great, because it’s so damn simple. The only thing that really seems weird to me is that it is very separate from the browser itself; hopefully this is just temporary, and by the time it’s really "done" you’ll be able to just make any page an application directly from Firefox.

This doesn’t make web applications perfect, of course. There’s the offline issue. There’s usability issues, like keybindings. There’s lots of issues, but all of those issues apply just as much to the web as to a desktop application, and should be solved both places. Those things can be worked on orthogonally (most interestingly in Web Forms 2.0 and Web Applications 1.0 at WHAT-WG). Still, HTML and Javascript right now are totally workable for most applications.

Javascript
Web

Comments (18)

Permalink

Logo

So Logo is 40 years old. I’ll take this as an opportunity to talk about Logo-the-language (as opposed to Logo-the-graphics or Logo-the-educational-experience). It’s a much better language than most people appreciate.

Logo is Lisp. It’s an old Lisp but it’s very Lisp. Let’s look at a classic example:


TO square :size
  REPEAT 4 [FD :size RT 90]
END
 

This translates to something like this (in Scheme):


(define (square size)
  (repeat 4 (lambda ()
             (begin (fd size)
                    (rt 90)))))
 

Well, technically it translates to this:


(define (square size)
  (repeat 4 '(fd size rt 90)))

That is, [...] is a quoted list; nothing inside it is evaluated. This is actually a lot like Tcl:


proc square {size} {
  repeat 4 {
    fd $size
    rt 90
  }
}
 

In Tcl {...} is just a string literal, but one without substitution, and where you can nest your braces. It’s a lot like a quoted list in Lisp, except where lists are the fundamental type in Lisp, strings are the fundamental type in Tcl.

To get an idea of how this works, here’s the implementation of repeat in these different languages:


TO repeat :count :block
  IF :count > 0 [EVAL :block
                 REPEAT (:count - 1) :block]
END

(define (repeat count block)
  (if (> count 0)
      (begin (block) (repeat (- count 1) block))))

proc repeat {count block} {
  while {$count > 0} {
      uplevel 1 $block
      set count [expr {$count - 1}]
  }
}
 

Tcl doesn’t really encourage recursion, and it’s only partially encouraged in Logo — some implementations implement tail call optimization, but not all of them.

Scoping is an interesting difference here. In Scheme the scoping is lexical, which is the norm in modern languages. That is, any variables you refer to in a lambda (like size in the example) are bound according to where in the source you define that anonymous function. In Tcl the uplevel statement says to evaluate the block in the calling scope. In Logo it’s all implicit because Logo is dynamically scoped. That is, each function call inherits all the variables from the calling function. So you can write something like this:


TO house :size
  square
  FD :size
  RT 60
  triangle
END

TO square
  REPEAT 4 [FD :size RT 90]
END

TO triangle
  REPEAT 3 [FD :size RT 120]
END
 

Here :size is inherited in called functions. You can write some really bad code using dynamic scoping, with lots of magic side effects, but Logo isn’t meant for writing large programs so it usually doesn’t come up. A nice side effect of dynamic scoping is that EVAL works pretty well.

Another interesting aspect of Logo (and Tcl) is that it has very few special forms. In one of Logo’s more pure implementations the only special form is TO, and even that wouldn’t have to be a special form (there’s a function DEFINE that does the same thing). For instance, here’s how you set a variable:


MAKE "variable <value>

That is, you call the function MAKE, give it a variable name, and then a value. Some dialects allow MAKE :variable <value>, but some like UCBLogo actually interpret that to mean: set the variable named by :variable.

Another interesting aspect of Logo is how it handles parenthesis. You’ll notice there aren’t many. Lisp is known (and oft criticized) for its parenthesis. Logo shows they aren’t strictly required; it
does this by using the arity of functions to inform parsing. An example:


SETXY ABS :x :y
 

The equivalent Scheme:

(setxy (abs x) y)

If you know that SETXY takes two arguments, and that ABS takes one argument, you can figure out how to parse the Logo. Comparing it to Forth is kind of interesting:


y @ x &#64; abs setyx
 

Reverse the order, replace @ with :, and you have Logo. @ and : also share a lot in common: :variable in Logo is syntactic sugar for THING "variable (symbols in Logo are spelled "symbol, like 'symbol in Scheme, #symbol in Smalltalk, or :symbol in Ruby). THING "variable tells Logo to look up the value associated with the given symbol. Similarly in Forth, y refers to an address, and @ says to lookup the value at that address.

But back to parsing – Forth is based on trust and foreknowledge. You know that abs pops one thing from the stack, and setyx pops two things from the stack. You trust those words to act that way, because there’s nothing stopping them from popping more or less from the stack than they claim. Logo isn’t quite as trusting, but it does see that SETXY takes two values, and grabs two values. In the same way in the first example, when it sees [FD :size RT 90], it can tell that it’s two commands — newlines aren’t required.

One awkward part of this lack of parenthesis is that without knowing what functions you are referring to the expressions can’t be trully parsed. As a result most Logos are really interpreters. If anyone cared enough of course you could optimize this considerably, and maybe some of the more performant Logos like StarLogo or NetLogo do, but I don’t really know. PyLogo is pretty naive about it, and it’s not that fast as a result (but not terrible).

And of course I should take a chance to plug PyLogo, which runs Logo from Python, and lets Logo code easily call Python, and vice versa. Just easy_install PyLogo and you can run pylogo --console to amuse yourself with the language (the docs from UCBLogo might be helpful, and PROCEDURES shows all the functions, while HELP "IFELSE will show the help for a particular command.

Another related language is Rebol, which is very close to Logo without the turtles (though with a bunch of new literals and object-oriented features as well). Many things called Logo are just turtle graphics with an extremely poor "language" bolted on in front. Don’t be fooled! On the web Turtle Tracks is one of the more true implementations (though I can’t get graphics, hm).

Programming

Comments (8)

Permalink

Workingenv is dead, long live Virtualenv!

A lot of people have found workingenv useful, but it’s always been a bit fragile. If you’ve seen the .../site.py is not a setuptools-generated site.py; please remove it. message, you know what I mean.

For a while I tried to refactor and improve workingenv, but it didn’t go very well. So I decided to ditch it completely and revisit the ideas of virtual-python.py. That script works by copying the Python executable, and in doing so change sys.prefix — it’s pretty consistent that all other paths in Python derive from sys.prefix.

The result is virtualenv, which I think is now featureful enough for general use. It might still be buggy, but it’s worked well for some of us, and I expect the bugs to all be much easier than they were in workingenv.

Unlike virtual-python.py, virtualenv works on Windows and in the latest release also Mac framework builds. It also handles site-packages better, so you can manage some of your packages using packages from your OS distribution (e.g., debs or rpms), while also installing environment-local packages.

So, in summary: use virtualenv, don’t use workingenv. And if you were using the --requirements option to workingenv, the package PoachEggs lets you do a similar batch installation after you’ve created the environment.

Python

Comments (33)

Permalink