guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: macro like "my" in Perl


From: Ken Anderson
Subject: Re: macro like "my" in Perl
Date: Wed, 26 Jun 2002 09:15:42 -0400

In Jscheme, not guile, i recently redefined (define) so that groups of internal defines are turned into let* or letrec as appropriate, so you can write code without additional indenting:

 (define (graph)
  (define objRoot (BranchGroup.))
  (define objTrans (TransformGroup.))
  (define (addToRoot obj) (.addChild objRoot obj))
  (.setCapability objTrans TransformGroup.ALLOW_TRANSFORM_WRITE$)
  (.addToRoot objTrans)
  (.addChild objTrans (ColorCube. 0.4))
  (define yAxis (Transform3D.))
  (define rotationAlpha (Alpha. -1 4000L))
  (define rotator
    (RotationInterpolator. rotationAlpha objTrans yAxis
                           0.0f
                           (* 2.0F (.floatValue Math.PI$))))
  (define bounds (BoundingSphere. (Point3d. 0.0 0.0 0.0) 100.0))
  (.setSchedulingBounds rotator bounds)
  (addToRoot rotator)
  (.compile objRoot)
  objRoot)


At 10:25 PM 6/25/2002, Alex Shinn wrote:
>>>>> "Paul" == Paul Jarc <address@hidden> writes:

    Paul> I'm looking for something like Perl's "my":

    [...]

    Paul>  (new-scope
    Paul>    (my-define foo #t)
    Paul>    (do-random-stuff-with foo)
    Paul>    (my-define bar foo)
    Paul>    (do-other-stuff-with bar))

let* can do this if you want:

  (let* ((foo #t)
         (dummy (do-random-stuff-with foo))
         (bar foo))
    (do-other-stuff-with bar))

but that's rather poor style.  If you just want bar to be some function
of foo, you can do

  (let* ((foo #t)
         (bar (some-random-function-of foo)))
    (do-other-stuff-with bar))

or you can declare all the variables you need up front

  (let* ((foo #t) (bar #f))
    (do-random-stuff-with foo)
    (set! bar foo)
    (do-other-stuff-with bar))

or nest let

  (let ((foo #t))
    (do-random-stuff-with foo)
    (let ((bar foo))
      (do-other-stuff-with bar)))

I guess that's the real complaint... nested lets indent the code too
much, but for some straight but very long procedural algorithms it's
less clear to make all the variable decls up front when their use is
localized.

You can write new-scope as a low-level macro that walks the code,
turning my-define into set! and accumulating all the variable names used
into one top-level let.  Something like

(define-macro (new-scope . code)
  (let ((vars (map cadr (filter (lambda (x) (eq? (car x) 'my-define))
                                code))))
    `(let (,@(map (lambda (x) (list x #f)) vars))
       ,@(map (lambda (x) (if (and (pair? x) (eq? (car x) 'my-define))
                              (cons 'set! (cdr x))
                              x))
              code))))

but make it recurse (this only works if all the my-define's are at the
top level).

--
Alex

_______________________________________________
Guile-user mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/guile-user




reply via email to

[Prev in Thread] Current Thread [Next in Thread]