First class environments: Difference between revisions

Added FreeBASIC
m (→‎{{header|Phix}}: see also nested func)
(Added FreeBASIC)
 
(5 intermediate revisions by 5 users not shown)
Line 29:
{{works with|BBC BASIC for Windows}}
Here the 'environment' consists of all the dynamic variables; the static integer variables (A%-Z%) are not affected.
<langsyntaxhighlight lang="bbcbasic"> DIM @environ$(12)
@% = 4 : REM Column width
Line 74:
IF LEN(e$) < 216 e$ = STRING$(216, CHR$0)
SYS "RtlMoveMemory", ^@%+108, !^e$, 216
ENDPROC</langsyntaxhighlight>
'''Output:'''
<pre>
Line 102:
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat">( (environment=(cnt=0) (seq=))
& :?environments
& 13:?seq
Line 135:
)
& out$(After !environments)
)</langsyntaxhighlight>
Output:
<pre> Before
Line 185:
=={{header|C}}==
Well, this fits the semantics, not sure about the spirit…
<langsyntaxhighlight Clang="c">#include <stdio.h>
 
#define JOBS 12
Line 220:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 249:
 
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">
<lang Clojure>
(def hailstone-src
"(defn hailstone-step [env]
Line 271:
(print-step envs)
(recur f (map f envs)))))))
</syntaxhighlight>
</lang>
 
{{out}}
Line 301:
D doesn't have first class environments, this is an approximation.
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.array;
 
struct Prop {
Line 328:
 
writefln("Counts:\n%(% 4d%)", envs.map!(env => env.cnt));
}</langsyntaxhighlight>
{{out}}
<pre> 1 2 3 4 5 6 7 8 9 10 11 12
Line 354:
=={{header|EchoLisp}}==
'''(environment-new ((name value) ..) ''' is used to create a new envrionment. '''(eval form env)''' is used to evaluate a form in a specified environment.
<langsyntaxhighlight lang="scheme">
(define (bump-value)
(when (> value 1)
Line 373:
(env-show 'value envs))
(env-show 'count envs))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 409:
</pre>
There is a lot of code below to manage the tabular printout. Otherwise the task is simple.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( first_class_environments ).
 
Line 469:
end,
print_loop().
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 492:
=={{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.
<langsyntaxhighlight lang="factor">USING: assocs continuations formatting io kernel math
math.ranges sequences ;
 
Line 512:
[ dup done? ] [ step ] until nl
"Counts:" print
[ [ drop "%4d " printf ] with-datastack drop ] each nl</langsyntaxhighlight>
{{out}}
<pre>
Line 538:
0 1 7 2 5 8 16 3 19 6 14 9
</pre>
 
=={{header|FreeBASIC}}==
{{trans|Wren}}
<syntaxhighlight lang="vbnet">Type E
As Integer _valor, _contar
Public:
Declare Sub Constructor_(value As Integer, count As Integer)
Declare Function Valor() As Integer
Declare Function Contar() As Integer
Declare Sub Hailstone()
End Type
 
Sub E.Constructor_(value As Integer, count As Integer)
This._valor = value
This._contar = count
End Sub
 
Function E.Valor() As Integer
Return This._valor
End Function
 
Function E.Contar() As Integer
Return This._contar
End Function
 
Sub E.Hailstone()
Print Using "####"; This._valor;
If (This._valor = 1) Then Exit Sub
This._contar = This._contar + 1
This._valor = Iif(This._valor Mod 2 = 0, This._valor \ 2, 3 * This._valor + 1)
End Sub
 
 
Dim As Integer jobs = 12
Dim As E envs(jobs)
 
For i As Integer = 0 To jobs - 1
envs(i).Constructor_(i + 1, 0)
Next i
 
Print "Sequences:"
Dim As Integer done = 0
While done = 0
For i As Integer = 0 To jobs - 1
envs(i).Hailstone()
Next i
Print
done = 1
For i As Integer = 0 To jobs - 1
If envs(i).Valor() <> 1 Then
done = 0
Exit For
End If
Next i
Wend
 
Print "Counts:"
For i As Integer = 0 To jobs - 1
Print Using "####"; envs(i).Contar();
Next i
Print
 
Sleep</syntaxhighlight>
{{out}}
<pre>Same as Wren entry.</pre>
 
=={{header|Go}}==
{{trans|C}}
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 599 ⟶ 665:
}
fmt.Println()
}</langsyntaxhighlight>
 
{{out}}
Line 630 ⟶ 696:
 
First let's implement the algorithm of calculating Hailstone series:
<langsyntaxhighlight lang="haskell">hailstone n
| n == 1 = 1
| even n = n `div` 2
| odd n = 3*n + 1</langsyntaxhighlight>
 
and a data structure representing the environment
 
<langsyntaxhighlight lang="haskell">data Environment = Environment { count :: Int, value :: Int }
deriving Eq</langsyntaxhighlight>
 
In Haskell operations with first class environments could be implemented using several approaches:
Line 652 ⟶ 718:
Let's define a collection of environments:
 
<langsyntaxhighlight lang="haskell">environments = [ Environment 0 n | n <- [1..12] ]</langsyntaxhighlight>
 
and a <code>process</code>, which changes an environment according to a task.
Line 658 ⟶ 724:
Approach 1.
 
<langsyntaxhighlight lang="haskell">process (Environment c 1) = Environment c 1
process (Environment c n) = Environment (c+1) (hailstone n)</langsyntaxhighlight>
 
Approach 3. (needs <code>import Control.Monad.State</code>)
 
<langsyntaxhighlight lang="haskell">process = execState $ do
n <- gets value
c <- gets count
when (n > 1) $ modify $ \env -> env { count = c + 1 }
modify $ \env -> env { value = hailstone n }</langsyntaxhighlight>
 
Repetitive batch processing of a collection we implement as following:
 
<langsyntaxhighlight lang="haskell">fixedPoint f x
| fx == x = [x]
| otherwise = x : fixedPoint f fx
Line 683 ⟶ 749:
mapM_ (prettyPrint value) result
putStrLn (replicate 36 '-')
prettyPrint count (last result)</langsyntaxhighlight>
 
{{Out}}
Line 711 ⟶ 777:
Or in "transposed" way
 
<langsyntaxhighlight lang="haskell">main = do
let result = map (fixedPoint process) environments
mapM_ (prettyPrint value) result
putStrLn (replicate 36 '-')
putStrLn "Counts: "
prettyPrint (count . last) result</langsyntaxhighlight>
 
{{Out}}
Line 737 ⟶ 803:
=={{header|Icon}} and {{header|Unicon}}==
The simplest way to create an environment with variables isolated from code in Icon/Unicon is to create instances of records or class objects.
<langsyntaxhighlight Iconlang="icon">link printf
 
procedure main()
Line 760 ⟶ 826:
else env.sequence := 3 * env.sequence + 1
}
end</langsyntaxhighlight>
{{libheader|Icon Programming Library}}
[http://www.cs.arizona.edu/icon/library/src/procs/printf.icn printf.icn provides formatting]
Line 792 ⟶ 858:
 
Here is my current interpretation of the task requirements:
<langsyntaxhighlight lang="j">coclass 'hailstone'
 
step=:3 :0
Line 826 ⟶ 892:
old=: state
end.
)</langsyntaxhighlight>
{{out|Example use}}
<langsyntaxhighlight lang="j"> environments=: conew&'hailstone'"0 (1+i.12)
run_hailstone_ environments
1 1 10 2 16 3 22 4 28 5 34 6
Line 849 ⟶ 915:
1 1 1 1 1 1 1 1 2 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1
0 1 7 2 5 8 16 3 19 6 14 9</langsyntaxhighlight>
In essence: run is a static method of the class <code>hailstone</code> which, given a list of objects of the class runs all of them until their hailstone sequence number stops changing. It also displays the hailstone sequence number from each of the objects at each step. Its result is the step count from each object.
 
=={{header|Java}}==
<syntaxhighlight lang="java">
 
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
 
public final class FirstClassEnvironments {
 
public static void main(String[] aArgs) {
code();
}
private static void code() {
do {
for ( int job = 0; job < JOBS; job++ ) {
switchTo(job);
hailstone();
}
System.out.println();
} while ( ! allDone() );
 
System.out.println(System.lineSeparator() + "Counts:");
for ( int job = 0; job < JOBS; job++ ) {
switchTo(job);
System.out.print(String.format("%4d", count));
}
System.out.println();
}
private static boolean allDone() {
for ( int job = 0; job < JOBS; job++ ) {
switchTo(job);
if ( sequence > 1 ) {
return false;
}
}
return true;
}
private static void hailstone() {
System.out.print(String.format("%4d", sequence));
if ( sequence == 1 ) {
return;
}
count += 1;
sequence = ( sequence % 2 == 1 ) ? 3 * sequence + 1 : sequence / 2;
}
private static void switchTo(int aID) {
if ( aID != currentId ) {
environments.get(currentId).seq = sequence;
environments.get(currentId).count = count;
currentId = aID;
}
sequence = environments.get(aID).seq;
count = environments.get(aID).count;
}
private static class Environment {
public Environment(int aSeq, int aCount) {
seq = aSeq; count = aCount;
}
private int seq, count;
}
private static int sequence, count, currentId;
private static List<Environment> environments =
IntStream.rangeClosed(1, 12).mapToObj( i -> new Environment(i, 0 ) ).collect(Collectors.toList());
private static final int JOBS = 12;
 
}
</syntaxhighlight>
{{ 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>
 
=={{header|jq}}==
Line 871 ⟶ 1,042:
 
Let us therefore define a function named "code" accordingly:
<langsyntaxhighlight lang="jq">def code:
# Given an integer as input, compute the corresponding hailstone value:
def hail: if . % 2 == 0 then ./2|floor else 3*. + 1 end;
if .value > 1 then (.value |= hail) | .count += 1 else . end;
</syntaxhighlight>
</lang>
 
To generate the n-th environment, it is useful to define a function:
Line 900 ⟶ 1,071:
 
Putting it all together:
<langsyntaxhighlight lang="jq">filter_and_last( generate;
map(.value) | @tsv;
"", "Counts:", (map(.count) | @tsv ))</langsyntaxhighlight>
 
 
Line 939 ⟶ 1,110:
=={{header|Julia}}==
{{trans|C}}
<langsyntaxhighlight lang="julia">const jobs = 12
 
mutable struct Environment
Line 994 ⟶ 1,165:
 
runtest()
</langsyntaxhighlight>{{output}}<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
Line 1,021 ⟶ 1,192:
=={{header|Kotlin}}==
This is based on the C entry except that, instead of using object references (Kotlin/JVM doesn't support explicit pointers) to switch between environments, it saves and restores the actual values of the two variables on each job switch. I see no reason why objects shouldn't be used to represent the environments as long as they have no member functions.
<langsyntaxhighlight lang="scala">// version 1.1.3
 
class Environment(var seq: Int, var count: Int)
Line 1,076 ⟶ 1,247:
fun main(args: Array<String>) {
code()
}</langsyntaxhighlight>
 
{{out}}
Line 1,111 ⟶ 1,282:
* Lua 5.2: an upvalue called <code>_ENV</code>
 
<langsyntaxhighlight lang="lua">
local envs = { }
for i = 1, 12 do
Line 1,145 ⟶ 1,316:
io.write(("% 4d"):format(env.count))
end
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,174 ⟶ 1,345:
=={{header|Nim}}==
{{trans|C}}
<langsyntaxhighlight Nimlang="nim">import strformat
 
const Jobs = 12
Line 1,231 ⟶ 1,402:
forAllJobs:
stdout.write fmt"{count[]: 4d}"
echo ""</langsyntaxhighlight>
 
{{out}}
Line 1,259 ⟶ 1,430:
=={{header|Order}}==
Order supports environments as a first-class type, but since all values are immutable, updating a value means using one environment to update the next in a chain (nothing unusual for languages with immutable data structures):
<langsyntaxhighlight lang="c">#include <order/interpreter.h>
#define ORDER_PP_DEF_8hail ORDER_PP_FN( \
Line 1,302 ⟶ 1,473:
8seq_iota(1, 13))),
8h_loop(8S))
)</langsyntaxhighlight>
{{out}}
<syntaxhighlight lang="text">(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)</langsyntaxhighlight>
The C preprocessor cannot output newlines, so the output is all on one line, but easily parsable.
 
Line 1,318 ⟶ 1,489:
Next, repeatedly perform the task, until the required conditions are met, and print the counts.
 
<langsyntaxhighlight lang="perl">
use strict;
use warnings;
Line 1,359 ⟶ 1,530:
printf "%4s", ${$_->varglob('count')} for @enviornments;
print "\n";
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,388 ⟶ 1,559:
Emulation using edx as an "enviroment index" into static sequences. (You could of course nest the three sequences inside a single "environments" sequence, if you prefer.)<br>
See also [[Nested_function#Phix]]
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function hail(integer n)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
if remainder(n,2)=0 then
<span style="color: #008080;">function</span> <span style="color: #000000;">hail</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
n /= 2
<span style="color: #008080;">if</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
else
<span style="color: #000000;">n</span> <span style="color: #0000FF;">/=</span> <span style="color: #000000;">2</span>
n = 3*n+1
<span style="color: #008080;">else</span>
end if
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">*</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
return n
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">n</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence hails = tagset(12),
counts = repeat(0,12),
<span style="color: #004080;">sequence</span> <span style="color: #000000;">hails</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">12</span><span style="color: #0000FF;">),</span>
results = columnize({hails})
<span style="color: #000000;">counts</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">),</span>
 
<span style="color: #000000;">results</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({</span><span style="color: #000000;">hails</span><span style="color: #0000FF;">})</span>
function step(integer edx)
integer n = hails[edx]
<span style="color: #008080;">function</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">edx</span><span style="color: #0000FF;">)</span>
if n=1 then return 0 end if
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">hails</span><span style="color: #0000FF;">[</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">]</span>
n = hail(n)
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
hails[edx] = n
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">hail</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
counts[edx] += 1
<span style="color: #000000;">hails</span><span style="color: #0000FF;">[</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
results[edx] &= n
<span style="color: #000000;">counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
return 1
<span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">n</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">1</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
procedure main()
bool done = false
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
while not done do
<span style="color: #004080;">bool</span> <span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
done = true
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #000000;">done</span> <span style="color: #008080;">do</span>
for i=1 to 12 do
<span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
if step(i) then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
done = false
<span style="color: #008080;">if</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
for i=1 to max(counts)+1 do
for j=1 to 12 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">counts</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
puts(1,iff(i<=length(results[j])?sprintf("%4d",{results[j][i]}):" "))
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
end for
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])?</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%4d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]}):</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">))</span>
puts(1,"\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
printf(1," %s\n",{join(repeat("===",12))})
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for j=1 to 12 do
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"==="</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">))})</span>
printf(1,"%4d",{counts[j]})
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
end for
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%4d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]})</span>
puts(1,"\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end procedure
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
main()</lang>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
Emulation using edx as a dictionary_id (creating a separate dictionary for each environment):
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function hail(integer n)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
if remainder(n,2)=0 then
<span style="color: #008080;">function</span> <span style="color: #000000;">hail</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
n /= 2
<span style="color: #008080;">if</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
else
<span style="color: #000000;">n</span> <span style="color: #0000FF;">/=</span> <span style="color: #000000;">2</span>
n = 3*n+1
<span style="color: #008080;">else</span>
end if
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">*</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
return n
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">n</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function step(integer edx)
integer n = getd("hail",edx)
<span style="color: #008080;">function</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">edx</span><span style="color: #0000FF;">)</span>
if n=1 then return 0 end if
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"hail"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">)</span>
n = hail(n)
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
setd("hail",n,edx)
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">hail</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
setd("count",getd("count",edx)+1,edx)
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"hail"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">)</span>
setd("results",getd("results",edx)&n,edx)
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"count"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"count"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">)</span>
return 1
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"results"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"results"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">))&</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">edx</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">1</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence dicts = {}
 
<span style="color: #004080;">sequence</span> <span style="color: #000000;">dicts</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
procedure main()
for i=1 to 12 do
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
integer d = new_dict()
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
setd("hail",i,d)
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">()</span>
setd("count",0,d)
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"hail"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
setd("results",{i},d)
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"count"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
dicts &= d
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"results"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">},</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #000000;">dicts</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">d</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
bool done = false
while not done do
<span style="color: #004080;">bool</span> <span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
done = true
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #000000;">done</span> <span style="color: #008080;">do</span>
for i=1 to 12 do
<span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
if step(dicts[i]) then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
done = false
<span style="color: #008080;">if</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dicts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
done = false
integer i = 1
<span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
while not done do
<span style="color: #004080;">integer</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
done = true
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #000000;">done</span> <span style="color: #008080;">do</span>
for j=1 to 12 do
<span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
sequence res = getd("results",dicts[j])
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
if i<length(res) then done = false end if
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"results"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dicts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
puts(1,iff(i<=length(res)?sprintf("%4d",{res[i]}):" "))
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)?</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%4d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]}):</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">))</span>
puts(1,"\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
i += 1
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
printf(1," %s\n",{join(repeat("===",12))})
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
for j=1 to 12 do
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"==="</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">))})</span>
integer count = getd("count",dicts[j])
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
printf(1,"%4d",{count})
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"count"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dicts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
end for
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%4d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">count</span><span style="color: #0000FF;">})</span>
puts(1,"\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end procedure
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
main()</lang>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
(same for both)
Line 1,527 ⟶ 1,704:
=={{header|PicoLisp}}==
Runtime environments can be controlled with the '[http://software-lab.de/doc/refJ.html#job job]' function:
<langsyntaxhighlight PicoLisplang="picolisp">(let Envs
(mapcar
'((N) (list (cons 'N N) (cons 'Cnt 0))) # Build environments
Line 1,546 ⟶ 1,723:
(job E
(prin (align 4 Cnt)) ) ) # print the step count
(prinl) )</langsyntaxhighlight>
{{out}}
<pre> 1 2 3 4 5 6 7 8 9 10 11 12
Line 1,572 ⟶ 1,749:
=={{header|Python}}==
In Python, name bindings are held in dicts, one for global scope and another for local scope. When [http://docs.python.org/release/3.1.3/library/functions.html#exec exec]'ing code, you are allowed to give your own dictionaries for these scopes. In this example, two names are held in dictionaries that are used as the local scope for the evaluation of source.
<langsyntaxhighlight lang="python">environments = [{'cnt':0, 'seq':i+1} for i in range(12)]
 
code = '''
Line 1,589 ⟶ 1,766:
for env in environments:
print('% 4d' % env['cnt'], end='')
print()</langsyntaxhighlight>
{{out}}
<pre> 1 2 3 4 5 6 7 8 9 10 11 12
Line 1,616 ⟶ 1,793:
=={{header|R}}==
 
<langsyntaxhighlight Rlang="r">code <- quote(
if (n == 1) n else {
count <- count + 1;
Line 1,631 ⟶ 1,808:
 
cat("\nCounts:\n")
eprint(envs, "count")</langsyntaxhighlight>
 
{{out}}
Line 1,659 ⟶ 1,836:
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
 
Line 1,688 ⟶ 1,865:
(displayln (make-string (* 4 12) #\=))
(show-nums (get-var-values 'count))
</syntaxhighlight>
</lang>
 
Output:
Line 1,718 ⟶ 1,895:
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2015-12-17}}
Fairly straightforward. Set up an array of hashes containing the current values and iteration counts then pass each hash in turn with a code reference to a routine to calculate the next iteration.
 
Set up an array of hashes containing the current values and iteration counts then pass each hash in turn with a code reference to a routine to calculate the next iteration.
<lang perl6>my $calculator = sub ($n is rw) {
 
return ($n == 1) ?? 1 !! $n %% 2 ?? $n div 2 !! $n * 3 + 1
<syntaxhighlight lang="raku" line>my $calculator = sub ($n is rw) {
};
$n == 1 ?? 1 !! $n %% 2 ?? $n div 2 !! $n * 3 + 1
}
 
sub next (%this, &get_next) {
return %this if %this.<value> == 1;
%this.<value> .= &get_next;
%this.<count>++;
return %this;
};
 
my @hailstones = map { %(value => $_, count => 0) }, 1 .. 12;
 
while not all( map { $_.<value> }, @hailstones ) == 1 {
say [~] map { $_.<value>.fmt(": '%4s")' }, @hailstones;
@hailstones[$_] .= &next($calculator) for ^@hailstones;
}
 
say "\nCounts\n" ~ [~] map { $_.<count>.fmt: '%4s' }, @hailstones;</syntaxhighlight>
say 'Counts';
 
say [~] map { $_.<count>.fmt("%4s") }, @hailstones;</lang>
 
{{out}}
Line 1,764 ⟶ 1,939:
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>
 
=={{header|REXX}}==
The formatting is sensitive to a terminating Collatz sequence and is shown as blanks &nbsp; (that is,
Line 1,776 ⟶ 1,949:
The '''hailstone''' function (subroutine) could be coded in─line to further comply with the task's requirement that
<br>the solution have a &nbsp; ''single piece of code to be run repeatedly in each of these environments''.
<langsyntaxhighlight lang="rexx">/*REXX pgm illustrates N 1st─class environments (using numbers from a hailstone seq).*/
parse arg n . /*obtain optional argument from the CL.*/
if n=='' | n=="," then n= 12 /*Was N defined? No, then use default.*/
Line 1,809 ⟶ 1,982:
/*──────────────────────────────────────────────────────────────────────────────────────*/
hailstone: procedure expose @.; parse arg y; _= word(@.y, words(@.y) )
if _==1 then return ''; @.0= 0; if _//2 then return _*3 + 1; return _%2</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
 
Line 1,965 ⟶ 2,138:
{{trans|PicoLisp}}
The ''object'' is an environment for instance variables. These variables use the <code>@</code> sigil. We create 12 objects, and put <code>@n</code> and <code>@cnt</code> inside these objects. We use <code>Object#instance_eval</code> to switch the current object and bring those instance variables into scope.
<langsyntaxhighlight lang="ruby"># Build environments
envs = (1..12).map do |n|
Object.new.instance_eval {@n = n; @cnt = 0; self}
Line 1,993 ⟶ 2,166:
end
end
puts</langsyntaxhighlight>
Ruby also provides the ''binding'', an environment for local variables. The problem is that local variables have lexical scope. Ruby needs the lexical scope to parse Ruby code. So, the only way to use a binding is to evaluate a string of Ruby code. We use <code>Kernel#binding</code> to create the bindings, and <code>Kernel#eval</code> to evaluate strings in these bindings. The lines between <code><<-'eos'</code> and <code>eos</code> are multi-line string literals.
<langsyntaxhighlight lang="ruby"># Build environments
envs = (1..12).map do |n|
e = class Object
Line 2,030 ⟶ 2,203:
eval('printf "%4s", cnt', e) # print the step count
end
puts</langsyntaxhighlight>
{{out}}
<pre>
Line 2,058 ⟶ 2,231:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">func calculator({.is_one} ) { 1 }
func calculator(n {.is_even}) { n / 2 }
func calculator(n ) { 3*n + 1 }
Line 2,082 ⟶ 2,255:
 
say 'Counts';
say enviornments.map{ |h| "%4s" % h{:count} }.join;</langsyntaxhighlight>
{{out}}
<pre>
Line 2,110 ⟶ 2,283:
=={{header|Tcl}}==
The simplest way to make a first-class environment in Tcl is to use a dictionary; the <code>dict with</code> command (and <code>dict update</code>; not shown here) will expand a dictionary and bind it to variables for the duration of its body script.
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
for {set i 1} {$i <= 12} {incr i} {
Line 2,140 ⟶ 2,313:
}
}
puts ""</langsyntaxhighlight>
{{out}}
<pre>
Line 2,174 ⟶ 2,347:
 
So that's what we use here. However, to create a dynamic class you have to wrap it in a function which then returns a reference to the class object.
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var environment = Fn.new {
Line 2,215 ⟶ 2,388:
System.print("Counts:")
for (env in envs) Fmt.write("$4d", env.count)
System.print()</langsyntaxhighlight>
 
{{out}}
Line 2,245 ⟶ 2,418:
=={{header|zkl}}==
In zkl, classes wrap state. All instances of a class share code but each instance binds code to itself. In this task, class creation, instead of returning a new class instance, it returns a bound function. Calling this function calculates the next hailstone in the environment the function is bound to. To get the counts from the class/environment, we ask the function for its container and then pull the count.
<langsyntaxhighlight lang="zkl">class Env{
var n,cnt=0;
fcn init(_n){n=_n; returnClass(self.f)}
Line 2,255 ⟶ 2,428:
n
}
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">var es=(1).pump(12,List,Env);
while(1){
ns:=es.run(True);
Line 2,263 ⟶ 2,436:
}
println("Counts:");
es.pump(String,fcn(e){"%4d".fmt(e.container.cnt)}).println();</langsyntaxhighlight>
{{out}}
<pre>
2,122

edits