Newsgroups: comp.lang.python,comp.lang.tcl,comp.lang.scheme,comp.lang.misc,comp.lang.perl
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!pipex!uunet!news.cygnus.com!nntp!lord
From: lord@cygnus.com (Tom Lord)
Subject: Comparing syntaxes  (Re: What language would you use?)
In-Reply-To: Tom Christiansen's message of 6 Nov 1994 03:12:57 GMT
Message-ID: <LORD.94Nov5225343@cygnus.com>
Sender: news@cygnus.com
Nntp-Posting-Host: cygnus.com
Organization: Cygnus Support
References: <39b7ha$j9v@zeno.nscf.org> <39hhjp$lgn@csnews.cs.Colorado.EDU>
Date: Sun, 6 Nov 1994 06:53:43 GMT
Lines: 124
Xref: glinda.oz.cs.cmu.edu comp.lang.python:2372 comp.lang.tcl:21406 comp.lang.scheme:10969 comp.lang.misc:18786 comp.lang.perl:38078



I'm not into point by point refutations or replies, but i saw a
neat segue:

Tchrist writes:

    However, I think you'll find that if someone understand this:

	long fact(long i) {
	    if (i < 1) {
		return 1;
	    } else {
		return i * fact(i - 1);
	    } 
	} 

    That this isn't very far removed from it:

	sub fact {  
	    my $n = shift;
	    if ($n < 1) {
		return 1;
	    } else {
		return $n * fact($n - 1);
	    } 
	} 

After this syntactic comparison, tchrist goes on to post some scheme
code (but not code that computes factorial).  I guess its only
fair if i post some scheme code.  I'm going to give three scheme
versions.  The first mimics the C version.  The second is how a 
scheme hacker would normally write fact.  The third is the most interesting
in this context -- I saved the best for last.

First, there is the mimicy version.  I think it looks a lot like
the C version, except puffier.


	(define (fact i)		; warning -- untested code
	  (if (< i 1)
	     1
	     (* i (fact (+ -1 i)))))


Next is the text book version.  A hacker who wanted to optimize her
implementation of factorial wouldn't write a recursive function -- she'd
write a loop.  In Scheme, loops have a startling appearence.  In this
case, the loop is implemented by a tail recursive nested function.

	; If you haven't learned scheme, but know c or perl
	; or almost any other popular language, this will
	; be hard to follow.
	;
	(define (fact i)		; warning -- untested code
	   (define (loop next-factor answer-so-far)
		(if (< next-factor 1)
		   answer-so-far
		   (loop (- next-factor 1) (* next-factor answer-so-far))))
	   (loop i 1))


As you can see, a tail recursive nested function looks quite a bit
different from, say a `for' loop in C.  But in fact, a `for' loop in C
is just another kind of notation for the same idea.  Which brings me
to the third example of factorial in Scheme.

I've mentioned that the GEL project will produce a C-like syntax for
Scheme.  I have a prototype of this syntax, and as it turns out, my
test suite contains an implementation of factorial.  Personally, i
think this is slightly cleaner than both the C and Perl verions

	     /* warning -- doesn't implement quite the same
	      * function as tchrist's examples, but it's close.
	      */
	     define fact(x)
	     {
	       var total;
	       for (total = 1; x; x = x - 1)
	          total = total * x;
	       return total;
	      }

I have a 700 line yacc grammar and a 500 line scheme program that
translate definitions in the c-like syntax.  In this case, the
translator produces a tail recursive loop comperable to what a scheme
programmer would have written in the first place.  This isn't Rocket
Science -- many people have implemented similar syntaxes before -- but
i hope it will help to make people more comfortable programming with
the Gnu extension language.


-t

p.s. for schemeheads

For the code above, I get the translation:

     (define (fact x)
       (let* ((total #f))
         (let ((break (lambda (return) total)))
           (begin
             (set! total 1)
             (letrec ((continue
                        (lambda (return)
                          (if (ctax:test x)
                            (begin
                              (set! total (ctax:times total x))
                              (continue (set! x (ctax:minus x 1))))
                            (break return)))))
               (continue #f))))))

This is pretty close to what a hacker who likes scheme syntax would
have written in the first place.  Probably a scheme hacker wouldn't
have modifed TOTAL by side effects, and would have added an
extra parameter to the loop.



--
----

If you would like to volunteer to help with the GNU extension language
project, please write to lord@gnu.ai.mit.edu.
