Archive for October, 2009

Better draw code (with bitmaps and lines)

Friday, October 16th, 2009

Here is a better version of the drawing code, with Adria’s bitmap contribution (which should help with the unwanted window-clearing on some systems and also make the window redraw when resized, etc.), some enhancements that I made to the bitmap code because it wasn’t working right with iterative drawing, plus two other changes:

  • A “line” procedure to draw a line that takes 9 arguments — x1 y1 x2 y2 width r g b a — and draws a line from (x1, y1) to (x2, y2) that’s width pixels wide, with color red=r, green=g, blue=b, and transparency alpha=a.
  • I changed the name of “make-window” to “show-window” because that’s really what it does.

Here it is: better-draw

Let me know if you have any problems with it.

A Scheme “while loop”

Thursday, October 15th, 2009

There was a question in class about whether Scheme has an iteration construct like the “while loops” of other languages, in which there is a condition and a body and the body is executed repeatedly until the condition becomes false. I showed how to do this using “do”, but noted that it was a little awkward because you have to specify an empty variable list, the negation of the condition, etc. I also said that one could define a syntax transformation that would give you a real, more natural “while.” Here’s a version of what I was talking about:

(define-syntax (while stx)
  (syntax-case stx ()
      ((_ condition expression ...)
       #`(do ()
           ((not condition))
           expression
           ...))))

If you haven’t previously seen “define-syntax” then this will look quite odd, but you can use it without understanding it. Just include it in your code and then you can do something like this:

(define x 0)

(while (< x 5)
       (printf "~A\n" x)
       (set! x (+ x 1)))

That will print:

0
1
2
3
4

The first thing after “while” is the condition. It will be evaluated and if it is true (producing anything other than #f) then everything else in the expression will be evaluated. Then the condition will be evaluated again and, if it is true, it everything else in the expression will be evaluated again. And so on, until the condition evaluates to false (#f), at which point the whole “while” expression will be done (and won’t return anything).

modification of lee’s drawing code

Thursday, October 15th, 2009

It works exactly the same in terms of what you do, except that it works smoothly on all platforms (e. g. , it will not clear when you resize on a Mac.)

Attached is the modified file. Now go have unlawful fun, y’all!

leesdrawing

Simple loops in Scheme

Saturday, October 10th, 2009

After that post on memoization, which used very fancy features of Scheme, I thought I’d post some answers to questions I’ve received on much less fancy stuff, for creating iterative (non-recursive) loops in Scheme. Here’s about the simplest kind of iterative loop:

(for ((x (in-range 3 12)))
 (printf "~A\n" x))

The thing after the variable name can be anything that produces a sequence or list, so this also works:

(for ((x '(fee fi fo fum)))
 (printf "~A\n" x))

Those loops just execute their bodies for “side effects,” but there are related procedures that will return a result of all of the looping, like:

(for/list ((x (in-range 3 12)))
 (* x 2))

This returns a list of whatever was returned from each time through the body of the loop.

“for” and friends can also loop over more than one variable at a time and do some other somewhat fancy things. The “do” procedure is sort of the most powerful variant of all of these, making it easy (among other things) to leave the loop whenever a condition is met, instead of keeping going through as many times as indicated at the beginning. Because of its generality the syntax is also a little confusing at first, but here’s a fairly simple example:

(do ((car1-position 0 (+ car1-position 5))
     (car2-position 100 (- car2-position 4)))
  ((> car1-position car2-position)
   (printf "Crash detected, Car1: ~A, Car2: ~A\n"
           car1-position car2-position)
   (abs (- car1-position car2-position)))
  (printf "Cruising along, Car1: ~A, Car2: ~A\n"
          car1-position car2-position))

Other procedures that loop in some sense, and that are worth checking out, are “map” and the various versions of “fold”.

-Lee

Memoization

Friday, October 9th, 2009

In class I talked about “memoization” as a strategy for improving the efficiency of recursive functions like the Fibonacci function we were experimenting with. The idea is to store each value as you calculate it, so that later calls with the same arguments can immediately return the previously calculated value instead of re-calculating it. In the half-implemented version we produced in class the previously calculated values were stored in a list with the value for argument 1 being in position 1 of the list, the value for argument 2 being in position 2, etc. But a more general strategy is to store pairs of (argument value) so that calculated answers can be added to the “memo” in arbitrary order,  so that you can memoize functions that take arguments other than positive integers, etc.

Scheme allows us to abstract this idea in a particularly powerful way. Using the definition of memoize provided below — which uses some fancy stuff that we haven’t covered in class — one can first define fibonacci in the totally normal, non-memoized way, and then do this:

(set! fibonacci (memoize fibonacci))

Henceforth fibonacci will be memoized, meaning that it will first check to see if it has previously calculated the answer and return the previously-calculated answer if it has. If it hasn’t then it will calculate it from scratch (but using any previously-calculated answers that it needs in its recursive calls) and store the new value (and return it).

To try this out first use my definition of memoize:

(define memoize
  (lambda (f) ;; returns a memoized version of function f
    (let ((memo '()))
      (lambda args
        (let ((match (assoc args memo)))    ;; look up args
          (if match
              (cadr match)                  ;; return stored value
              (let ((value (apply f args))) ;; or calculate if necessary
                (set! memo                  ;; and store new value
                      (cons (list args value) memo))
                value)))))))

Then define fibonacci in the ordinary, unmemoized way that most directly reflects the way we describe the function in English:

(define fibonacci
  (lambda (n)
    (cond ((< n 2) 0)
          ((= n 2) 1)
          (else (+ (fibonacci (- n 2))
                   (fibonacci (- n 1)))))))

Now if you test this version without memoizing, using “time” to see how long it takes, you get something like:

> (time (fibonacci 30))
cpu time: 500 real time: 518 gc time: 0
514229

But if you add the following after your ordinary definition of fibonacci:

(set! fibonacci (memoize fibonacci))

Then you get:

> (time (fibonacci 30))
cpu time: 0 real time: 1 gc time: 0
514229

And you can easily go up to inputs of many thousand now.

Some improvements that someone might want to make to my memoize function: 1) It already works for functions that take any number of arguments, but make it work for functions that return any number of values (something we haven’t yet covered), 2) Make it use a more efficient memo data structure, like a hashtable.

BTW my idea for this was based on Paul Graham’s similar function in Common Lisp, but the Scheme version is pretty different.

-Lee

Update: I had a bug in the fibonacci definition in my first post of this, (= n 3) instead of (= n 2); I’ve fixed it and rerun the timings.

code-immersion software overview (part 2) — architecture

Thursday, October 8th, 2009

This post will talk about the general architecture of the code-immersion system. That is, it will give a general idea of how all the parts interact with each other, which should elucidate how the entire system works. Read the rest of this entry »

Vectors, Lines, and Fun Shapes

Thursday, October 8th, 2009

Built off Lee’s basic graphics code, a couple of procedures, to create vectors, lines, and some fun shapes/patterns.

Run with (sunBurst)

if you want check out (line) and (sunRay) I will warn you it’s completely uncommented

—> vectors-lines-and-fun.ss <—

code-immersion software overview (part 1) – package files

Tuesday, October 6th, 2009

Also posted to my personal blog at http://ianmcorvidae.net/

This post will go through each of the files of the code-immersion package and describe their function within the package. Files are in no particular order, but hopefully hopefully minimal things will rely on stuff described in files later in the list. Read the rest of this entry »

Some simple drawing code

Tuesday, October 6th, 2009

Here’s some simple code for drawing shapes in a new window.

-Lee

Dice roller for combat sim

Tuesday, October 6th, 2009

so apparently I’m not the only one doing one, so to make some of your lives easier, here’s the dice roller:

#lang scheme

(define gigadice
(lambda (sides quantity)
(cond
((zero? quantity) ‘())
(else
(cons (+ 1 (random sides)) (gigadice sides (sub1 quantity)))))))

It’s actually really simple–it’s just a random number generator and a recursive call.