First class environments: Difference between revisions

Content added Content deleted
m (→‎{{header|Phix}}: added syntax colouring, made p2js compatible)
m (syntax highlighting fixup automation)
Line 29: Line 29:
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
Here the 'environment' consists of all the dynamic variables; the static integer variables (A%-Z%) are not affected.
Here the 'environment' consists of all the dynamic variables; the static integer variables (A%-Z%) are not affected.
<lang bbcbasic> DIM @environ$(12)
<syntaxhighlight lang="bbcbasic"> DIM @environ$(12)
@% = 4 : REM Column width
@% = 4 : REM Column width
Line 74: Line 74:
IF LEN(e$) < 216 e$ = STRING$(216, CHR$0)
IF LEN(e$) < 216 e$ = STRING$(216, CHR$0)
SYS "RtlMoveMemory", ^@%+108, !^e$, 216
SYS "RtlMoveMemory", ^@%+108, !^e$, 216
ENDPROC</lang>
ENDPROC</syntaxhighlight>
'''Output:'''
'''Output:'''
<pre>
<pre>
Line 102: Line 102:


=={{header|Bracmat}}==
=={{header|Bracmat}}==
<lang bracmat>( (environment=(cnt=0) (seq=))
<syntaxhighlight lang="bracmat">( (environment=(cnt=0) (seq=))
& :?environments
& :?environments
& 13:?seq
& 13:?seq
Line 135: Line 135:
)
)
& out$(After !environments)
& out$(After !environments)
)</lang>
)</syntaxhighlight>
Output:
Output:
<pre> Before
<pre> Before
Line 185: Line 185:
=={{header|C}}==
=={{header|C}}==
Well, this fits the semantics, not sure about the spirit…
Well, this fits the semantics, not sure about the spirit…
<lang C>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>


#define JOBS 12
#define JOBS 12
Line 220: Line 220:


return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 249: Line 249:


=={{header|Clojure}}==
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">
<lang Clojure>
(def hailstone-src
(def hailstone-src
"(defn hailstone-step [env]
"(defn hailstone-step [env]
Line 271: Line 271:
(print-step envs)
(print-step envs)
(recur f (map f envs)))))))
(recur f (map f envs)))))))
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 301: Line 301:
D doesn't have first class environments, this is an approximation.
D doesn't have first class environments, this is an approximation.
{{trans|Python}}
{{trans|Python}}
<lang d>import std.stdio, std.algorithm, std.range, std.array;
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.array;


struct Prop {
struct Prop {
Line 328: Line 328:


writefln("Counts:\n%(% 4d%)", envs.map!(env => env.cnt));
writefln("Counts:\n%(% 4d%)", envs.map!(env => env.cnt));
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre> 1 2 3 4 5 6 7 8 9 10 11 12
<pre> 1 2 3 4 5 6 7 8 9 10 11 12
Line 354: Line 354:
=={{header|EchoLisp}}==
=={{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.
'''(environment-new ((name value) ..) ''' is used to create a new envrionment. '''(eval form env)''' is used to evaluate a form in a specified environment.
<lang scheme>
<syntaxhighlight lang="scheme">
(define (bump-value)
(define (bump-value)
(when (> value 1)
(when (> value 1)
Line 373: Line 373:
(env-show 'value envs))
(env-show 'value envs))
(env-show 'count envs))
(env-show 'count envs))
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 409: Line 409:
</pre>
</pre>
There is a lot of code below to manage the tabular printout. Otherwise the task is simple.
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 ).
-module( first_class_environments ).


Line 469: Line 469:
end,
end,
print_loop().
print_loop().
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 492: Line 492:
=={{header|Factor}}==
=={{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.
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
<syntaxhighlight lang="factor">USING: assocs continuations formatting io kernel math
math.ranges sequences ;
math.ranges sequences ;


Line 512: Line 512:
[ dup done? ] [ step ] until nl
[ dup done? ] [ step ] until nl
"Counts:" print
"Counts:" print
[ [ drop "%4d " printf ] with-datastack drop ] each nl</lang>
[ [ drop "%4d " printf ] with-datastack drop ] each nl</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 541: Line 541:
=={{header|Go}}==
=={{header|Go}}==
{{trans|C}}
{{trans|C}}
<lang go>package main
<syntaxhighlight lang="go">package main


import "fmt"
import "fmt"
Line 599: Line 599:
}
}
fmt.Println()
fmt.Println()
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 630: Line 630:


First let's implement the algorithm of calculating Hailstone series:
First let's implement the algorithm of calculating Hailstone series:
<lang haskell>hailstone n
<syntaxhighlight lang="haskell">hailstone n
| n == 1 = 1
| n == 1 = 1
| even n = n `div` 2
| even n = n `div` 2
| odd n = 3*n + 1</lang>
| odd n = 3*n + 1</syntaxhighlight>


and a data structure representing the environment
and a data structure representing the environment


<lang haskell>data Environment = Environment { count :: Int, value :: Int }
<syntaxhighlight lang="haskell">data Environment = Environment { count :: Int, value :: Int }
deriving Eq</lang>
deriving Eq</syntaxhighlight>


In Haskell operations with first class environments could be implemented using several approaches:
In Haskell operations with first class environments could be implemented using several approaches:
Line 652: Line 652:
Let's define a collection of environments:
Let's define a collection of environments:


<lang haskell>environments = [ Environment 0 n | n <- [1..12] ]</lang>
<syntaxhighlight lang="haskell">environments = [ Environment 0 n | n <- [1..12] ]</syntaxhighlight>


and a <code>process</code>, which changes an environment according to a task.
and a <code>process</code>, which changes an environment according to a task.
Line 658: Line 658:
Approach 1.
Approach 1.


<lang haskell>process (Environment c 1) = Environment c 1
<syntaxhighlight lang="haskell">process (Environment c 1) = Environment c 1
process (Environment c n) = Environment (c+1) (hailstone n)</lang>
process (Environment c n) = Environment (c+1) (hailstone n)</syntaxhighlight>


Approach 3. (needs <code>import Control.Monad.State</code>)
Approach 3. (needs <code>import Control.Monad.State</code>)


<lang haskell>process = execState $ do
<syntaxhighlight lang="haskell">process = execState $ do
n <- gets value
n <- gets value
c <- gets count
c <- gets count
when (n > 1) $ modify $ \env -> env { count = c + 1 }
when (n > 1) $ modify $ \env -> env { count = c + 1 }
modify $ \env -> env { value = hailstone n }</lang>
modify $ \env -> env { value = hailstone n }</syntaxhighlight>


Repetitive batch processing of a collection we implement as following:
Repetitive batch processing of a collection we implement as following:


<lang haskell>fixedPoint f x
<syntaxhighlight lang="haskell">fixedPoint f x
| fx == x = [x]
| fx == x = [x]
| otherwise = x : fixedPoint f fx
| otherwise = x : fixedPoint f fx
Line 683: Line 683:
mapM_ (prettyPrint value) result
mapM_ (prettyPrint value) result
putStrLn (replicate 36 '-')
putStrLn (replicate 36 '-')
prettyPrint count (last result)</lang>
prettyPrint count (last result)</syntaxhighlight>


{{Out}}
{{Out}}
Line 711: Line 711:
Or in "transposed" way
Or in "transposed" way


<lang haskell>main = do
<syntaxhighlight lang="haskell">main = do
let result = map (fixedPoint process) environments
let result = map (fixedPoint process) environments
mapM_ (prettyPrint value) result
mapM_ (prettyPrint value) result
putStrLn (replicate 36 '-')
putStrLn (replicate 36 '-')
putStrLn "Counts: "
putStrLn "Counts: "
prettyPrint (count . last) result</lang>
prettyPrint (count . last) result</syntaxhighlight>


{{Out}}
{{Out}}
Line 737: Line 737:
=={{header|Icon}} and {{header|Unicon}}==
=={{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.
The simplest way to create an environment with variables isolated from code in Icon/Unicon is to create instances of records or class objects.
<lang Icon>link printf
<syntaxhighlight lang="icon">link printf


procedure main()
procedure main()
Line 760: Line 760:
else env.sequence := 3 * env.sequence + 1
else env.sequence := 3 * env.sequence + 1
}
}
end</lang>
end</syntaxhighlight>
{{libheader|Icon Programming Library}}
{{libheader|Icon Programming Library}}
[http://www.cs.arizona.edu/icon/library/src/procs/printf.icn printf.icn provides formatting]
[http://www.cs.arizona.edu/icon/library/src/procs/printf.icn printf.icn provides formatting]
Line 792: Line 792:


Here is my current interpretation of the task requirements:
Here is my current interpretation of the task requirements:
<lang j>coclass 'hailstone'
<syntaxhighlight lang="j">coclass 'hailstone'


step=:3 :0
step=:3 :0
Line 826: Line 826:
old=: state
old=: state
end.
end.
)</lang>
)</syntaxhighlight>
{{out|Example use}}
{{out|Example use}}
<lang j> environments=: conew&'hailstone'"0 (1+i.12)
<syntaxhighlight lang="j"> environments=: conew&'hailstone'"0 (1+i.12)
run_hailstone_ environments
run_hailstone_ environments
1 1 10 2 16 3 22 4 28 5 34 6
1 1 10 2 16 3 22 4 28 5 34 6
Line 849: Line 849:
1 1 1 1 1 1 1 1 2 1 1 1
1 1 1 1 1 1 1 1 2 1 1 1
1 1 1 1 1 1 1 1 1 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</lang>
0 1 7 2 5 8 16 3 19 6 14 9</syntaxhighlight>
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.
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.


Line 871: Line 871:


Let us therefore define a function named "code" accordingly:
Let us therefore define a function named "code" accordingly:
<lang jq>def code:
<syntaxhighlight lang="jq">def code:
# Given an integer as input, compute the corresponding hailstone value:
# Given an integer as input, compute the corresponding hailstone value:
def hail: if . % 2 == 0 then ./2|floor else 3*. + 1 end;
def hail: if . % 2 == 0 then ./2|floor else 3*. + 1 end;
if .value > 1 then (.value |= hail) | .count += 1 else . 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:
To generate the n-th environment, it is useful to define a function:
Line 900: Line 900:


Putting it all together:
Putting it all together:
<lang jq>filter_and_last( generate;
<syntaxhighlight lang="jq">filter_and_last( generate;
map(.value) | @tsv;
map(.value) | @tsv;
"", "Counts:", (map(.count) | @tsv ))</lang>
"", "Counts:", (map(.count) | @tsv ))</syntaxhighlight>




Line 939: Line 939:
=={{header|Julia}}==
=={{header|Julia}}==
{{trans|C}}
{{trans|C}}
<lang julia>const jobs = 12
<syntaxhighlight lang="julia">const jobs = 12


mutable struct Environment
mutable struct Environment
Line 994: Line 994:


runtest()
runtest()
</lang>{{output}}<pre>
</syntaxhighlight>{{output}}<pre>
1 2 3 4 5 6 7 8 9 10 11 12
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 10 2 16 3 22 4 28 5 34 6
Line 1,021: Line 1,021:
=={{header|Kotlin}}==
=={{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.
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.
<lang scala>// version 1.1.3
<syntaxhighlight lang="scala">// version 1.1.3


class Environment(var seq: Int, var count: Int)
class Environment(var seq: Int, var count: Int)
Line 1,076: Line 1,076:
fun main(args: Array<String>) {
fun main(args: Array<String>) {
code()
code()
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 1,111: Line 1,111:
* Lua 5.2: an upvalue called <code>_ENV</code>
* Lua 5.2: an upvalue called <code>_ENV</code>


<lang lua>
<syntaxhighlight lang="lua">
local envs = { }
local envs = { }
for i = 1, 12 do
for i = 1, 12 do
Line 1,145: Line 1,145:
io.write(("% 4d"):format(env.count))
io.write(("% 4d"):format(env.count))
end
end
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 1,174: Line 1,174:
=={{header|Nim}}==
=={{header|Nim}}==
{{trans|C}}
{{trans|C}}
<lang Nim>import strformat
<syntaxhighlight lang="nim">import strformat


const Jobs = 12
const Jobs = 12
Line 1,231: Line 1,231:
forAllJobs:
forAllJobs:
stdout.write fmt"{count[]: 4d}"
stdout.write fmt"{count[]: 4d}"
echo ""</lang>
echo ""</syntaxhighlight>


{{out}}
{{out}}
Line 1,259: Line 1,259:
=={{header|Order}}==
=={{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):
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):
<lang c>#include <order/interpreter.h>
<syntaxhighlight lang="c">#include <order/interpreter.h>
#define ORDER_PP_DEF_8hail ORDER_PP_FN( \
#define ORDER_PP_DEF_8hail ORDER_PP_FN( \
Line 1,302: Line 1,302:
8seq_iota(1, 13))),
8seq_iota(1, 13))),
8h_loop(8S))
8h_loop(8S))
)</lang>
)</syntaxhighlight>
{{out}}
{{out}}
<lang>(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)</lang>
<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)</syntaxhighlight>
The C preprocessor cannot output newlines, so the output is all on one line, but easily parsable.
The C preprocessor cannot output newlines, so the output is all on one line, but easily parsable.


Line 1,318: Line 1,318:
Next, repeatedly perform the task, until the required conditions are met, and print the counts.
Next, repeatedly perform the task, until the required conditions are met, and print the counts.


<lang perl>
<syntaxhighlight lang="perl">
use strict;
use strict;
use warnings;
use warnings;
Line 1,359: Line 1,359:
printf "%4s", ${$_->varglob('count')} for @enviornments;
printf "%4s", ${$_->varglob('count')} for @enviornments;
print "\n";
print "\n";
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,388: Line 1,388:
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>
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]]
See also [[Nested_function#Phix]]
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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>
<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>
Line 1,438: Line 1,438:
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
Emulation using edx as a dictionary_id (creating a separate dictionary for each environment):
Emulation using edx as a dictionary_id (creating a separate dictionary for each environment):
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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>
<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>
Line 1,503: Line 1,503:
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
(same for both)
(same for both)
Line 1,533: Line 1,533:
=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Runtime environments can be controlled with the '[http://software-lab.de/doc/refJ.html#job job]' function:
Runtime environments can be controlled with the '[http://software-lab.de/doc/refJ.html#job job]' function:
<lang PicoLisp>(let Envs
<syntaxhighlight lang="picolisp">(let Envs
(mapcar
(mapcar
'((N) (list (cons 'N N) (cons 'Cnt 0))) # Build environments
'((N) (list (cons 'N N) (cons 'Cnt 0))) # Build environments
Line 1,552: Line 1,552:
(job E
(job E
(prin (align 4 Cnt)) ) ) # print the step count
(prin (align 4 Cnt)) ) ) # print the step count
(prinl) )</lang>
(prinl) )</syntaxhighlight>
{{out}}
{{out}}
<pre> 1 2 3 4 5 6 7 8 9 10 11 12
<pre> 1 2 3 4 5 6 7 8 9 10 11 12
Line 1,578: Line 1,578:
=={{header|Python}}==
=={{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.
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.
<lang python>environments = [{'cnt':0, 'seq':i+1} for i in range(12)]
<syntaxhighlight lang="python">environments = [{'cnt':0, 'seq':i+1} for i in range(12)]


code = '''
code = '''
Line 1,595: Line 1,595:
for env in environments:
for env in environments:
print('% 4d' % env['cnt'], end='')
print('% 4d' % env['cnt'], end='')
print()</lang>
print()</syntaxhighlight>
{{out}}
{{out}}
<pre> 1 2 3 4 5 6 7 8 9 10 11 12
<pre> 1 2 3 4 5 6 7 8 9 10 11 12
Line 1,622: Line 1,622:
=={{header|R}}==
=={{header|R}}==


<lang R>code <- quote(
<syntaxhighlight lang="r">code <- quote(
if (n == 1) n else {
if (n == 1) n else {
count <- count + 1;
count <- count + 1;
Line 1,637: Line 1,637:


cat("\nCounts:\n")
cat("\nCounts:\n")
eprint(envs, "count")</lang>
eprint(envs, "count")</syntaxhighlight>


{{out}}
{{out}}
Line 1,665: Line 1,665:


=={{header|Racket}}==
=={{header|Racket}}==
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
#lang racket


Line 1,694: Line 1,694:
(displayln (make-string (* 4 12) #\=))
(displayln (make-string (* 4 12) #\=))
(show-nums (get-var-values 'count))
(show-nums (get-var-values 'count))
</syntaxhighlight>
</lang>


Output:
Output:
Line 1,727: Line 1,727:
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.
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.


<lang perl6>my $calculator = sub ($n is rw) {
<syntaxhighlight lang="raku" line>my $calculator = sub ($n is rw) {
return ($n == 1) ?? 1 !! $n %% 2 ?? $n div 2 !! $n * 3 + 1
return ($n == 1) ?? 1 !! $n %% 2 ?? $n div 2 !! $n * 3 + 1
};
};
Line 1,747: Line 1,747:
say 'Counts';
say 'Counts';


say [~] map { $_.<count>.fmt("%4s") }, @hailstones;</lang>
say [~] map { $_.<count>.fmt("%4s") }, @hailstones;</syntaxhighlight>


{{out}}
{{out}}
Line 1,782: Line 1,782:
The '''hailstone''' function (subroutine) could be coded in─line to further comply with the task's requirement that
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''.
<br>the solution have a &nbsp; ''single piece of code to be run repeatedly in each of these environments''.
<lang rexx>/*REXX pgm illustrates N 1st─class environments (using numbers from a hailstone seq).*/
<syntaxhighlight lang="rexx">/*REXX pgm illustrates N 1st─class environments (using numbers from a hailstone seq).*/
parse arg n . /*obtain optional argument from the CL.*/
parse arg n . /*obtain optional argument from the CL.*/
if n=='' | n=="," then n= 12 /*Was N defined? No, then use default.*/
if n=='' | n=="," then n= 12 /*Was N defined? No, then use default.*/
Line 1,815: Line 1,815:
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
hailstone: procedure expose @.; parse arg y; _= word(@.y, words(@.y) )
hailstone: procedure expose @.; parse arg y; _= word(@.y, words(@.y) )
if _==1 then return ''; @.0= 0; if _//2 then return _*3 + 1; return _%2</lang>
if _==1 then return ''; @.0= 0; if _//2 then return _*3 + 1; return _%2</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
{{out|output|text=&nbsp; when using the default input:}}


Line 1,971: Line 1,971:
{{trans|PicoLisp}}
{{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.
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.
<lang ruby># Build environments
<syntaxhighlight lang="ruby"># Build environments
envs = (1..12).map do |n|
envs = (1..12).map do |n|
Object.new.instance_eval {@n = n; @cnt = 0; self}
Object.new.instance_eval {@n = n; @cnt = 0; self}
Line 1,999: Line 1,999:
end
end
end
end
puts</lang>
puts</syntaxhighlight>
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.
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.
<lang ruby># Build environments
<syntaxhighlight lang="ruby"># Build environments
envs = (1..12).map do |n|
envs = (1..12).map do |n|
e = class Object
e = class Object
Line 2,036: Line 2,036:
eval('printf "%4s", cnt', e) # print the step count
eval('printf "%4s", cnt', e) # print the step count
end
end
puts</lang>
puts</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,064: Line 2,064:
=={{header|Sidef}}==
=={{header|Sidef}}==
{{trans|Raku}}
{{trans|Raku}}
<lang ruby>func calculator({.is_one} ) { 1 }
<syntaxhighlight lang="ruby">func calculator({.is_one} ) { 1 }
func calculator(n {.is_even}) { n / 2 }
func calculator(n {.is_even}) { n / 2 }
func calculator(n ) { 3*n + 1 }
func calculator(n ) { 3*n + 1 }
Line 2,088: Line 2,088:


say 'Counts';
say 'Counts';
say enviornments.map{ |h| "%4s" % h{:count} }.join;</lang>
say enviornments.map{ |h| "%4s" % h{:count} }.join;</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,116: Line 2,116:
=={{header|Tcl}}==
=={{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.
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.
<lang tcl>package require Tcl 8.5
<syntaxhighlight lang="tcl">package require Tcl 8.5


for {set i 1} {$i <= 12} {incr i} {
for {set i 1} {$i <= 12} {incr i} {
Line 2,146: Line 2,146:
}
}
}
}
puts ""</lang>
puts ""</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,180: Line 2,180:


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.
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.
<lang ecmascript>import "/fmt" for Fmt
<syntaxhighlight lang="ecmascript">import "/fmt" for Fmt


var environment = Fn.new {
var environment = Fn.new {
Line 2,221: Line 2,221:
System.print("Counts:")
System.print("Counts:")
for (env in envs) Fmt.write("$4d", env.count)
for (env in envs) Fmt.write("$4d", env.count)
System.print()</lang>
System.print()</syntaxhighlight>


{{out}}
{{out}}
Line 2,251: Line 2,251:
=={{header|zkl}}==
=={{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.
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.
<lang zkl>class Env{
<syntaxhighlight lang="zkl">class Env{
var n,cnt=0;
var n,cnt=0;
fcn init(_n){n=_n; returnClass(self.f)}
fcn init(_n){n=_n; returnClass(self.f)}
Line 2,261: Line 2,261:
n
n
}
}
}</lang>
}</syntaxhighlight>
<lang zkl>var es=(1).pump(12,List,Env);
<syntaxhighlight lang="zkl">var es=(1).pump(12,List,Env);
while(1){
while(1){
ns:=es.run(True);
ns:=es.run(True);
Line 2,269: Line 2,269:
}
}
println("Counts:");
println("Counts:");
es.pump(String,fcn(e){"%4d".fmt(e.container.cnt)}).println();</lang>
es.pump(String,fcn(e){"%4d".fmt(e.container.cnt)}).println();</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>