This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Scheme is too complicated


Maciej Stachowiak writes:
...
> Actually, writing and reading to the same memory a lot can be more
> costly on some architectures than the write-once-read-many (modulo GC)
> behavior of some functional programs. In particular, in a shared
> memory multiprocessor architecture it is nice to avoid writing a lot
> to memory that someone else might be reading a lot.

Yes, I guess distributed and threaded computing have similar problems, 
both of which can be helped by a functional style.

...
> I agree with you that good libraries are essential to compact code
> size - but a key aspect of this is how well the language supports
> powerful abstractions. Perl, Python, Guile, etc all support
> abstraction much better than C, but I think a Scheme-based language
> can potentially do even better.

I think Scheme has the possiblity to just about anything (heck, all
those language are Turing-complete :).  However, I'm more concerned
about doing those things in an aesthetic manner.  Even C can pass
functions as arguments.  It's not the kind of thing you do for fun,
though.

> Can you give me an example of what you mean by "wrapping everything in
> lambdas" and how it is bad? Schemers tend to be big on passing code to
> control-flow constructs by passing it as procedures, which I think is
> quite logical in many cases.

Well, sometimes the procedure you pass will be organized just like you 
want it.  Maybe:

(map - some-list) to get the negetives of the list.

But in more complicated (and more real) examples you usually end up
needing to wrap the function because the arguments don't quite fit
right.

(for-each (lambda (x) (display x) (newline)) some-list)

That's not a good example, but I can't think of anything better.  I
know I've done this a lot, though.

That lambda just isn't pretty.  I guess I don't like the "lambda" form 
much anyway -- "lambda" is a meaningless word (mathematical roots
aside) and the form doesn't have enough visual hints -- I have to
think about it when I interpret a lambda, it's not visually
intuitive.  That can't be changed, though, as lambda is so at the core 
of Scheme.

But avoiding the need to wrap functions in lambdas is nice.


> Mikael suggested a while ago that we should set things up so that
> calling procedure-source on a primitive that only is a primitive for
> performance reasons, i.e. it can be written in Scheme in terms of
> other things, should produce equivalent Scheme code. We could do this
> by storing the Scheme implementations on disk somewhere and reading
> them on demand.

That would be really nice.  The one catch with having the two sorts of 
code is keeping them in synch, specifically if there's any
idiosyncracies to the code.

> > There's two issues: what could a good library system in Guile fix, and
> > what could language extensions in Guile fix.  I wouldn't stand behind
> > language extensions -- when does it stop being Scheme and become some
> > little brother of Common Lisp?  But maybe there's a way to do these
> > things in Scheme and I just don't see it.
> >
> 
> By language extensions do you mean syntactic extensions or just adding
> more primitive procedures? I agree that syntactic extensions are
> generally to be frowned upon. OTOH macros being used to implement
> obvious extensions to the syntax that are just wrappers around
> existing syntax is, IMO, pretty benign.

I'd shy away from language extensions.  Lots of primitives (which
should look mostly like library procedures) is exactly what this is
all trying to facilitate, after all.

> > Readability: Scheme has a way of leading to long expressions.  When
> > you get down to it, any functional procedure will be made up of one
> > (long) expression.  That's hard for humans to parse.  I like the
> > highlighting that DrScheme does -- when you are at a open or close
> > parenthesis, it highlights (without being obnoxious) the expression
> > that is enclosed by that parenthesis.  The passive nature of the
> > highlighting is what makes it nice.  (The static code analysis that
> > DrScheme does is also nice, but I'm not sure it's helpful enough to
> > warrant the complexity of implementing the interface)
> 
> Hmm, does any Emacs expert know if this can this be done with Emacs's
> font-lock-mode?

As a hint, Emacs does exactly this sort of highlighting if you double
click on a parenthesis in Scheme mode.

> > Along the library side, it would be nice to think about the naming
> > system for all the library procedures and coming up with a consistent,
> > concise, and meaningful system for naming (this also helps mnemonics).
> > I wish I could give a concrete example, but I haven't really worked
> > with any complex libraries in Scheme.  However, what I haven't seen
> > that I think is important is that Guile should be viewed as including
> > not only the core language, but a set of modules which provide
> > commonly-used functionality.  These are too essential to the language
> > and it's practical use too simply be add-ons.
> 
> Well, I hope the normal Guile package/installation comes with a bunch
> of useful extensions, but bundled as modules rather than built into
> the library.

Whether they are always included in the environment or not isn't
really important.  That conscious and proactive control is kept over
these core modules is important.  I.e., the most used modules
shouldn't be considered "extensions" but core parts of Guile (which
happen to be modularized).

> > A rich set of datatypes could also be a powerful addition.  Make
> > dictionaries, not hash tables -- mostly that's just a matter of
> > terminology, but I think it's important.  As a programmer, I don't
> > care about the fact that hash tables use hashing, I care about the
> > fact that hash tables are a collection of values indexed by keys.
> > 
> 
> There are a lot of data structures that are a collection of values
> indexed by keys. Association lists and hash tables, to name two useful
> ones, both have their place. Association lists are mainly useful in
> that they can be treated as lists directly, and Scheme's list
> operators can be used to do a lot of stuff quickly and easily. Hash
> tables are nice in that they have constant-time access.

I think it's confusing to have these two types.  A dictionary is a
dictionary, and I think it muddies the waters to have a bunch of types 
that are all equivalent to this concept.

A lot of my aesthetic opinions come from working in Smalltalk (Squeak, 
particularly).  The library system there is very elegant and
flexible.  One of best examples (or the thing most commonly used) is
the Collection classes.

They generalize all of the same operations that Scheme has over lists, 
and they do it uniformly for all collections.  If Guile could do the
same it would be really great.

That would mean having something like "map" that works for any kind of 
collection (list, vector, dictionary, etc) returning the same kind of
collection it receives.  The same for for-each, filter, etc.  Then the 
need for an association list would disapear.  It can also lead to very 
compact code that is still very readable, and makes learning how to
use a new type of collection extremely simple (since all the same
operations work on it).

> > If/when debugging in Guile becomes pleasant, allow people to actually
> > use these reference implementations so that they can access everything
> > their code does to a fine degree of granularity.  For instance, if you
> > provide a bad hash function to a hash-table, the error (or worse: the
> > lack of error) might pop up inside some hash-table function.  Being
> > able to inspect the innards of that function will make it much easier
> > to find the bug.
> 
> Are you referring to bugs in user code or bugs in system code? If the
> bug is in system code, debugging a Scheme version of C code might not
> help unless the Scheme code and the C code happen to have the same
> bug.

I'm thinking of user code.  For instance, the hash function might not
be called until you are inside some hash-table code.  Tracing this
back to the hash function could be difficult if the hash-table code is 
opaque.

[snipping some keyword comments I agree with]
> > An object system could also help.  With dynamic typing, it seems so
> > close... all the compromises are there (space, time, lack of static
> > analysis), but the benefits are not completely reaped.  An object
> > system allows a function which can work conceptually for many
> > datatypes to actually do so, without cond statements (which are
> > ugly).
> 
> Dynamically typed languages _can_ be mostly statically analyzed. A
> good type inference engine can infer the type of almost any Scheme
> expression (the general problem is uncomputable but I think the losing
> cases are rare enough that you can just provide some fallback for such
> cases). 

I certainly wouldn't argue for static typing!  But dynamic typing has
some compromises over static typing (mostly time and space).  The
static analysis is an often-mentioned benefit of static typing, but
personally I agree with you that it's mostly nonsense.  Most bugs that
static analysis catches are typos, and a lint can catch them fine too.
I've never had an interesting (read: difficult) bug caught by a
compiler.  Wait, if the compiler caught it, it wouldn't be difficult.
Hmm.  I guess I should say I've never had an interesting bug in a
dynamically typed language that a compiler could have caught.

Some sort of lint would be nice, though... it's hard to do that
without being closely tied to the Guile runtime, though, which means
understanding the entire program, modules, etc.  I don't know if you
could really do a proper lint in Emacs.  Unless Emacs was integrated
with Guile.  Isn't that supposed to happen sometime? (Anytime soon?)

> That's not really relevant to your point though. I agree that a good
> object system is key. I actually have a pretty spiffy Guile project on
> the back burner waiting for a good standard object system (I might
> just break down and use the interpreted tinyclos to prototype).

Is there anyone in the Scheme community even working towards a
standard object system?  If there isn't, then tinyclos is as good as
anything, I'd suppose.


<------------------------------------------------------------------->
< Ian Bicking                 |  bickiia@earlham.edu                >
< drawer #419 Earlham College |  http://www.cs.earlham.edu/~bickiia >
< Richmond, IN 47374          |  (765) 973-2824                     >
<------------------------------------------------------------------->