Saturday 24 November 2012

Window Peeler

I've said before that AutoHotkey is a great program that every Windows users should have and use. Here's yet another use I found for it to make my (and yours) life easier. Have you ever had two full-screen windows on the same monitor and wanted to switch between them quickly? I encounter that situation regularly. With two or three monitors, I use one in portrait orientation for email and viewing documents, and the others for everything else. To switch between windows, the Task Bar, Alt+Tab and Windows+Tab are great, but when I have 20+ windows open, it can take a fair bit of fiddling and time to switch between email and documents on the same monitor. I wanted a better solution. So I wrote this script (download):

;;;; Window Peeler - Show next window under mouse pointer
#NoEnv ;; Standard prelude
#SingleInstance force
SendMode Input

SetWorkingDir %A_ScriptDir%

;; Pick one of your mouse buttons (XButton1 = Back, XButton2 = Forward, MButton = middle button, LButton = left button, etc.) and use it here:
XButton1::
  MouseGetPos,,, WinId
  WinSet, Bottom,, ahk_id %WinId%
  ;MouseGetPos,,, WinId
  ;WinActivate, ahk_id %WinId%
Return


It moves the window under the cursor to the back when the back button is pressed on your mouse (assuming you have that button). That leaves the next window down on top! The two commented out lines of code activate that window, but I like it without that because it makes the script run quicker. It's a very simple script.

To make it trigger on another combination, for example Control+RightMouseButton, replace XButton1:: with ^RButton:: (^ is for Control).

P.S. Note that mouse software may interfere with the Back and Forward mouse button events. In the Logitech software, I had to set the action for that button to Other: Generic Button.

What do you think? Please leave a comment.

Saturday 17 November 2012

MathP is not CL Standards Compliant

Bad news! MathP, my very own mathematics notation library for Common Lisp, breaks the ANSI CL standard. The problem is that unread-char cannot be called consecutively without calling something that will read a character (like read-char). From the CL Hyperspec page for unread-char:
It is an error to invoke unread-char twice consecutively on the same stream without an intervening call to read-char (or some other input operation which implicitly reads characters) on that stream

I used it to basically peek multiple characters ahead, like peek-char, but for multiple characters. This may be why MathP doesn't work in CLISP. That allows me to have arbitrary operators. For example, I could have the following as distinct operators:
  • * for multiplication
  • ** (perhaps for exponentiation)
  • .* (perhaps for element-wise multiplication, like in MATLAB)
  • *. (dot product?)
  • *.* (perhaps for element-wise exponentiation)
  • etc.

I thought I was being clever, but such a use contravenes the standard pretty clearly. So I'm interested in alternatives. Does anyone know if it's possible to do multiple unread-chars with other stream implementations? Also, can you read lisp from them with standard reading functions?

Tuesday 13 November 2012

Welcome to Seth Frederick Barton Johansen

Welcome to the world, Seth Frederick Barton Johansen! Seth is the son of Tamara and myself. He was born on the 3rd of November 2012, at 12:21 PM EST at the Wesley Hospital. He weighed 2728g (6 pounds), which is a bit small, but just fine. He also got a bit jaundiced (swallowing blood isn't good for you at that age).
 He's now 10 days old, and looking good:


Seth is a biblical name and means "Appointed". Seth was the son of Adam, and is an ancestor to Jesus. He replaced Abel, who was killed by Cain (Genesis 4:25).

He is a little bundle of joy. Good work Tamara (if you're reading this) - you did a great job growing him and giving birth to him - I'm very privileged to be married to you. Thanks Wesley Hospital for supporting Tamara and Seth through labour and the next few days, and to our heavenly father for his blessings, including our first son.
The heart of man plans his way, but the LORD establishes his steps. (Proverbs 16:9)

Also, thanks for the well wishes, hugs, flowers, and gifts everyone. They are lovely and appreciated.

P.S. The Wesley Hospital is a great place to have a baby - I can hardly recommend it highly enough. The staff were very friendly and helpful, and went beyond my expectations.

Saturday 10 November 2012

Some Random Windows Tips


Having used Windows 7 for a while now, I an glad I discovered the Windows Button shortcuts. For me, they save a lot of fiddling with windows. For example, take the Windows+Arrows shortcuts. You may have noticed that it is possible to full-screen (maximise) a window by dragging it to the top of the screen, and to half-screen a window by dragging it to the side of the screen. But if you have multiple monitors, you'll notice that you can't half-screen a window by dragging to the edge of a monitor that abuts another monitor. Do not despair, it's still possible with the Windows+Arrows shortcuts! Here are the basics:
Half-screen a window by dragging it to the left, or pressing Windows+Left.
Moving in the other direction works as well:
Half-screen a window by dragging it to the right, or pressing Windows+Right.
To maximise a window, just press Windows+Up. If you have multiple monitors, you can 'hop' a window around by repeatedly pressing Windows+Left or Windows+Right combination:
Moving a window through all monitors and half-screen positions by repeatedly pressing Windows+Right (or Windows+Left).

Here are some more of my favourite Windows key combinations:
  • Windows+D shows the desktop by minimising all windows (like Windows+M);
  • Windows+E opens an explorer window;
  • Windows+L locks the computer;
  • Windows+Tab does a 3D version of Alt-Tabbing.
Many more shortcuts can be found here. While we're on the topic of Windows, here are some other tidbits:
  • Ever had a window that is off-screen and you can't get it back? To get it back, activate the window from the Start Menu, and then press Alt+Space, then M, then press an arrow key (any will do), then move the mouse. I've used this trick since Windows XP to bring back rogue windows.
  • To run a program quickly from the keyboard, just press the Windows key, then type in the first few letters of your program's name. If you type enough of the name for it to be the first choice in the Start menu, you can press enter to run it.
Got some favourite Windows shortcuts of your own? Let me know it the comments.

Saturday 3 November 2012

MathP and Macros

MathP and macros can be used together a fair bit. I've added a 'math-macro' capability to do custom parsing within MathP input, but you can write macros within MathP (as of version 1.11). I've added direct support for backquote (which has been tested in Corman Common Lisp). Here are some examples of how it all works:

Math-Macro

Macros that use structure in a way that conflicts with the mathematical notation of MathP (that's most macros) can define custom parsing rules. Here's the defun math-macro:
(define-math-macro 'defun (fn (maths)
        (multiple-value-bind (args todo) (parse-argument-list (cdr maths));; Skip name
            (push (car maths) *global-callables*);; Register the function (for recursion and later)
            (multiple-value-bind (body todo) (parse-assignment todo)
                (values `((defun ,(car maths) ,args ,@body)) todo)))))

The above shows that the defun math-macro parses the maths (after the defun symbol) as a name, an argument list and an assignment expression. So input maths of '(defun f (x y) x + y z) would be parsed to a list of one form: (defun f (x y) (+ x y)). The remaining maths (the second return value) would be '(z).

The above also shows how parsing is done in MathP. Note that maths is an argument to parsing functions (including the defun parsing function), and that parsing functions return two values. The first is a list of Lisp forms and the second is the maths remaining to be parsed.

But that's really only useful to give existing macros syntax. Let's dive deeper.

Backquote

As of MathP v1.1, it is now possible to use backquote (including nested backquotes etc.) in MathP. Backquote is used extensively in macro definitions, but can also be used outside of macros. We'll look at backquote first, to lay the foundation for MathP macros. Backquotes in Common Lisp are described in Section 2.4.6 of the Hyperspec. I've attempted to preserve it's behaviour but there are differences. First, a backquoted MathP expression gets wrapped in a progn if it needs it. One potential point of confusion is that in MathP, quote will quote list content without parsing it, but backquote parses content. Here are some examples of the similarities and differences:

#M'a[4]; expands to '(aref a 4)
and
#M`a[4]; expands to `(aref a 4)
#M'(1 2 3+4); expands to '(1 2 3 + 4)
but
#M`(1 2 3+4); expands to `(progn 1 2 (+ 3 4))

Backquote inside MathP

Firstly, a math-macro has been defined for defmacro. It has the same syntax as the defun math-macro. Here's a definition of aif like from On Lisp:
#Mdefmacro aif(test then &optional else) `(it=,test if it ,then ,else)

To include a documentation string, just put it and the body into brackets:
#M{defmacro aif(test then &optional else)
   {"Anaphoric if defined in MathP"
    `(it=,test if it ,then ,else)}}


It's also possible to nest backquotes, but writing a macro with nested backquotes is left as an exercise for the reader.

MathP inside Backquote (Backquote across Lisp and MathP)

I've found that the handling of backquote in Corman Common Lisp doesn't make it possible to consistently backquote a form in Lisp, and unquote something inside it from MathP. If you have a better result in another implementation, please leave a comment. For example (and please excuse the contrived-ness):


(defmacro make-more-func (number) `(lambda (n) #M n+,number))