Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Scheme as a religion

51 views
Skip to first unread message

H.

unread,
Jan 3, 2006, 6:17:11 PM1/3/06
to
As an avoid computer science student who hopes to attend to UC Berkeley
next fall, I started watching the Berkeley webcasts of 61A (taught by
Brian Harvey, based on the SICP book), and watched a few of the
original lectures by Abelson and Sussman available off of the mit site.
I also googled "Scheme" and "SICP" to see what comes up...and have come
to the conclusion that Scheme seems as much like a religion as a
language. The general concensus I get is that it is widely admired by
academics who seem to thoroughly enjoy criticizing the limitations of
other languages while extolling the virtues of Scheme, and not so
widely respected by and sometimes scoffed at those in the industry who
use commercial languages like C++ and Java.

I am torn somewhere in between the extremes, but the purpose of this
post is that there are some evangelical aspecs of Scheme that I don't
get, in that the concepts don't seem so novel to me. Of course, that
could be a function of the year (2005); if the concepts presented in
Scheme were once new, they aren't anymore. The first time I watched
"Citizen Kane" I didn't get what was so great about it; after taking a
film history course I could better appreciate that the film broke
several barriers. Now in 2005, those barriers don't exist, and so
without the history, some aspects don't seem very amazing (it was the
first film to use deep focus, for instance, which isn't new now.) A
similar metaphor may exist for Scheme.

To me, Scheme seems difficult to grok on first reading (or even second,
or third) comprehend by it's rule of relying so much on single
parenthesis. (Yes, I think the LISP nickname of "Lots of Irritating
Single Parenthesis" fits). It seems to me that there are scripting
languages that are easier to read and write that teach many of the same
concepts.

For instance, two of the concepts taught in Scheme are first-class
objects and recursion. Both of these are present in JavaScript which I
personally find much easier to use, because there are () and {}
available, each used for a different purposes, and explicit keywords
like "return" that specify what gets returned from a function, as
opposed to Scheme's implicit model (things get returned for being
listed last, but not always). Also, Scheme sometimes uses what I
consider "trick notation" to call a fuction/procedure, in that if you
add an extra set of parens around something, you call it as well as
define it, whereas in JavaScript the notation is more explicit with far
less room for confusion. Scheme backers defend the language by saying
"sure, it's hard to read sometimes, but look at the all of the things
it can do," pointing to things like first-class objects and tail
recursion. But I'm not convinced. Convince me; I haven't been
converted. It's not that I want to be converted (to being an
evangelical Schemer) -- it's that I want to understand why others are.

-----------------------------------

As a last note: not to evangelicize JavaScript either, there clearly
some areas for which JavaScript does not teach the same metaphors. The
only way to create linked lists, for instance, is to create your own
linked list data structures, whereas in Scheme, the whole weird car,
cdr, cadr terms can prepare the student for linked lists. But as to why
beginning programming students have to be exposed to terms like car,
cdr, cddar, caaddr, etc, I don't get that either. Please don't tell me
that those names are in the least way transparent or aid in
understanding. The nomenclature alone is a stumbling block to the
powerful concepts for which they stand.

H.

unread,
Jan 3, 2006, 6:28:43 PM1/3/06
to
Frell. Accessing the Usenet via Google Groups really screws with my
line breaks. Live and learn.

Brian Harvey

unread,
Jan 3, 2006, 6:56:03 PM1/3/06
to
"H." <hbe...@gmail.com> writes:
>As an avoid computer science student who hopes to attend to UC Berkeley
>next fall [...] Convince me; I haven't been
>converted.

Well, perhaps I'll have a longer opportunity next year :-) but for now,
let's just say this:

Our goal isn't to convince you to love Scheme. On the contrary, our goal
is to convince you that *even if you never use Scheme again*, the big ideas
are still valuable. Too many students think, for example, that once they're
programming in (for example) Java, they can/should forget about recursion.

It sounds as if you're already convinced about some, but not all, of the big
ideas. So, that'll give you a leg up; you won't be fighting as hard as some
other students to think about every problem in the FOR...NEXT style.

We use Scheme as a teaching language because experience shows that it gets
in the way less than other languages. We can teach the entire language in
the first week, and then spend the rest of the semester on serious ideas.
[Actually that isn't quite true; I should say that we can teach most of the
language, enough to write pretty much any program you want, in the first week.
The more obscure language features we don't teach at all, even though some
people argue that they're the "jewels" of Scheme -- look through that thread
currently running on the newsgroup and look for "macros" and "continuations."]

As for the parts of Lisp notation that you don't like: Some you'll get used
to pretty quickly; others you shouldn't really be using very much anyway.
For example, your programs should not be full of CDADDRs; instead, you'll
define data-structure-specific synonyms like this:
(define date-of-birth cdaddr)

But you should think about why it is that, despite almost half a century of
new language invention, Lisp remains the second-oldest language still in
widespread use (and a lot of the Fortran users are dying off :-). It must be
doing something right.

Thant Tessman

unread,
Jan 3, 2006, 7:52:13 PM1/3/06
to
H. wrote:

> [...] The general concensus I get is that it is widely admired by


> academics who seem to thoroughly enjoy criticizing the limitations of
> other languages while extolling the virtues of Scheme, and not so
> widely respected by and sometimes scoffed at those in the industry who

> use commercial languages like C++ and Java. [...]

My experience is that very few people in the commercial world know
anything about Scheme. However, some of us have used Scheme in a
commercial setting and find much about the language to admire. But the
important point, as Brian Harvey said, is that it will change the way
you think about programming.

To add some perspective to all of this, I have encountered people who
scoff at C++, and think that C is the only programming language worth
taking seriously. I'm no fan of C++, but I'm knowledgeable enough to
know that these folks usually aren't arguing from an informed position.

-thant

--
"Parentheses? What parentheses? I haven't noticed any parentheses
since my first month of Lisp programming. I like to ask people who
complain about parentheses in Lisp if they are bothered by all the
spaces between words in a newspaper..." -- Kenny Tilton

Adam Fabian

unread,
Jan 3, 2006, 8:39:34 PM1/3/06
to
I'm learning Scheme. So I'm not knowledgeable about it, or
indoctrinated. So, my reasons are probably going to sound trivial,
but I think they're important.

Scheme appears to be extremely consistent and simple. The parentheses
don't bother you much after dealing with them for a while; they almost
'become invisible.' This probably depends on your editor; emacs is
extremely good at things like highlighting matching parentheses,
indenting lisp code, etc. For price of the parentheses, you actually
strip out the complexity of *having syntax* and a great deal of the
rules of precedence of a language like C, or even perl. Almost all of
the predicate functions end with a question mark, and destructive
functions with an exclamation mark. I think that a programming
language is actually a tool for managing complexity, and the more
irrelevant things it can keep out of your way, the more room you have
in your brain and your life for more important things. Perfect
regularity and obviousness should be an ideal, and scheme seems to get
MUCH closer than any other language in than regard.

I've got a lot more experience with C and C++. Until you've dealt
with some alternatives, you don't even realize that there are ways
that you don't have to deal with all of this #include and preprocessor
nonsense, the size of an integer on your machine, explicitly managing
pointers, etc. Scheme just seems to allow you to express the basic
concepts more directly, without having to grovel around at the level
of bits or picking up unnecessary abstractions like "everything is an
object; programming is all about objects and nothing but objects."

But, like I said, it's entirely possible that I don't know what I'm
talking about. =)

H.

unread,
Jan 3, 2006, 9:06:01 PM1/3/06
to
Wow, thanks for the fast response.

As a total side note, I really like the open nature of the cs
department at Berkeley. I've looked at old 61A midterms (and 61B and C
as well), and watched many of the webcasts, and picked up your course
reader at Copy Central (I live in San Francisco;,it was a quick jaunt).
So if time allowed between other classes -- I'm at ccsf now --I
followed along. This got to be unrealistic as the semester progressed
and the courseload and normal life stuff ate up my time. Winter break
now though and back to Berkeley webcasts.

Either I get into Berkeley and meet the profs I've seen webcast -- , or
I don't, and in that case, I learned a heck of a lot anyhow. So yeah,
kudos to everyone there.

Whoops, not Scheme related. To keep it at least semi-relevant to the
forum:
'(hey everyone check out Berkeley webcasts at
http://webcast.berkeley.edu/courses/index.php)
(define 61A 'SICP-Course)

Bruce Lewis

unread,
Jan 3, 2006, 10:35:27 PM1/3/06
to
"H." <hbe...@gmail.com> writes:

> less room for confusion. Scheme backers defend the language by saying
> "sure, it's hard to read sometimes, but look at the all of the things
> it can do,"

Which Scheme backers say it's hard to read sometimes? I don't. After
two weeks working with Scheme everything's totally clear and
unambiguous. I programmed C for 12 years and never memorized the
precedence rules. I could look at C code and not be able to tell for
sure what it did without consulting a book. Not so with Scheme.

alex...@gmail.com

unread,
Jan 3, 2006, 10:54:39 PM1/3/06
to

We need an obfuscated Scheme contest.

Tom Lord

unread,
Jan 3, 2006, 11:53:54 PM1/3/06
to
To the other replies you are getting I'll add some hacker lore
and historic perspective:


Only fifty years ago the idea of a programming language was
still something of a novelty to most people working with
computers. It was an idea that had to be invented and that
didn't make much practical sense until machines became powerful
enough. It was back then that lisp was invented, initially as a
paper-and-pen notation for reasoning about programs (and
initially not using the parenthesis syntax you see today). See:

http://citeseer.ist.psu.edu/steele93evolution.html

and seek out the McCarthey paper it cites.

As you'll learn, being an "avoid student of computer science" (I
love that typo), we nowadays have a fairly systematic and in
some areas very deep understanding about the nature of
programming languages and their implementations. You are right
that there is a lot in Javascript and other languages that is
similar to lisp in general and Scheme in particular --- what you
will hopefully learn over time is how to understand and describe
the similarties and differences in very concise ways, focussing
on "deep stuff". But I'm not here to dish the academic lessons
-- I'm just giving you a hacker map. Oh, speaking of which:
grab yourself a copy of the Scheme standard and note the
appendix contain a semantic definition of the language.
Understanding why people think that that appendix is (at least
historically) important -- tracing down and reading some of the
original materials that relate to it -- can give you a lot of
perspective. If you venture into Church, meditate a bit about
Strachey, gosh rest his soul. Great Scott, man, these folks
drew the first maps.

Anyway, a bit over a scant 30 years ago there was an explosion
both in the freedom researchers had to explore the possibilities
of programming languages and the math tools they had to
understand where they were going. A mere 30 years ago --
imagine that! Heck, I'm older than that.

Because everything was so new every research institution was
pretty much on its own. There was no "download GCC" let alone
"pick one of N browsers that contain a Javascript interpreter".
Stanford had its programming tools. MIT had its. Abstractly
speaking, this era of programming languages was like the western
expansion of the U.S. in the 19th century: vast territory wide
open to pioneers. When a sub-field of math is in that stage you
can expect fundamentals to be discovered and discovered they
were. This is where Scheme enters the picture and, bringing it,
a very gifted writer.

Guy Steele, who you may have heard of from Java fame, was a grad
student at MIT in the early seventies. He was just down the
hall from and interacting with --- well, half the damn world as
far as computer science is concerned. Glomming around around in
recently exploding language-theory space, immersed in the
well-grounded practicality of a lab that maintained pretty much
its entire stack of software tools, in search of a thesis having
something to do with the hot topic of compiler construction --
but wanting (one presumes) to get the hell out of dodge without
having to implement all of PL/1 -- Steele took the lisp of the
time and some ideas from more disciplined languages of the time,
looked for simplifications, and came up with Scheme (with a
little help from his advisor, et al.).

What made Scheme so interesting, back then? A number of things:

One thing not to ignore is Steele's thesis, available at a
library near you. Make like a bunny and go read a copy -- it's
fun. If the library is closed when you get there, do a lap in
the meantime, Frenchy. Maybe that's a load.

Steele showed how a Scheme could be reduced to a very small core
of basic constructs and, thus reduced, could be well treated by
an optimizing compiler. He was worried about how to achieve
parsimony in a compiler -- to make it a human-scale program --
and he found a neat trick that explained why function calls and
goto were more similar than different. Reading the old thing
won't lead you to the forefront of modern compiler construction
(and, indeed, there are more efficient routes to learning that
material) but -- damn it's nicely written and invites much idle
contemplation. If you look around you might even find a copy of
his compiler on-line (it take some work to run it in a modern
scheme, it's slow as heck, it's a bit buggy, and I hope for your
sake you've seen cleaner code -- still, like reading Chaucer for
English students, it's a good exercise). It's not a good work
to read to learn any major bit of CS (though, at your stage,
you'll pick up many minor bits and a general attitude). It's a
good work to read to learn a bit about being an intellectual.

Of course, while you're rummaging through the stacks, you better
go read the "lambda the ultimate...." papers. There's enough
on-line about these already that that's all I'll say.

Scheme seems, from my perspective, to have startled the people
around it with its elegant simplicity combined with the
seemingly fundamental notes it struck. Let us know when you
grok how Scheme relates to something called "Hewitt's Actors
Model". Talk about programming patterns....

You asked about "Scheme as religion"? That's where it started
-- it's discovery/invention struck a really deep note. Nobody
expected that. 14 years after it was written Steele's *thesis*
was still being handed around in the hacker undergound as a work
of art. You'll eventually understand how remarkable it is that
anybody bothers to read a thesis that many years later, let
alone pass it along to friends in the manner one might pass
along an obscure Hendrix bootleg. (Oh, speaking of Hendrix:
avoid "Tiny C" except for comparison purposes.)


So: first approximation -- yeah, Scheme is nothing special.
Many modern languages are informed by it. Some of its mystique
is just echoes from history because, in the early days, Scheme
was pretty startling. The same parsimony that made it so
interesing back then makes it a handy vehicle for some
contemporary (or nearly so) researchers. It also as
B.H. remarks (I'm taking his word for this) makes it an
efficient vehicle for teaching Big Ideas.

Lemme change gears a bit and shift away from historic narrative
for two last points:

1) GET OFF YOUR PARENTHESIS PHOBIA AND LEARN EMACS. No, knowing
how to move the cursor around doesn't count as knowing Emacs --
that counts as knowing how to use Emacs as if it were VI.

Look, yr program source texts represent trees. Parens make it
really simple for your text editor to perform tree transforms.
Learn emacs really well. Spend 6m on it. Learn the lisp modes.

Ok, sure -- there are two valid points of view here. Read Larry
Wall on why Perl syntax is so cool for the other one. He's not
wrong but, really, lisp syntax is a heck of a lot more human
friendly than you might realize at first glance. There are few
things quite as pathetic as watching a programmer who doesn't
really get emacs try to edit lisp code, though.


2) Let's talk about quality.

What separates the true scheme hackers from most (not all)
other hackers is a deep care for quality.

Go read "Zen and the Art of Motorcycle Repair". It's a
terrible book. It's heavy handed -- pretentious even. It's
dull. Where it reaches for hights it sinks to lows and is
basically trite. It has exactly one redeeming virtue and,
alas, it's a big virtue: it'll give you a sense of what some
of us righteously and appropriately mean when we toss around
the word "quality". In tht regard, it'll help you to
appropriately think about most commercial programming efforts
(including the quasi-commercial bulk of the so-called "FOSS
community") as the work of irresponsible, insane bozos. Get
a grip on quality. Aim for a bike you can Own.

Think about the literature and history hints I've given you
above in that context -- in the context of care for quality.

Lemme add the word "craft".

Lemme add the phrase "human scale".

Do with those what you will.

Scheme is a big ball of mud but, with these hints, you can
start to grok why this particular mud smells so good to some
of us. (Plus, you can start to read all the *later* and
often very interesting Scheme literature I haven't given you
hints about.)


-t

Anton van Straaten

unread,
Jan 4, 2006, 3:32:02 AM1/4/06
to
"H." <hbe...@gmail.com> wrote:
> The general concensus I get is that it is widely admired by
> academics who seem to thoroughly enjoy criticizing the limitations of
> other languages while extolling the virtues of Scheme, and not so
> widely respected by and sometimes scoffed at those in the industry who
> use commercial languages like C++ and Java.

It is also admired by some in industry who feel constrained by
commercial languages like C++ and Java. As it happens, the latter group
are the smartest people. ;)

> I am torn somewhere in between the extremes, but the purpose of this
> post is that there are some evangelical aspecs of Scheme that I don't
> get, in that the concepts don't seem so novel to me. Of course, that
> could be a function of the year (2005); if the concepts presented in
> Scheme were once new, they aren't anymore.

That's true of some of the concepts in Scheme, but not all of them.
Even some of the concepts which have since been adopted by other
languages haven't always been properly implemented -- closures in Python
are one example, and the arbitrary limitations on recursion in many
languages is another. This seriously limits the usefulness of these
features. There's no single mainstream language that implements all of
Scheme's most useful features in a non-broken way.

> To me, Scheme seems difficult to grok on first reading (or even second,
> or third) comprehend by it's rule of relying so much on single
> parenthesis. (Yes, I think the LISP nickname of "Lots of Irritating
> Single Parenthesis" fits). It seems to me that there are scripting
> languages that are easier to read and write that teach many of the same
> concepts.

They may teach some of the some concepts, but they also miss some very
important ones. That's a problem if you're really trying to learn
underlying principles rather than just to become an average coder.

> For instance, two of the concepts taught in Scheme are first-class
> objects and recursion. Both of these are present in JavaScript

By first-class objects, I'm guessing you mean first-class procedures.
Javascript does have those, although their power is hampered by some
other restrictions of Javascript, so they aren't as nearly as useful as
they might otherwise be.

One such restriction is recursion, which is severely limited in most
Javascript implementations, to the point where it can't be used for many
of the most useful recursive algorithms. For example, you can't do
recursive processing of even fairly small structures in most Javascript
implementations, simply because you run into stack limits. (One
exception to this is the Rhino implementation of Javascript that's been
modified to support continuations, but that's not standard and only runs
on the JVM.)

Another important feature missing from Javascript are proper
lexically-scoped (i.e. block-scoped) local variables.

A big part of Scheme's power is the combination of first-class
procedures, the related nested lexical scoping for variables, and
recursion that's not arbitrarily restricted. These features are all
characteristics of lambda calculus, and are shared by the functional
language family, including ML and Haskell. None of the mainstream
languages support this full functional feature set, which is a pity,
because it's an important and powerful integrated set of capabilities
that isn't really at odds with imperative languages.

This functional foundation is only one of the powerful aspects of Scheme
-- others include macros and first-class continuations, which again may
be found in various diluted forms in other languages, but not in any
single mainstream language. While these features might not be taught in
introductory courses, it helps that Scheme scales from a simple
introductory subset to something much more powerful that supports
constructions that are essentially impossible to express in mainstream
languages. Scheme is a language for the expression of computational
ideas, which remains as useful at the PhD level as it is in first year.
The same isn't true of Javascript. ;)

> which I
> personally find much easier to use, because there are () and {}
> available, each used for a different purposes

That's a little like saying you find the Qwerty keyboard easier to use
than Dvorak -- it's a matter of familiarity. Many people (including me)
have switched from languages with C-style syntaxes to Scheme/Lisp. Once
you have some experience with it, the s-expression syntax is no more
difficult to use, and actually has many unique advantages.

> and explicit keywords
> like "return" that specify what gets returned from a function, as
> opposed to Scheme's implicit model (things get returned for being
> listed last, but not always).

There's a reason for that difference, which is that Scheme is mostly
expression-oriented, as opposed to statement-oriented. The "return"
statement in Javascript and other imperative languages is actually a
goto-like jumping statement which interrupts the flow of execution
(unless it is the last statement in a function, of course). You can do
the same sort of jumping in Scheme using the call/cc function, if you
need to, but Scheme will teach you that such jumping is unnecessary, and
could be described as overkill. Again, the issue here of one of
learning the difference between what Scheme is doing, vs. what the
imperative languages do, and learning how to read Scheme.

> Also, Scheme sometimes uses what I
> consider "trick notation" to call a fuction/procedure, in that if you
> add an extra set of parens around something, you call it as well as
> define it, whereas in JavaScript the notation is more explicit with far
> less room for confusion.

Not sure exactly what you're referring to. But for an example of this
sort of difference, compare this Scheme:

((lambda (x) (+ x 1)) 5)

to this equivalent Javascript:

(function (x) { return x+1; })(5);

If one of these is clearly trickier than the other, I'd say it's the
Javascript, and that's not for want of experience. Heavy use of
anonymous functions in Javascript is not as convenient as in Scheme. A
demonstration of this can be seen if you try writing what's known as
"continuation-passing-style" (CPS) code in Javascript -- it's known as a
difficult to read style, but it's even more difficult to read in
Javascript than it is in Scheme, because of return statements and the
way in which anonymous functions are written in Javascript.

> As a last note: not to evangelicize JavaScript either, there clearly
> some areas for which JavaScript does not teach the same metaphors.

Right, another problem with most scripting languages is that they tend
to provide certain predefined high-level data structures, which don't
have well-defined performance characteristics and don't support
efficiently defining other kinds of structures.

> The
> only way to create linked lists, for instance, is to create your own
> linked list data structures, whereas in Scheme, the whole weird car,
> cdr, cadr terms can prepare the student for linked lists. But as to why
> beginning programming students have to be exposed to terms like car,
> cdr, cddar, caaddr, etc, I don't get that either. Please don't tell me
> that those names are in the least way transparent or aid in
> understanding. The nomenclature alone is a stumbling block to the
> powerful concepts for which they stand.

Most modern teaching texts use names like 'first' and 'rest' instead of
car and cdr. All that is needed to achieve that renaming are simple
definitions like "(define first car)".

However, note that the compound names like caaddr are actually concise
path specifiers for navigating a tree. As an exercise, come up with
some other way to do this, and compare this for transparency etc. to
car, cdr and their derivatives. I suspect that a strong reason that the
car & cdr names have survived is that ultimately, changing their names
doesn't buy you much.

In short, the impression that religion is involved is misleading. Or
put it this way: any worshipping that might take place has a solid
technical justification, even if that isn't apparent from a superficial
comparison to more common languages.

Anton

Joe Marshall

unread,
Jan 4, 2006, 3:35:20 AM1/4/06
to

H. wrote:
> The general concensus I get is that it is widely admired by
> academics who seem to thoroughly enjoy criticizing the limitations of
> other languages while extolling the virtues of Scheme, and not so
> widely respected by and sometimes scoffed at those in the industry who
> use commercial languages like C++ and Java.

Actually, no. Every couple of years a new language comes along that is
supposed to be the `ultimate' be-all and end-all language. It will
solve all the
problems of the previous languages. (I think it is ruby this year,
right?
Taking over from Python, which took over from Java, which took over
from C++....)

And each time, the so-called designer of the language makes some truly
bone-headed mistake that cripples the language in a fundamental way.
Of course
nearly any flaw can be worked around when you are doing small things,
but as the
languages get bigger and bigger (and they *always* do) the flaws in the
foundation
become more and more pronounced until the next language fixes that flaw
(while
simultaneously re-introducing another).

Now this wouldn't be so damned pathetic if the kind of errors in
computer language
design weren't the very same ones that were a) discovered a long time
ago, quite
probably *before* the author of the new language was born, b) fixed a
long time ago,
most likely before the author of the new language was out of his
diapers, and c) was
probably taught to the author of the new language *if he had been
paying attention*
in his very first CS class.

Is it religious to say that tail recursion is important? Hewitt
pointed out that tail-recursion
is *critical* if you don't want to cripple your semantics. This was
back in 1973.
Steele and Sussman got it right away. Scheme people keep pointing out
that not only
is this *important* it is *relatively easy* to do right. And nearly
every damn language
that comes down the pike does it wrong.

First class procedure values? These are even older. It turns out that
the `objects' from
which `object-oriented' languages get their name are simple
window-dressing on first-class
procedure values. So if you get these right, you solve two problems at
once. And it's
been known for a long time how to do it right. It's harped upon in
every beginning Scheme
course. And nearly every damn language that comes down the pike does
it wrong.

> I am torn somewhere in between the extremes, but the purpose of this
> post is that there are some evangelical aspecs of Scheme that I don't
> get, in that the concepts don't seem so novel to me.

They aren't novel, they are old, well-understood, and solved issues.
But it took
thirty years of harping on the advantages (and obvious necessity for)
garbage collection
for anyone to take it seriously. I have been saying `garbage
collection is critical
to a language' since the mid 80s and only recently has the reaction
been `of course'.
If we harp on about tail-recursion for another twenty years, maybe that
will catch on, too.

> Of course, that
> could be a function of the year (2005); if the concepts presented in
> Scheme were once new, they aren't anymore.

They aren't. But is anyone listening?

> To me, Scheme seems difficult to grok on first reading (or even second,
> or third) comprehend by it's rule of relying so much on single
> parenthesis. (Yes, I think the LISP nickname of "Lots of Irritating
> Single Parenthesis" fits). It seems to me that there are scripting
> languages that are easier to read and write that teach many of the same
> concepts.

No, there aren't.

Give yourself a chance to get used to the parens (it can take a couple
of months).
Then write a parser for your `easy to read' scripting language. Be
forewarned:
I will laugh at you and say `I told you so'.

> For instance, two of the concepts taught in Scheme are first-class
> objects and recursion. Both of these are present in JavaScript which I
> personally find much easier to use, because there are () and {}
> available, each used for a different purposes,

Oh? And what are the differences, exactly?

> and explicit keywords
> like "return" that specify what gets returned from a function, as
> opposed to Scheme's implicit model (things get returned for being
> listed last, but not always).

An explicit `return' is either stupid or dangerous. It is stupid in
those cases
where you *must* specify the word return even though no other logical
action makes
sense. Dangerous in that if allowed anywhere in the code it can make
the program
virtually impossible to analyze.

> Also, Scheme sometimes uses what I
> consider "trick notation" to call a fuction/procedure, in that if you
> add an extra set of parens around something, you call it as well as
> define it, whereas in JavaScript the notation is more explicit with far
> less room for confusion.

I don't know what you mean by this.

> Scheme backers defend the language by saying
> "sure, it's hard to read sometimes, but look at the all of the things
> it can do," pointing to things like first-class objects and tail
> recursion. But I'm not convinced. Convince me; I haven't been
> converted. It's not that I want to be converted (to being an
> evangelical Schemer) -- it's that I want to understand why others are.

I can convince you. How much money do you have?

> As a last note: not to evangelicize JavaScript either, there clearly
> some areas for which JavaScript does not teach the same metaphors. The
> only way to create linked lists, for instance, is to create your own
> linked list data structures, whereas in Scheme, the whole weird car,
> cdr, cadr terms can prepare the student for linked lists. But as to why
> beginning programming students have to be exposed to terms like car,
> cdr, cddar, caaddr, etc, I don't get that either. Please don't tell me
> that those names are in the least way transparent or aid in
> understanding. The nomenclature alone is a stumbling block to the
> powerful concepts for which they stand.

No one here thinks CAR, CADR, etc. is somehow mystically better than
FIRST, SECOND, THIRD, etc. It's just a stupid tradition that's grown
into the
culture. I can talk colloquially about the `third element' of
something or I can talk
precisely about the `third element of a Lisp linked list' and it can be
difficult to know
if I'm trying to be precise or general. But if I say `it broke because
the CADDR was NIL
instead of a FIXNUM' then other lisp hackers will instantly know that
I'm not talking
about the vague `third part of something' but rather I'm talking about
a particular slot
in a particular kind of data structure. It's just not that big a deal
to have CADR and
CADDAR lying around in the language at this point. It's `shop talk'.

Joe Marshall

unread,
Jan 4, 2006, 3:41:27 AM1/4/06
to
Actually, no one I know programs in Scheme or Lisp directly. Neither
is suitable for solving anything but the most trivial problems `out of
the box'.

Anyone who uses Scheme or Lisp uses it only as the basis for an
extended domain-specific language that may or may not resemble the base
language, depending on how they feel about syntax.

It's a funny religion when its adherents don't use the purported object
of worship except to change it into something else.

Ulrich Hobelmann

unread,
Jan 4, 2006, 4:11:35 AM1/4/06
to
Joe Marshall wrote:
> Actually, no one I know programs in Scheme or Lisp directly. Neither
> is suitable for solving anything but the most trivial problems `out of
> the box'.
>
> Anyone who uses Scheme or Lisp uses it only as the basis for an
> extended domain-specific language that may or may not resemble the base
> language, depending on how they feel about syntax.

Would you say it's wrong to extend the Java language with classes and
methods to achieve what you're going for?

Would you say it's wrong to extend Lisp or Scheme with functions and
macros until it does what you want?

Why?

> It's a funny religion when its adherents don't use the purported object
> of worship except to change it into something else.

It's nothing else.

--
the bottom line is that a JavaSchool that won't teach C and won't teach
Scheme is not really teaching computer science, either. -- Joel Spolsky

Joe Marshall

unread,
Jan 4, 2006, 4:14:41 AM1/4/06
to
Unfortunately, I have no other choice in Java. If I wanted to extend
the language with something like orthogonal persistence or delegate
classes I'm just out of luck.

Ulrich Hobelmann

unread,
Jan 4, 2006, 5:00:27 AM1/4/06
to

Maybe you could use some kind of preprocessor, that translates lambda
expressions into interfaces and anonymous classes. But the resulting
code might not be too readable either.

Pascal Costanza

unread,
Jan 4, 2006, 5:13:50 AM1/4/06
to
Ulrich Hobelmann wrote:
> Joe Marshall wrote:
>
>> Unfortunately, I have no other choice in Java. If I wanted to extend
>> the language with something like orthogonal persistence or delegate
>> classes I'm just out of luck.
>
> Maybe you could use some kind of preprocessor, that translates lambda
> expressions into interfaces and anonymous classes. But the resulting
> code might not be too readable either.

Remember: It's never about possibility, it's always about convenience.
Due to Turing equivalence, you can always do everything in every
language. If that were the only criterion, we could program in assembly
language. The important contribution of programming languages is to make
things more convenient.

Yes, you could write a preprocessor for Java, but this would be very
hard, especially because your users would expect a Java-style (i.e.,
highly irregular) syntax. You would also most certainly break
compatibility with existing sources. (Even Sun wasn't able to avoid that
wrt to the extensions they added to Java over the years.)

The nice thing about Lisp/Scheme is that it is so straightforward to
extend the language, with very little distractions from secondary issues.


Pascal

--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/

rsher...@gmail.com

unread,
Jan 4, 2006, 10:01:11 AM1/4/06
to
>For instance, two of the concepts taught in Scheme are first-class
>objects and recursion. Both of these are present in JavaScript which I
>personally find much easier to use,

This is the second time this week I've seen somebody say this. Having
done some functional programming in Javascript, I beg to differ. Its
entire library is centered around imperative functions with
side-effects, and arrays instead of lists. Even if you were inclined
to create your own functional library, the design of the language
doesn't play well with it. You don't get to recur much without running
out of stack, and there's no tail recursion. You're basically forced
to use iteration and side-effects.

Javascript has closures, but they're a pain in the ass.

Scheme:
(let* ((x 2)
(y (* x 2))
(z (* y 2)))
(list x y z))

Equivalent Javascript (It's actually not quite equivalent because it
returns an array instead of a list, but close enough):

(function(x) {
return (function (y) {
return (function (z) {
return [x,y,z];
}(y*2));
})(x*2);
})(2);

This took me 5-10 minutes to write because I forgot about Javascript's
bizarre whitespace rules, which make this fail silently if you put a
break after the "return"s. And it's butt ugly.

In real life, of course, you would just do this:
var x=2;
var y=x*2;
var z=y*2;
[x,y,z]

But this isn't doing the same thing. The difference may appear subtle
or unimportant, but there are times when it really matters, as it did
to this guy:
http://joust.kano.net/weblog/archive/2005/08/08/a-huge-gotcha-with-javascript-closures/
who did "hours of debugging" because he didn't understand closures (and
still didn't when he wrote this article. Judging from most of the
comments, he's in good company among Javascript programmers).

>and explicit keywords like "return" that specify what gets returned from a function

Scheme has this. It's called "call-with-current-continuation," and it
does a lot more. You can define return like this:

(define (fact x)
(call/cc
(lambda (return)
(when (< x 0)
(return "error"))
(if (= x 0)
(return 1)
(return (* x (f (- x 1))))))))

And if you really want it to look like Javascript, you can do something
like this:

(define-macro (function name ll . body)
`(define ,name
(lambda ,ll
(call/cc
(lambda (return)
,@body)))))

Which allows you to define a Javascript-like function with "return":

(function fact (x)
(when (< x 0)
(return "error"))
(if (= x 0)
(return 1)
(return (* x (f (- x 1))))))

(fact 5) => 120

But nobody does this because it's ugly and unnecessary.

Don't delude yourself that Javascript and other modern scripting
languages are in the same league as Scheme as functional languages.
They just aren't. If you want a functional language with more syntax,
look as ML or Haskell instead. Mainstream languages exist which have
most of Scheme's features, but the whole package is missing. And the
whole package is what it's really all about. Ruby and Python have no
unique features that aren't available in any other language, but they
have become popular because they are put together in a way that makes
them superior to other languages for certain people.

>Of course, that could be a function of the year (2005)

You must have been frozen in a glacier for the past 4 days. Welcome to
the future. We all have flying cars and self-aware robotic slaves now.

Isaac Gouy

unread,
Jan 4, 2006, 12:32:52 PM1/4/06
to

Joe Marshall

unread,
Jan 4, 2006, 1:32:17 PM1/4/06
to
Sure, there are workarounds. Using something like openjava or writing
a preprocessor is one. Let's pretend that I did that.

Now I have a compiler and vm for a java-like language that I can use to
compile and run my extended code, but I really can't share this code
with anyone without forcing them to adopt the new compiler and
platform. If I were clever and figured out how to do what I wanted
using the existing Java VM, then I could share my .class files, but
this is a rather crude way to share. I can share the executable form,
but not the source it came from.

Ok, so I bundle the preprocessor along with the source and arrange for
the output to be compatible with existing Java VMs. I've got my
orthogonal persistence. But suppose Pascal Costanza has done something
similar with delegates or with versioned classes. How can the hapless
user combine our two preprocessors to get both features? And what is
the cost of maintaining this when Sun decides to come out with a new
version of Java?

The barrier to extending Java in this way is extraordinarily high
compared to the barrier of extending Java through the `usual' channels
of writing classes and methods.

Ulrich Hobelmann asks:


> Would you say it's wrong to extend the Java language with classes and
> methods to achieve what you're going for?

> Would you say it's wrong to extend Lisp or Scheme with functions and
> macros until it does what you want?

No. These are wonderful things to do. But when I'm extending Java, I
cannot break with certain parts of the Java model (the syntax and base
semantics) without extraordinary difficulty. If I limit myself to
adding classes, methods, and interfaces to a body of Java code, I
extend Java, but only in a restricted sense that ensures that the
result remains Java.

On the other hand, if I extend Lisp or Scheme with macros (to change
the syntax or evaluation model) or with reader macros (to change the
lexical structure) or with new functions or data types that are
indistinguishable from the primitive ones, the resulting language is
only Scheme or Lisp in the sense that *all* languages are.

H.

unread,
Jan 4, 2006, 1:37:34 PM1/4/06
to
Thanks for the extensive reply.

>
> Scheme:
> (let* ((x 2)
> (y (* x 2))
> (z (* y 2)))
> (list x y z))

I have a question about this snippet, but it's not related to the
current thread. I notice tht you use "let*" instead of "let", when
"let" alone seems like it would work fine, because y is dependent on x
and z on y. Therefore, I was wondering if there is some special reason
you used the "let*" form that I'm not aware of, or if it was just by
habit. Humor me, please; I'm just learning the language. : )


>
> Equivalent Javascript (It's actually not quite equivalent because it
> returns an array instead of a list, but close enough):
>
> (function(x) {
> return (function (y) {
> return (function (z) {
> return [x,y,z];
> }(y*2));
> })(x*2);
> })(2);

This doesn't look so bad to me; I just draw circles in my head to
organize the code. But admittedly the Scheme version is much cleaner.

>
> This took me 5-10 minutes to write because I forgot about Javascript's
> bizarre whitespace rules, which make this fail silently if you put a

> break after the "return"s...

I'm not familiar with the whitespace rules of which you speak. I spent
a few minutes googling about trying to find reference to them, but
can't. Could you please clarify? I've written lots of JavaScript code
(for a job actually), and never came across it before. My interest is
piqued.

> In real life, of course, you would just do this:
> var x=2;
> var y=x*2;
> var z=y*2;
> [x,y,z]
>
> But this isn't doing the same thing. The difference may appear subtle
> or unimportant, but there are times when it really matters, as it did
> to this guy:
> http://joust.kano.net/weblog/archive/2005/08/08/a-huge-gotcha-with-javascript-closures/
> who did "hours of debugging" because he didn't understand closures (and
> still didn't when he wrote this article.

I read the article, and re-read it, and I re-looked up the definition
of closures, which I think of as static variables, trying to understand
the statement"he didn't understand closures (and still didn't when he
wrote this article)."

So there are two issues:
1. Do I properly understand what closures are? Unknown. I think of them
as being more or less equivalent to static variables in C++, which
retain their information between function calls. How is my comparison
correct and/or incorrect?

2. Does this guy understand what closures are? I don't understand. How
does he not understand what closures are? --because he didn't
understand why his first snippet of code didn't work?

> Scheme has this. It's called "call-with-current-continuation," and it
> does a lot more.

Admittedly, I've looked at call//cc a little bit, but found it
confusing, and then felt really stupid because I read that a decently
smart person could understand all of Scheme in ten minutes. Thus, I'm
not decently smart. That's fine; working on that assumption, educate
me. : ). Perhaps if I learn enough I can masquerade in the "decently
smart" category.

You can define return like this:
>
> (define (fact x)
> (call/cc
> (lambda (return)
> (when (< x 0)
> (return "error"))
> (if (= x 0)
> (return 1)
> (return (* x (f (- x 1))))))))

It looks like this snippet both defines "return" and uses it in the
same construction. I'll have to look at it more; you're both using it
as an argument and then using it as a known special form. (?). I'm
confused how you're both defining a factorial function and defining
return at the same time. Did I miss some steps?

[...]


>
> Which allows you to define a Javascript-like function with "return":
>
> (function fact (x)
> (when (< x 0)
> (return "error"))
> (if (= x 0)
> (return 1)
> (return (* x (f (- x 1))))))
>
> (fact 5) => 120
>
> But nobody does this because it's ugly and unnecessary.

I've been spoiled, corrupted; I don't find it ugly. But unnecessary,
certainly.


>
Ruby and Python have no
> unique features that aren't available in any other language, but they
> have become popular because they are put together in a way that makes
> them superior to other languages for certain people.

As has JavaScript; it's put together in a way that makes it edible for
the masses, which could just as well be defined as "certain people." So
I'm confused if I should learn a language if it appeals to certain
people; could that not apply to most every language in existence?

(I'm not trying to be difficult, although it may seem that way. I do
tend to interpret on the literal side of things, for better or worse.)

Thanks.

H.

unread,
Jan 4, 2006, 1:41:30 PM1/4/06
to
Even if you have 10 nested level of parens, determining what goes with
what? I use a brace checker when entering code into the interpreter,
but it's not there when writing by hand. Even Abelson and Sussman used
a brace checker when entering code to make sure they were closing off
what they thought they were closing off. If it's really as easy as
claimed, why would the brace checker be necessary at all?

H.

unread,
Jan 4, 2006, 1:58:32 PM1/4/06
to
In reference to the quote:

"Parentheses? What parentheses? I haven't noticed any parentheses
since my first month of Lisp programming. I like to ask people who
complain about parentheses in Lisp if they are bothered by all the
spaces between words in a newspaper..." -- Kenny Tilton

Here is my take, as someone just getting used to Scheme: the
parentheses are great for deliminating things, as spaces are for words.
The problem for me is that they serve double, triple, and quadruple
duty. They have multiple meanings depending on context.

What would happen, for instance, if we used only the comma in English,
for everything, for questions and pauses and periods and colons, etc,
it would be difficult on first reading to tell if the writer meant the
comma to be used for a pause or end of sentence, by having a period,
that's an instant sign that the end of the sentence has occurred, that
is why I like having (), {}, and [] available for different things, {}
is used for the body of something, () for control loops, and [] for
array declarations, harder to learn, easier to read, if you found this
paragraph difficult to read, it's because i've used only commas, which
is sometimes how reading advanced Scheme feels to me, it must be
deconstructed in context to find out what symbolic meaning each ( and )
has.

I'm sure, of course, it's easy for those more experienced than myself.
: )

H.

unread,
Jan 4, 2006, 2:04:07 PM1/4/06
to
>>Actually, no one I know programs in Scheme or Lisp directly. Neither
>>is suitable for solving anything but the most trivial problems `out of
>>the box'.

I've heard it claimed in a UC Berkeley lecture that writing things in
Lisp or Scheme would actually speed up the implementation for things,
that, for instance, if there was a programming contest in Java, it
might be faster to write a Java to Lisp interpreter, and write the
solution in Lisp. I have no idea if it's true.


12. Joe Marshall
Jan 4, 12:41 am show options
Newsgroups: comp.lang.scheme
From: "Joe Marshall" <eval.ap...@gmail.com> - Find messages by this
author
Date: 4 Jan 2006 00:41:27 -0800
Local: Wed, Jan 4 2006 12:41 am
Subject: Re: Scheme as a religion
Reply | Reply to Author | Forward | Print | Individual Message | Show
original | Report Abuse

Actually I think the reverent adherents are academics, who, based on
replies in this thread, have no intention of changing it into anything
else.

Jens Axel Søgaard

unread,
Jan 4, 2006, 2:07:05 PM1/4/06
to
H. wrote:

>>Scheme has this. It's called "call-with-current-continuation," and it
>>does a lot more.
>
> Admittedly, I've looked at call//cc a little bit, but found it
> confusing, and then felt really stupid because I read that a decently
> smart person could understand all of Scheme in ten minutes. Thus, I'm
> not decently smart. That's fine; working on that assumption, educate
> me. : ). Perhaps if I learn enough I can masquerade in the "decently
> smart" category.

Grokking call/cc in its glory takes a bit more than 10 minutes :-)


Take a look at Daniel P. Friedman's "Applications of Continuations:
Invited Tutorial" at

<http://www.cs.indiana.edu/hyplan/dfried/appcont.pdf>

--
Jens Axel Søgaard

Brian Harvey

unread,
Jan 4, 2006, 2:11:33 PM1/4/06
to
"H." <hbe...@gmail.com> writes:
> I notice tht you use "let*" instead of "let", when
>"let" alone seems like it would work fine, because y is dependent on x
>and z on y.

Nope. The whole difference between LET and LET* is that the former evaluates
all the value expressions before any of the local variables are created, while
the latter does one variable at a time.

>Admittedly, I've looked at call//cc a little bit, but found it
>confusing, and then felt really stupid because I read that a decently
>smart person could understand all of Scheme in ten minutes.

Whoever wrote that should have said "a decently smart person can understand
all of Scheme except for macros and continuations in ten minutes."

IMHO *nobody* understands Scheme macros and continuations; that's why they
keep finding bugs in RnRS wherein, for example, some other feature doesn't
work if you use call/cc in the middle of it, and it's why there are recurring
threads in the newsgroup in which major macro wizards disagree about how to
implement something or other. :-)

Those two features are sort of like quantum physics: They kind of work, but
they're clearly way too complicated to be what God really had in mind when
he created the universe (unlike the rest of Scheme, which is clearly God's
programming language). They're waiting for someone to discover a huge
simplification.

(The above is a metaphor; I'm an atheist.)

Brian Harvey

unread,
Jan 4, 2006, 2:17:50 PM1/4/06
to
"H." <hbe...@gmail.com> writes:
> that
>is why I like having (), {}, and [] available for different things, {}
>is used for the body of something, () for control loops, and [] for
>array declarations

Many Scheme interpreters allow [] instead of (), so you can feel free to use
'[] when entering data. (But I prefer to use [] for the cases that really
are exceptional, namely COND clauses and LET bindings. It's one of the
shining virtues of Scheme that expressions are data, so we *like* having
procedure bodies look like (because they are) lists.)

Nils M Holm

unread,
Jan 4, 2006, 2:24:12 PM1/4/06
to
H. <hbe...@gmail.com> wrote:
> Thanks for the extensive reply.
> >
> > Scheme:
> > (let* ((x 2)
> > (y (* x 2))
> > (z (* y 2)))
> > (list x y z))
>
> I have a question about this snippet, but it's not related to the
> current thread. I notice tht you use "let*" instead of "let", when
> "let" alone seems like it would work fine, because y is dependent on x
> and z on y. [...]

LET would not work in this case /because/ the value of Y depends on X
and the value of Z on Y (and so ultimately on X, too). LET first
evaluates /all/ of the values and then binds the values to its
arguments, so X is either unbound or bound outside of LET when the
values of Y and Z are evaluated.

For example:

(define x 'outer)
(let ((x 'inner)
(y x))
y)
=> outer

but

(define x 'outer)
(let* ((x 'inner)
(y x))
y)
=> inner

LET* is just a short form of nested LET. Instead of

(let* ((x 'inner)
(y x))
y)

you can write

(let ((x 'inner))
(let ((y x))
y))

> So there are two issues:
> 1. Do I properly understand what closures are? Unknown. I think of them
> as being more or less equivalent to static variables in C++, which
> retain their information between function calls. How is my comparison
> correct and/or incorrect?

A closure is a function that captures its outer context at the time
of its creation:

(define x 'outer)
(define f
(let ((x 'inner))
(lambda () x)))

After evaluating the value of F (which is a closure), X remains bound
to OUTER.

x => outer

At the time of the creation of F, though, X is bound to INNER.
Therefore, all instances of X inside of F get the value INNER:

(f) => inner

> > (define (fact x)
> > (call/cc
> > (lambda (return)
> > (when (< x 0)
> > (return "error"))
> > (if (= x 0)
> > (return 1)
> > (return (* x (f (- x 1))))))))
>
> It looks like this snippet both defines "return" and uses it in the
> same construction. I'll have to look at it more; you're both using it
> as an argument and then using it as a known special form. (?). I'm
> confused how you're both defining a factorial function and defining
> return at the same time. Did I miss some steps?

(LAMBDA (RETURN) ...) is a function that is passed to CALL/CC.
CALL/CC captures the current continuation and passes it to that
function where it gets bound to RETURN:

(call/cc (lambda (return) ...))

becomes

((lambda (return) ...) #<continuation>)

where #<continuation> is the continuation captured by CALL/CC.
Applying RETURN to a value makes CALL/CC return that value.

--
Nils M Holm <n m h @ t 3 x . o r g> -- http://www.t3x.org/nmh/

alex...@gmail.com

unread,
Jan 4, 2006, 2:32:39 PM1/4/06
to

It's a good point, actually. Some effort is required to see which '('
goes with which ')'. Proper indentation helps here (Abelson and Sussman
liked to enter expressions in one line). Also, your editor can help:
Emacs has a submode (on the internet somewhere), where it will make the
faces of the more nested expressions slightly darker or lighter than
their parent's. I think you can also have a rainbow or something
instead.

Joe Marshall

unread,
Jan 4, 2006, 2:34:20 PM1/4/06
to
A student, in hopes of understanding the Lambda-nature, came to
Greenblatt. As they spoke a Multics system hacker walked by. "Is it
true", asked the student, "that PL-1 has many of the same data types as
Lisp?" Almost before the student had finshed his question, Greenblatt
shouted "FOO!" and hit the student with a stick.
(Danny Hillis)
---------------

I amused myself for some time thinking of responses to your post. In
the end, however, I decided that as entertaining it might be (to me)
for you to attain enlightenment in the old-school manner, that a more
socratic approach might be fruitful.

You've formed your opinion through googling and watching web-casts. Do
you now believe that you are sufficiently well informed about computer
languages to weigh the merits of learning a particular one?

Which companies in the computer industry do you think are `scoffing' at
Scheme and Lisp?

Why do you hope to attend Berkeley rather than, say, DeVry Institute?
Why attend a university that teaches things that are not respected by
industry? Why spend your hard-earned money listening to `academics'?

Why do you think universities such as Berkeley, MIT, Harvard, Stanford,
Yale, etc. have universally been suckered into this `religion' while
lesser-known schools have remained immune? Do you find it unusual that
universities give tenure to people who are `scoffed at'?

In my experience, the people who promote Scheme and Lisp are amazingly
smart. I consider myself very fortunate to have been able to work with
these people. Which do you think is more likely: that these people
who are at the forefront of computer science have been universally
blindsided by a hokey religion involving parenthesis and first-class
functions, or that they have carefully considered the rationale for
using a tool such as Scheme or Lisp and decided that it was a superior
tool *despite* the noticable drawbacks?


>To me, Scheme seems difficult to grok on first reading (or even second,
>or third) comprehend by it's rule of relying so much on single
>parenthesis. (Yes, I think the LISP nickname of "Lots of Irritating
>Single Parenthesis" fits). It seems to me that there are scripting
>languages that are easier to read and write that teach many of the same
>concepts.

Couldn't the surface syntax of Scheme or Lisp be changed to make it
easier to read? Couldn't it at least be made a tiny bit simpler than
it is? Why hasn't this happened?

Why would professors choose to use a language that is difficult to read
when `there are scripting languages that are easier to read and write
that teach many of the same concepts'? Are the professors ignorant of
these alternatives?

> As a last note: not to evangelicize JavaScript either, there clearly
> some areas for which JavaScript does not teach the same metaphors. The
> only way to create linked lists, for instance, is to create your own
> linked list data structures, whereas in Scheme, the whole weird car,
> cdr, cadr terms can prepare the student for linked lists. But as to why
> beginning programming students have to be exposed to terms like car,
> cdr, cddar, caaddr, etc, I don't get that either. Please don't tell me
> that those names are in the least way transparent or aid in
> understanding. The nomenclature alone is a stumbling block to the
> powerful concepts for which they stand.

I mentioned earlier that the names `car', 'caddr' etc. are simply
traditional jargon and have little rational defense other than
`historical background and common usage', but let us suppose there were
some hidden reason known only to Nineteenth Level Masons of the
Scottish Rite and therefore they cannot be questioned by us mere
mortals.

How many of these nomenclature idiosyncracies are there? A dozen? A
thousand? Do you think you should pursue a career in computer science
if a handful of odd-sounding names is that big a barrier to
understanding?

Nils M Holm

unread,
Jan 4, 2006, 2:35:37 PM1/4/06
to
H. <hbe...@gmail.com> wrote:
> Admittedly, I've looked at call//cc a little bit, but found it
> confusing, and then felt really stupid because I read that a decently
> smart person could understand all of Scheme in ten minutes. [...]

IMO, confusion is a pretty normal state of mind when dealing with
continuations. Understanding them takes /definitely/ more than 10
minutes, and even after studying them for quite a while, there are
always some surprises left.

H.

unread,
Jan 4, 2006, 2:58:57 PM1/4/06
to
>>Nope. The whole difference between LET and LET* is that the former evaluates
>>all the value expressions before any of the local variables are created, while
>>the latter does one variable at a time.

Yeah, thanks.. I temporarily flip-flopped them in my head. Hopefully I
can get these glitches out of my head before I find myself in your
classroom. (The nature of monikers like "H." is that you won't know who
I am straightaway and thus if I say something really stupid here I
won't have to worry about it.)

Back to let*, Didn't I hear you say in a lecture that good Scheme
programs should never have to use let*?

Does that mean that:


(let* ((x 2)
(y (* x 2))
(z (* y 2)))
(list x y z))

is not an ideal example of closure and there is a better one?

The code snippet was an example of why lisp code can be easier to grok
than JavaScript code in a certain situation involving function
closures. I am wondering if the only cases where this is so involve
nested lets.

Anton van Straaten

unread,
Jan 4, 2006, 3:22:26 PM1/4/06
to
H. wrote:
>>This took me 5-10 minutes to write because I forgot about Javascript's
>>bizarre whitespace rules, which make this fail silently if you put a
>>break after the "return"s...
>
>
> I'm not familiar with the whitespace rules of which you speak. I spent
> a few minutes googling about trying to find reference to them, but
> can't. Could you please clarify? I've written lots of JavaScript code
> (for a job actually), and never came across it before. My interest is
> piqued.

I believe the OP was saying that if you write the following:

return
function () {
...
}

That this is equivalent to:

return;
function () {
...
}

...which doesn't do what was intended. Javascript has various default
situations in which it assumes statement termination, which can really
get in the way if you're writing certain kinds of nested expressions.

> I read the article, and re-read it, and I re-looked up the definition
> of closures, which I think of as static variables, trying to understand
> the statement"he didn't understand closures (and still didn't when he
> wrote this article)."
>
> So there are two issues:
> 1. Do I properly understand what closures are? Unknown. I think of them
> as being more or less equivalent to static variables in C++, which
> retain their information between function calls. How is my comparison
> correct and/or incorrect?

It's incorrect in that there can only be one "instance" of a particular
static variable in C++, whereas you can have any number of instances of
a closure created by the same function. Simple example:

(define (adder x)
(lambda (y)
(+ x y)))

Or in JS: function adder(x) { return function (y) { return x+y; }}

Now, if you invoke adder n times with n different values for x, you have
n closures, each of which has a different value for x in its
environment. You can't do that with static variables alone.

> 2. Does this guy understand what closures are? I don't understand. How
> does he not understand what closures are? --because he didn't
> understand why his first snippet of code didn't work?

His descriptions of how to "work around" the perfectly correct behavior
that he describes indicate that he has incorrect expectations about what
closures should do.

It's interesting to note that while his ultimate "workaround" shows a
correct use of closures, that he resorted to defining a named function
called "createFunction" in order to achieve this. In the comments,
Maarten posted a correct inline version, which looks like this:

var f = function (y) { return function() { alert(y) } }(x);

However, this is harder than it needs to be in Javascript because of the
lack of a lexically-scoped 'let'. The above could be expressed in
Scheme as:

(let ((y x))
(let ((f (lambda () (alert y))))
...))

i.e. y is being used merely to "fix" the current value of x, so that
subsequent changes to the value of x won't affect the generated
closures. Having to implement 'let' by performing function
applications, as in the Javascript case, is a big barrier to effective
use of closures, and probably goes a long way towards explaining the
difficulty that many Javascript programmers have with the concept.

This is hardly the sort of thing one wants in a language used for
teaching, and nor do you want it if you're actually going to try and
make serious use of closures.

>> You can define return like this:
>>
>>
>> (define (fact x)
>> (call/cc
>> (lambda (return)
>> (when (< x 0)
>> (return "error"))
>> (if (= x 0)
>> (return 1)
>> (return (* x (f (- x 1))))))))
>>

> I'm
> confused how you're both defining a factorial function and defining
> return at the same time. Did I miss some steps?

Since "return" returns from the function in which it's used, it has to
be defined for each function. The above function defines what "return"
means for "fact", and then uses it. You can bake that into the language
using a macro, as the OP pointed out.

The same issue exists in Javascript -- you can't, for example, define an
ordinary global function that behaves like "return". Instead, it has to
be built into the language. The difference in Scheme is that you can
see what "return" really means, you can implement it yourself, and you
can implement function definition constructs that support it by default
if you want to. You can also implement function definition constructs
that have other semantics. Such things are essentially impossible in
Javascript.

> I've been spoiled, corrupted; I don't find it ugly. But unnecessary,
> certainly.

It's not so much that "return" is syntactically ugly, but that its
goto-like behavior is semantic overkill, and hence ugly. Appreciating
that requires an understanding of both functional language semantics and
imperative language semantics.

Anton

rsher...@gmail.com

unread,
Jan 4, 2006, 3:24:11 PM1/4/06
to
>I'm not familiar with the whitespace rules of which you speak. I spent
>a few minutes googling about trying to find reference to them, but
>can't. Could you please clarify? I've written lots of JavaScript code
(>for a job actually), and never came across it before. My interest is
>piqued.

function f() { return 2;}
f() -> 2

function f() { return
2;
}
f() -> undefined

In most languages, a line break after return wouldn't make any
difference.

>Admittedly, I've looked at call//cc a little bit, but found it
>confusing, and then felt really stupid because I read that a decently
>smart person could understand all of Scheme in ten minutes. Thus, I'm
>not decently smart.

call/cc was the hardest thing about Scheme for me to learn, and I'm not
sure I really understand them even now. At this point you probably
shouldn't worry too much about them - learn the basics first. Just
know that with call/cc you can implement generators, coroutines,
threads, exceptions, and other neat stuff that would be black magic
controlled by benevolent dictators in other languages. For this
example, you can think of it as defining a procedure "return" which
returns its argument to fact's caller.

>> unique features that aren't available in any other language, but they
>> have become popular because they are put together in a way that makes
>> them superior to other languages for certain people

>As has JavaScript; it's put together in a way that makes it edible for


>the masses, which could just as well be defined as "certain people." So
>I'm confused if I should learn a language if it appeals to certain
>people; could that not apply to most every language in existence?

Every language (that has gained any traction) must be doing something
right for some people, or they wouldn't be using it. PHP is good for
people who want to write simple web applications without learning too
much, but do you really care? I don't. I don't mean to imply that you
should learn a language just because it appeals to "certain people,"
unless you're in that group for that particular language.

Anton van Straaten

unread,
Jan 4, 2006, 3:26:33 PM1/4/06
to
Joe Marshall wrote:
> A student, in hopes of understanding the Lambda-nature, came to
> Greenblatt. As they spoke a Multics system hacker walked by. "Is it
> true", asked the student, "that PL-1 has many of the same data types as
> Lisp?" Almost before the student had finshed his question, Greenblatt
> shouted "FOO!" and hit the student with a stick.
> (Danny Hillis)
> ---------------
>
> I amused myself for some time thinking of responses to your post. In
> the end, however, I decided that as entertaining it might be (to me)
> for you to attain enlightenment in the old-school manner, that a more
> socratic approach might be fruitful.

Alternatively, you could mail a stick to Brian Harvey -- he might need
it in the upcoming weeks!

H.

unread,
Jan 4, 2006, 3:27:04 PM1/4/06
to
>>In short, the impression that religion is involved is misleading. Or
>>put it this way: any worshipping that might take place has a solid
>>technical justification, even if that isn't apparent from a superficial
>>comparison to more common languages.

Yes, well, I figured my comparison was superficial: ergo, the post, in
order that I could learn in which ways my comparison was such. I've
learned quite a bit, and realized at the same time, how very little I
know.

H.

unread,
Jan 4, 2006, 3:44:20 PM1/4/06
to
>>PHP is good for
>>people who want to write simple web applications without learning too
>>much, but do you really care? I don't.

Ha. I get the point. But this was a funny example because I made my
bread and butter in the web industry for a few years, and so at the
time I cared. But like, I said, I get the point. Had I not earned my
living that way, I probably wouldn't have cared.

About php: writing a web application without learning too much seems to
apply in the "cold fusion" camp more than php, not that php is hard to
use, but cfml uses tag-based markup based familiar to anyone who can
write html. php was first created because it filled an open-source
space that asp and cold fusion didn't. Microsoft and their active
server pages and Allaire* and their cold fusion markup language both
required software on servers, which, of course, wasn't free. php was. I
think their popularity was due to as much about the fact they were free
than about being easier than cfml.

*Allaire was subsequently bought out by Macromedia and Macromedia by
Adobe. Little fish gets eaten by big fish gets eaten by a bigger fish.
But that's another story.

Tom Lord

unread,
Jan 4, 2006, 3:47:53 PM1/4/06
to
> No one here thinks CAR, CADR, etc. is somehow mystically better than
> FIRST, SECOND, THIRD, etc. It's just a stupid tradition that's grown
> into the culture.

Maybe I'm "no one" but I think CAR, CADR, etc are a very smart
tradition
and are much better than FIRST, SECOND, THIRD, etc. I agree there
is nothing mystical about it.

The C[AD]+R family of functions provide nice short names for every
possible
element of a binary tree up to depth four. FIRST, SECOND, etc. are
longer
and less regular names for a smaller number of tree parts, even if you
add REST.

-t

H.

unread,
Jan 4, 2006, 3:54:06 PM1/4/06
to
The binary point is a good one. Still, it seems like there should be
something more intuitive than car, cadr, etc. Like the first letter
represents how many elements over, the second letter represents how
many to step over on that one element, and the third letter represents
whether we want the element we are on or the remainder of the list.

Brian Harvey

unread,
Jan 4, 2006, 4:12:53 PM1/4/06
to
"H." <hbe...@gmail.com> writes:
> (The nature of monikers like "H." is that you won't know who
>I am straightaway and thus if I say something really stupid here I
>won't have to worry about it.)

I know you didn't mean it this way, but that's actually somewhat insulting.
You think I only like to teach students who already know everything?
Believe me, what I like is students who ask questions.

>Back to let*, Didn't I hear you say in a lecture that good Scheme
>programs should never have to use let*?

What I'm guessing I said is that if you use LET* /a lot/ then you're probably
thinking in the wrong paradigm. "Never" is way too strong; I've certainly
found uses for it.

Ray Dillinger

unread,
Jan 4, 2006, 7:57:38 PM1/4/06
to
alex...@gmail.com wrote:
>
> We need an obfuscated Scheme contest.
>

if call/cc and macros are allowed, that would be like
using an atom bomb to kill a bunnyrabbit.

Bear

H.

unread,
Jan 4, 2006, 8:32:34 PM1/4/06
to
hey, that's neat about []. I didn't know that. I just tried it in UCB
Scheme and it works fine. Thanks.

H.

unread,
Jan 4, 2006, 8:51:30 PM1/4/06
to
>>I know you didn't mean it this way, but that's actually somewhat insulting.

Sorry :0. That definitely wasn't the intention.

>>You think I only like to teach students who already know everything?

I see your point. That would make your job rather boring, and less
purposeful too.

And yet, being Berkeley, being one of the best engineering departments
in the nation, I would expect that you expect a certain quality of
question, and a certain type of student. I suspect that a lot of
students are concerned they might not live up to that expectation
(okay: I'm concerned I might not live up to it. But not from lack of
trying.)

I should add: I received a 99 and 100 average in programming courses
I've taken, but the difficulty level was pathetic, as in pathetically
easy. I have a resume of work accomplishments, but they weren't
difficult (if you've ever used Dreamweaver, I wrote part of the code in
their extensible scripting language, which resembles JavaScript, which
is why I compare everything back to that language). But that wasn't
hard either. It's actually easy to earn a living in the computer
industry knowing surprisingly little and without a college degree,
which is what I did once, and then decided it wasn't intellectually
satisfying. But Berkeley is a whole different level than the chicken
code I once got paid to write. So for me, there's this concern: what
will the professor think? Will s/he think less of me as I ask such and
such a question? I'm glad to hear that in your case, it's no.

>> Believe me, what I like is students who ask questions.

Good. Glad to hear it. Asking questions, perhaps to the point of
annoyance, is right up my alley. : )

Ray Blaak

unread,
Jan 4, 2006, 8:59:28 PM1/4/06
to
"H." <hbe...@gmail.com> writes:
> So for me, there's this concern: what will the professor think? Will s/he
> think less of me as I ask such and such a question? I'm glad to hear that in
> your case, it's no.

Overtime I have learned that it is better to ask the question than not. At the
very least, for selfish reasons, you are only getting your money's worth of
tuition if you try to learn something.

Also, in practice there is a very high probability that more than a few others
benefit from the question as well.

--
Cheers, The Rhythm is around me,
The Rhythm has control.
Ray Blaak The Rhythm is inside me,
rAYb...@STRIPCAPStelus.net The Rhythm has my soul.

H.

unread,
Jan 4, 2006, 9:09:48 PM1/4/06
to

>>Why would professors choose to use a language that is difficult t >>read when `there are scripting languages that are easier to read >>and write that teach many of the same concepts'? Are the >>professors ignorant of these alternatives?

I don't know what languages professors are aware of. That's one of the
reasons I'm posting the question.

>>but let us suppose there were
>>some hidden reason known only to Nineteenth Level Masons of >>the Scottish Rite and therefore they cannot be questioned by us >>mere mortals.

To reply in the same tongue-in-check tone: I was in Scotland this
summer (this is true), and I didn't see any 19th Level Masons of the
Scottish Right. The tour book unfortunately didn't list them.

>>How many of these nomenclature idiosyncracies are there? A >>dozen? A thousand? Do you think you should pursue a career in >>computer science if a handful of odd-sounding names is that big a >>barrier to understanding?

Perhaps I should clarify, it's not that I can't understand them, it's
that it seems odd to have those names. But I see your point -- now --
about their usefulness.

>>You've formed your opinion through googling and watching >>web-casts. Do you now believe that you are sufficiently well >>informed about computer languages to weigh the merits of learning a particular one?

Most definitely not. Ergo, the post.

>>Which companies in the computer industry do you think are `scoffing' at Scheme and Lisp?

Not companies, individuals I know who had to lean Scheme in academia
and then went into the computer industry.

>> In my experience, the people who promote Scheme and Lisp are amazingly smart. I consider myself very fortunate to have been able >> to work with these people.

If this group of people is any indication, I must heartedly agree (that
those who advocate Scheme are incredibly sharp).

Joe Marshall

unread,
Jan 5, 2006, 12:19:55 AM1/5/06
to
H. wrote:
>
> I don't know what languages professors are aware of. That's one of the
> reasons I'm posting the question.

I've recently finished up a 3-year project with the `Programming
Languages and Theory' Group at Northeastern University. I worked with
a number of the professors there. All they do is think about, talk
about, and write about programming languages. It's almost an
obsession. We had visitors from all over the world dropping in to
discuss the latest innovations in programming languages. For example,
Jeffrey Mark Siskind talked about his efforts to add automatic
differentiation to functional languages. (The idea is basically this:
in a functional language, a program is a mathematical function. In
theory, you ought to be able to do calculus on the entire program.)
Oleg Kiselyov gave a talk about Kanren, a declarative logic programming
system with first-class relations. (In English: the language contains
operations that allow the programs to logically reason about other
programs. You can not only write a program, you can have the computer
construct a proof that the program is correct.) David MacQueen came by
to discuss his thoughts on types. Strother Moore came by to discuss
the work he's doing with ACL2 (he developed the language used by AMD to
formally prove that there are no logic errors in the floating point
system.) Martin Odersky came by to discuss his language `Scala'. The
languages group at Microsoft came by to discuss their language design.
People from Sun come by to discuss the future of Java. And it's not
just dry, theoretic stuff, either. Everybody has cool projects and
demos that show off their language ideas. There is stuff people are
doing that I would have sworn was impossible (and I could have given
you a compelling argument why!), yet there it is, running.

These guys are not out of touch with what is going on.

Now if this sounds insanely geeky and dull, then you probably don't
want a career in computer science. For me, it was a total blast
hanging out and discussing computer language ideas with these guys.

If you asked these guys what computer language was the `best', you'd
get at least as many opinions as people you had asked. (Unlike most
intellectual fields, the minimum number of computer scientists needed
to have an argument is less than 2.) If you asked them what computer
language to learn *first*, they would all agree on Lisp. (The static
type people might mutter under their breath, and there may be some
debate over whether Scheme is best variant of Lisp).

If you want a career in computer science, you won't get past square one
without knowing Scheme. Period. From there, it is much easier to move
on to whatever other language you find interesting.

If you just want a job in computers, then pick Java or C++ (or C# if
you want a career in Microsoft products).

> >>but let us suppose there were
> >>some hidden reason known only to Nineteenth Level Masons of >>the Scottish Rite and therefore they cannot be questioned by us >>mere mortals.
>
> To reply in the same tongue-in-check tone: I was in Scotland this
> summer (this is true), and I didn't see any 19th Level Masons of the
> Scottish Right. The tour book unfortunately didn't list them.

It is, after all, a secret society. They don't try to get written up
by Michelin's? Have you even seen a Mason lodge with a `Zagat's guide'
sticker in the window? ``Citysearch award Best Secret Society 2004''?

David Rush

unread,
Jan 5, 2006, 12:26:51 AM1/5/06
to
H. wrote:
> In reference to the quote:
>
> "Parentheses? What parentheses? I haven't noticed any parentheses
> since my first month of Lisp programming. I like to ask people who
> complain about parentheses in Lisp if they are bothered by all the
> spaces between words in a newspaper..." -- Kenny Tilton
>
> Here is my take, as someone just getting used to Scheme: the
> parentheses are great for deliminating things, as spaces are for words.
> The problem for me is that they serve double, triple, and quadruple
> duty. They have multiple meanings depending on context.

Talk about waving a red flag in front of a bull :)

Actually, Scheme is one of the few languages where it's puctuation is
free of multiple meanings. If you don;t see that, you haven't grasped
the deep-structure of the language yet.

drr
--
who is desperately in need of sleep

David Rush

unread,
Jan 5, 2006, 12:47:40 AM1/5/06
to

Deep-structural understanding is absent again. Lisp doesn't really have
lists (surprise) it has binary trees which are conventionally used to
represent lists. So once again, by a lovely (and parsimonious)
reduction of cases c[ad]+r is sufficient.

david rush
--
Have another red pill. They're yummy.

Joe Marshall

unread,
Jan 5, 2006, 12:47:54 AM1/5/06
to
Good point.

And vice versa: for the most part, there aren't multiple punctuations
that mean the same thing, either.

(I never liked the square bracket hack.)

David Rush

unread,
Jan 5, 2006, 1:03:16 AM1/5/06
to
Joe Marshall wrote:
> It's a funny religion when its adherents don't use the purported object
> of worship except to change it into something else.

Kinda like most religions in the world, actually :)

david rush
--
But Scheme is a cult ;)

Brian Harvey

unread,
Jan 5, 2006, 1:08:41 AM1/5/06
to
Ray Dillinger <be...@sonic.net> writes:
>> We need an obfuscated Scheme contest.
>if call/cc and macros are allowed, that would be like
>using an atom bomb to kill a bunnyrabbit.

But, we already have this! It's just that instead of an annual event, it is
triggered whenever someone posts a request for the newsgroup to do his
homework. :-)

Brian Harvey

unread,
Jan 5, 2006, 1:18:48 AM1/5/06
to
"H." <hbe...@gmail.com> writes:
>And yet, being Berkeley, being one of the best engineering departments
>in the nation, I would expect that you expect a certain quality of
>question, and a certain type of student.

I hate to disappoint you, but far too many Berkeley students ask questions
like "will this be on the exam?" and "what do I have to do to get an A in
this course?" and "can I do some extra credit work [to make up for my
amazingly bad exam performance]?"

If you ask questions *about computer science* instead of about grade-grubbing,
you'll be better than average no matter how much ignorance is displayed in
the question.

I confess that on bad days I get annoyed by questions that pose an analogy
between something in computer science and something in cosmology or quantum
physics (even though I did that myself earlier in this thread! Do as I say,
not as I do). :-)

Brian Harvey

unread,
Jan 5, 2006, 1:27:33 AM1/5/06
to
"Joe Marshall" <eval....@gmail.com> writes:
> (Unlike most
>intellectual fields, the minimum number of computer scientists needed
>to have an argument is less than 2.)

This was the only thing in your otherwise excellent message that I found
dubious. Do you have any evidence for the first four words? I've never met
any serious intellectual in any area who couldn't entertain divergent ideas.

H.

unread,
Jan 5, 2006, 2:38:10 AM1/5/06
to
I get the fact that structures are data are just about everything else.
Procedures are data, and all that jazz. Lists are pairs are lists are
trees are abstract data types and so on.

But consider conditional statements, where both the condition and the
body are defined by the same syntax. I think that the conditional
statements are one meaning, and what happens if the condition is
meant(the body) are another.

if
[condition]
then
[do something]

is the pseudocode, and in Scheme, single parens are used for both the
condition and do something.In both "if" and "cond". So in this case,
the punctuation does in fact have multiple meanings to me. I'm not
saying it's good or bad, but that it is. Thus I don't agree with
"Scheme is one of the few languages where it's punctuation is free of
multiple meanings."

Giorgos Keramidas

unread,
Jan 5, 2006, 3:12:02 AM1/5/06
to
On 4 Jan 2006 23:38:10 -0800, "H." <hbe...@gmail.com> wrote:
> I get the fact that structures are data are just about everything else.
> Procedures are data, and all that jazz. Lists are pairs are lists are
> trees are abstract data types and so on.
>
> But consider conditional statements, where both the condition and the
> body are defined by the same syntax. I think that the conditional
> statements are one meaning, and what happens if the condition is
> meant(the body) are another.
>
> if
> [condition]
> then
> [do something]
>
> is the pseudocode, and in Scheme, single parens are used for both the
> condition and do something.In both "if" and "cond". So in this case,
> the punctuation does in fact have multiple meanings to me.

That's because you miss the fact that '(if cond body) is an
``expression'' too.

> I'm not saying it's good or bad, but that it is. Thus I don't agree
> with "Scheme is one of the few languages where it's punctuation is
> free of multiple meanings."

Not really. There is only one 'meaning' in parentheses, and this is to
delimit ``expressions''.

This is an expression:

1

This is an expression too:

(1 2)

This is yet another expression:

(if 1 2)

The following are also expressions:

(if 1 (2 3))
(if (1 2) 3)
(if (1 2) (3 4))

There's nothing 'special' about the positioning of what you call 'body',
which alters the meaning of the parentheses.

The 'meaning' of every expression part is something that depends on
other factors (i.e. if the car of the first cons cell contains a symbol
and if that symbol is bound to a function, etc), but it doesn't really
depend on the particular characters used to delimit expressions. Given
a suitably modified reader, you can even write something that resembles
Scheme using brackets, if that's what suits you:

{if condition body}
{define foo '{1 2 3}}
{define fact
{lambda {k}
{cond {{< k 0} #f}
{{< n 2} 1}
{t {letrec
{{fact-iter {lambda {i num accum}
{if {> i num}
accum
{fact-iter {+ i 1} num {* i accum}}}}}}
{fact-iter 1 k 1}}}}}}

Anton van Straaten

unread,
Jan 5, 2006, 5:35:41 AM1/5/06
to
H. wrote:
> if
> [condition]
> then
> [do something]
>
> is the pseudocode, and in Scheme, single parens are used for both the
> condition and do something.

Hmm? (if x y z) is a valid Scheme IF expression, assuming x, y, and z
are all defined variables. I don't see the single parens you mention
for the condition or the actions. Scheme programs are made up of
expressions. If there are parens inside an IF expression, it's because
they form part of a particular subexpression. They'd still be needed if
you moved that subexpression outside the IF. The parens don't have
special meaning relative to the IF.

Anton

Brian Harvey

unread,
Jan 5, 2006, 5:56:10 AM1/5/06
to
Giorgos Keramidas <kera...@ceid.upatras.gr> writes:
>This is an expression too:
> (1 2)

No, it isn't.


H, what Giorgos is trying to tell you (while overplaying his hand :-) is
that you are making a mistake by thinking as if Scheme were one of Those
languages, in which there is a distinction between expressions, which
return a value, and instructions, which don't. The reason you say
if (condition) then {body};
in language X isn't that one is the condition of an IF and the other is
the body of an IF, but (a more fundamental property) that one returns a
value, and the other doesn't.

For example, note that you say
((x < 3) ? (a + b) : (a - b))
and in that case the "condition" and "body" are both parenthesized, not
braced, because they're all expressions, not instructions.


Scheme deliberately eliminates this distinction; everything returns a value,
even if the value is just OKAY or #UNSPECIFIED or something like that.
So in Scheme the condition and the body are the same kind of thing, not two
different kinds.

There are, as I said before, a few special forms in Scheme in which parens
are used for things other than delimiting an expression. For example, in
the following forms, the square brackets represent parentheses that don't
delimit an expression:

(lambda [x y] (+ x y))
(cond [(= x y) 'yes] [else 'no])
(let [[x (+ 3 4)] [y 6]] (* x y))

Giorgos Keramidas

unread,
Jan 5, 2006, 6:16:47 AM1/5/06
to
On Thu, 5 Jan 2006 10:56:10 +0000 (UTC),
b...@abbenay.CS.Berkeley.EDU (Brian Harvey) wrote:
> Giorgos Keramidas <kera...@ceid.upatras.gr> writes:
>>This is an expression too:
>> (1 2)
>
> No, it isn't.

Hmmm, I thought this would be unclear. It was meant to be the literal
list '(1 2), as printed by the REPL when it's the result of evaluating
'(1 2). On second thought, you're right, and I should have typed the
REPL input; not its output :)

> H, what Giorgos is trying to tell you (while overplaying his hand :-)

Indeed :)

> There are, as I said before, a few special forms in Scheme in
> which parens are used for things other than delimiting an
> expression. For example, in the following forms, the square
> brackets represent parentheses that don't delimit an
> expression:
>
> (lambda [x y] (+ x y))
> (cond [(= x y) 'yes] [else 'no])
> (let [[x (+ 3 4)] [y 6]] (* x y))

Ah! Of course...

Jens Axel Søgaard

unread,
Jan 5, 2006, 9:25:25 AM1/5/06
to
Brian Harvey wrote:
> Giorgos Keramidas <kera...@ceid.upatras.gr> writes:
>
>>This is an expression too:
>> (1 2)
>
> No, it isn't.

Yes it is :-)

It just happen to provoke a runtime error if evalutated.

It was a bad choice of example though.

--
Jens Axel Søgaard

Brian Harvey

unread,
Jan 5, 2006, 10:08:09 AM1/5/06
to
=?ISO-8859-1?Q?Jens_Axel_S=F8gaard?= <use...@soegaard.net> writes:
>>>This is an expression too:
>>> (1 2)
>> No, it isn't.
>Yes it is :-)

Hmm, where do you draw the line? Is
)1 2(
an expression? How about
(lambda)
?

Nils M Holm

unread,
Jan 5, 2006, 10:27:45 AM1/5/06
to

How about this:

An expression is either an atom X or the normal form of (CONS X Y)
where both X and Y are expressions.

Because (CONS 'LAMBDA '()) => (LAMBDA), this is an expression.

)1 2( is not an expression, because it cannot be constructed using
above definition.

Of course the use of the term "expression" for both programs and
data is a bit confusing, but it only reflects an ambiguity that is
part of the Scheme language itself:

What is (+ 5 7) ?

Is it a list of three elements or a function application? Its meaning
depends on its context. In

(+ 5 7) => 12

it is a function application, but in

(quote (+ 5 7)) => (+ 5 7)

it is a list. Is it an expression in both cases? If so, why is
(1 2) in

(quote (1 2)) => (1 2)

not an expression? If not, how do you explain that (+ 5 7) is an
expression at one time and something else another time?

--
Nils M Holm <n m h @ t 3 x . o r g> -- http://www.t3x.org/nmh/

H.

unread,
Jan 5, 2006, 11:41:41 AM1/5/06
to

As a total side note, what is the best way to show came before? --
before what I'm writing here or after? I'm using Google Groups, so this
is all done my hand - copy and paste and then manually add the >s. Ack.
<rant>It's not like the Google engineers aren't smart enough to have
some feature that automatically does that for you.</rant>

In response to Anton: you are right. I was so used to seeing
expressions around things, I forgot about the case of (if x y z). (Side
comment: Having been a student of "those other languages," I can't help
but compare this to the ternary operator. I wish I could see Scheme
from a Scheme perspective instead of seeing it through
JavaScript-Java-C++ shaded glasses.)

But, as Brian Harvey pointed out, cond is actually an exception, which
to me is like the if/then/else construct in "those other languages." So
you right "The parens don't have special meaning relative to the IF"
except that I believe they do in cond, if I understand Professor Harvey
correctly.

Peter Olsen

unread,
Jan 5, 2006, 11:53:41 AM1/5/06
to
Joe Marshall wrote:

> Actually, no one I know programs in Scheme or Lisp directly. Neither
> is suitable for solving anything but the most trivial problems `out of
> the box'.
>
> Anyone who uses Scheme or Lisp uses it only as the basis for an
> extended domain-specific language that may or may not resemble the base
> language, depending on how they feel about syntax.


>
> It's a funny religion when its adherents don't use the purported object
> of worship except to change it into something else.

I agree with this completely.

I have tried to use Scheme for "real-world" (i.e. "I get paid")
applications and failed.

Like many religions, Scheme has deep schisms over the One True Faith.
Every implementation has implemented "features" on which you can't
depend. Unfortunately basic Scheme implementations seem to be so
Spartan that many of these "features" are necessary for practical work.

Python, my second favorite language, has taken an opposite tack. While
Scheme has formal standarization, implementations vary from it. Python
has no formal standardization (at least that I've found) but an overall
de facto standard (imposed by Guido Rossum, Benevelent Dictator For
Life --- BFDL) is followed closely by all implementations. Deviations
seem to be in such things as low-level system calls and the more arcane
optimization options. (And I try to avoid these anyway.)

Furthermore Python follows a philosophy of "batteries included"
(meaning that while the language itself is simple, there are many
standard modules to extend it). Scheme seems to follow a philosophy of
"If you need batteries, learn electrochemistry and build them."

The one exception I've found is Aubrey Jaffer's SLIB. This is a
wonderful start (Thanks Aubrey!!), but it's not enough.

I'm an engineer with problems to solve, not a language evangelist, so
my suggestion is to pick a reasonably good implementation ("Pick your
Scheme, any Scheme!!"), set that as a standard-in-fact, and build on
it.

But I don't think this has the slightest chance of happening. I
believe that most Schemers would rather be orthodox than successful.

For a good explanation of why this is so --- and why at least an order
of magnitude more programmers use C (A Language Once Cursed By God)
than Scheme or Lisp --- see Richard Gabriel's "Worse is Better" paper
(formally "Good News, Bad News, and How To Win Big"). I think the
critical passage is sort of a Gresham's Law of Software:

> However, I believe that worse-is-better, even in its strawman
> form, has better survival characteristics than the-right-thing,
> and that the New Jersey approach when used for software
> is a better approach than the MIT approach.

The difference is that, unlike debased coinage, debased software will
be improved. It will become ubiquitous and people will improve it so
as to better scratch their personal itch (see Eric Raymond's "The
Cathedral and the Bazaar.") Scheme is still more elegant and enjoyable
(at least to me). But C has evolved into Python --- a practical
language for real ("paid") projects --- and Scheme is still your
Grandmother's crystal --- safely tucked away: sometimes admired but
never used.

I invite you to flame me --- I expect many of you will anyway --- but
only if you include practical ("suitable for paid work") examples to
prove me wrong. (I'll be very happy if you do.)

My definition of "suitable for paid work" is that

1. A system must work with little change on at least Windows and
Unix. Changing headers is acceptable. Changing more than a trivial
number of procedure calls isn't. Changing any algorithmic details
isn't. ("Complete Scheme except for tail-recursion" is an obvious
failure.)

2. It must either offer or support libraries for rapid, accurate,
and easy to program computational mathematics. (Has anyone found a
Scheme implementation of the singular-value decomposition?)

3. It must be maintainable (and the customer must be able to find
and hire other maintainers after I've gone). (Compare the number of CS
grads with Java experience to those with Scheme. Yeah, I know Scheme
is better, but Java gets you paid.)

4. It must either include good libraries for common housekeeping
tasks (sorting, searching, array operations, string manipulation) or
there must be good ones easily available (and they must be standard
across platforms).

5. It must be reasonably fast overall.

6. The overall structure (but not the syntax or details of function
calls or program flows) must be explainable to an intelligent customer
who is interested enough to invest a reasonable amount of time.
(Scheme is good here --- as (I believe) are most functional programming
languages. But Python offers easy access to both functional and
object-orient programming paradigms.)

7. Offer a complete and consistent development across platforms. (I
use Emacs, but it's not always available. Except for the Palm ---
clearly a special case --- Python offers IDLE on every platform I've
used.)

Python offers all of these. So far as I can tell, Scheme fails on at
least the first three and maybe the fourth and fifth as well.
(Admittedly, the core Python interpreter isn't blinding fast, but it's
at least as fast as the Scheme interpreters I've tried, and --- more
important --- most of the modules in which most of my code spends most
of its time ARE very fast.)

Thanks for reading my post (and please prove me wrong!).

Peter Olsen
pcolsen gmail com (insert appropriate punctuation)

"Engineering is the art of applying a professional knowledge of
mathematics and the physical sciences to improve the quality of life."

P.S. Please excuse my acute spam-phobia.,

H.

unread,
Jan 5, 2006, 12:08:56 PM1/5/06
to
>For example, note that you say
>((x < 3) ? (a + b) : (a - b))
>and in that case the "condition" and "body" are both parenthesized, not
>braced, because they're all expressions, not instructions.

Perhaps I'm thinking in a different (probably wrong) metaphor. Because
when I think "ternary operator", I think of there being two different
sets of instructions after the ?, which also happen to be expressions.
The evaluation of the parentheses before the ? determines which of the
different instructions to follow. Yes, they are expressions, but they
are still instructions, no? I know I must seem rather intractable
arguing semantics in such a fashion. Really, I'm just trying to
understand. Does something being an expression mean we no longer think
of it as an instruction?

>There are, as I said before, a few special forms in Scheme in which parens
>are used for things other than delimiting an expression.

> (lambda [x y] (+ x y))
> (cond [(= x y) 'yes] [else 'no])
> (let [[x (+ 3 4)] [y 6]] (* x y))


Could we not add define to this list, in the special case where define
is used to define a procedure?

(define (make-great wd) (se wd '(is great)))

With this list (regardless of whether define is included or not), I ask
myself, why did the designers of Scheme make these forms special (in
giving double duty to parens)? The lambda I get, it was necessary to
make the form work. But consider cond:

(cond [(= x y) 'yes] [else 'no])

I ask myself why it was't defined like:

(cond (= x y) 'yes else 'no)

in other words:
(cond (expression1) (expression2) (expression3) (expression4) else
(finalexpression))

whereby the even expressions are evaluated if the odd ones before them
are true. (And of course the number of expressions before the else
clause is any realistic positive integer, not necessarily 4).

A similar question applies for "let", but I understand the decisions
made for cond, let will probably fall into place...

H.

unread,
Jan 5, 2006, 12:15:29 PM1/5/06
to
I was thinking about this part of the response last night:

>Our goal isn't to convince you to love Scheme. On the contrary, our goal
i>s to convince you that *even if you never use Scheme again*, the big
ideas
>are still valuable.

which I believe is very cogent.

I was also thinking about this part:

>Too many students think, for example, that once they're
>programming in (for example) Java, they can/should forget about recursion.

and that at Berkeley, most students are like me, in that they come in
the cs division having already learned a programming language to some
extent or another, most likely Java or C++. And thus, in a sense, my
"prior corruption" is not unique. : ).

Bruce Lewis

unread,
Jan 5, 2006, 12:54:09 PM1/5/06
to
"Peter Olsen" <pco...@gmail.com> writes:

> But C has evolved into Python --- a practical
> language for real ("paid") projects --- and Scheme is still your
> Grandmother's crystal --- safely tucked away: sometimes admired but
> never used.
>
> I invite you to flame me --- I expect many of you will anyway --- but
> only if you include practical ("suitable for paid work") examples to
> prove me wrong. (I'll be very happy if you do.)

http://www.google.com/search?q=eaton+vance+msl

Financial analysts have been using a Scheme-based interface to organize
their thinking for years.

> My definition of "suitable for paid work" is that

Oh...currently consituting paid work won't do it?

Giorgos Keramidas

unread,
Jan 5, 2006, 1:05:07 PM1/5/06
to
On 5 Jan 2006 09:08:56 -0800, "H." <hbe...@gmail.com> wrote:
> With this list (regardless of whether define is included or not), I ask
> myself, why did the designers of Scheme make these forms special (in
> giving double duty to parens)? The lambda I get, it was necessary to
> make the form work. But consider cond:
>
> (cond [(= x y) 'yes] [else 'no])
>
> I ask myself why it was't defined like:
>
> (cond (= x y) 'yes else 'no)

Because having it defined this way 'maps' easily to something
that 'iterates' over the list of cond arguments, and repeats for
every one of them:

(if (car test)
(return (eval (cdr test))))

For instance, if you didn't have (cond), but you did have
tail-recursion, an #'and function and macros, you could implement
a cond of your own starting with something like this:

guile> (defmacro my-cond (test . rest)
`(letrec ((my-cond-check (lambda (test-list)
test-list)))
(my-cond-check (append ',test ',rest))))
guile> (my-cond ((#t 0)) (else foo))
((#t 0) (else foo))
guile>

Can you guess how we can write a tail recursive procedure called
(my-cond-test) that returns the value of (eval (cdr element)) for
the first element of the resulting list whose (car) is true?

Bruce Lewis

unread,
Jan 5, 2006, 1:07:17 PM1/5/06
to
"H." <hbe...@gmail.com> writes:

> (cond [(= x y) 'yes] [else 'no])
>
> I ask myself why it was't defined like:
>
> (cond (= x y) 'yes else 'no)
>
> in other words:
> (cond (expression1) (expression2) (expression3) (expression4) else
> (finalexpression))

See R5RS section 4.2.1 for more on the syntax of cond. There may be
more than one consequent for a particular predicate.

> A similar question applies for "let", but I understand the decisions
> made for cond, let will probably fall into place...

Yes, the grouping in cond/case, let/let*/letrec, and syntax-rules is
conceptually similar.

H.

unread,
Jan 5, 2006, 1:12:19 PM1/5/06
to
eergh. I meant that last "right" to be "write"; sometimes when I'm
typing fast, the words exchange themselves in odd ways. Sorry about the
elementary-level mistake.

Anton van Straaten

unread,
Jan 5, 2006, 1:26:18 PM1/5/06
to
H. wrote:
> Perhaps I'm thinking in a different (probably wrong) metaphor. Because
> when I think "ternary operator", I think of there being two different
> sets of instructions after the ?, which also happen to be expressions.
> The evaluation of the parentheses before the ? determines which of the
> different instructions to follow. Yes, they are expressions, but they
> are still instructions, no? I know I must seem rather intractable
> arguing semantics in such a fashion. Really, I'm just trying to
> understand.
>
> Does something being an expression mean we no longer think
> of it as an instruction?

What do you mean by "instruction"? Do you mean something like a
statement in an imperative language, used for its side effects rather
than its value?

Or perhaps the issue you're getting at is that when evaluating something
like an IF or a COND, only certain of the expressions are evaluated.

Either way, this doesn't change the fact that the evaluation of an IF or
a COND expression involves evaluating certain of its subexpressions, and
the value of one of those subexpressions becomes the final value of the
IF or COND. That's all there is to it.

>>There are, as I said before, a few special forms in Scheme in which parens
>>are used for things other than delimiting an expression.
>> (lambda [x y] (+ x y))
>> (cond [(= x y) 'yes] [else 'no])
>> (let [[x (+ 3 4)] [y 6]] (* x y))
>
>
>
> Could we not add define to this list, in the special case where define
> is used to define a procedure?
>
> (define (make-great wd) (se wd '(is great)))

Yes.

> With this list (regardless of whether define is included or not), I ask
> myself, why did the designers of Scheme make these forms special (in
> giving double duty to parens)? The lambda I get, it was necessary to
> make the form work. But consider cond:
>
> (cond [(= x y) 'yes] [else 'no])
>
> I ask myself why it was't defined like:
>
> (cond (= x y) 'yes else 'no)
>
> in other words:
> (cond (expression1) (expression2) (expression3) (expression4) else
> (finalexpression))

First, why did you put an "else" in there? Why not leave it out? The
answer to that comes down to a human factors issue -- it makes the code
more readable.

That's not all there is to it, though. The "extra" parentheses make the
structure of the code explicit, delimiting important relationships
between the parts of an expression. This not only makes the code easier
for us to read, it makes it easier for the computer to process.

In Scheme, that's not just a benefit to an implementor of Scheme, it's
also a benefit to the programmer, because Scheme programmers often deal
with code in their programs, whether via macros or other means.

For example, consider the following list, which can also be interpreted
as a program:

'(let ((a 5)
(b 6)
(c 7))
(+ a b c))

It has a structure like this: (LET <bindings> <body>).

The <bindings> clause has a structure like this:

((<variable1> <expression1>) (<variable2> <expression2>) ...)

It's useful for both humans and machines to be able to decompose
expressions in this hierarchical way. The extra parentheses mean that
when you use the READ procedure to read in that list/program, the
resulting internal representation already has a useful structure,
without having to do any further rearrangement.

There are other reasons: to use the COND example, in a long COND
expression without the "extra" parens, it would get difficult to
distinguish conditions from their associated expressions. The
parentheses makes the syntax a bit less context-sensitive, and easier
for a human to read. It also adds redundancy, which improves error
checking ability: without the extra parens, if one of the expressions
got deleted, or split into two, it would affect the meaning of the
entire COND in a way that could be hard to pinpoint or untangle. With
the extra parens, the consequences of such an error are more contained.

Anton

Joe Marshall

unread,
Jan 5, 2006, 3:18:13 PM1/5/06
to
I stand corrected.

But I still assert that computer science is at the low end of the
range.

Jens Axel Søgaard

unread,
Jan 5, 2006, 3:19:02 PM1/5/06
to

Well, I think that (1 2) should parse as a <procedure call>,
since both 1 and 2 are legal <expression>s.

)1 2( doesn't parse.

(lambda) - hmm - tricky.

If lambda a variable or macro binding of lambda exists then yes.
If there is no binding that shadows the normal meaning of
lambda, then ... (checking grammar) ... no?

--
Jens Axel Søgaard

Jens Axel Søgaard

unread,
Jan 5, 2006, 3:21:47 PM1/5/06
to
Nils M Holm wrote:

> How about this:
>
> An expression is either an atom X or the normal form of (CONS X Y)
> where both X and Y are expressions.
>
> Because (CONS 'LAMBDA '()) => (LAMBDA), this is an expression.

> Of course the use of the term "expression" for both programs and


> data is a bit confusing, but it only reflects an ambiguity that is
> part of the Scheme language itself:

The grammar for <datum> and <expression> are different in RnRS,
so I think there ought to no ambiguity.

--
Jens Axel Søgaard

rsher...@gmail.com

unread,
Jan 5, 2006, 4:04:42 PM1/5/06
to
>I ask myself why it was't defined like:
>(cond (= x y) 'yes else 'no)
>in other words:
>(cond (expression1) (expression2) (expression3) (expression4) else
>(finalexpression))

If you want to express conditionals in some other way than cond, you
are free to do so. Your idea of what cond should look like reminds me
of Allegro Common Lisp's if* macro.

http://www.franz.com/support/documentation/7.0/doc/operators/excl/if_s.htm

which allows you to write (if* <test> then <do stuff> elseif ... else
...) like more traditional languages. Most people apparently disagree,
because I've never seen it used outside of code from Allegro, but it
illustrates how you can modify the language to suit your own needs and
aesthetics.

Björn Lindström

unread,
Jan 5, 2006, 4:23:59 PM1/5/06
to
"Peter Olsen" <pco...@gmail.com> writes:

> Like many religions, Scheme has deep schisms over the One True Faith.
> Every implementation has implemented "features" on which you can't
> depend.

Why wouldn't you be able to depend on those features?

(I don't understand the quotation marks either. If you don't like these
"features", why would you feel you need them?)

If you've gotten the idea into your head that all your code has to be
portable between Scheme implementations, then I'd say you are mainly to
blame for making the work hard for yourself.

--
Björn Lindström <bk...@stp.lingfil.uu.se>
Student of computational linguistics, Uppsala University, Sweden

Brian Harvey

unread,
Jan 5, 2006, 6:16:39 PM1/5/06
to
"H." <hbe...@gmail.com> writes:
> >((x < 3) ? (a + b) : (a - b))
>Perhaps I'm thinking in a different (probably wrong) metaphor. Because
>when I think "ternary operator", I think of there being two different
>sets of instructions after the ?, which also happen to be expressions.
>The evaluation of the parentheses before the ? determines which of the
>different instructions to follow. Yes, they are expressions, but they
>are still instructions, no?

In C/C++/Java:

"expression" means "returns a value."
"instruction" means "does not return a value."

You can, of course, use words to mean whatever you want them to mean, but
only in Wonderland. :-)

[It's a little confusing in practice because of the C assignment operator.
Technically,
x = 5
is an *expression* whose value is 5 (so that you can say y = x = 5), but
x = 5;
is an *instruction* that does not return a value.]

My point is that in Scheme there is no such thing as an instruction; this is
part of what everyone means when they talk about the uniformity of the
semantics that gives rise to a uniformity of notation. Putting this another
way, thinking about semantics and forgetting syntax altogether for a moment,
Scheme *does not have* anything like C/C++/Java's IF-THEN-ELSE instruction.
The thing that's called IF in Scheme is semantically like C's ?: operator;
it returns a value, so (if ... ...) is an expression, not an instruction.

So, now you can think about syntax, and you should expect Scheme's IF syntax
to be more like C's ?: syntax than like C's IF syntax, following the
semantics. So, no braces.

[One possible source of confusion is that Scheme lets you leave out the else
part of the operation; it's as if you could say
(x < 3 ? "yes" : )
in C. The value of this expression is Unspecified, which means that the
result may be different in different implementations. But it returns some
value or another!]

Brian Harvey

unread,
Jan 5, 2006, 6:43:49 PM1/5/06
to
Nils M Holm <before-2...@online.de> writes:
>An expression is either an atom X or the normal form of (CONS X Y)
>where both X and Y are expressions.
>
>Because (CONS 'LAMBDA '()) => (LAMBDA), this is an expression.

This is an interesting point of view, but I think not that of R5RS, which
says:

Datum is what the read procedure (section 6.6.2) successfully parses. Note
that any string that parses as an expression will also parse as a datum.

... but it doesn't say that any datum is an expression. In the particular
case of lambda expressions, we have

<lambda expression> -> (lambda <formals> <body>)

... and neither <formals> nor <body> can be empty, so (lambda) doesn't
qualify.

It's true that in the formal syntax, any expression can be an operator, but
LAMBDA by itself is not an expression, and anyway, if they had a way to make
the syntax say <expression-whose-value-is-a-procedure> they would have!

Pierpaolo BERNARDI

unread,
Jan 6, 2006, 1:18:28 AM1/6/06
to
H. wrote:

> As a total side note, what is the best way to show came before? --
> before what I'm writing here or after? I'm using Google Groups, so this
> is all done my hand - copy and paste and then manually add the >s. Ack.
> <rant>It's not like the Google engineers aren't smart enough to have
> some feature that automatically does that for you.</rant>

Don't use the "Reply" button at the bottom of the post.
Use the "Show Options" at the top of the post, and
then use the "Reply" button you find in the options.

H.

unread,
Jan 6, 2006, 2:33:56 AM1/6/06
to

> In C/C++/Java:
>
> "expression" means "returns a value."
> "instruction" means "does not return a value."
>
> You can, of course, use words to mean whatever you want them to mean, but
> only in Wonderland. :-)
>
> [It's a little confusing in practice because of the C assignment operator.
> Technically,
> x = 5
> is an *expression* whose value is 5 (so that you can say y = x = 5), but
> x = 5;
> is an *instruction* that does not return a value.]

I'm befuddled how x=5 differs from (define x 5) and why one is an
instruction and the other is an expression.


> My point is that in Scheme there is no such thing as an instruction;

But there are semantics in Scheme that give way to imperative
programming, no? e.g. "begin" as on the third line in:

straight out of 31-aug-2005, Lecture 2, Fall 2005:
(define (buzzloop start end)
(if (= end start) 'done
(begin (display (buzz start))
(display "\M")
(buzzloop (+ start 1) end))))

Between time 31:10 and 32:07, Garcia mentions that "begin" is an
example of the imperative style, and thus isn't functional programming.
I was under the impression that imperative style programming could be
equated to giving instructions, ergo I conclude there is such a thing
as an instruction in Scheme. (which part is wrong?)


> part of what everyone means when they talk about the uniformity of the
> semantics that gives rise to a uniformity of notation. Putting this another
> way, thinking about semantics and forgetting syntax altogether for a moment,
> Scheme *does not have* anything like C/C++/Java's IF-THEN-ELSE instruction.
> The thing that's called IF in Scheme is semantically like C's ?: operator;
> it returns a value, so (if ... ...) is an expression, not an instruction.

This part I get. : )

>
> So, now you can think about syntax, and you should expect Scheme's IF syntax
> to be more like C's ?: syntax than like C's IF syntax, following the
> semantics. So, no braces.

Grokked.

Max Hailperin

unread,
Jan 6, 2006, 9:43:20 AM1/6/06
to
"H." <hbe...@gmail.com> writes:

> > In C/C++/Java:
> >
> > "expression" means "returns a value."
> > "instruction" means "does not return a value."
> >
> > You can, of course, use words to mean whatever you want them to mean, but
> > only in Wonderland. :-)

...


> I'm befuddled how x=5 differs from (define x 5) and why one is an
> instruction and the other is an expression.

A very good befuddlement indeed. Before I get into it, an aside:
Brian's use of "instruction" is a bit less than standard. I'd say
most programming language literature would use "statement" for what he
calls an "instruction". (Thus, to echo his earlier example, "x=5" is
an expression but "x=5;" is a statement.)

Now as to (define x 5). You are quite right that this is *not* an
expression. If you read R5RS, you will see that it is classified as a
different kind of thing entirely, a "definition". A definition in
Scheme isn't quite the same as a statement in C -- but then again a
definition in C isn't quite the same a statement in C (though it
became more similar in the latest revision of C). However, a
definition is more like a statement than it is like an expression.
Various people (on this newsgroup and otherwise) will tell you things
like "everything in Scheme is an expression". They are exaggerating.
If you want the precise, accurate information, you need to check the
R5RS.

> > My point is that in Scheme there is no such thing as an instruction;
>
> But there are semantics in Scheme that give way to imperative
> programming, no? e.g. "begin" as on the third line in:
>
> straight out of 31-aug-2005, Lecture 2, Fall 2005:
> (define (buzzloop start end)
> (if (= end start) 'done
> (begin (display (buzz start))
> (display "\M")
> (buzzloop (+ start 1) end))))
>
> Between time 31:10 and 32:07, Garcia mentions that "begin" is an
> example of the imperative style, and thus isn't functional programming.
> I was under the impression that imperative style programming could be
> equated to giving instructions, ergo I conclude there is such a thing
> as an instruction in Scheme. (which part is wrong?)

In the informal sense of "giving instructions", yes, you are 100%
right. In terms of the formal categories of programming language
features, no these aren't statements (or what Brian called
"instructions"). Instead, they are "expressions with side effects".
The procedure application (display ...) is an expression, the same as
any other procedure application in Scheme. As such, it does compute a
value -- the R5RS simply leaves unspecified what that value is, so
each Scheme system can choose its own. In the context (begin (display
...) ...), this unspecified value is ignored. However, the important
point is that evaluating the expression also caused an effect --
something got displayed. The (begin ... ...) construct itself is an
expression, and has a value. In this case, that value is the symbol
done (provided that start and end are such that an infinite loop
doesn't result).

-max

Jens Axel Søgaard

unread,
Jan 6, 2006, 9:57:58 AM1/6/06
to
H. wrote:
>>In C/C++/Java:
>>
>> "expression" means "returns a value."
>> "instruction" means "does not return a value."
>>
>>You can, of course, use words to mean whatever you want them to mean, but
>>only in Wonderland. :-)
>>
>>[It's a little confusing in practice because of the C assignment operator.
>>Technically,
>> x = 5
>>is an *expression* whose value is 5 (so that you can say y = x = 5), but
>> x = 5;
>>is an *instruction* that does not return a value.]
>
>
> I'm befuddled how x=5 differs from (define x 5) and why one is an
> instruction and the other is an expression.

To be fair (define x 5) is both a declaration of x and an assignment
to x. Thus (define x 5) would in some languages be written

int x;
x=5;

The construct that resembles x=5 most in Scheme is (set! x 5)
which *is* an expression.

E.g.

> (define x 'foo)
> (list (set! x 5))
(#<void>)

Since R5RS leaves the return value if (set! ...) unspecified
you might see another result on your implementation.

--
Jens Axel Søgaard

David Rush

unread,
Jan 6, 2006, 12:37:52 PM1/6/06
to
Peter Olsen wrote:

> Joe Marshall wrote:
> I invite you to flame me --- I expect many of you will anyway ---

Woo-hoo!

> only if you include practical ("suitable for paid work") examples to
> prove me wrong. (I'll be very happy if you do.)

Well I've been paid for it in information retrieval, data mining,
networking, and now internet content management. OTOH, that's also
because I make a habit of not telling my management *how* I solve their
problems until they're actually solved. It's one of the few advantages
of getting older :)

> My definition of "suitable for paid work" is that

Very few of these have much to do with the language as such. Most have
to do with the community and/or certain kinds of specific business
requirements. Such concerns *are* valid from a corporate PoV, but when
I'm being a good corporate citizen I'm *not* trying to maximize my
coding efficiency. If you see a conflict between my previous paragraph
and this one, just remember that many things don't make sense in a
large corporation.

And remember, there is no Scheme Underground :)

> "Engineering is the art of applying a professional knowledge of
> mathematics and the physical sciences to improve the quality of life."

Yes! Yes! Yes! And Scheme is one of the most mathematical languages.

david rush
--
Corporate subversive

phil...@gmail.com

unread,
Jan 6, 2006, 5:01:50 PM1/6/06
to
Ok, this thread has inspired me to buckle down and REALLY learn emacs
(I've used it for years, but haven't learned the lisp modes).

Problem: My favorite computer is a Mac 15-in Powerbook (the ti-book),
and even though I've had it for quite a while, I'm still not
comfortable with the keyboard and mousepad. I know I could buy a USB
keyboard and external mouse, and in fact I do use a trackball when I'm
willing to sit at a desk. But what's the point of buying a laptop if
you have to sit at a desk to hack?

What have other Powerbook schemers/lispers done about this?

Björn Lindström

unread,
Jan 6, 2006, 6:50:52 PM1/6/06
to
phil...@gmail.com writes:

Well, this will hardly be a problem when using Emacs. While it has mouse
support, you will find that using only the keyboard is more efficient.

Actually, while I do have a trackball and a graphical environment, I
still prefer to run Emacs in text mode in a terminal emulator.

For your purposes, provided you run MacOS X, you'll probably be best
served by the Carbon Emacs port, avaliable at

http://emacswiki.org/cgi-bin/wiki/CarbonEmacsPackage

Jérémie Lumbroso

unread,
Jan 6, 2006, 7:22:07 PM1/6/06
to
[Phew ... I spent over an hour and half catching up on this colorful
conversation (silently sad I couldn't pitch in at the beginning).]


I'm a newcomer to Scheme. (Please I apologize in advance for rambling;
if you can't stand it, skip to the '****')

I started programming early, on Apple's Hypercard because my family had
an established tradition of being Apple-only---until that tradition was
stuffed, and my dad got a PC with the just-out Win95, and I went on
using VB.

As I had become increasingly stiffled by VB (Microsoft still considered
it a sort-of toy language, and it made it very hard to access Win's API
or DirectX, etc.), I switched to C/C++, and then later on to C# (when
it came out). C# was something of a revelation to me. Why? Because I'd
got more and more concerned about the elegance of my code, and I
believed that, as far as OO languages went, C# (along with MS' .NET
framework) was far more elegant than C/C++ and Java. Not that I'm
deluding myself in comparing their worth, but to me, at the time, the
brand new C# had a consistency that I found lacked in other languages
(but of course the consistency came from the fact that C# had not yet
lived through a generation of demanding programmers).

I've evolved in C#, by pathologically rewriting everything. I have the
rewriting disease, that I'm sure all of you know about (and only the
best of you have conquered): I write a program, then start rewriting it
before it reaches final stage, then rewrite that rewrite before it
reaches final stage, etc. ad nauseum.


Well, the programming language of my university's introductory
programming course happens to be Scheme. I learned Scheme very quickly,
because I've reached that point where you've tried out so many
programming languages that they start, basically, all looking
superficially alike (at least the basic concepts). And I have come to
love it a lot.

And more importantly, Scheme triggered a desire to use functional
languages as much as possible (to such an extent that my computer is
now the home to interpreters for most popular functional
languages-and in several cases, more than one interpreter!).


To explain this, I'll also add that in the past few years, my interest
in maths has soared. I'm not sure why. To the extent that it is now
*so* refreshing and liberating, to find programming languages such as
Scheme or Haskell, that try to approach that mathematical abstraction.
That is why I've come to love functional programming.

****

Now, *FIRST OF ALL*, H., I want to stress the fact that my enthusiasm
would probably not have been as strong had I not been spoon-fed with
DrScheme ( http://www.drscheme.org/ ), and incredibly implementation of
Scheme. I'm not sure if you know it, but if you don't, you'll like it
for these reasons (among others):
* it runs smoothly out of the box;
* it features a full-fledge integrated development environment, with
editor and "live" interpreter;
* it makes the whole parenthesis thing almost beautiful, because it
handles indentation and syntax coloring so well.


Second, I read you asking something about why Scheme does something
different whether you put parenthesis or not. It think I may have
either read into the question something that you did not actually ask,
but here's my comment:

; a function
(define (hello-world)
(display "Hello world!"))

Were you finding it weird that:

hello-world

And:

(hello-world)

... are not the same thing? Well, actually that is one thing that I
find extremely impressive and awe-inspiring about Scheme. Admitedly, a
lot of imperative languages are now implementing anonymous functions
(and C# is getting it's very own lambda and closures in the next
version), but that seems to be in response to the success they are
getting in functional languages.

(This is not an expert's point of view, BTW.)

Functions are object. "hello-world" is an object. But Lisp's syntax has
it that you have the construct (<function> <arguments>) which is
universal safe for the "special forms"; this makes sense, as it is kind
of like maths f(x,y,z) where first the name of the function appears
then the arguments. Like in maths, "f" is a function, and "f(x,y,z)" or
"f()" (if it were actually possible, and semantically correct to have a
parameterless function) are images of said-parameters by the function.

I find it very useful to have functions treated as objects; for
instance you can have lists of functions, or list of list of functions,
or whatever.


I actually have a somewhat decent example of this I wrote, of a scholar
implementation of the Gaussian reduction algorithm in Scheme, in which
the challenge I'd set myself was to not use an inkling of imperative
programming-and in effect, the entire program is (almost) all
recursive.

In it, the main function operates on a coefficient matrix, and outputs
a list of primitives (+ - * /) with a few arguments (+ 5, + 6, / 5,
etc.)---those primitive operations which were necessary to reduce the
matrix.

That list of primitives is then "applied" to the constant matrix (the
values of second member of the linear system) to calculate values of
the unknowns. In short, for a given linear system, you only have to
calculate the list of primitives once, and then you can apply it
however many times you want to different constant matrices.

But I (considerably) digress ...


OK, in a nutshell what got my panties in a twist: Scheme is a
functional language that is much closer to maths than C, C++, Java,
etc. Outside a nutshell (oh, I know, I'm a Groucho copy-cat!): download
DrScheme.

I'll try to collect my thoughts and write something that's up to par
with any of the other contributors (or at least honorably trying to
be).


Regards,

Jérémie
(jeremie.lumbroso gmail com)

Giorgos Keramidas

unread,
Jan 6, 2006, 7:39:12 PM1/6/06
to
On Sat, 07 Jan 2006 00:50:52 +0100,
bk...@stp.lingfil.uu.se (Björn Lindström) wrote:
> Actually, while I do have a trackball and a graphical environment, I
> still prefer to run Emacs in text mode in a terminal emulator.

<aol>me too</aol>

Although I appreciate all the hard work people have put in making it
possible to run Emacs with GTK under X11, I regularly build cvs-emacs
snapshots --without-x11 and run Emacs in an xterm :-)

H.

unread,
Jan 6, 2006, 9:12:05 PM1/6/06
to

Tom Lord wrote:
> To the other replies you are getting I'll add some hacker lore
> and historic perspective:
>
this was quite interesting, thanks.

. If you venture into Church, meditate a bit about
> Strachey, gosh rest his soul. Great Scott, man, these folks
> drew the first maps.

No meditation involved. Just wipipedia and google I'm afraid. Alonzo
Church, Christopher Strachey,Guy Steele, Harold Abelson, Gerald Jay
Sussman. And Richard Stallman, Donald Knuth, Alan Kay, Ivan Sutherland,
Alan Turing, and Kristen_Nygaard for good measure. I like history: I
tend to read at least blurbs of creators whenever I star to use a
language, e.g.:, Dennis Ritchie, Ken Thompson, James Gosling, Bjarne
Stroustup.
>

> Because everything was so new every research institution was
> pretty much on its own. There was no "download GCC" let alone
> "pick one of N browsers that contain a Javascript interpreter".

I remember those days. : ).


>
> Guy Steele, who you may have heard of from Java fame, was a grad
> student at MIT in the early seventies. He was just down the
> hall from and interacting with --- well, half the damn world as
> far as computer science is concerned.

I know that some of the frequenters of this boad went to MIT, and so
now I'm curious if any of them got to be involved with the thought
processes that went on, with ither Stelle, Sussman, or Abelson.
Entirely off the main topic of this thread, I admit, but I am curious.
Being present at the beginning of any major revolution (at the source
of the revolution) is something to be proud of and cherish.


> One thing not to ignore is Steele's thesis, available at a
> library near you.

I'm having a little trouble finding this, because I'm not sure what
it's called. Care to enlighten?


>
> Of course, while you're rummaging through the stacks, you better
> go read the "lambda the ultimate...." papers. There's enough
> on-line about these already that that's all I'll say.

I've browsed through these, but not in depths, this summer. Having used
Scheme more, I may appreciate them more now.

Let us know when you
> grok how Scheme relates to something called "Hewitt's Actors
> Model". Talk about programming patterns....

I need to do my research here. From as far as I can tell, you are
referring to logic programming & Prolog based systems?
>
> You asked about "Scheme as religion"? That's where it started
> -- it's discovery/invention struck a really deep note. Nobody
> expected that. 14 years after it was written Steele's *thesis*
> was still being handed around in the hacker undergound as a work
> of art.

Thanks for the history. Coming later in this timeline, it's good to
know how things evolved before.
>

>
> 1) GET OFF YOUR PARENTHESIS PHOBIA AND LEARN EMACS. No, knowing
> how to move the cursor around doesn't count as knowing Emacs --
> that counts as knowing how to use Emacs as if it were VI.

I don't really understand how learning Emacs has to do with the
parentheses issue. I've bene using a syntax checker that closes parens
when I use the computer (UCB Scheme). When I jot down code on the back
of things when I'm away from my computer, I'm slowly realizing it's not
so much of an issue. But I don't get the emacs part.
>
> Look, yr program source texts represent trees. Parens make it
> really simple for your text editor to perform tree transforms.
> Learn emacs really well. Spend 6m on it. Learn the lisp modes.

Can you recommend an Emacs emulation for XP? Here is the most prominent
one in a google search:
http://math.claremontmckenna.edu/ALee/emacs/emacs.html
So I'll go with this one unless those more experienced than I chime in
further.

> What separates the true scheme hackers from most (not all)
> other hackers is a deep care for quality.
>
> Go read "Zen and the Art of Motorcycle Repair".

You mean "zen and the art of motorcycle maintenence"? I'm read that
one. But I can't find "zen and the art of motorcycle repair" on amazon.

>
> Lemme add the word "craft".
>
> Lemme add the phrase "human scale".
>
> Do with those what you will.
>
> Scheme is a big ball of mud but, with these hints, you can
> start to grok why this particular mud smells so good to some
> of us. (Plus, you can start to read all the *later* and
> often very interesting Scheme literature I haven't given you
> hints about.)
>

Yes, well, I appreciate your time and I'll do what I can.

H.

unread,
Jan 6, 2006, 9:14:35 PM1/6/06
to

> Don't use the "Reply" button at the bottom of the post.
> Use the "Show Options" at the top of the post, and
> then use the "Reply" button you find in the options.

[sarcasm] Oh yeah, of course. I feel so silly now, as that as a
*completely obvious interface*[/sarcasm]

Thanks. And to be explicit: I'm being sarcastic about the interace, not
your response, which I quite appreciate.

Björn Lindström

unread,
Jan 6, 2006, 9:45:17 PM1/6/06
to
"H." <hbe...@gmail.com> writes:

> Can you recommend an Emacs emulation for XP? Here is the most
> prominent one in a google search:
> http://math.claremontmckenna.edu/ALee/emacs/emacs.html So I'll go with
> this one unless those more experienced than I chime in further.

There's no need for emulation. Emacs works in Windows. Here's a better
page about that, though:

http://www.gnu.org/software/emacs/windows/ntemacs.html

Giorgos Keramidas

unread,
Jan 7, 2006, 12:02:40 AM1/7/06
to
On 6 Jan 2006 18:12:05 -0800, "H." <hbe...@gmail.com> wrote:

> Tom Lord wrote:
>> Guy Steele, who you may have heard of from Java fame, was a grad
>> student at MIT in the early seventies. He was just down the
>> hall from and interacting with --- well, half the damn world as
>> far as computer science is concerned.
>
> I know that some of the frequenters of this boad went to MIT, and so
> now I'm curious if any of them got to be involved with the thought
> processes that went on, with ither Stelle, Sussman, or Abelson.
> Entirely off the main topic of this thread, I admit, but I am curious.
> Being present at the beginning of any major revolution (at the source
> of the revolution) is something to be proud of and cherish.
>
>
>> One thing not to ignore is Steele's thesis, available at a
>> library near you.
>
> I'm having a little trouble finding this, because I'm not sure what
> it's called. Care to enlighten?

http://library.readscheme.org/page1.html

You'll find a lot of stuff that ranges from very interesting to mind
boggingly addictive at http://library.readscheme.org/index.html

Giorgos Keramidas

unread,
Jan 7, 2006, 12:09:38 AM1/7/06
to

(off-topic
Heh! If you find out who thought this was a "smart thing" to do, to
stop Google Groups' users from writing sensible posts that don't work
'correctly', for some definition of 'correctly', only with the
forum-like view of the web interface, pass him over to Keith Thompson
at comp.lang.c, then to me, and then he's all yours to have all the
fun you like :-P)

David Rush

unread,
Jan 6, 2006, 12:15:36 PM1/6/06
to
H. wrote:
> With this list (regardless of whether define is included or not), I ask
> myself, why did the designers of Scheme make these forms special (in
> giving double duty to parens)?

You're still not going down the right road. Parens delimit *forms*.
Some forms are expressions, and some forms aren't. You can generally
tell by looking at the head atom of the form. Some forms have a
complicated structure and to the degree that the structure if
complicated, they are not good forms.

This is one of the reasons why I dislike let-values and and-let. The
sub-form complexity comes very close to crossing a comprehensibility
line. The same problem also applies to syntax-rules, but I consider
that a necessary evil.

david rush
--
Wearing a formal suit

David Rush

unread,
Jan 6, 2006, 12:24:02 PM1/6/06
to

H. wrote:
> As a total side note, what is the best way to show came before? --
> before what I'm writing here or after? I'm using Google Groups, so this
> is all done my hand - copy and paste and then manually add the >s. Ack.
> <rant>It's not like the Google engineers aren't smart enough to have
> some feature that automatically does that for you.</rant>

drop down the _show options_ link in the message header. and use *that*
_Reply_ link. It works *way* better.

> I wish I could see Scheme
> from a Scheme perspective instead of seeing it through
> JavaScript-Java-C++ shaded glasses.)

Time to write a lot of code, dude. It's a lot of fun in Scheme :)

david rush
--
under-hacker ordinaire

H.

unread,
Jan 7, 2006, 1:30:23 AM1/7/06
to

David Rush wrote:
> H. wrote:
> > The binary point is a good one. Still, it seems like there should be
> > something more intuitive than car, cadr, etc. Like the first letter
> > represents how many elements over, the second letter represents how
> > many to step over on that one element, and the third letter represents
> > whether we want the element we are on or the remainder of the list.
>
> Deep-structural understanding is absent again. Lisp doesn't really have
> lists (surprise) it has binary trees which are conventionally used to
> represent lists. So once again, by a lovely (and parsimonious)
> reduction of cases c[ad]+r is sufficient.
>
> david rush
> --

In regards to "Lisp doesn't really have lisps," of course it has lists.
Now we could argue about whether lists are used to represent binary
trees or binary trees are used to represent lists, which seems like a
chicken-and-egg argument. But I don't think one can assert that the
chicken doesn't really exist, only the egg, or the egg doesn't really
exist, only the chicken. Not that the metaphor *completely* fits. The
point is, imho, lisp has lists.

In regards to the "deep-structural understanding is absent again," that
could well be the case. I can write deep recursion procedures, but I
don't believe that that qualifies me as someone who can grok fully (at
this point) deep structural understanding. It doesn't seem all that
difficult, and yet, the fact that there is all this discussion about it
leads me to believe I am missing something in the "whole picture"
approach. I can, without a lot of trouble, appreciate how being able to
do certain problems does not mean that that I've achieved Total
Understanding. I managed to get an A in Calculus but I felt more like
a trained monkey than a mathemetician.

But if you could help me and explain to me how my idea showed a lack of
deep-structural understanding, that would be great. : )

H.

unread,
Jan 6, 2006, 4:07:02 PM1/6/06
to

> The construct that resembles x=5 most in Scheme is (set! x 5)
> which *is* an expression.
>
> E.g.
>
> > (define x 'foo)
> > (list (set! x 5))
> (#<void>)
>
> Since R5RS leaves the return value if (set! ...) unspecified
> you might see another result on your implementation.
>
> --
> Jens Axel Søgaard

As a side note, I don't understand why list was used in this example
because it seems extraneous (and a bit confusing). I undersand the
example if it's just:

(define x 'foo)
(set! x 5)

but what does the list add? To try to understand it better, I changed
the second line into a define, as follows:
(define x 'foo)
(define baz (list (set! x 5)))

and then typed:
baz
which gave me:
(okay)

which makes sense because "okay" is what is returned when a variable is
set, and this has properly been placed inside of a list. But I don't
understand why anyone would ever want to do it.

alex...@gmail.com

unread,
Jan 6, 2006, 7:56:15 PM1/6/06
to

Technophobia? What do you do when you need to select 3.5 pages and
paste it elsewhere?

Actually, I use xterm vim myself, but that's only because all gvim
builds I've seen suck.

Jérémie Lumbroso

unread,
Jan 6, 2006, 9:18:44 PM1/6/06
to

> Can you recommend an Emacs emulation for XP? Here is the most prominent
> one in a google search:
> http://math.claremontmckenna.edu/ALee/emacs/emacs.html
> So I'll go with this one unless those more experienced than I chime in
> further.

Try DrScheme!!

H.

unread,
Jan 6, 2006, 9:28:22 PM1/6/06
to

>
> Second, I read you asking something about why Scheme does something
> different whether you put parenthesis or not. It think I may have
> either read into the question something that you did not actually ask,
> but here's my comment:
>
> ; a function
> (define (hello-world)
> (display "Hello world!"))
>
> Were you finding it weird that:
>
> hello-world
>
> And:
>
> (hello-world)
>
> ... are not the same thing?

Not really. One is invoking the procedure and one is not. But it's not
that one is anonymous and one is not. An anonymous procedure has no
name, think:
( (lambda (square n) (* n n) ) 5)

which creates and invokes an anonymous function.


Well, actually that is one thing that I
> find extremely impressive and awe-inspiring about Scheme. Admitedly, a
> lot of imperative languages are now implementing anonymous functions
> (and C# is getting it's very own lambda and closures in the next
> version), but that seems to be in response to the success they are
> getting in functional languages.

see above. I agree anonymous functions are good. Though I don't think
your initial example quite captured that.

But Lisp's syntax has
> it that you have the construct (<function> <arguments>) which is
> universal safe for the "special forms"

It's called "prefix notation," as opposed to say, "in-fix notation".
Just thought I would clarify the terms if you haven't heard them
before. : )

> I find it very useful to have functions treated as objects; for
> instance you can have lists of functions, or list of list of functions,
> or whatever.

I came into Scheme used to scripting languages, so I had seen this
before. First-class objects are useful, although perhaps having used
them before in other languages I didn't quite "get" the enthusiasm
about having them in Scheme.

Where Scheme really excels is the way tail-recursion can be done,
allowing vast recursive procedures without running out of memory or
crashing the machine, or so forth...


> OK, in a nutshell what got my panties in a twist: Scheme is a
> functional language that is much closer to maths than C, C++, Java,
> etc. Outside a nutshell (oh, I know, I'm a Groucho copy-cat!): download
> DrScheme.

I downloaded this once. : ). I actually switched to UCB Scheme because
it had a set of extras added which corresponded to the lectures I was
watching. Maybe I'll go back and re-try Dr. Scheme since you seem to be
very enthusiastic about it.

Thanks.

Nils M Holm

unread,
Jan 7, 2006, 3:19:45 AM1/7/06
to
H. <hbe...@gmail.com> wrote:
> > > (define x 'foo)
> > > (list (set! x 5))
> > (#<void>)
>
> As a side note, I don't understand why list was used in this example
> because it seems extraneous (and a bit confusing). I undersand the
> example if it's just:

Some Scheme implementations do not output unspecific values. Adding
LIST turns that value into a list containing an unspecific value,
which always prints.

--
Nils M Holm <n m h @ t 3 x . o r g> -- http://www.t3x.org/nmh/

Jens Axel Søgaard

unread,
Jan 7, 2006, 6:33:56 AM1/7/06
to
H. wrote:
>>The construct that resembles x=5 most in Scheme is (set! x 5)
>>which *is* an expression.
>>
>>E.g.
>>
>> > (define x 'foo)
>> > (list (set! x 5))
>> (#<void>)
>>
>>Since R5RS leaves the return value if (set! ...) unspecified
>>you might see another result on your implementation.

> As a side note, I don't understand why list was used in this example


> because it seems extraneous (and a bit confusing). I undersand the
> example if it's just:
>
> (define x 'foo)
> (set! x 5)
>
> but what does the list add?

In the Scheme implementation I use the non-standard value void is
returned. By convention this is not printed by the REPL when returned
alone, so without the list I get:

> (define x 5)
> (set! x 'foo)
>

Since the point of the example was that (set! ...) was an expression
I needed it to be clear that it acutally returned a value. Thus
I put the result in a list, so I was sure it got printed.

--
Jens Axel Søgaard

Jérémie Lumbroso

unread,
Jan 7, 2006, 10:01:19 AM1/7/06
to
> Not really. One is invoking the procedure and one is not. But it's not
> that one is anonymous and one is not. An anonymous procedure has no
> name, think:
> ( (lambda (square n) (* n n) ) 5)
>
> which creates and invokes an anonymous function.

Oh. I wasn't talking about anonymous functions at that point. Though I
see why, because of what I wrote afterwards, you could have thought so.


> I downloaded this once. : ). I actually switched to UCB Scheme because
> it had a set of extras added which corresponded to the lectures I was
> watching. Maybe I'll go back and re-try Dr. Scheme since you seem to be
> very enthusiastic about it.

Well, when I was reading SICP, I continued using DrScheme's more modern
flavor of the dialect, event though it differs quite a bit from the one
documented in the book. For the most part, you can just redefine the
functions that don't exist, or tinker a bit with those you can't easily
redefine (of course I understand how you might want to avoid that for
an introductory course).

I was suggesting DrScheme, because if your first reaction to Scheme was
horror at its parenthesis-syntax, then UCB Scheme must be doing
something wrong for you.


- Jérémie

It is loading more messages.
0 new messages