First class environments: Difference between revisions

Content added Content deleted
(Add Factor)
Line 428: Line 428:
{Environment, Step count}
{Environment, Step count}
[{12,9}, {11,14}, {10,6}, {9,19}, {8,3}, {7,16}, {6,8}, {5,5}, {4,2}, {3,7}, {2,1}, {1,0}]
[{12,9}, {11,14}, {10,6}, {9,19}, {8,3}, {7,16}, {6,8}, {5,5}, {4,2}, {3,7}, {2,1}, {1,0}]
</pre>

=={{header|Factor}}==
Factor is a stack language without the need for variable bindings. Values are variables through and through. This simplifies matters somewhat. It means we can use data stacks (sequences) for our first class environments. The <code>with-datastack</code> combinator takes a data stack (sequence) and quotation as input, and inside the quotation, it is as though one is operating on a new data stack populated with values from the sequence. The resultant data stack is then once again stored as a sequence for safe keeping.
<lang factor>USING: assocs continuations formatting io kernel math
math.ranges sequences ;

: (next-hailstone) ( count value -- count' value' )
[ 1 + ] [ dup even? [ 2/ ] [ 3 * 1 + ] if ] bi* ;

: next-hailstone ( count value -- count' value' )
dup 1 = [ (next-hailstone) ] unless ;

: make-environments ( -- seq ) 12 [ 0 ] replicate 12 [1,b] zip ;

: step ( seq -- new-seq )
[ [ dup "%4d " printf next-hailstone ] with-datastack ] map
nl ;

: done? ( seq -- ? ) [ second 1 = ] all? ;

make-environments
[ dup done? ] [ step ] until nl
"Counts:" print
[ [ drop "%4d " printf ] with-datastack drop ] each nl</lang>
{{out}}
<pre>
1 2 3 4 5 6 7 8 9 10 11 12
1 1 10 2 16 3 22 4 28 5 34 6
1 1 5 1 8 10 11 2 14 16 17 3
1 1 16 1 4 5 34 1 7 8 52 10
1 1 8 1 2 16 17 1 22 4 26 5
1 1 4 1 1 8 52 1 11 2 13 16
1 1 2 1 1 4 26 1 34 1 40 8
1 1 1 1 1 2 13 1 17 1 20 4
1 1 1 1 1 1 40 1 52 1 10 2
1 1 1 1 1 1 20 1 26 1 5 1
1 1 1 1 1 1 10 1 13 1 16 1
1 1 1 1 1 1 5 1 40 1 8 1
1 1 1 1 1 1 16 1 20 1 4 1
1 1 1 1 1 1 8 1 10 1 2 1
1 1 1 1 1 1 4 1 5 1 1 1
1 1 1 1 1 1 2 1 16 1 1 1
1 1 1 1 1 1 1 1 8 1 1 1
1 1 1 1 1 1 1 1 4 1 1 1
1 1 1 1 1 1 1 1 2 1 1 1

Counts:
0 1 7 2 5 8 16 3 19 6 14 9
</pre>
</pre>