[rescue] fans fans fans...

Joshua D Boyd jdboyd at cs.millersville.edu
Fri Jun 21 14:30:17 CDT 2002


On Fri, Jun 21, 2002 at 01:54:37PM -0500, Jonathan C. Patschke wrote:
> On Fri, 21 Jun 2002, Dave McGuire wrote:
> 
> >   So you STILL haven't pointed me in the right direction for getting a
> > quick intro to this too-many-parens-for-normal-people language.  What
> > environment should I download?
> 
> I'm more of a Schemer than a Lisper (and I use Scheme about 1% as often
> as I use C), but I think Scheme is a far-cleaner language than Lisp is,
> anyway.  On the flipside, Common Lisp is far more complete than R5RS
> Scheme and defines a standard GUI toolkit and message-passing system
> (among other things).

Of course, that standard GUI toolkit only works smoothly if you buy a
standardly expensive dev. environment from what I've seen.  CLIM is
great.  If you use MCL or Franz's product.
 
> I like DrScheme for poking around in.  I have yet to find an environment
> for embedded Scheme, so I'm working on my own (Wily) that allows one to
> embed Scheme-like code (possibly user-defined) into a C program.

Guile is pretty easy to embed.  They provide a simple tutorial on
their site. I'm looking at scheme in one define (siod) also (for when
I want it to be really in the project, as opposed to just linking in
guile. 
 
> > What platform should I build it on?
> 
> DrScheme runs well on Unix, MacOS, and Windows.  It even runs well on
> IRIX.  Rice requires it to run flawlessly on MacOS, Solaris, and Windows,
> as that's what they use (there's only one SGI left in the CS department).
 
> > Are there any *PRACTICAL* introductory texts, either printed on
> > online, that I should read?  Bearing in mind that I've always been a
> > procedural programmer..
> 
> Josh will kill me for saying this, but Scheme and LISP are not generally
> practical languages, especially not from the viewpoint of procedural
> programmer.  I had only used procedural languages (and a tiny bit of OO in
> C++ and Java) prior to learning Scheme, and I still don't tend to think
> of problems in a way that lends to solving them in Scheme.  This has
> probably clouded my thinking, as I tend to think in C or assembly, and
> Lisp/Scheme were designed to think like people supposedly think.

Oddly, a lot of things, I think of in terms of functional programming,
but it is the difficulty in getting scheme or lisp to talk to the rest
of the world that drives me back to C.
 
> For example: iteration, as you typically think of it, does not happen in
> Scheme, for Scheme does not have what you would call a proper loop.
> 
>   Problem:
>     Given a list of numbers, find their sum.
>   C Solution[1]:
>     Find the length of the list, iterate over the list, adding each value
>     to an accumulator.  Can be done with a single loop and one
>     initialization statement.
>   Scheme Solution[1]:
>     Create a wrapper function that accept a list of numbers and passes it
>     and a 0 to a helper function.   Create a helper function (usually
>     unnamed) that accepts a list of numbers and an accumulator.  The
>     helper function should first check if the list is empty.  If so, it
>     should return the accumulator.  Otherwise, it should add the first
>     number in the list to the accumulator, and call itself using the new
>     accumulator and the remainder of the list as arguments.
> 
> Both solutions -do- the same thing, but the languages have different ways
> of expressing them.  There's a lot more to learning Scheme than just
> syntax and API.  There is an assload of idiom there that still trips me
> up.

You make that function sound so much harder than it is.

In C++
int addlist (List l) {
    int i, a=0;
    for (i=0; i<l.length(); i++)
	a+=l[i];
	
    return a;
}

...

List l = {1, 2, 3, 4, 5};
cout << addlist(l) << endl;
// note cheat on list construction

Easy enough in C++ .

In scheme:
> (define (addlist l)
        (if (eq? l '()) 0
           (+ (car l) (addlist (cdr l)))))
> (addlist '(1 2 3 4))
10

In that scheme example, '() represents an empty list.  '( means the
start of a list that isn't to be evaluate right away (in other words,
it is data not code).  car returns the first item in a list, and cdr
returns the rest of the list.  car and cdr are unfortunate names that
come to us from the first implementation where they were named for
similar asm functions on a long past IBM machine.

So, yes, you have to think in terms of recursion (a least until you
learn how to write iterator macros), but largely the result is that
you are providing a good mathematical view of your program.

And, scheme doesn't cause stack overflows from excessive recursion
like C does (well, in theory it doesn't.  Some crude implementations
might still do it, but those are usually one of implementations that
some guy did for fun).

 
> Now, once you get past that, Scheme does a lot of things more easily than
> C does:
>   * Bignums (required as parts of R5RS)
>   * Arbitrarily-large data structures (with automatic garbage collection)
>   * On-the-fly function composition (functions are lists)
>   * Functional encapsulation (unnamed functions within functions)
>   * Processing data structures that are recursive in nature (ex: XML)
> 
> It basically boils down to using Scheme/LISP for the problems in which
> your brain thinks that way, and using C/perl/Pascal for problems in which
> your brain things that way.  It's basically the same argument for C++/Java
> versus C.  Some problems fit an object-oriented model better than others.

Expressing procedural ideas in scheme ranges from difficult to
dangerous.  But, if you can get a grip on forming your ideas as
functions, you start to get somewhere.  

I'm telling you, I've learned more from my few math courses then from
all my CS classes combined.  One of the most lasting things is that
almost everything we do in programming can be expressed in graph
theory, set theory, or something related.  When you look at a document
as a graph of graphs of graphs, it is easy to view all operations as a
graph transformation.  The document structure is a tree with sentences
as leafs. Each sentences is a list (ie, the simplest form of tree) of
words.  Each words are a list of letters.  Spell cheching is the
function of seeing if each word (node in the sentence tree) is in the
dictionary set.  Printing is the function of transforming the
highlevel graph (containing lots of highlevel data and meta
information) into a list (of formatting commands).

And so on and so on.  In short, if you can grok doing complex things
in sed, you will probably be fine in functional languages.  And of
course, obvious math things (like prime research, crypto research,
graphics, etc) are particullarly great for functional languages.

-- 
Joshua D. Boyd



More information about the rescue mailing list