[taos-glug] Re: my progress report

  • From: Jonathan Bartlett <johnnyb@xxxxxxxxxx>
  • To: taos-glug@xxxxxxxxxxxxx
  • Date: Mon, 4 Aug 2003 20:04:50 -0700 (PDT)

I'll give you a little further explanation.  Some of these are not taught
in the book.

>  * it's lack of syntax (code == data - this allows you to write programs
> that build and modify programs)

Basically, this is the fact that programs are simply lists.  (* 2 3) is
simply a list of 3 elements.  If I happen to send that list to the
interpretter, it gets interpretted, but it's valid scheme data, too.  I
can use this fact to do customized preprocessing on code.  We'll get back
to this fact in macros.

>  * closures
>

Closures are what happen when you create functions at runtime.  Let's say
you have:

(let
    (
        (a 1)
        (b 2)
    )
    (lambda (x) (* x b))
)

In this case, we are creating a function and returning it.  The function
has one parameter - x, but it also has full access to the symbol table
within it's lexical scope at the time of creation.  That means if b is 5
on one invocation and 6 on the next, I will have two separate functions -
the code will be the same, but the variable values it has access to will
be different.  These variables are said to be "closed" over the created
procedure.

>  * continuations

I don't know if the book deals w/ continuations or not.  Imagine if you
had threads, coroutines, try/except blocks, and gotos all packaged within
the same function, which was guaranteed to maintain internal consistency
(unlike normal gotos).  (call-with-current-continuation) is one of the
most ingenious functions I've ever seen, but it's only implemented as far
as I'm aware in Scheme and ML, although I've been playing around with
creating a partial C implementation.

>  * macros

This of C macros - pretty ugly, because they deal entirely on a textual
basis.  With Scheme, since programs are just list data, Scheme macros can
operate on the program structure itself, not just it's texttual
representation.  This paves the way for enormous flexibility.

>  * support for lazy evaluation

Lazy evaluation is the ability to delay computation until any later time.
So, let's say you have an expensive operation, q.  You can delay it's
application by saying (delay (q x)).  This will result in a value that is
a suspension - meaning that it hasn't actually run the operation yet.
Lets say you did (set! z (delay (q x))).  Now, if you want the value, you
simply do (force z).  The first time, it will run the computation, and
every other time it will return the value it had when first forced.  This
allows you to decouple function execution and data storage - if you end up
not using a value, you don't have to spend time computing it.

There are languages like SASL and Haskell where the entire language is
built on lazy evaluation.  With scheme, it's an alternative, but not
forced.

>  * first-class functions

You said you already were familiar with this

>  * first-class symbols

With scheme, when you have a symbol like 'hello, doing equality
comparisons with symbols (eq? 'hello 'hello) is reduced to a single
machine instruction.  Many programming books call this "interned" strings.
They are used mostly for variable storage and named constants, but have
other uses as well.

>  * strictly-typed but loosely bound

The types in Scheme are strict - i.e. - an "int" cannot auto-morph into a
string like it can in Perl.  However, the variables are not tied to
specific types, so they are loosely bound.

> Jon

It's me again!

Jon


Other related posts: