?

Log in

No account? Create an account

t3knomanser's Fustian Deposits

Programs as Data: Revisited

How Random Babbling Becomes Corporate Policy

run the fuck away

Mad science gone horribly, horribly wrong(or right).

Programs as Data: Revisited

Previous Entry Share Next Entry
run the fuck away
Remember my whole shtick about LISP? About how programs were represented the same way as data: lists of symbols.

I wanted to come up with a nice, vivid illustration of that, so I wrote a simple mad-lib application. Your mad-lib is the program. Like so:
(madlib "This is a " (noun) " of the " (adjective) " madlib system. Hopefully it is " (present-tense-verb))

A list of symbols- anything in "double-quotes"* is just plain-old text. I wanted to avoid using strings, but the "." character broke down when I did that. Pity.

noun, adjective and present-tense-verb are actually functions that I predefined. In this example, they actually prompt you for input, but they could just as easily grab random terms from a dictionary, or do some other wizardry. The details don't matter. The core idea is that someone that doesn't know LISP could write a datafile following the format above. An end user could then load that file into my engine that provides all the functions, and execute it.

The mad-lib is executable code. This is one of the big ideas in LISP and its variants, and it's something that I discussed briefly in my previous bit on the topic. This is an example of the "little-language" pattern- creating small, simple, single-purpose languages. This example is a very little language, but still an interesting exercise.

Now, I did cheat a bit. The variant of LISP I'm using, MzScheme offers macro functionality. Macros let you add features to the language; it's a way of inventing new keywords and behaviors. I don't want to get technical, but in this example, it provides a way for me to easily define place-holders.

(require (lib "defmacro.ss")) ;for making macros

(define-macro define-marker (lambda (name get-func) ; create new placeholders using this format:
  `(begin                                           ; (define-marker place-name (instructions on how to get the term))
     (define ,name 
       (lambda ()
         (,get-func))))))

(define-marker noun (lambda () (begin (display "noun:") (read-line)))) ;create a noun placeholder
(define-marker verb (lambda () (begin (display "verb:")(read-line)))) ;verb
(define-marker adjective (lambda () (begin (display "adjective:")(read-line)))) ;adjective
(define-marker present-tense-verb (lambda () (begin (display "verb ending in 'ing':")(read-line)))) ;ing verb
;All of the above prompt the user for input- the "lambda" section could be replaced to change that
(define madlib string-append) ;make madlib the same thing as the string-append function


A very, very small app, but one that defines a data-structure and is able to execute properly formatted data.

Oh, yeah- there are huge security risks in the way it's currently implemented. That's not the point.

*Yes, I know those are unnecessary quotes. It's visual illustration.
Powered by LiveJournal.com