Clojure.contrib’s logging/spy macro is really useful for quick investigation of bugs with unclear stack traces, and to check that intermediate values in a calculation are being returned and composed correctly. Lazy sequences don’t get logged correctly, however:

> (log/spy [1 2 3 4 5])
[1 2 3 4 5] ;;; prints " [1 2 3 4 5] => [1 2 3 4 5]" to the log
> (log/spy (take 3 [1 2 3 4 5]))
(1 2 3) ;;; prints "(take 3 [1 2 3 4 5]) => clojure.lang.LazySeq@8592" to the log

The spy macro logs a string realization of the sequence per se, rather than its constituents. In the case of a concrete, fully realized sequence such as the literal vector in the first example, all values are known in advance, and the vector’s string realization in the log can helpfully be its actual contents. In the case of the lazy sequence returned by take, however, we get a less than helpful class name and some sort of instance identifier code rather than the actual contents of the sequence. A lazy sequence saves resources by merely promising to provide the values when asked. If they’re never asked for, they’re never computed. Since they haven’t been computed, they can’t be printed. A lazy sequence can also potentially be infinitely long, another good reason why they are not realized by default when converting the sequence to a string.

In our case, we don’t care about the resource usage, and we’re sure the sequence is finite. We want to force all values to be computed for manual inspection. (There are several ways of going about this.) The following modification of the spy macro converts the lazy sequence into a regular seq:

(defmacro lazy-spy
  "Evaluates expr and outputs the form and its result to the debug log.
   If the result is a lazy sequence, it is realized concretely in the log.
   Returns the result of expr."
  [expr]
  `(let [a# ~expr] (log/log :debug (str '~expr " => "
                                    (if (= clojure.lang.LazySeq (class a#))
                                      (seq a#)
                                       a#)))
        a#))

This gives us:

> (lazy-spy  (take 3 [1 2 3 4 5]))
(1 2 3) ;;; prints "(take 3 [1 2 3 4 5]) => (1 2 3)" to the log

Clojure posts you might also like:

Popularity: 23% [?]

Clojure, Log4J, and clojure.contrib.logging can play nicely together. Here’s a reasonable default configuration.

  1. If using Leiningen, add

    :dependencies [
                     [log4j "1.2.15" :exclusions [javax.mail/mail
                                                  javax.jms/jms
                                                  com.sun.jdmk/jmxtools
                                                  com.sun.jmx/jmxri]]
    ]
    

    to your project.clj file and rerun lein deps to auto-install the Log4J JAR.

    If not using Leiningen, acquire a Log4J JAR and put it on your classpath.

  2. Create a file called log4j.properties on your classpath and put the following into it:
    # Based on the example properties given at http://logging.apache.org/log4j/1.2/manual.html
    # Set root logger level to DEBUG and its only appender to A1.
    log4j.rootLogger=DEBUG, A1
    
    # A1 is set to be a ConsoleAppender.
    log4j.appender.A1=org.apache.log4j.ConsoleAppender
    
    # A1 uses PatternLayout.
    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
    log4j.appender.A1.layout.ConversionPattern= %-5p %c - %m%n
    

That’s the short version. Read on for the gory details. Continue Reading »

Popularity: 95% [?]

Why the EU is screwed, from our friends at Der Spiegel:
Why the EU is screwed

Popularity: 4% [?]

Flashing the BIOS without a floppy drive can be done with an Ultimate Boot CD (free!) and a USB memory stick. BIOS upgrades usually come in the form of an MS-DOS executable meant to be run from a bootable floppy, but modern computers don’t usually have floppy drives anymore, and who has a copy of DOS lying around anyway?

  1. Download a copy of the free Ultimate Boot CD and burn it to disk. FreeDOS (and a lot of other useful stuff) is preinstalled on the CD. As the name implies, FreeDOS is a free, open source, binary-compatible replacement for MS-DOS.
  2. Download the replacement BIOS from your motherboard’s manufacturer. Unpack it onto a USB flash drive.
  3. Plug your flash drive into the target computer and boot it with your Ultimate Boot CD. Select FreeDOS from the menu.
  4. FreeDOS asks a number of configuration questions while booting. You can usually leave all at their default except for the ASPIUSB driver. ASPIUSB is not enabled by default (at the time of this writing), but is necessary for the use of a USB flash drive under DOS, so enable it when prompted.
  5. If you miss the prompt for the USB driver, don’t worry. Type “menu” at a command prompt and enable USB devices from the popup menu.
  6. Change to your flash drive by typing e.g. R: and execute the BIOS flash utility as per the manufacturer’s instructions. (If you don’t know which drive letter to use, type “menu” and select the option to display active drive letters.)

Popularity: 17% [?]