DEFINE and LET 
Author Message
 DEFINE and LET

   Date: Sun, 1 May 1994 10:11:55 GMT

   What's the difference between

     (define (foo) (define bar 3) ...)

   and

     (define (foo) (let ((bar 3)) ...))

   ?

None whatsoever.  But consider

  (define bar "Baz!")
  (define (foo) (define bar (lambda () bar)) ...)
  (foo) => #<Procedure ...>

vs.

  (define bar "Baz!")
  (define (foo) (let ((bar (lambda () bar))) ...))
  (foo) => "Baz!"



Sat, 19 Oct 1996 01:56:01 GMT  
 DEFINE and LET
Subject: DEFINE and LET

Date: Sun, 1 May 1994 10:11:55 GMT

Quote:

>Simple question.

>What's the difference between

>  (define (foo) (define bar 3) ...)

>and

>  (define (foo) (let ((bar 3)) ...))

  (define (foo) (define bar 3) ...)
is equivalent to
  (define (foo) (letrec ((bar 3)) ...))
[see section 5.2.2 "Internal Definitions" in the IEEE
Standard or R^4RS].

ASIDE: {I know you did not ask this, but just in case...}

The difference between LET and LETREC is roughly that LET
can be thought of a "parallel assignment" where each LET
binding can be computed without looking at any other LET
binding. LETREC bindings are mutually known.

E.g. in
  (let ( (fact
          (lambda (n)
           (if (< n 2) 1 (* n (fact (sub1 n))))))
       )
    (fact 5))
The FACT internal to the lambda form must be known in the
outer scope {outside the LET} or it is undefined. If you
say:
  (letrec ( (fact
          (lambda (n)
           (if (< n 2) 1 (* n (fact (sub1 n))))))
       )
    (fact 5))
The binding of FACT in the lambda is known to be the value
within the scope of the letrec--i.e. the call to FACT
recursive.

Note:
  (define a 5)
  (let ( (a 1) (b a) ) (+ a b))  ;--> 6
  (let* ( (a 1) (b a) ) (+ a b)) ;--> 2
; The let* is equivalent to
; (let ( (a 1) )
;   (let ( (b a) ) ; previous bindings visable
;       (+ a b)))
  (letrec ( (a 1) (b a) ) (+ a b)) ;; ERROR!!
;; Letrec bindings need to be able to be evaluated
;; without assigning or referencing a value of
;; any other binding of the same letrec.

Hope this helps,
-Ken



Sat, 19 Oct 1996 00:33:13 GMT  
 DEFINE and LET
|> Simple question.
|>
|> What's the difference between
|>
|>   (define (foo) (define bar 3) ...)
|>
|> and
|>
|>   (define (foo) (let ((bar 3)) ...))
|>
|> ?
|>

Depends on the "...". If the first define is followed by further defines,
it is an error for them to use "bar" in the first case, while it is no
problem in the second. Example:

(define (foo) (define bar 3) (define bux bar) bux)  -> error!

(define (foo) (let ((bar 3)) (define bux bar) bux))
(foo) -> 3

- axel



Mon, 21 Oct 1996 00:40:28 GMT  
 DEFINE and LET


   [ ... ]

   > (define (foo) (define bar 3) (define bux bar) bux)  -> error!

   [ ... ]

   That's funny.  SCM has no problem with the former and indeed "(foo) ==> 3".

SCM is not the definition of Scheme.  If some implementation let's you
get away with broken code, then you just got lucky in one case and
unlucky in general.  This is because potential portability problems
escape undetected.

SCM is a particularly bad example -- it even accepted

        (if foo
            (define bar (baz ...)))

I found this kind of code in SLIB when I tried to adapt SLIB to VSCM,
and naturally -- VSCM choked on that.

Of course, SCM is a pure interpreter, and the cost of checking
everything at run-time might be too high.  But then -- what's more
precious -- the extra time spent on sanity checks or the time to walk,
understand, and re-write the code when you try to port it?

--
-Matthias



Mon, 21 Oct 1996 04:29:50 GMT  
 DEFINE and LET
    Matthias> But
    Matthias> then -- what's more precious -- the extra time spent on
    Matthias> sanity checks or the time to walk, understand, and
    Matthias> re-write the code when you try to port it?

Which again reminds me to ask whether anyone has put together a
lint-like checker for Shceme. Many portability problems could be found
statically, as well as many programming errors that usually show up as
runtime errors. I have been thinking about rewriting the sclint
checker I wrote a couple of years ago, but I was hoping that someone
had already done the job. Anyone have good type checker that I could
plug in? It would be nice to catch things like (+ car ls 1) that I
seem to do all the time.

--
Pertti Kellom\"aki (TeX format)  #       These opinions are mine,
  Tampere Univ. of Technology    #              ALL MINE !
      Software Systems Lab       #  (but go ahead and use them, if you like)



Mon, 21 Oct 1996 18:02:12 GMT  
 DEFINE and LET

|> Which again reminds me to ask whether anyone has put together a
|> lint-like checker for Shceme. Many portability problems could be found
|> statically, as well as many programming errors that usually show up as
|> runtime errors. I have been thinking about rewriting the sclint
|> checker I wrote a couple of years ago, but I was hoping that someone
|> had already done the job. Anyone have good type checker that I could
|> plug in? It would be nice to catch things like (+ car ls 1) that I
|> seem to do all the time.

In the C-world, I have never had to use lint, because all modern C compilers
produce those warnings as byproducts of their analysis. A scheme compiler
that does things like data flow analysis and type inference should easily be
able to produce a warning or two. Hey, compiler writers, wouldn't that be
an idea?

--axel



Tue, 22 Oct 1996 22:37:35 GMT  
 DEFINE and LET

Quote:
>In the C-world, I have never had to use lint, because all modern C compilers
>produce those warnings as byproducts of their analysis

The advantage of lint, even with ANSI C or C++, is that it looks at more than
one file at a time. The compiler doesn't.

The same could hold for a Scheme-lint.



Tue, 22 Oct 1996 17:42:57 GMT  
 DEFINE and LET

   SCM is a particularly bad example -- it even accepted

           (if foo
               (define bar (baz ...)))

   I found this kind of code in SLIB when I tried to adapt SLIB to VSCM,
   and naturally -- VSCM choked on that.

This was a bug in one file in SLIB and is fixed in slib2a1.  It was
due to the strange compulsion some people feel port their code not
only to SLIB but to each scheme implementation but without slib
present.  I no longer accept such code for SLIB.

   Of course, SCM is a pure interpreter, and the cost of checking
   everything at run-time might be too high.  But then -- what's more
   precious -- the extra time spent on sanity checks or the time to walk,
   understand, and re-write the code when you try to port it?

If VSCM did not report this as an error (and hence required you to
walk, understand, ... the code), then perhaps this particular bug is
tricky to implement a check for.  The other SLIB implementations did
not {*filter*}on it.  And although I can certainly be accused of trading
safety for speed, I doubt all the other implementors can.



Wed, 23 Oct 1996 23:30:36 GMT  
 DEFINE and LET


   |> Which again reminds me to ask whether anyone has put together a
   |> lint-like checker for Shceme. Many portability problems could be found
   |> statically, as well as many programming errors that usually show up as
   |> runtime errors. I have been thinking about rewriting the sclint
   |> checker I wrote a couple of years ago, but I was hoping that someone
   |> had already done the job. Anyone have good type checker that I could
   |> plug in? It would be nice to catch things like (+ car ls 1) that I
   |> seem to do all the time.

   In the C-world, I have never had to use lint, because all modern C compilers
   produce those warnings as byproducts of their analysis.

In the C-world, I have had to use lint a lot because C compilers don't
check argument agreement between multiple source files.  If you use
K&R C (no prototypes, as opposed to ANSI) for portability then this is
a problem.

   A scheme compiler that does things like data flow analysis and type
   inference should easily be able to produce a warning or two. Hey,
   compiler writers, wouldn't that be an idea?

That doesn't cut it either.  Most Scheme implememtations provide
features beyond the R4RS spec.  Those scheme implementations may lack
compilers or have compilers which can't compile the extra features.
So the domain of code which can be statically checked is more limited
than users will want to check.

Also, unless declarations are provided, the analysis that a Scheme
compiler would perform would usually be limited to each individual top
level definition.  And so wouldn't provide the lint-type information.



Fri, 25 Oct 1996 02:43:51 GMT  
 DEFINE and LET

: |> Which again reminds me to ask whether anyone has put together a
: |> lint-like checker for Shceme. Many portability problems could be found
: |> statically, as well as many programming errors that usually show up as
: |> runtime errors. I have been thinking about rewriting the sclint
: |> checker I wrote a couple of years ago, but I was hoping that someone
: |> had already done the job. Anyone have good type checker that I could
: |> plug in? It would be nice to catch things like (+ car ls 1) that I
: |> seem to do all the time.

: In the C-world, I have never had to use lint, because all modern C compilers
: produce those warnings as byproducts of their analysis. A scheme compiler
: that does things like data flow analysis and type inference should easily be
: able to produce a warning or two. Hey, compiler writers, wouldn't that be
: an idea?

Andrew Wright wrote Soft Types for Scheme - it's excellent. Check out

        titan.cs.rice.edu:public/wright/softscheme.tar.Z

From the announcement:

        I am pleased to announce the first public release of Soft
        Scheme, my practical *soft* type system for R4RS Scheme.  Also
        available is Rice technical report TR93-218 titled "A practical soft
        type system for Scheme" by Andrew K. Wright and Robert Cartwright.

        Soft Scheme provides the benefits of static typing for dynamically
        typed Scheme.  Like a static type checker, a soft type checker infers
        types for variables and expressions.  But rather than reject programs
        containing untypable fragments, a soft type checker inserts explicit
        run-time checks to transform untypable programs to typable form.
        These run-time checks indicate potential program errors, enabling
        programmers to detect errors prior to program execution.  Soft type
        checking minimizes the number of run-time checks in the compiled code,
        enabling dynamically typed languages to attain the efficiency of
        statically typed languages like ML.

Have fun,

Christian

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

 TU Braunschweig                                Tel.:0531 - 391 - 7465
 Institut fuer Programmiersprachen              Fax.:0531 - 391 - 8111
 D-38106 Braunschweig



Fri, 25 Oct 1996 14:36:41 GMT  
 DEFINE and LET
At least some of what you've been talking about re: lint for scheme is
provided by Andrew Wright's SoftScheme (ftp'able from
titan.cs.rice.edu, somewhere, maybe also the scheme repository).
Provides soft typechecking, a very nice pattern matching macro,
structures.  Works as a batch processor, file based.

dr



Sat, 26 Oct 1996 04:52:58 GMT  
 
 [ 16 post ]  Go to page: [1] [2]

 Relevant Pages 

1. using define versus let for local procedures

2. Why this? (define f (let ((x x)) ...)

3. Lets define "pointer"

4. Lets define "pointer"

5. let vs define

6. defining structs within a let clause

7. let vs define stupid question?

8. Database interface: let us define a standard

9. Lets define "megawidget support" (LONG)

10. Distinguish between the usage of Lambda and Let, Let*

11. Distinguish between the usage of Lambda and Let, Let*

12. let and let*

 

 
Powered by phpBB® Forum Software