Responsibility Begins Here - Hmmmm.

“Responsibility Begins Here” is DOW chemical’s slogan.

From this week’s Harpers weekly:

Gardeners across Britain were reporting a harvest of deformed, dangerous vegetables, traced back to the Dow AgroSciences herbicide aminopyralid, which can wind up in manure. It was “scandalous,” said a woman with a patch near Bushy Park in London, “that a weedkiller sprayed more than one year ago, that has passed through an animal’s gut, was kicked around on a stable floor, stored in a muck heap in a field, then on an allotment site and was finally dug into or mulched on to beds last winter is still killing ’sensitive’ crops and will continue to do so for the next year.”

Hmmmm.

Comments

Announce: geohash version 0.1.0

I came across geohash.org while browsing the Semantic Web last night. This site uses a simple latitude/longitude encoding to convert locations into short strings. Here, for example, is the URL for my house.

http://geohash.org/drs3nbcszvze

The nice thing is that strings with common prefixes are geographically close to one another. I saw that there were several ports of the algorithm to Ruby, Perl, PHP, etc. but no Common Lisp love. The geohash system on Common-Lisp.net fixes that! Enjoy

Comments

Announce: simple-http version 1.2.0

Simple-HTTP is a fork of Brian Mastenbrook’s trivial-http. If you need a serious HTTP client with all the trimming, you should look at Edi Weitz’s Drakma. On the other hand, if all want is a some basic HTTP support and don’t want to deal with lots of other dependencies, then simple-http may be something that meets your needs.

(P.S., the website needs a bit of love… Well to be honest, all my websites need some work but simple-http’s needs tough love!).

Comments

what does it mean about the human condition that…

The domain “sadlyno” is taken (both .com and .net) but the domain “happilyyes” is wide open…?

Comments

mega-multi-touch for me!

Scientific American has a (breathless, but only slightly) report on multi-touch technology (think iPhone but big and with lots of hands touching at once).

A wall-size screen developed by Perceptive Pixel can respond to as many as 10 fingers or multiple hands. Microsoft and Mi tsubishi are offering smaller, specialized systems for hotels, stores, and engineering and design firms.

I’ll take five!

Comments

And this makes sense because…

I learned today that toasters are also audio and video accessories.

toasters.png

Thanks Amazon! Who would have guessed?

Interesting, I also learned (on the same page) that the Panisonic Microwave oven is a toaster and that 2 stars is higher than 3.5 stars which is higher than 3 which is higher than 5.

sort-by-reviews.png

(note that I am sorting by review score here…).

What’s up with that?!

Comments

announcing: metatilities-base and lift

Doing some more cleanup; the biggest improvement is that lift:with-timeout is now supported in SBCL with and without threads. The non-threaded version uses timers; I like ‘em.

  • metatilities

    • moved file-newer-than-file-p from here to metatilities-base

    • did a whole bunch of symbol unexporting and exporting between here and metatiliites

  • metatilities-base (0.6.3)

    • added pathname-samep and moved file-newer-than-file-p from metatilities to metatilities-base.

    • did a whole bunch of symbol unexporting and exporting between here and metatiliites

  • lift (1.5.0)

    • improved while-counting-repetitions and while-counting

    • implemented with-timeout for SBCL without thread support (yeah!)

    • added errorp argument to find-testsuite and find-test-case

Enjoy.

Comments (1)

Watching Juno

I am so in love with Ellen Page. J. K. Simmons too!

Nice movie too. The writing is wonderful though a bit precocious for any real 16-year old.

Comments

let me count the (number of) ways

When benchmarking, it is all too easy to use the Common Lisp [time][time] macro to see how long something takes. For example,

(time (dotimes (i 1000) (do-my-function)))

There are at least two problems with this simple approach. Firstly, time doesn’t make it easy to record the values it computes; secondly, if your function is very fast, you may end up timing how quickly your lisp execute dotimes rather than measuring what you want. A better way to approach this sort of question is to ask “how many times can I execute my function in, e.g., 5-seconds?” The only downside of this approach is that it takes a little more code to set things up. Once you have the code, however, Bob is your uncle. [LIFT][] includes a small (and sadly under-documented) selection of functions and macros to help you benchmark and profile your code. Two of these are:

(defun count-repetitions (fn delay)
  "Funcalls `fn` repeatedly for `delay` seconds. Returns
the number of times `fn` was called. Warning: the code
assumes that `fn` will not be called more than a fixnum
number of times."
   ...)

and

(defmacro while-counting-repetitions ((&optional (delay 1.0)) &body body)
"Execute `body` repeatedly for `delay` seconds. Returns
the number of times `body` is executed per second.
Warning: assumes that `body` will not be executed more
than a fixnum number of times. The `delay` defaults to
1.0."
  ...)

The main difference between the two variants — well, aside from one being a macro and one a function — is that count-repetitions must funcall your function whereas while-counting-repetitions includes your code in-line.

Let’s use them to look at three different solutions for the perennial “I want to turn a string into a keyword” problem. I’m also going to require that all of the strings be lowercased (just because). One solution uses read-from-string

(defun form-keyword-1 (name)
  (read-from-string (format nil "~(:~A~) " name)))

another uses intern. We’ll look at two variants: the first looks up the keyword package each time; the second does it just once:

(defun form-keyword-2a (name)
  (intern (string-downcase name) (find-package '#:keyword)))

(defun form-keyword-2b (name)
  (intern (string-downcase name)
    (load-time-value (find-package '#:keyword))))

Lastly, let’s see if there is any cost to calling intern unnecessarily by adding a variant that first uses find-symbol and only calls intern if it must.

(defun form-keyword-3 (name)
  (let ((downcased-name (string-downcase name))
        (keyword-package (load-time-value (find-package '#:keyword))))
    (or (find-symbol downcased-name keyword-package)
        (intern downcased-name keyword-package))))

Here’s what it looks like to try a simple test. We’ll use 5-seconds as our delay.

cl-user> (lift:count-repetitions
           (lambda () 
             (form-keyword-1 "hello")
             (form-keyword-1 "butter")) 
           5.0)
57214.8

So form-keyword-1 (the read-from-string variant) can run about 57,000-times a second (this is under ACL in EMACS under Slime). The other three variants give counts of:

          ACL        SBCL
 1:    57,215      37,354
2a:   689,888     329,896
2b:   986,085     447,137
 3: 1,028,928     461,868

(Note: I’m using a somewhat out of date SBCL so these numbers shouldn’t be used to compare these two Lisps).

That’s a pretty huge difference on both of these Lisps. Allegro especially benefits from the load-time-value resolution of the keyword package and both Lisps should a slight improvement when calling find-symbol first (which actually surprised me. I would have thought that intern would have handled that logic already.)

Now lets see if funcalling is doing anything to change the results by switching over to the while-counting-repetitions macro:

cl-user> (lift:while-counting-repetitions (5) 
           (form-keyword-1 "hello")
           (form-keyword-1 "butter"))
57633.6

Here’s the table

          ACL        SBCL
 1:    57,634      37,960
2a:   686,941     328,316
2b:   992,373     451,186
 3: 1,050,546     448,714

In this example, at least, the macro and the function appear to have no advantages one over the other.

Comments (2)

Announcing: versions that go bump in the night

CL-Containers and dynamic-classes have both been updated:

  • CL-Containers (0.10.2) sees a patch for insert-new-item from Daniel Dickison (thanks!) and some minor tweaks and one new test case.

  • dynamic-classes (1.0.1) sees an actual (though sadly empty) test-system. It feels much better not being saddled with one cut and pasted from LIFT.

Enjoy!

Comments

« Previous entries ·