With UCBLOGO all procedures are global. But variables may be local . To implement local procedures we can attach procedures to variables. The actuai procedure name is genereted by gensym which genereates unique names. The procedures are global but there access is local. A procedure name is created as local variable and the procedure localdefine generates a unique procedure name using gensym and attach the procedure's name to the local variable. The procedure localrun execute the procedure with its parameters. When the procedure is no more used we erase its local name. to Testlocalprocedure local "proc localDefine "proc [[x][pr :x]] localrun [ proc [here proc1]] embededproc er :proc end To see that the same procedure name is local we define a different procedure with the same name inside the procedure embededproc which is called by Testlocalprocedure. to embededproc local "proc localdefine "proc [[x][(pr "----- :x "-----)]] localrun [proc [here proc2]] er :proc end ? testlocalprocedure here proc1 ----- here proc2 ----- If we don't define a local procedure in embededproc the procedure defined in Testlocalprocedure (which is under the scope of the variable proc) is used. to embededproc ,local "proc ,localdefine "proc [[x][(pr "----- :x "-----)]] localrun [proc [here proc2]] er :proc end ? testlocalprocedure here proc1 here proc2 Procedure as black box Locales procedures are needed to hide procedures used as tool in a main procedure. We are only interested only the action of the main procedure.The tools are defined as local procedures inside the body of the main procedure. Example from Structure and Interpretation of Computer Programs, 1.1.8 Procedures as Black-Box Abstractions. Internal definitions and block structure We have one kind of name isolation available to us so far: The formal parameters of a procedure are local inside the body of the procedure. The square-root program illustrates another way in which we would like to control the use of names. The existing program consists of separate procedures: (define (sqrt x) (sqrt-iter 1.0 x)) (define (sqrt-iter guess x) (if (good-enough? guess x) guess (sqrt-iter (improve guess x) x))) (define (good-enough? guess x) (< (abs (- (square guess) x)) 0.001)) (define (improve guess x) (average guess (/ x guess))) The problem with this program is that the only procedure that is important to users of sqrt is sqrt. The other procedures (sqrt-iter, good-enough?, and improve) only clutter up their minds. They may not define any other procedure called good-enough? as part of another program to work together with the square-root program, because sqrt needs it. The problem is especially severe in the construction of large systems by many separate programmers. For example, in the construction of a large library of numerical procedures, many numerical functions are computed as successive approximations and thus might have procedures named good-enough? and improve as auxiliary procedures. We would like to localize the subprocedures, hiding them inside sqrt so that sqrt could coexist with other successive approximations, each having its own private good-enough? procedure. To make this possible, we allow a procedure to have internal definitions that are local to that procedure. For example, in the square-root problem we can write (define (sqrt x) (define (good-enough? guess x) (< (abs (- (square guess) x)) 0.001)) (define (improve guess x) (average guess (/ x guess))) (define (sqrt-iter guess x) (if (good-enough? guess x) guess (sqrt-iter (improve guess x) x))) (sqrt-iter 1.0 x)) Such nesting of definitions, called block structure, is basically the right solution to the simplest name-packaging problem. But there is a better idea lurking here. (define (sqrt x) (define (good-enough? guess) (< (abs (- (square guess) x)) 0.001)) (define (improve guess) (average guess (/ x guess))) (define (sqrt-iter guess) (if (good-enough? guess) guess (sqrt-iter (improve guess)))) (sqrt-iter 1.0)) UCBLogo version: to sqrtnew :x ;Assuming square abs average already defined local "good.enough localdefine "good.enough [[guess x] [op (abs (( square :guess) - :x ) )< 0.0001 ]] local "improve localdefine "improve [[guess x] [op average :guess (:x / :guess) ]] local "sqrt.iter localdefine "sqrt.iter [[guess x] [op ifelse (localrun [good.enough :guess :x] ) [ :guess][ localrun [sqrt.iter (localrun [improve :guess :x] ):x]]]] localmake "temp ( round ( 10000 * ( localrun [sqrt.iter 1.0 :x] ) ) ) / 10000 er thing "sqrt.iter er thing "good.enough er thing "improve op :temp end ? show procedures [abs average buryall created embededproc erlocals localdefine localrun mytest showt sqrtiter sqrtnew sqrtnew2 square testlocalprocedure unburyall] ? pr sqrtnew 2 1.4142 ? show procedures [abs average buryall created embededproc erlocals localdefine localrun mytest showt sqrtiter sqrtnew sqrtnew2 square testlocalprocedure unburyall] ? We see that after running sqrtnew the procedures are the same then before In addition to internalizing the definitions of the auxiliary procedures, we can simplify them. Since x is bound in the definition of sqrt, the procedures good-enough?, improve, and sqrt-iter, which are defined internally to sqrt, are in the scope of x. Thus, it is not necessary to pass x explicitly to each of these procedures. Instead, we allow x to be a free variable in the internal definitions, as shown below. Then x gets its value from the argument with which the enclosing procedure sqrt is called. This discipline is called lexical scoping.27 (define (sqrt x) (define (good-enough? guess) (< (abs (- (square guess) x)) 0.001)) (define (improve guess) (average guess (/ x guess))) (define (sqrt-iter guess) (if (good-enough? guess) guess (sqrt-iter (improve guess)))) (sqrt-iter 1.0)) Ucblogo version: to sqrtnewwithoutx :x ;Assuming square abs average already defined local "good.enough localdefine "good.enough [[guess ] [op (abs (( square :guess) - :x ) )< 0.0001 ]] local "improve localdefine "improve [[guess ] [op average :guess (:x / :guess) ]] local "sqrt.iter localdefine "sqrt.iter [[guess x] [op ifelse (localrun [good.enough :guess ] ) [ :guess][ localrun [sqrt.iter (localrun [improve :guess ] ):x]]]] localmake "temp ( round ( 10000 * ( localrun [sqrt.iter 1.0 :x] ) ) ) / 10000 er thing "sqrt.iter er thing "good.enough er thing "improve op :temp end