Repeat: Difference between revisions
(Repeat en Verilog) |
(Added uBasic/4tH version) |
||
Line 1,955: | Line 1,955: | ||
It should be noted that the “command” can be an arbitrary script, not just a call to a procedure: |
It should be noted that the “command” can be an arbitrary script, not just a call to a procedure: |
||
<lang tcl>repeat {puts "hello world"} 3</lang> |
<lang tcl>repeat {puts "hello world"} 3</lang> |
||
=={{header|uBasic/4tH}}== |
|||
<lang>Proc _Repeat (_HelloWorld, 5) : End |
|||
_Repeat Param (2) : Local (1) : For c@ = 1 To b@ : Proc a@ : Next : Return |
|||
_HelloWorld Print "Hello world!" : Return</lang> |
|||
Output: |
|||
<pre> |
|||
Hello world! |
|||
Hello world! |
|||
Hello world! |
|||
Hello world! |
|||
Hello world! |
|||
0 OK, 0:35 |
|||
</pre> |
|||
=={{header|Ursa}}== |
=={{header|Ursa}}== |
Revision as of 13:14, 15 March 2022
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Write a procedure which accepts as arguments another procedure and a positive integer.
The latter procedure is executed a number of times equal to the accepted integer.
11l
<lang 11l>F repeat(f, n)
L 1..n f()
F procedure()
print(‘Example’)
repeat(procedure, 3)</lang>
- Output:
Example Example Example
6502 Assembly
This routine is a bit messy, and assumes the called routine doesn't clobber the zero-page memory used to maintain it. This can be modified to push/pop those values before/after the routine is executed.
<lang 6502asm>macro RepeatProc,addr,count ;VASM macro syntax
- input
- addr = the label of the routine you wish to call repeatedly
- count = how many times you want to DO the procedure. 1 = once, 2 = twice, 3 = three times, etc. Enter "0" for 256 times.
lda #<\addr sta z_L ;a label for a zero-page memory address lda #>\addr sta z_H ;a label for the zero-page memory address immediately after z_L lda \count jsr doRepeatProc endm
doRepeatProc: sta z_C ;another zero-page memory location loop_RepeatProc: jsr Trampoline_RepeatProc dec z_C lda z_C bne loop_RepeatProc rts
Trampoline_RepeatProc: db $6c,z_L,$00
- when executed, becomes an indirect JMP to the address stored at z_L and z_H. Some assemblers will let you type
- JMP (z_L) and it will automatically replace it with the above during the assembly process.
- This causes an indirect JMP to the routine. Its RTS will return execution to just after the "JSR Trampoline_RepeatProc"
- and flow into the loop overhead.</lang>
Once the macro and the underlying subroutine are created, this is very simple to use: <lang 6502asm>RepeatProc foo,#20 ;perform the subroutine "foo" twenty times.</lang>
Action!
<lang Action!>DEFINE PTR="CARD"
PROC OutputText(CHAR ARRAY s)
PrintE(s)
RETURN
PROC Procedure=*(CHAR ARRAY s)
DEFINE JSR="$20" DEFINE RTS="$60" [JSR $00 $00 ;JSR to address set by SetProcedure RTS]
PROC SetProcedure(PTR p)
PTR addr
addr=Procedure+1 ;location of address of JSR PokeC(addr,p)
RETURN
PROC Repeat(PTR procFun CHAR ARRAY s BYTE n)
BYTE i
SetProcedure(procFun) FOR i=1 TO n DO Procedure(s) OD
RETURN
PROC Main()
Repeat(OutputText,"Action!",5)
RETURN</lang>
- Output:
Screenshot from Atari 8-bit computer
Action! Action! Action! Action! Action!
Ada
<lang Ada>with Ada.Text_IO;
procedure Repeat_Example is
procedure Repeat(P: access Procedure; Reps: Natural) is begin for I in 1 .. Reps loop
P.all; -- P points to a procedure, and P.all actually calls that procedure
end loop; end Repeat; procedure Hello is begin Ada.Text_IO.Put("Hello! "); end Hello;
begin
Repeat(Hello'Access, 3); -- Hello'Access points to the procedure Hello
end Repeat_Example;</lang>
Output:
Hello! Hello! Hello!
ALGOL 68
<lang algol68>
- operator that executes a procedure the specified number of times #
OP REPEAT = ( INT count, PROC VOID routine )VOID:
TO count DO routine OD;
- make REPEAT a low priority operater #
PRIO REPEAT = 1;
- can also create variant that passes the iteration count as a parameter #
OP REPEAT = ( INT count, PROC( INT )VOID routine )VOID:
FOR iteration TO count DO routine( iteration ) OD;
main: (
# PROC to test the REPEAT operator with # PROC say something = VOID: print( ( "something", newline ) );
3 REPEAT say something;
# PROC to test the variant # PROC show squares = ( INT n )VOID: print( ( n, n * n, newline ) );
3 REPEAT show squares
) </lang> Output:
something something something +1 +1 +2 +4 +3 +9
ALGOL W
As well as the names of procedures, Algol W allows statements to be passed as parameters where a procedure is expected. <lang algolw>begin
% executes the procedure routine the specified number of times % procedure repeat ( integer value count; procedure routine ) ; for i := 1 until count do routine; begin integer x; % print "hello" three times % repeat( 3, write( "hello" ) ); % print the first 10 squares % write(); x := 1; repeat( 10 , begin writeon( i_w := s_w := 1, x * x ); x := x + 1 end ) end
end.</lang>
- Output:
hello hello hello 1 4 9 16 25 36 49 64 81 100
AppleScript
<lang applescript>-- applyN :: Int -> (a -> a) -> a -> a on applyN(n, f, x)
script go on |λ|(a, g) |λ|(a) of mReturn(g) end |λ| end script foldl(go, x, replicate(n, f))
end applyN
SAMPLE FUNCTIONS FOR REPEATED APPLICATION --------
on double(x)
2 * x
end double
on plusArrow(s)
s & " -> "
end plusArrow
on squareRoot(n)
n ^ 0.5
end squareRoot
TESTS --------------------------
on run
log applyN(10, double, 1) --> 1024 log applyN(5, plusArrow, "") --> " -> -> -> -> -> " log applyN(3, squareRoot, 65536) --> 4.0
end run
GENERIC FUNCTIONS --------------------
-- foldl :: (a -> b -> a) -> a -> [b] -> a on foldl(f, startValue, xs)
tell mReturn(f) set v to startValue set lng to length of xs repeat with i from 1 to lng set v to |λ|(v, item i of xs, i, xs) end repeat return v end tell
end foldl
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
-- 2nd class handler function lifted into 1st class script wrapper. if script is class of f then f else script property |λ| : f end script end if
end mReturn
-- Egyptian multiplication - progressively doubling a list, appending -- stages of doubling to an accumulator where needed for binary -- assembly of a target length -- replicate :: Int -> a -> [a] on replicate(n, a)
set out to {} if 1 > n then return out set dbl to {a} repeat while (1 < n) if 0 < (n mod 2) then set out to out & dbl set n to (n div 2) set dbl to (dbl & dbl) end repeat return out & dbl
end replicate</lang>
- Output:
(*1024*) (* -> -> -> -> -> *) (*4.0*)
Applesoft BASIC
http://hoop-la.ca/apple2/2016/winterwarmup/#repeat.bas
Arturo
<lang rebol>print "---------------------------" print "As a loop" print "---------------------------" loop 4 'x ->
print "Example 1"
repeatFunc: function [f,times][
loop times 'x -> do f
]
print "---------------------------" print "With a block param" print "---------------------------" repeatFunc [print "Example 2"] 4
repeatFunc: function [f,times][
loop times 'x -> f
]
print "---------------------------" print "With a function param" print "---------------------------" repeatFunc $[][print "Example 3"] 4</lang>
- Output:
--------------------------- As a loop --------------------------- Example 1 Example 1 Example 1 Example 1 --------------------------- With a block param --------------------------- Example 2 Example 2 Example 2 Example 2 --------------------------- With a function param --------------------------- Example 3 Example 3 Example 3 Example 3
AutoHotkey
<lang AutoHotkey>repeat("fMsgBox",3) return
repeat(f, n){ loop % n %f%() }
fMsgBox(){ MsgBox hello }</lang>
AWK
<lang AWK>
- syntax: GAWK -f REPEAT.AWK
BEGIN {
for (i=0; i<=3; i++) { f = (i % 2 == 0) ? "even" : "odd" @f(i) # indirect function call } exit(0)
} function even(n, i) {
for (i=1; i<=n; i++) { printf("inside even %d\n",n) }
} function odd(n, i) {
for (i=1; i<=n; i++) { printf("inside odd %d\n",n) }
} </lang>
output:
inside odd 1 inside even 2 inside even 2 inside odd 3 inside odd 3 inside odd 3
Batch File
<lang dos> @echo off
- _main
setlocal call:_func1 _func2 3 pause>nul exit/b
- _func1
setlocal enabledelayedexpansion for /l %%i in (1,1,%2) do call:%1 exit /b
- _func2
setlocal echo _func2 has been executed exit /b </lang>
BQN
BQN has a builtin called Repeat which fulfills the criteria for the challenge(and allows multiple iteration counts), hence there is a recursive implementation of repeat added in as well.
<lang bqn>•Show {2+𝕩}⍟3 1
_repeat_ ← {(𝕘>0)◶⊢‿(𝔽_𝕣_(𝕘-1)𝔽)𝕩}
•Show {2+𝕩} _repeat_ 3 1</lang><lang>7 7</lang>
C
<lang c>#include <stdio.h>
void repeat(void (*f)(void), unsigned int n) {
while (n-->0) (*f)(); //or just f()
}
void example() {
printf("Example\n");
}
int main(int argc, char *argv[]) {
repeat(example, 4); return 0;
} </lang>
C#
<lang csharp>using System;
namespace Repeat {
class Program { static void Repeat(int count, Action<int> fn) { if (null == fn) { throw new ArgumentNullException("fn"); } for (int i = 0; i < count; i++) { fn.Invoke(i + 1); } }
static void Main(string[] args) { Repeat(3, x => Console.WriteLine("Example {0}", x)); } }
}</lang>
- Output:
Example 1 Example 2 Example 3
C++
<lang cpp>template <typename Function> void repeat(Function f, unsigned int n) {
for(unsigned int i=n; 0<i; i--) f();
}</lang> usage: <lang cpp>#include <iostream> void example() {
std::cout << "Example\n";
}
repeat(example, 4);</lang>
<lang cpp> repeat([]{std::cout << "Example\n";}, 4);</lang>
Clojure
<lang clojure>(defn repeat-function [f n]
(dotimes [i n] (f)))</lang>
- Output:
user=> (repeat-function #(println "bork") 3) bork bork bork
Common Lisp
<lang lisp>(defun repeat (f n)
(dotimes (i n) (funcall f)))
(repeat (lambda () (format T "Example~%")) 5)</lang>
Cowgol
<lang cowgol>include "cowgol.coh";
- Only functions that implement an interface can be passed around
- The interface is a type and must be defined before it is used
- This defines an interface for a function that takes no arguments
interface Fn();
- This function repeats a function that implements Fn
sub Repeat(f: Fn, n: uint32) is
while n != 0 loop f(); n := n - 1; end loop;
end sub;
- Here is a function
sub Foo implements Fn is
print("foo ");
end sub;
- Prints "foo foo foo foo"
Repeat(Foo, 4); print_nl(); </lang>
D
<lang d>void repeat(void function() fun, in uint times) {
foreach (immutable _; 0 .. times) fun();
}
void procedure() {
import std.stdio; "Example".writeln;
}
void main() {
repeat(&procedure, 3);
}</lang>
- Output:
Example Example Example
Delphi
<lang Delphi> program Repeater;
{$APPTYPE CONSOLE} {$R *.res}
type
TSimpleProc = procedure; // Can also define types for procedures (& functions) which // require params.
procedure Once; begin
writeln('Hello World');
end;
procedure Iterate(proc : TSimpleProc; Iterations : integer); var
i : integer;
begin
for i := 1 to Iterations do proc;
end;
begin
Iterate(Once, 3); readln;
end.
</lang>
Alternative
<lang Delphi> program Repeater;
{$APPTYPE CONSOLE} {$R *.res}
uses
System.SysUtils;
procedure Iterate(proc: TProc; Iterations: integer); var
i: integer;
begin
for i := 1 to Iterations do proc;
end;
begin
Iterate( procedure begin writeln('Hello World'); end, 3); readln;
end. </lang>
- Output:
Hello World Hello World Hello World
EchoLisp
<lang lisp> (define (repeat f n) (for ((i n)) (f)))
(repeat (lambda () (write (random 1000))) 5)
→ 287 798 930 989 794
- Remark
- It is also possible to iterate a function
- f(f(f(f( ..(f x)))))
(define cos10 (iterate cos 10) (define cos100 (iterate cos10 10)) (cos100 0.6)
→ 0.7390851332151605
(cos 0.7390851332151605)
→ 0.7390851332151608 ;; fixed point found
</lang>
F#
<lang fsharp>open System
let Repeat c f =
for _ in 1 .. c do f()
let Hello _ =
printfn "Hello world"
[<EntryPoint>] let main _ =
Repeat 3 Hello
0 // return an integer exit code</lang>
Factor
Factor comes with the times word which does exactly this. For example, <lang factor>3 [ "Hello!" print ] times</lang>
- Output:
Hello! Hello! Hello!
The implementation of times: <lang factor>: times ( ... n quot: ( ... -- ... ) -- ... )
[ drop ] prepose each-integer ; inline</lang>
Forth
<lang forth>: times ( xt n -- )
0 ?do dup execute loop drop ;</lang>
Or, taking care to keep the data stack clean for the XT's use, as is often desired:
<lang forth>: times { xt n -- }
n 0 ?do xt execute loop ;</lang>
Or as a novel control structure, which is not demanded by this task but which is just as idiomatic in Forth as the XT-consuming alternatives above:
<lang forth>: times[ ]] 0 ?do [[ ; immediate compile-only
- ]times postpone loop ; immediate compile-only</lang>
Usage:
<lang forth>[: cr ." Hello" ;] 3 times
- 3-byes ( -- ) 3 times[ cr ." Bye" ]times ;
3-byes</lang>
- Output:
HelloHello Hello Bye Bye
Bye
FreeBASIC
<lang freebasic>' FB 1.05.0 Win64
Sub proc()
Print " proc called"
End Sub
Sub repeat(s As Sub, n As UInteger)
For i As Integer = 1 To n Print Using "##"; i; s() Next
End Sub
repeat(@proc, 5) Print Print "Press any key to quit" Sleep</lang>
- Output:
1 proc called 2 proc called 3 proc called 4 proc called 5 proc called
Gambas
Note: Gambas (3.14.0) cannot perform this task as specified, as it does not have delegates, and pointers do not seem to work with procedures. What does work is using Object.Call, which is intended for executing procedures from external libraries. However the accepting procedure must refer to the object containing the procedure, and refer to the procedure by a String name. In this case, the current module/class reference (Me) is used, but the String name must be passed. This arrangement will only work within the same module/class. It may be possible to pass the parent reference to a method (taking 3 parameters) in another class if the named procedure is Public. The empty array ([]) in Object.Call represent a procedure without parameters, which are not an explicit requirement for this Task, but might require another parameter to the accepting procedure. <lang gambas> Public Sub Main()
RepeatIt("RepeatableOne", 2)
RepeatIt("RepeatableTwo", 3)
End
'Cannot pass procedure pointer in Gambas; must pass procedure name and use Object.Call() Public Sub RepeatIt(sDelegateName As String, iCount As Integer)
For iCounter As Integer = 1 To iCount Object.Call(Me, sDelegateName, []) Next
End
Public Sub RepeatableOne()
Print "RepeatableOne"
End
Public Sub RepeatableTwo()
Print "RepeatableTwo"
End</lang> Output:
RepeatableOne RepeatableOne RepeatableTwo RepeatableTwo RepeatableTwo
Go
<lang go>package main
import "fmt"
func repeat(n int, f func()) {
for i := 0; i < n; i++ { f() }
}
func fn() {
fmt.Println("Example")
}
func main() {
repeat(4, fn)
}</lang>
Haskell
Such a function already exists <lang Haskell>import Control.Monad (replicateM_)
sampleFunction :: IO () sampleFunction = putStrLn "a"
main = replicateM_ 5 sampleFunction</lang>
And if the requirement is for something like a Church numeral, compounding the application of a given function n times (rather than repeating the same IO event n times) then we could also write something like applyN below: <lang Haskell>applyN :: Int -> (a -> a) -> a -> a applyN n f = foldr (.) id (replicate n f)
main :: IO () main = print $ applyN 10 (\x -> 2 * x) 1</lang>
- Output:
1024
Isabelle
Isabelle does not have procedures with side effects. So we cannot do things such as printing a string to stdout. Isabelle only has pure mathematical functions. <lang Isabelle>theory Scratch
imports Main
begin
text‹ Given the function we want to execute multiple times is of type \<^typ>‹unit ⇒ unit›. › fun pure_repeat :: "(unit ⇒ unit) ⇒ nat ⇒ unit" where
"pure_repeat _ 0 = ()"
| "pure_repeat f (Suc n) = f (pure_repeat f n)"
text‹ Functions are pure in Isabelle. They don't have side effects. This means, the \<^const>‹pure_repeat› we implemented is always equal to \<^term>‹() :: unit›, independent of the function \<^typ>‹unit ⇒ unit› or \<^typ>‹nat›. Technically, functions are not even "executed", but only evaluated. › lemma "pure_repeat f n = ()" by simp
text‹ But we can repeat a value of \<^typ>‹'a› \<^term>‹n› times and return the result in a list of length \<^term>‹n› › fun repeat :: "'a ⇒ nat ⇒ 'a list" where
"repeat _ 0 = []"
| "repeat f (Suc n) = f # (repeat f n)"
lemma "repeat Hello 4 = [Hello, Hello, Hello, Hello]"
by code_simp
lemma "length (repeat a n) = n" by(induction n) simp+
text‹ Technically, \<^typ>‹'a› is not a function. We can wrap it in a dummy function which takes a \<^typ>‹unit› as first argument. This gives a function of type \<^typ>‹unit ⇒ 'a›. ›
fun fun_repeat :: "(unit ⇒ 'a) ⇒ nat ⇒ 'a list" where
"fun_repeat _ 0 = []"
| "fun_repeat f (Suc n) = (f ()) # (fun_repeat f n)"
lemma "fun_repeat (λ_. Hello) 4 =
[Hello, Hello, Hello, Hello]" by code_simp
text‹ Yet, \<^const>‹fun_repeat› with the dummy function \<^typ>‹unit ⇒ 'a› is equivalent to \<^const>‹repeat› with the value \<^typ>‹'a› directly. › lemma "fun_repeat (λ_. a) n = repeat a n" by(induction n) simp+
end</lang>
J
<lang J>
NB. ^: (J's power conjunction) repeatedly evaluates a verb.
NB. Appending to a vector the sum of the most recent NB. 2 items can generate the Fibonacci sequence.
(, [: +/ _2&{.) (^:4) 0 1
0 1 1 2 3 5
NB. Repeat an infinite number of times NB. computes the stable point at convergence
cosine =: 2&o.
cosine (^:_ ) 2 NB. 2 is the initial value
0.739085
cosine 0.739085 NB. demonstrate the stable point x==Cos(x)
0.739085
cosine^:(<_) 2 NB. show the convergence
2 _0.416147 0.914653 0.610065 0.819611 0.682506 0.775995 0.713725 0.755929 0.727635 0.74675 0.733901 0.742568 0.736735 0.740666 0.738019 0.739803 0.738602 0.739411 0.738866 0.739233 0.738986 0.739152 0.73904 0.739116 0.739065 0.739099 0.739076 0.739091 0.7...
# cosine^:(<_) 2 NB. iteration tallyft
78
f =: 3 :'smoutput hi'
f
hi
NB. pass verbs via a gerund repeat =: dyad def 'for_i. i.y do. (x`:0)0 end. EMPTY'
(f`)repeat 4
hi hi hi hi
NB. pass a verb directly to an adverb
Repeat =: adverb def 'for_i. i.y do. u 0 end. EMPTY'
f Repeat 4
hi hi hi hi </lang>
Java
<lang java>import java.util.function.Consumer; import java.util.stream.IntStream;
public class Repeat {
public static void main(String[] args) { repeat(3, (x) -> System.out.println("Example " + x)); }
static void repeat (int n, Consumer<Integer> fun) { IntStream.range(0, n).forEach(i -> fun.accept(i + 1)); }
}</lang>
Output:
Example 1 Example 2 Example 3
jq
We first define "repeat" naively but in accordance with the task specification; we then define an optimized version that illustrates a general technique for taking advantage of jq's support for tail-call optimization (TCO).
Since jq is a purely functional language, repeat(f; n) is unlikely to be very useful so we define a similar filter, repeatedly(f; n), which generates n+1 terms: . (the input), f, f|f, ... ; that is, using conventional functional notation, it generates: x, f(x), f(f(x)), ...
Unoptimized version: <lang jq>def unoptimized_repeat(f; n):
if n <= 0 then empty else f, repeat(f; n-1) end;</lang>
Optimized for TCO: <lang jq>def repeat(f; n):
# state: [count, in] def r: if .[0] >= n then empty else (.[1] | f), (.[0] += 1 | r) end; [0, .] | r;</lang>
Variant: <lang jq># If n is a non-negative integer,
- then emit a stream of (n + 1) terms: ., f, f|f, f|f|f, ...
def repeatedly(f; n):
# state: [count, in] def r: if .[0] < 0 then empty else .[1], ([.[0] - 1, (.[1] | f)] | r) end; [n, .] | r;</lang>
Examples: <lang jq>0 | [ repeat(.+1; 3) ]</lang> produces: [1,1,1] <lang jq>0 | repeatedly(.+1; 3)</lang> produces:
0 1 2 3
Julia
<lang julia>function sayHi() println("Hi") end
function rep(f, n) for i = 1:n f() end end
rep(sayHi, 3)</lang>
- Output:
Hi Hi Hi
Kotlin
<lang scala>// version 1.0.6
fun repeat(n: Int, f: () -> Unit) {
for (i in 1..n) { f() println(i) }
}
fun main(args: Array<String>) {
repeat(5) { print("Example ") }
}</lang>
- Output:
Example 1 Example 2 Example 3 Example 4 Example 5
Lean
It runs on Lean 3.4.2:
<lang Lean>def repeat : ℕ → (ℕ → string) → string
| 0 f := "done" | (n + 1) f := (f n) ++ (repeat n f)
- eval repeat 5 $ λ b : ℕ , "me "
</lang>
LiveCode
<lang LiveCode>rep "answer",3
command rep x,n
repeat n times do merge("x n") end repeat
end rep</lang>
Lua
No particular magic required as Lua allows functions to be passed as arguments. <lang Lua>function myFunc ()
print("Sure looks like a function in here...")
end
function rep (func, times)
for count = 1, times do func() end
end
rep(myFunc, 4) </lang>
- Output:
Sure looks like a function in here... Sure looks like a function in here... Sure looks like a function in here... Sure looks like a function in here...
Mathematica/Wolfram Language
Note that anything of this form is not considered good practice. <lang Mathematica>repeat[f_, n_] := Do[f[], {n}]; repeat[Print["Hello, world!"] &, 5];</lang>
- Output:
Hello, world! Hello, world! Hello, world! Hello, world! Hello, world!
min
This operator already exists in min and is called times
.
<lang min>("Hello" puts!) 3 times</lang>
- Output:
Hello Hello Hello
MiniScript
<lang MiniScript>sayHi = function()
print "Hi!"
end function
rep = function(f, n)
for i in range(1, n) f end for
end function
rep @sayHi, 3</lang>
- Output:
Hi! Hi! Hi!
МК-61/52
<lang>1 П4
3 ^ 1 6 ПП 09 С/П
П7 <-> П0 КПП7 L0 12 В/О
ИП4 С/П КИП4 В/О</lang>
Modula-2
<lang modula2>MODULE Repeat; FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
TYPE F = PROCEDURE;
PROCEDURE Repeat(fun : F; c : INTEGER); VAR i : INTEGER; BEGIN
FOR i:=1 TO c DO fun END
END Repeat;
PROCEDURE Print; BEGIN
WriteString("Hello"); WriteLn
END Print;
BEGIN
Repeat(Print, 3);
ReadChar
END Repeat.</lang>
Nanoquery
<lang Nanoquery>def repeat(f,n)
for i in range(1, n) f() end
end
def procedure()
println "Example"
end
repeat(procedure, 3)</lang>
Nim
<lang nim>proc example =
echo "Example"
- Ordinary procedure
proc repeatProc(fn: proc, n: int) =
for x in 0..<n: fn()
repeatProc(example, 4)
- Template (code substitution), simplest form of metaprogramming
- that Nim has
template repeatTmpl(n: int, body: untyped): untyped =
for x in 0..<n: body
- This gets rewritten into a for loop
repeatTmpl 4:
example()
import std/macros
- A macro which takes some code block and returns code
- with that code block repeated n times. Macros run at
- compile-time
macro repeatMacro(n: static[int], body: untyped): untyped =
result = newStmtList()
for x in 0..<n: result.add body
- This gets rewritten into 4 calls to example()
- at compile-time
repeatMacro 4:
example()
</lang>
Objeck
<lang objeck>class Repeat {
function : Main(args : String[]) ~ Nil { Repeat(Example() ~ Nil, 3); } function : Repeat(e : () ~ Nil, i : Int) ~ Nil { while(i-- > 0) { e(); }; } function : Example() ~ Nil { "Example"->PrintLine(); }
}</lang>
OCaml
<lang ocaml>let repeat ~f ~n =
for i = 1 to n do f () done
let func () =
print_endline "Example"
let () =
repeat ~n:4 ~f:func
</lang>
Oforth
This method is already defined : times. This method can be used on all runnables (functions, methods, blocks, ...).
<lang Oforth>: hello "Hello, World!" println ; 10 #hello times</lang>
- Output:
Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!
Ol
<lang scheme>
- sample function
(define (function) (display "+"))
- simple case for 80 times
(for-each (lambda (unused) (function)) (iota 80)) (print) ; print newline
- ==> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- detailed case for 80 times
(let loop ((fnc function) (n 80))
(unless (zero? n) (begin (fnc) (loop fnc (- n 1)))))
(print) ; print newline
- ==> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
</lang>
PARI/GP
<lang parigp>repeat(f, n)=for(i=1,n,f()); repeat( ()->print("Hi!"), 2);</lang>
- Output:
Hi! Hi!
Pascal
<lang pascal>program Repeater;
type
TProc = procedure(I: Integer);
procedure P(I: Integer); begin
WriteLn('Iteration ', I);
end;
procedure Iterate(P: TProc; N: Integer); var
I: Integer;
begin
for I := 1 to N do P(I);
end;
begin
Iterate(P, 3);
end. </lang>
- Output:
Iteration 1 Iteration 2 Iteration 3
Perl
<lang perl>sub repeat {
my ($sub, $n) = @_; $sub->() for 1..$n;
}
sub example {
print "Example\n";
}
repeat(\&example, 4);</lang>
Phix
procedure Repeat(integer rid, integer n) for i=1 to n do rid() end for end procedure procedure Hello() ?"Hello" end procedure Repeat(Hello,5)
Phixmonti
<lang Phixmonti>def myFunc
"Sure looks like a function in here..." print nl
enddef
def rep /# func times -- #/
for drop
dup exec
endfor drop
enddef
getid myFunc 4 rep </lang>
PicoLisp
<lang PicoLisp># The built-in function "do" can be used to achieve our goal,
- however, it has a slightly different syntax than what the
- problem specifies.
- Native solution.
(do 10 (version))
- Our solution.
(de dofn (Fn N)
(do N (Fn)) )
(dofn version 10)</lang>
PowerShell
(Made more PowerShelly.)
<lang PowerShell> function Out-Example {
"Example"
}
function Step-Function ([string]$Function, [int]$Repeat) {
for ($i = 1; $i -le $Repeat; $i++) { "$(Invoke-Expression -Command $Function) $i" }
}
Step-Function Out-Example -Repeat 3 </lang>
- Output:
Example 1 Example 2 Example 3
Prolog
<lang prolog>repeat(_, 0). repeat(Callable, Times) :- succ(TimesLess1, Times), Callable, repeat(Callable, TimesLess1).
test :- write('Hello, World'), nl. test(Name) :- format('Hello, ~w~n', Name).</lang>
- Output:
?- repeat(test, 3). Hello, World Hello, World Hello, World true ; false. ?- repeat(test('Fred'), 3). Hello, Fred Hello, Fred Hello, Fred true ; false.
PureBasic
<lang PureBasic>Prototype.i fun(x.i)
Procedure.i quark(z.i)
Debug "Quark "+Str(z) : ProcedureReturn z-1
EndProcedure
Procedure rep(q.fun,n.i)
Repeat : n=q(n) : Until n=0
EndProcedure
rep(@quark(),3)</lang>
- Output:
Quark 3 Quark 2 Quark 1
Python
Procedural
<lang Python>#!/usr/bin/python def repeat(f,n):
for i in range(n): f();
def procedure():
print("Example");
repeat(procedure,3); #prints "Example" (without quotes) three times, separated by newlines.</lang>
Functional
Repeated function application:
<lang python>Application of a given function, repeated N times
from itertools import repeat from functools import reduce from inspect import getsource
- applyN :: Int -> (a -> a) -> a -> a
def applyN(n):
n compounding applications of the supplied function f. Equivalent to Church numeral n. def go(f): return lambda x: reduce( lambda a, g: g(a), repeat(f, n), x ) return lambda f: go(f)
- MAIN ----------------------------------------------------
def main():
Tests - compounding repetition of function application. def f(x): return x + 'Example\n'
def g(x): return 2 * x
def h(x): return 1.05 * x
print( fTable(__doc__ + ':')( lambda fx: '\nRepeated * 3:\n (' + ( getsource(fst(fx)).strip() + ')(' + repr(snd(fx)) + ')' ) )(str)( liftA2(applyN(3))(fst)(snd) )([(f, '\n'), (g, 1), (h, 100)]) )
- GENERIC -------------------------------------------------
- compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
Right to left function composition. return lambda f: lambda x: g(f(x))
- fst :: (a, b) -> a
def fst(tpl):
First member of a pair. return tpl[0]
- liftA2 :: (a0 -> b -> c) -> (a -> a0) -> (a -> b) -> a -> c
def liftA2(op):
Lift a binary function to a composition over two other functions. liftA2 (*) (+ 2) (+ 3) 7 == 90 def go(f, g): return lambda x: op( f(x) )(g(x)) return lambda f: lambda g: go(f, g)
- snd :: (a, b) -> b
def snd(tpl):
Second member of a pair. return tpl[1]
- fTable :: String -> (a -> String) ->
- (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
Heading -> x display function -> fx display function -> f -> xs -> tabular string. def go(xShow, fxShow, f, xs): ys = [xShow(x) for x in xs] w = max(map(len, ys)) return s + '\n' + '\n'.join(map( lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)), xs, ys )) return lambda xShow: lambda fxShow: lambda f: lambda xs: go( xShow, fxShow, f, xs )
- MAIN ---
if __name__ == '__main__':
main()</lang>
- Output:
Application of a given function, repeated N times: Repeated * 3: (def f(x): return x + 'Example\n')('\n') -> Example Example Example Repeated * 3: (def g(x): return 2 * x)(1) -> 8 Repeated * 3: (def h(x): return 1.05 * x)(100) -> 115.7625
Quackery
This is a function which is part of the Quackery language. times performs the word or nest after it the number of times specified on the stack. The definition is reproduced here, along with the additional functionality included in the language; i counts down to zero, i^ counts up from zero, step specifies the increment size from an argument on the stack (default is 1), conclude sets the iteration countdown to the final value (0) and refresh sets the iteration countdown to the initial value. times is nestable, and words such as witheach (which makes use of times to iterate over a nest) inherit its additional functionality.
The word rosetta-times is also defined here, using times. It takes both the repeat number and the function as stack arguments.
<lang Quackery> [ stack ] is times.start ( --> s )
protect times.start
[ stack ] is times.count ( --> s ) protect times.count
[ stack ] is times.action ( --> s ) protect times.action
[ ]'[ times.action put dup times.start put [ 1 - dup -1 > while times.count put times.action share do times.count take again ] drop times.action release times.start release ] is times ( n --> )
[ times.count share ] is i ( --> n )
[ times.start share i 1+ - ] is i^ ( --> n )
[ 0 times.count replace ] is conclude ( --> )
[ times.start share times.count replace ] is refresh ( --> )
[ times.count take 1+ swap - times.count put ] is step ( --> s )
[ nested ' times nested swap join do ] is rosetta-times ( n x --> )</lang>
- Output:
rosetta-times demonstrated in the Quackery shell. (REPL)
/O> [ say "hello" cr ] is hi ... 5 ' hi rosetta-times ... hello hello hello hello hello Stack empty.
R
<lang R> f1 <- function(...){print("coucou")}
f2 <-function(f,n){ lapply(seq_len(n),eval(f)) }
f2(f1,4) </lang>
Racket
The racket guide has a section called "Iterators and Comprehensions", which shows that for isn't just for repeating n times!
<lang Racket>#lang racket/base (define (repeat f n) ; the for loop is idiomatic of (although not exclusive to) racket
(for ((_ n)) (f)))
(define (repeat2 f n) ; This is a bit more "functional programmingy"
(when (positive? n) (f) (repeat2 f (sub1 n))))
(display "...") (repeat (λ () (display " and over")) 5) (display "...") (repeat2 (λ () (display " & over")) 5) (newline)</lang>
- Output:
... and over and over and over and over and over... & over & over & over & over & over
Raku
(formerly Perl 6)
<lang perl6>sub repeat (&f, $n) { f() xx $n };
sub example { say rand }
repeat(&example, 3);</lang>
- Output:
0.435249779778396 0.647701200726486 0.279289335968417
Of course, we could have just written
example() xx 3;
or even
(say rand) xx 3;
directly – the custom repeat
subroutine is just here to satisfy the task description.
Notes on the xx
operator:
- Unlike other operators, it evaluates its left-hand-side argument lazily - that's why we can simply call
f()
there rather than passing it as a function object. - The operator has a return value: A list consisting of the return values of the left-hand-side (and building lists is in fact what
xx
is usually used for).
General notes:
- The
&
sigil in therepeat
subroutine signature restricts that parameter to types that implement theCallable
role, and makes it available inside therepeat
subroutine body as if it were a lexically scoped sub. - The parentheses in the last line are necessary to disambiguate it as a call to our custom subroutine, rather than an attempt to use the built-in
repeat { ... } while ...
construct.
REXX
The procedure name (that is being repeatedly executed) isn't restricted to an internal REXX subroutine (procedure),
it may be an external program (procedure) written in any language.
<lang rexx>/*REXX program executes a named procedure a specified number of times. */
parse arg pN # . /*obtain optional arguments from the CL*/
if #== | #=="," then #= 1 /*assume once if not specified. */
if pN\== then call repeats pN, # /*invoke the REPEATS procedure for pN.*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
repeats: procedure; parse arg x,n /*obtain the procedureName & # of times*/
do n; interpret 'CALL' x; end /*repeat the invocation N times. */ return /*return to invoker of the REPEATS proc*/
/*──────────────────────────────────────────────────────────────────────────────────────*/ yabba: say 'Yabba, yabba do!'; return /*simple code; no need for PROCEDURE.*/</lang>
- output when using the input of: yabba 4
Yabba, yabba do! Yabba, yabba do! Yabba, yabba do! Yabba, yabba do!
output when the input is: $date 3
[The (external) $DATE.REX program isn't supplied here.]
day-of-year= 159 Gregorian date= 06/08/2014 Sunday day-of-year= 159 Gregorian date= 06/08/2014 Sunday day-of-year= 159 Gregorian date= 06/08/2014 Sunday
Ring
<lang ring> Func Main
times(5,:test)
Func Test
see "Message from the test function!" + nl
Func Times nCount, F
for x = 1 to nCount Call F() next
</lang>
Ruby
<lang ruby>4.times{ puts "Example" } # idiomatic way
def repeat(proc,num)
num.times{ proc.call }
end
repeat(->{ puts "Example" }, 4)</lang>
Rust
Rust has higher-order functions.
<lang rust>fn repeat(f: impl FnMut(usize), n: usize) {
(0..n).for_each(f);
}</lang>
Here we define the function repeat
which takes the function Fn(usize)
, which is an anonymous trait constraint by the impl Trait
syntax, in such a way that it's size can be known statically at compile time. The range iterator 0..n
is used, in combination with the Iterator::for_each
method to consume it.
Closure
It's idiomatic to use a closure.
<lang rust>fn main() {
repeat(|x| print!("{};", x), 5);
}</lang>
- Output:
0;1;2;3;4;
Static Function
Also possible to define a static function.
<lang rust>fn function(x: usize) {
print!("{};", x);
}
fn main() {
repeat(function, 4);
}</lang>
- Output:
0;1;2;3;
Static Method
Sometimes it may be convenient to call a static method.
<lang rust>struct Foo; impl Foo {
fn associated(x: usize) { print!("{};", x); }
}
fn main() {
repeat(Foo::associated, 8);
}</lang>
- Output:
0;1;2;3;4;5;6;7;
Trait Method
You can also use implemented trait-methods as a function-argument. This works because the implemented type is usize
which is what the iterator supplied to Fn(usize)
.
<lang rust>trait Bar {
fn run(self);
}
impl Bar for usize {
fn run(self) { print!("{};", self); }
}
fn main() {
repeat(Bar::run, 6);
}</lang>
- Output:
0;1;2;3;4;5;
Mutable Closure
The most interesting application would probably be a mutable closure, which requires changing the type signature from Fn
to FnMut
, because they are constrained by slightly different rules, but otherwise work the same.
<lang rust>fn repeat(f: impl FnMut(usize), n: usize) {
(0..n).for_each(f);
}
fn main() {
let mut mult = 1; repeat(|x| { print!("{};", x * mult); mult += x; }, 5);
}</lang>
- Output:
0;1;4;12;28;
Scala
Intuitive solution
- Call by name
- Type parameterization
- Higher order function
<lang scala> def repeat[A](n:Int)(f: => A)= ( 0 until n).foreach(_ => f)
repeat(3) { println("Example") }</lang>
Advanced Scala-ish
- Call by name
- Type parameterization
- Implicit method
- Tail recursion
- Infix notation
<lang scala>object Repeat2 extends App {
implicit class IntWithTimes(x: Int) { def times[A](f: => A):Unit = { @tailrec def loop( current: Int): Unit = if (current > 0) { f loop(current - 1) } loop(x) } }
5 times println("ha") // Not recommended infix for 5.times(println("ha")) aka dot notation
}</lang>
Most Scala-ish
- Call by name
- Type parameterization
- Implicit method
- Tail recursion
- Infix notation
- Operator overloading
<lang scala>import scala.annotation.tailrec
object Repeat3 extends App {
implicit class UnitWithNtimes(f: => Unit) { def *[A](n: Int): Unit = { // Symbol * used instead of literal method name @tailrec def loop(current: Int): Unit = if (current > 0) { f loop(current - 1) } loop(n) } }
print("ha") * 5 // * is the method, effective should be A.*(5)
}</lang>
Scheme
Scheme is mostly made up from expressions which return values. However some functions, such as display, return an unspecified value. The actual value returned varies depending on the Scheme implementation itself.
<lang scheme> (import (scheme base)
(scheme write))
(define (repeat proc n)
(do ((i 0 (+ 1 i)) (res '() (cons (proc) res))) ((= i n) res)))
- example returning an unspecified value
(display (repeat (lambda () (display "hi\n")) 4)) (newline)
- example returning a number
(display (repeat (lambda () (+ 1 2)) 5)) (newline) </lang>
- Output:
(Using chibi-scheme: returns #<undef> from display.)
hi hi hi hi (#<undef> #<undef> #<undef> #<undef>) (3 3 3 3 3)
Seed7
<lang seed7>$ include "seed7_05.s7i";
const proc: myRepeat (in integer: times, in proc: aProcedure) is func
local var integer: n is 0; begin for n range 1 to times do aProcedure; end for; end func;
const proc: main is func
begin myRepeat(3, writeln("Hello!")); end func;</lang>
- Output:
Hello! Hello! Hello!
Sidef
<lang ruby>func repeat(f, n) {
{ f() } * n;
}
func example {
say "Example";
}
repeat(example, 4);</lang>
Standard ML
<lang sml>fun repeat (_, 0) = ()
| repeat (f, n) = (f (); repeat (f, n - 1))
fun testProcedure () =
print "test\n"
val () = repeat (testProcedure, 5)</lang>
Stata
<lang stata>function repeat(f,n) { for (i=1; i<=n; i++) (*f)() }
function hello() { printf("Hello\n") }
repeat(&hello(),3)</lang>
Swift
<lang swift>func repeat(n: Int, f: () -> ()) {
for _ in 0..<n { f() }
}
repeat(4) { println("Example") }</lang>
Tcl
The usual way of doing a repeat would be: <lang tcl>proc repeat {command count} {
for {set i 0} {$i < $count} {incr i} { uplevel 1 $command }
}
proc example {} {puts "This is an example"}
repeat example 4</lang>
However, the time
command can be used as long as the return value (the report on the timing information) is ignored.
<lang tcl>time example 4</lang>
It should be noted that the “command” can be an arbitrary script, not just a call to a procedure:
<lang tcl>repeat {puts "hello world"} 3</lang>
uBasic/4tH
<lang>Proc _Repeat (_HelloWorld, 5) : End
_Repeat Param (2) : Local (1) : For c@ = 1 To b@ : Proc a@ : Next : Return _HelloWorld Print "Hello world!" : Return</lang> Output:
Hello world! Hello world! Hello world! Hello world! Hello world! 0 OK, 0:35
Ursa
<lang ursa>def repeat (function f, int n) for (set n n) (> n 0) (dec n) f end for end repeat
def procedure () out "Hello! " console end procedure
- outputs "Hello! " 5 times
repeat procedure 5</lang>
VBA
<lang vb>Private Sub Repeat(rid As String, n As Integer)
For i = 1 To n Application.Run rid Next i
End Sub
Private Sub Hello()
Debug.Print "Hello"
End Sub
Public Sub main()
Repeat "Hello", 5
End Sub</lang>
Verilog
<lang Verilog>module main;
initial begin repeat(5) begin $display("Inside loop"); end $display("Loop Ended"); end
endmodule</lang>
- Output:
Inside loop Inside loop Inside loop Inside loop Inside loop Loop Ended
Visual Basic .NET
<lang vbnet>Module Module1
Sub Repeat(count As Integer, fn As Action(Of Integer)) If IsNothing(fn) Then Throw New ArgumentNullException("fn") End If
For i = 1 To count fn.Invoke(i) Next End Sub
Sub Main() Repeat(3, Sub(x) Console.WriteLine("Example {0}", x)) End Sub
End Module</lang>
- Output:
Example 1 Example 2 Example 3
Wren
<lang ecmascript>var f = Fn.new { |g, n|
for (i in 1..n) g.call(n)
}
var g = Fn.new { |k|
for (i in 1..k) System.write("%(i) ") System.print()
}
f.call(g, 5)</lang>
- Output:
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
XBS
XBS has a built-in repeat keyword. <lang xbs>func rep(callback:function,amount:number,*args:array=[]):null{ repeat amount { callback(*args); } }
rep(func(a,b,c){ log(a+b+c); },3,1,2,3);</lang>
- Output:
6 6 6
XLISP
<lang lisp>(defun repeat (f n)
(f) (if (> n 1) (repeat f (- n 1)) ) )
- an example to test it
(repeat (lambda () (print '(hello rosetta code))) 5)</lang>
- Output:
(HELLO ROSETTA CODE) (HELLO ROSETTA CODE) (HELLO ROSETTA CODE) (HELLO ROSETTA CODE) (HELLO ROSETTA CODE)
Yabasic
<lang Yabasic>sub myFunc ()
print "Sure looks like a function in here..."
end sub
sub rep (func$, times)
for count = 1 to times execute(func$) next
end sub
rep("myFunc", 4)</lang>
Z80 Assembly
Return Trick
This technique is called the "Return Trick", it's efficient but makes the program more difficult to read. It works on the principle that the processor's RET command assumes the return address is the top item of the stack. The programmer can abuse this to "return" to a section of code that has never actually been executed. This is essentially just another form of the computed goto. Most processors that use the stack to store return addresses can use this technique, though the method of doing it depends on the processor itself.
<lang z80> ld b,&05 ;load the decrement value into b ld hl,myFunc ;load the address of "myFunc" into HL
call repeatProcedure
forever: jp forever ;trap the program counter here
repeatProcedure: ;input: b = times to repeat, hl = which procedure to repeat call trampoline
- the "ret" in myFunc will bring you here
djnz repeatProcedure ret ;exit "repeatProcedure" and proceed to "forever"
trampoline: push hl ret
- this is effectively a call to whatever is in HL, in this case "myFunc." The "ret" at the end of myFunc will return us to
- just after the line "call trampoline"
myFunc: ;this doesn't do anything useful but that's not the point
push hl ;not needed for this routine but if it altered HL we would need this so that we come back here next time we loop
or a
pop hl
ret
</lang>
Indirect Jump
Same as above but uses an indirect jump to the address in HL. <lang z80> trampoline: jp (hl) </lang>
zkl
<lang zkl>fcn repeat(f,n){ do(n){ f() } } repeat("ho ".print,3);</lang>
- Output:
ho ho ho
- Programming Tasks
- Solutions by Programming Task
- 11l
- 6502 Assembly
- Action!
- Ada
- ALGOL 68
- ALGOL W
- AppleScript
- Applesoft BASIC
- Arturo
- AutoHotkey
- AWK
- Batch File
- BQN
- C
- C sharp
- C++
- Clojure
- Common Lisp
- Cowgol
- D
- Delphi
- EchoLisp
- F Sharp
- Factor
- Forth
- FreeBASIC
- Gambas
- Go
- Haskell
- Isabelle
- J
- Java
- Jq
- Julia
- Kotlin
- Lean
- LiveCode
- Lua
- Mathematica
- Wolfram Language
- Min
- MiniScript
- МК-61/52
- Modula-2
- Nanoquery
- Nim
- Objeck
- OCaml
- Oforth
- Ol
- PARI/GP
- Pascal
- Perl
- Phix
- Phixmonti
- PicoLisp
- PowerShell
- Prolog
- PureBasic
- Python
- Quackery
- R
- Racket
- Raku
- REXX
- Ring
- Ruby
- Rust
- Scala
- Scheme
- Seed7
- Sidef
- Standard ML
- Stata
- Swift
- Tcl
- UBasic/4tH
- Ursa
- VBA
- Verilog
- Visual Basic .NET
- Wren
- XBS
- XLISP
- Yabasic
- Z80 Assembly
- Zkl