locals: modify examples to use new "--- Data stack:" output.
parent
b1c0a1be33
commit
ca51f43b3f
|
@ -74,9 +74,8 @@ IN: scratchpad
|
||||||
:: quadratic-roots ( a b c -- x y )
|
:: quadratic-roots ( a b c -- x y )
|
||||||
b sq 4 a c * * - sqrt :> disc
|
b sq 4 a c * * - sqrt :> disc
|
||||||
b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@ ;
|
b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@ ;
|
||||||
1.0 1.0 -6.0 quadratic-roots [ . ] bi@"
|
1.0 1.0 -6.0 quadratic-roots"
|
||||||
"2.0
|
"\n--- Data stack:\n2.0\n-3.0"
|
||||||
-3.0"
|
|
||||||
}
|
}
|
||||||
"If you wanted to perform the quadratic formula interactively from the listener, you could use " { $link POSTPONE: [let } " to provide a scope for the variables:"
|
"If you wanted to perform the quadratic formula interactively from the listener, you could use " { $link POSTPONE: [let } " to provide a scope for the variables:"
|
||||||
{ $example "USING: locals math math.functions kernel ;
|
{ $example "USING: locals math math.functions kernel ;
|
||||||
|
@ -84,9 +83,8 @@ IN: scratchpad
|
||||||
[let 1.0 :> a 1.0 :> b -6.0 :> c
|
[let 1.0 :> a 1.0 :> b -6.0 :> c
|
||||||
b sq 4 a c * * - sqrt :> disc
|
b sq 4 a c * * - sqrt :> disc
|
||||||
b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@
|
b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@
|
||||||
] [ . ] bi@"
|
]"
|
||||||
"2.0
|
"\n--- Data stack:\n2.0\n-3.0"
|
||||||
-3.0"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$nl
|
$nl
|
||||||
|
@ -94,27 +92,27 @@ $nl
|
||||||
{ $heading "Quotations with lexical variables, and closures" }
|
{ $heading "Quotations with lexical variables, and closures" }
|
||||||
"These next two examples demonstrate lexical variable bindings in quotations defined with " { $link POSTPONE: [| } ". In this example, the values " { $snippet "5" } " and " { $snippet "3" } " are put on the datastack. When the quotation is called, it takes those values as inputs and binds them respectively to " { $snippet "m" } " and " { $snippet "n" } " before executing the quotation:"
|
"These next two examples demonstrate lexical variable bindings in quotations defined with " { $link POSTPONE: [| } ". In this example, the values " { $snippet "5" } " and " { $snippet "3" } " are put on the datastack. When the quotation is called, it takes those values as inputs and binds them respectively to " { $snippet "m" } " and " { $snippet "n" } " before executing the quotation:"
|
||||||
{ $example
|
{ $example
|
||||||
"USING: kernel locals math prettyprint ;"
|
"USING: kernel locals math ;"
|
||||||
"IN: scratchpad"
|
"IN: scratchpad"
|
||||||
"5 3 [| m n | m n - ] call ."
|
"5 3 [| m n | m n - ] call( x x -- x )"
|
||||||
"2"
|
"\n--- Data stack:\n2"
|
||||||
}
|
}
|
||||||
$nl
|
$nl
|
||||||
|
|
||||||
"In this example, the " { $snippet "adder" } " word creates a quotation that closes over its argument " { $snippet "n" } ". When called, the result quotation of " { $snippet "5 adder" } " pulls " { $snippet "3" } " off the datastack and binds it to " { $snippet "m" } ", which is added to the value " { $snippet "5" } " bound to " { $snippet "n" } " in the outer scope of " { $snippet "adder" } ":"
|
"In this example, the " { $snippet "adder" } " word creates a quotation that closes over its argument " { $snippet "n" } ". When called, the result quotation of " { $snippet "5 adder" } " pulls " { $snippet "3" } " off the datastack and binds it to " { $snippet "m" } ", which is added to the value " { $snippet "5" } " bound to " { $snippet "n" } " in the outer scope of " { $snippet "adder" } ":"
|
||||||
{ $example
|
{ $example
|
||||||
"USING: kernel locals math prettyprint ;"
|
"USING: kernel locals math ;"
|
||||||
"IN: scratchpad"
|
"IN: scratchpad"
|
||||||
":: adder ( n -- quot ) [| m | m n + ] ;"
|
":: adder ( n -- quot ) [| m | m n + ] ;"
|
||||||
"3 5 adder call ."
|
"3 5 adder call( x -- x )"
|
||||||
"8"
|
"\n--- Data stack:\n8"
|
||||||
}
|
}
|
||||||
$nl
|
$nl
|
||||||
|
|
||||||
{ $heading "Mutable bindings" }
|
{ $heading "Mutable bindings" }
|
||||||
"This next example demonstrates closures and mutable variable bindings. The " { $snippet "<counter>" } " word outputs a tuple containing a pair of quotations that respectively increment and decrement an internal counter in the mutable " { $snippet "value" } " variable and then return the new value. The quotations close over the counter, so each invocation of the word gives new quotations with a new internal counter."
|
"This next example demonstrates closures and mutable variable bindings. The " { $snippet "<counter>" } " word outputs a tuple containing a pair of quotations that respectively increment and decrement an internal counter in the mutable " { $snippet "value" } " variable and then return the new value. The quotations close over the counter, so each invocation of the word gives new quotations with a new internal counter."
|
||||||
{ $example
|
{ $example
|
||||||
"USING: locals kernel math ;
|
"USING: accessors locals kernel math ;
|
||||||
IN: scratchpad
|
IN: scratchpad
|
||||||
|
|
||||||
TUPLE: counter adder subtractor ;
|
TUPLE: counter adder subtractor ;
|
||||||
|
@ -125,17 +123,15 @@ TUPLE: counter adder subtractor ;
|
||||||
[ value 1 + dup value! ] >>adder
|
[ value 1 + dup value! ] >>adder
|
||||||
[ value 1 - dup value! ] >>subtractor ;
|
[ value 1 - dup value! ] >>subtractor ;
|
||||||
<counter>
|
<counter>
|
||||||
[ adder>> call . ]
|
[ adder>> call( -- x ) ]
|
||||||
[ adder>> call . ]
|
[ adder>> call( -- x ) ]
|
||||||
[ subtractor>> call . ] tri"
|
[ subtractor>> call( -- x ) ] tri"
|
||||||
"1
|
"\n--- Data stack:\n1\n2\n1"
|
||||||
2
|
|
||||||
1"
|
|
||||||
}
|
}
|
||||||
$nl
|
$nl
|
||||||
"The same variable name can be bound multiple times in the same scope. This is different from reassigning the value of a mutable variable. The most recent binding for a variable name will mask previous bindings for that name. However, the old binding referring to the previous value can still persist in closures. The following contrived example demonstrates this:"
|
"The same variable name can be bound multiple times in the same scope. This is different from reassigning the value of a mutable variable. The most recent binding for a variable name will mask previous bindings for that name. However, the old binding referring to the previous value can still persist in closures. The following contrived example demonstrates this:"
|
||||||
{ $example
|
{ $example
|
||||||
"USING: kernel locals prettyprint ;
|
"USING: kernel locals ;
|
||||||
IN: scratchpad
|
IN: scratchpad
|
||||||
:: rebinding-example ( -- quot1 quot2 )
|
:: rebinding-example ( -- quot1 quot2 )
|
||||||
5 :> a [ a ]
|
5 :> a [ a ]
|
||||||
|
@ -143,23 +139,20 @@ IN: scratchpad
|
||||||
:: mutable-example ( -- quot1 quot2 )
|
:: mutable-example ( -- quot1 quot2 )
|
||||||
5 :> a! [ a ]
|
5 :> a! [ a ]
|
||||||
6 a! [ a ] ;
|
6 a! [ a ] ;
|
||||||
rebinding-example [ call . ] bi@
|
rebinding-example [ call( -- x ) ] bi@
|
||||||
mutable-example [ call . ] bi@"
|
mutable-example [ call( -- x ) ] bi@"
|
||||||
"5
|
"\n--- Data stack:\n5\n6\n6\n6"
|
||||||
6
|
|
||||||
6
|
|
||||||
6"
|
|
||||||
}
|
}
|
||||||
"In " { $snippet "rebinding-example" } ", the binding of " { $snippet "a" } " to " { $snippet "5" } " is closed over in the first quotation, and the binding of " { $snippet "a" } " to " { $snippet "6" } " is closed over in the second, so calling both quotations results in " { $snippet "5" } " and " { $snippet "6" } " respectively. By contrast, in " { $snippet "mutable-example" } ", both quotations close over a single binding of " { $snippet "a" } ". Even though " { $snippet "a" } " is assigned to " { $snippet "6" } " after the first quotation is made, calling either quotation will output the new value of " { $snippet "a" } "."
|
"In " { $snippet "rebinding-example" } ", the binding of " { $snippet "a" } " to " { $snippet "5" } " is closed over in the first quotation, and the binding of " { $snippet "a" } " to " { $snippet "6" } " is closed over in the second, so calling both quotations results in " { $snippet "5" } " and " { $snippet "6" } " respectively. By contrast, in " { $snippet "mutable-example" } ", both quotations close over a single binding of " { $snippet "a" } ". Even though " { $snippet "a" } " is assigned to " { $snippet "6" } " after the first quotation is made, calling either quotation will output the new value of " { $snippet "a" } "."
|
||||||
{ $heading "Lexical variables in literals" }
|
{ $heading "Lexical variables in literals" }
|
||||||
"Some kinds of literals can include references to lexical variables as described in " { $link "locals-literals" } ". For example, the " { $link 3array } " word could be implemented as follows:"
|
"Some kinds of literals can include references to lexical variables as described in " { $link "locals-literals" } ". For example, the " { $link 3array } " word could be implemented as follows:"
|
||||||
{ $example
|
{ $example
|
||||||
"USING: locals prettyprint ;
|
"USING: locals ;
|
||||||
IN: scratchpad
|
IN: scratchpad
|
||||||
|
|
||||||
:: my-3array ( x y z -- array ) { x y z } ;
|
:: my-3array ( x y z -- array ) { x y z } ;
|
||||||
1 \"two\" 3.0 my-3array ."
|
1 \"two\" 3.0 my-3array"
|
||||||
"{ 1 \"two\" 3.0 }"
|
"\n--- Data stack:\n{ 1 \"two\" 3.0 }"
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
ARTICLE: "locals-literals" "Lexical variables in literals"
|
ARTICLE: "locals-literals" "Lexical variables in literals"
|
||||||
|
@ -176,33 +169,34 @@ $nl
|
||||||
{ $heading "Object identity" }
|
{ $heading "Object identity" }
|
||||||
"This feature changes the semantics of literal object identity. An ordinary word containing a literal pushes the same literal on the stack every time it is invoked:"
|
"This feature changes the semantics of literal object identity. An ordinary word containing a literal pushes the same literal on the stack every time it is invoked:"
|
||||||
{ $example
|
{ $example
|
||||||
|
"USING: kernel ;"
|
||||||
"IN: scratchpad"
|
"IN: scratchpad"
|
||||||
"TUPLE: person first-name last-name ;"
|
"TUPLE: person first-name last-name ;"
|
||||||
": ordinary-word-test ( -- tuple )"
|
": ordinary-word-test ( -- tuple )"
|
||||||
" T{ person { first-name \"Alan\" } { last-name \"Kay\" } } ;"
|
" T{ person { first-name \"Alan\" } { last-name \"Kay\" } } ;"
|
||||||
"ordinary-word-test ordinary-word-test eq? ."
|
"ordinary-word-test ordinary-word-test eq?"
|
||||||
"t"
|
"\n--- Data stack:\nt"
|
||||||
}
|
}
|
||||||
"Inside a lexical scope, literals which do not contain lexical variables still behave in the same way:"
|
"Inside a lexical scope, literals which do not contain lexical variables still behave in the same way:"
|
||||||
{ $example
|
{ $example
|
||||||
"USE: locals"
|
"USING: kernel locals ;"
|
||||||
"IN: scratchpad"
|
"IN: scratchpad"
|
||||||
"TUPLE: person first-name last-name ;"
|
"TUPLE: person first-name last-name ;"
|
||||||
":: locals-word-test ( -- tuple )"
|
":: locals-word-test ( -- tuple )"
|
||||||
" T{ person { first-name \"Alan\" } { last-name \"Kay\" } } ;"
|
" T{ person { first-name \"Alan\" } { last-name \"Kay\" } } ;"
|
||||||
"locals-word-test locals-word-test eq? ."
|
"locals-word-test locals-word-test eq?"
|
||||||
"t"
|
"\n--- Data stack:\nt"
|
||||||
}
|
}
|
||||||
"However, literals with lexical variables in them actually construct a new object:"
|
"However, literals with lexical variables in them actually construct a new object:"
|
||||||
{ $example
|
{ $example
|
||||||
"USING: locals splitting ;"
|
"USING: locals kernel splitting ;"
|
||||||
"IN: scratchpad"
|
"IN: scratchpad"
|
||||||
"TUPLE: person first-name last-name ;"
|
"TUPLE: person first-name last-name ;"
|
||||||
":: constructor-test ( -- tuple )"
|
":: constructor-test ( -- tuple )"
|
||||||
" \"Jane Smith\" \" \" split1 :> last :> first"
|
" \"Jane Smith\" \" \" split1 :> last :> first"
|
||||||
" T{ person { first-name first } { last-name last } } ;"
|
" T{ person { first-name first } { last-name last } } ;"
|
||||||
"constructor-test constructor-test eq? ."
|
"constructor-test constructor-test eq?"
|
||||||
"f"
|
"\n--- Data stack:\nf"
|
||||||
}
|
}
|
||||||
"One exception to the above rule is that array instances containing free lexical variables (that is, immutable lexical variables not referenced in a closure) do retain identity. This allows macros such as " { $link cond } " to expand at compile time even when their arguments reference variables." ;
|
"One exception to the above rule is that array instances containing free lexical variables (that is, immutable lexical variables not referenced in a closure) do retain identity. This allows macros such as " { $link cond } " to expand at compile time even when their arguments reference variables." ;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue