Friday, November 24, 2006
Avoiding skipping audio in Debian etch with a 2.6 kernel
I'd had problems with audio skipping whenever I did something that required a
CPU-intensive repaint in X11. Most often, it was switching to and from Firefox.
Avoiding audio skipping in Linux
2.6
was right on the money. However, I'm following Debian testing (etch) and the
xserver-common package no longer exists. After a bit of poking around, it
appears that it's been renamed to x11-common, so the magic incantation on etch
is dpkg-reconfigure x11-common and setting the nice setting to 0.
Saturday, November 11, 2006
A Simple RPN Calculator in Haskell
Of late I have been playing around with Haskell, a pure functional programming language. Last night I hacked up a quick RPN calculator and was pleasantly surprised at how easy it was. Example usage: (Note that because the stack is implemented as a list, the top of the stack is the first element of the list)
> 5 4 * [20.0] > 14 [14.0,20.0] > * [280.0] > 2 * 48 - [512.0] > log 2 log / [9.0] > 2 [2.0,9.0] > swap [9.0,2.0] > ** [512.0] > 2 * sqrt [32.0]
Here's the code:
import Char import IO type RPNNumber = Double type Stack = [RPNNumber] type Operator = (Stack -> Stack) parse :: [Char] -> [Operator] parse = map parseOp . words binaryOp :: (RPNNumber -> RPNNumber -> RPNNumber) -> Operator binaryOp f = (\ (a:b:stack) -> f b a : stack) unaryOp :: (RPNNumber -> RPNNumber) -> Operator unaryOp f = (\ (a:stack) -> f a : stack) parseOp :: [Char] -> Operator parseOp "+" = binaryOp (+) parseOp "-" = binaryOp (-) parseOp "*" = binaryOp (*) parseOp "/" = binaryOp (/) parseOp "**" = binaryOp (**) parseOp "log" = unaryOp log parseOp "sqrt" = unaryOp sqrt parseOp "dup" = (\ (x:xs) -> x:x:xs) parseOp "swap" = (\ (a:b:xs) -> b:a:xs) parseOp "pop" = tail parseOp number = (\stack -> (read number) : stack) eval :: Stack -> [Operator] -> Stack eval = foldl $ flip ($) repl :: Stack -> IO () repl stack = do putStr "> " hFlush stdout line <- getLine newstack <- return $ eval stack (parse line) putStrLn $ show newstack repl newstack main = do repl []
That's only 42 lines of code, 25 without the optional type declarations and whitespace. The structure is pretty simple: A stack is a list of numbers, an operator is function that takes a stack and returns a new stack. The "parser" just splits a string into words and the maps each of those words to an operator.
binaryOp and unaryOp are helper functions that take functions and make them into operators. parseOp takes a string an returns the appropriate operator. Or, if its argument isn't recognized as an operator, parseOp assumes that it's a number and returns an operator that pushs it onto the stack.
The only function I'll admit to golfing is the "eval" function. Originally, I had it defined as:
eval stack [] = stack eval stack (f:fs) = eval (f stack) fs
I kept thinking, "that really looks like a fold". The next step was:
eval = foldl (\stack f = f stack)
And from there it was simple to realize that all I had to do was flip the function application operator:
eval = foldl $ flip ($)
Friday, November 03, 2006
Opening a query window quickly in Enterprise Manager
Enterprise Manager has some handy keyboard shortcuts, but I couldn't find any keybindings to quickly open a query window for the selected table. Enter AutoHotkey, a free, featureful keyboard mapping utility for Windows. Here's the stanza to bind Win+o to open a query window without the useless Diagram and Gird panes and fill in "WHERE" for me:
; Open a query in enterprise manager
#o::Send {AppsKey}oq^1^2{PgDn}{End}{Enter}WHERE{Space}
AutoHotkey can do a lot more than simple rebinding, so be sure to check it out if you have to use Windows for any significant amount of time.