Repeat
- 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.
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
Applesoft BASIC
http://hoop-la.ca/apple2/2016/winterwarmup/#repeat.bas
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
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 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>
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
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>
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
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>
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
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
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!
МК-61/52
<lang>1 П4
3 ^ 1 6 ПП 09 С/П
П7 <-> П0 КПП7 L0 12 В/О
ИП4 С/П КИП4 В/О</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!
PARI/GP
<lang parigp>repeat(f, n)=for(i=1,n,f()); repeat( ()->print("Hi!"), 2);</lang>
- Output:
Hi! Hi!
Perl
<lang perl>sub repeat {
my ($sub, $n) = @_; $sub->() for 1..$n;
}
sub example {
print "Example\n";
}
repeat(\&example, 4);</lang>
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.
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>
Python
<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>
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
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 /*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 the input is: 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>
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>
Sidef
<lang ruby>func repeat(f, n) {
{ f() } * n;
}
func example {
say "Example";
}
repeat(example, 4);</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>
zkl
<lang zkl>fcn repeat(f,n){ do(n){ f() } } repeat("ho ".print,3);</lang>
- Output:
ho ho ho