Thursday, December 22, 2005

Internet Explorer: Bocked!


Internet Explorer's enhanced security configuration just blocked it's own "about:internet" page. No, I'm not making this up, and I didn't Photoshop it ;)

Wednesday, December 21, 2005

Monday, December 19, 2005

Emacs: The Straw that Broke the Camel's Back


I'm a Vim user, but I try to be pretty open minded. I've used Emacs extensively in the past, and in the interest of being flexible, I decided to revisit the Emacs tutorial. I memorized most of it. I originally switched away from Emacs when I was doing PHP programming, and Vim accomodated me better. Having approached Emacs with an open mind (I really would have liked to try it out for six months), these are the things that dissuaded me:

  • The syntax highlighting in Emacs cannot compare to that of Vim, especially in multi-mode files such as Cheetah. Here's a screenshot of Vim. Notice that it's able to handle Cheetah, Python, HTML, and JavaScript all in the same file.

  • I found myself with my pinky permanently glued to the control key when I was editing existing code. Does everyone else ignore the tutorial and use the arrow keys instead of C-[npfb]?

  • I'm stuck with FreeBSD 4.7 in a certain programming environment, and Emacs there didn't come with Python support at all! In contrast, with the exception of brand-new languages like Io, there's a mode in Vim already installed for almost every programming language I've ever used (e.g. Haskell, OCaml, etc.).

  • When committing a CVS file, it didn't make use of my CVS/Template, which is a must for my programming situation.

  • Being compulsive obsessive, it was a bit irritating having a buffer in my buffer list for everything. I far prefer just having a buffer shown for each file that I'm actually editing. I like to permanently close buffers, but this seems to be discouraged in Emacs. I'm sure this is just a matter of workflow, and it doesn't really matter. To be fair, I've customized Vim to show my open buffers along the top, like tabs.

  • The thing that broke the camel's back was when I noticed how nicely Vim syntax highlighted a diff I was reading. I then tried the same thing in Emacs, and it didn't syntax highlight at all. I'm sure it can do it, but it didn't by default.

As an aside, it's fair to say that neither Emacs nor Vim is especially user friendly. That's true. However, for me personally, since I edit text all day, everyday, I'll choose whatever is most powerful for the type of editing I do. Since I do this everyday, the initial learning curve is less important to me.

I'll keep my further comments to myself. To prevent a flamewar, please only respond if:

  • You know at least 20 hotkeys in each editor you're arguing about.

  • You approach the argument with an open mind.

  • You have coded for at least 2 months in each editor you're arguing about.

Wednesday, December 14, 2005

Plone: Some Comments

I built a Web site using Plone. I read "The Definitive Guide to Plone" in order to do so. Along the way, I kept a log of my impressions, which I'll relay here. Most of them are complaints, usually because I've done better in Aquarium for that particular item. However, I should mention that Plone did indeed fill my needs, for which I am grateful. Some of the comments refer to TAL, some to Zope, and others to Plone itself.

  • The lack of elif and else in TAL drove me nuts.

  • In TAL, try to use conditional logic to toggle between a <b> or a <p> tag. The normal way of changing tag attributes won't help you change the tag itself.

  • The slot mechanism in Metal isn't as flexible as normal OO inheritance.

  • Why must the Zope object hierarchy match the inheritance/acquisition hierarchy (which is tied to the URL hierarchy)? I like my URL hiearchy to make sense for users, and for each object, I like to be able to say what it inherits from explicitly. I like for screens in completely different locations to be able to inherit from some other object in a distant location. Fortunately, TAL improves upon this.

  • Metal macros really are macros in that they execute in your namespace instead of taking arguments. This increases coupling.

  • You have to restart the server if you change the translation catalog.

  • Try to use TAL to output some JavaScript, and substitute in a small piece of that JavaScript from a Python string. Not pretty.

Tuesday, December 13, 2005

Haskell: Breadth-first Tree Traversal

As an exercise, I implemented breadth-first tree traversal (instead of the much more common depth-first tree traversal) in Haskell. It took me about 3 hours, mainly because I haven't even finished reading the turorial yet. It really struck me how truly lazy Haskell is! My own language, Squeamish, had lazy evaluation, but in Haskell, you have to somewhat bend over backwards with the imperative stuff to say, "Yeah, really, I'm done defining stuff. Uh, can you actually, uh, do some evaluation or something, and, uh, maybe even print the answer?"
{- Implement breadth-first tree traversal.

Name: Shannon -jj Behrens
Date: Tue Dec 13 03:18:34 PST 2005 -}

module Main where

-- The main definition of a tree.
data Tree a = Leaf a | Branch a (Tree a) (Tree a)

-- Depth-first tree traversal.
depthFirst :: Tree a -> [a]
depthFirst (Leaf x) = [x]
depthFirst (Branch x left right) = depthFirst left ++ [x] ++
depthFirst right

-- Breadth-first tree traversal.
breadthFirst :: Tree a -> [a]
breadthFirst x = _breadthFirst [x]

_breadthFirst :: [Tree a] -> [a]
_breadthFirst [] = []
_breadthFirst xs = map treeValue xs ++
_breadthFirst (concat (map immediateChildren xs))

-- Get the value of a given tree.
treeValue :: Tree a -> a
treeValue (Leaf x) = x
treeValue (Branch x left right) = x

-- Get the immediate children of a tree.
immediateChildren :: Tree a -> [Tree a]
immediateChildren (Leaf x) = []
immediateChildren (Branch x left right) = [left, right]

-- Define some tree.
mytree = Branch "1"
(Branch "2"
(Leaf "4")
(Leaf "5"))
(Branch "3"
(Leaf "6")
(Leaf "7"))

{- 1
/ 2 3
/ \ / 4 5 6 7

Here's another.
mytree = Branch "0"
(Leaf "1")
(Branch "2"
(Branch "3"
(Leaf "4")
(Leaf "5"))
(Leaf "6"))

0
/ 1 2
/ 3 6
/ 4 5 -}

-- Create one "do" out of a list of things to do.
doList :: [IO ()] -> IO ()
doList = foldr (>>) (return ())

-- Main.
main :: IO ()
main = do doList (map putStrLn (breadthFirst mytree))
The result is:
$ runhugs main.hs
1
2
3
4
5
6
7

Saturday, December 10, 2005

Fedora: Sanyo PM-8200 under Fedora Core 4

I'm using my Sanyo PM-8200 with Sprint as a wireless modem under Fedora Core 4 to send this post. I used the instructions here, with the exception that I skipped the "teathered" business, and the name of the device was "/dev/ttyACM0".

I'm pleased to say that it only took me 20 minutes to figure out how to get this to work, which is about how long it took me on my Mac.

Friday, December 09, 2005

Python: GCipher

I gave a talk about GCipher, a simple encryption utility, at tonight's BayPIGies meeting. In it, I cover PyGTK, a simple plugin mechanism, and asyncore. I've posted the slides and source code in case you are interested.

Tuesday, December 06, 2005

Off Topic: Which Character are You?

Which Fantasy/SciFi Character Are You?

Sorry, I couldn't resist posting this.

Sunday, December 04, 2005

GNU screen: A Graphical Replacement

GNU screen is an essential application, yet its learning curve is insanely steep. Even everyday users barely scratch the surface of what it can do due to lack of knowledge. Neither the defaults (e.g. no caption by default) nor the interface (e.g. tons of special key combinations that hopefully don't conflict with your existing applications) make things any easier. I've been thinking a lot about how to improve it.

Imagine what you could do if you were to use a GUI for some cool new version of screen. Now I know that there's a real benefit to the way screen works in that all you need on the client side is a terminal, and I'm sure many a GUI hater will think I'm missing the point of screen. Let's face it though, I do have a graphical desktop. Furthermore, I'm not talking about getting multiple terminals on the local system. Tabbed terminals solve that trivially. I'm talking about multiple terminals running on a remote system that may or may not be prone to sudden HUPs. Ideally, the GUI client could make things a lot more user friendly. Here's how you use screen:
(multiple ptys) <-> screen <-> ssh <-> your terminal
You type commands into your terminal, and screen does something with them. Sometimes the commands influence screen itself. Other times, screen passes them onto the active pty. Now, imagine an improved graphical version of screen. For the time being, I'll call it scrim, SCReen IMproved:
(multiple ptys) <-> scrim server <-> ssh <-> scrim client <-> (multiple GUI terminals, such as gnome-terminal)
Note that you now have 4 windows on the client, the scrim client and the 3 terminal applications. Perhaps you might use a terminal that supports tabs to consolidate the 3 terminals. Since the scrim client has its own window, it can be really easy to use, and there are no keybinding conflicts. The terminal applications each act like separate terminal sessions. A lot of multiplexing is going on between the scrim server and scrim client. There's a "tunnel" for each terminal, and a "tunnel" for the server and client to talk about configuration. Nonetheless, you can still close the scrim client and reconnect later without loosing anything. I'm not really proposing anything new except to say that an interface that's more like Remote Desktop could make using screen a lot more pleasant and reduce the learning curve.

Now, if I only had the time and intelligence to code it :) It makes me wonder how hard it would be to do something like this, writing the client and server in Python. Naturally, the server must be very standard, and there may be multiple clients for say, KDE, GNOME, OS X, etc. Specifically out of scope is dealing with any terminal code myself. Terminals are not for the faint of heart, and I think it's possible to just connect the two pty's and let terminal software do the hard work.

If you know of such an existing application, please tell me.

Friday, December 02, 2005

Haskell: First Class Types

It's interesting that Haskell makes such a big deal about first class functions but does not have first class types. Python does ;)

(Note, I'm not sure it makes a big difference, but I thought it was a humorous observation.)