Saturday 29 September 2012

Simple Error Handling in Lisp

Yup, simple error handling in Lisp. Lisp has a really powerful condition/error handling system (also known as it's condition system). We won't delve into that here. This post was actually inspired by MS Excel (I use MS Excel a lot at work). There's an iferror function that may be used in spreadsheet formulae. It is entered into a cell like so:
=IFERROR(1/0, "failed")
In the above formula, because there is an divide by zero error in the first argument, iferror returns the second argument instead. It's simplicity means it's easy to use and understand.

To replicate this behaviour in Common Lisp is fairly easy. I've included it in MathP. Here's the definition as a macro:
(defmacro iferror (try fallback)
    `(handler-case ,try (error () ,fallback)))
Using it is just as easy as in Excel:
(iferror (/ 1 0) 'failed)
I hope the above code is useful to you; Use it however you want. I accept no responsibility for problems arising from it's use. If you do find it useful, I'd be tickled pink to hear from you.

Do you know of a similar macro? Please leave a comment.

Saturday 22 September 2012

If you use Windows, please use AutoHotkey

AutoHotkey is a powertool for Windows. It is one of my indispensable tools. I can hardly praise it highly enough. I use it for many things. I have used it to make using Windows less painful, and coding Lisp easier. Here are a few samples of AutoHotkey I use it to:

Make Caps Lock type hyphen (-) instead (I use hyphen a lot - you can make it do what you want):
SetCapsLockState, AlwaysOff

Swap brackets to my liking. Once I started programming Lisp, I quickly realised that round brackets should be easier to type. I've swapped ( and ) with [ and ]. I've also made the closing brackets get typed in when you type one of the opening brackets: (, [, or {. This one was the whole reason I started looking for something like AutoHotkey. Nothing else I've found can do this on Windows.
; The dollar signs stop the hotkeys from going into an infinite loop.
$[::Send (){left}
$]::Send )
$(::Send []{left}
$)::Send ]
$+[::Send +[+]{left}

Shorten some git workflow shortcuts (for example, typing gst then Enter is equivalent to typing git status then Enter):
SetTitleMatchMode 2
#IfWinActive, MINGW32:/
::gco::git checkout
::gcom::git checkout master
::gds::git diff --stat
::gdi::git diff
::gpu::git push -u
::gmm::git merge master
::gst::git status
::gct::git commit
::gcta::git commit -a

These and some other bits of AutoHotkey are packaged into a single script here.

I hope the above and linked script is useful to you; Use it however you want. I accept no responsibility for problems arising from it's use, but if you do find it useful, I'd be tickled pink to hear from you.

Saturday 15 September 2012

MathP Examples

MathP is my Maths DSL for Common Lisp. Here are some examples of it in use. If you want to run these examples, don't forget to either use MathP (use-package '#:mathp), or qualify uses of fn as mathp:fn. Here we go:

In simple calculations. The REPL becomes a very powerful calculator:
#M dt=6 v=9 nl=2 v/dt*3600d0/nl
I appreciate brackets, but I also find it a lot quicker to write these kind of expressions at the REPL.

Here's the choose function:
#M(defun choose (n k)
   {assert(integerp(n) && integerp(k) && n >= k >= 0)
    result = 1
    #L(loop for i from 1 to k do #M result *= (n-k+i) / i)

Note the use of logical and (&&) as well as chained comparisons in the assert expression. I've also used the mutating assignment operator *=. MathP also contains +=, -=, /=, ^=, &= and |= (the last two perform logical and/or, not bitwise and/or).

To calculate normal distributions with closures:
#M e = exp(1d0)  scale = 1/sqrt(2*pi) #L
(defun normal-distribution (mean stdev)
    #M fn(x) scale/stdev * e^-(0.5d0*(x-mean)^2/stdev^2))
In the above, we use #L to read in a lisp form from within the MathP form. The top level of the MathP form with the #L would normally stop reading at the end of the line, but the lisp reader invoked by #L conveniently consumes it for us.

And to test the above normal distribution calculator:
(loop with dist = (normal-distribution 0 1)
      for x from -3 to 3.1 by 0.2
    do (format t "~&~4,1F ~A~%" x
               (make-string (round #M 40 * #!dist(x))
                            :initial-element #\=)))

The #! above is a syntax for funcall, where the actual function call looks like a normal function call in MathP.

And one last one, the binomial probability mass function:
#M defun binomial (p n k) choose(n k) * p^k * (1-p)^(n-k)

Sunday 9 September 2012

MathP: Math notation in Common Lisp

MathP is my attempt at adding mathematical notation to Common Lisp.

Lisp has a beautiful, eminently grokkable syntax (if that even makes sense). It's great for general programming, macros and getting stuff done. Another of it's strengths is creating domain specific languages (DSLs). If you've tried to write more than basic mathematics in Lisp, you'll no doubt have wanted to write things like x+y*z or a*x^2 + b*x + c. I think many people who have just learned Lisp coming from other Algol style languages miss that expressiveness. They, like me, probably wanted a mathematics DSL. Well, now you've got one. MathP lets you write the above expressions within Common Lisp. MathP is a mathematics DSL.

MathP syntax attempts to retain a lot of the existing syntax of Common Lisp, while providing infix operators for mathematical notation. As a bonus, MathP syntax for function calls is vaguely similar to M-expressions, and there is a rudimentary macro system. More detail, including several examples, can be found in the documentation.

MathP is released under a BSD licence. It's been tested in Corman Common Lisp (on Windows).

[Edit: updated to version 1.1 - Support for backquote et. al.]
MathP Source Code
MathP Documentation (PDF) (original ODT)

To use it, download the source then load it with a call to load, something like this:
(load ".../path/to/MathP.lisp").

Here are some examples to try out (more can be found in the documentation and in the tests at the end of the code):
  • #M area := length * width
  • Positive root for a quadratic: #M x := (-b + sqrt(b^2 - 4*a*c)) / (2*a)
  • Local function and shared syntax: #M f(x)=x^2+1 mapcar(#'f '(1 2 3 4))
  • Factorial: #M defun fact(n) if n<=1 1 n*fact(n-1)
  • Naive Choose: #M defun choose(n k) fact(n)/fact(k)/fact(n-k)
  • Recursive Choose: #M defun choose(n k) {k=min(k n-k) prod(i res)=if i>0 prod(i-1 res*(n-k+i)/i) res  prod(k 1)}

Welcome to Metalight!

Welcome to Metalight. I will be posting some thoughts centred around programming (mostly with Common Lisp, but also AutoHotkey), mathematics, and God. I hope you enjoy, and find the coming posts interesting and informative.

I chose the name of this blog (Metalight, i.e. meta-light) because light is a great metaphor for understanding. If light is shed on a topic, it can be understood and obstacles may be navigated. If no light is shed on a topic, it is very difficult to understand, and when problems arise, it is hard to tell what the problems are. I want to shed light on these topics.

Whoever loves his brother abides in the light, and in him there is no cause for stumbling.
1 John 2:10

P.S. Please check out my links page.