Jensen's Device: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 36: Line 36:
{{trans|C#}}
{{trans|C#}}


<lang 11l>F sum(&i, lo, hi, term)
<syntaxhighlight lang="11l">F sum(&i, lo, hi, term)
V temp = 0.0
V temp = 0.0
i = lo
i = lo
Line 48: Line 48:
print(sum(&i, 1, 100, () -> 1 / @i))
print(sum(&i, 1, 100, () -> 1 / @i))


main()</lang>
main()</syntaxhighlight>


{{out}}
{{out}}
Line 56: Line 56:


=={{header|Ada}}==
=={{header|Ada}}==
<lang ada>with Ada.Text_IO; use Ada.Text_IO;
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;


procedure Jensen_Device is
procedure Jensen_Device is
Line 81: Line 81:
begin
begin
Put_Line (Float'Image (Sum (I'Access, 1.0, 100.0, Inv_I'Access)));
Put_Line (Float'Image (Sum (I'Access, 1.0, 100.0, Inv_I'Access)));
end Jensen_Device;</lang>
end Jensen_Device;</syntaxhighlight>
<pre>
<pre>
5.18738E+00
5.18738E+00
Line 108: Line 108:
=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
{{trans|ALGOL 60}}
{{trans|ALGOL 60}}
<lang algol68>BEGIN
<syntaxhighlight lang="algol68">BEGIN
INT i;
INT i;
PROC sum = (REF INT i, INT lo, hi, PROC REAL term)REAL:
PROC sum = (REF INT i, INT lo, hi, PROC REAL term)REAL:
Line 123: Line 123:
COMMENT note the correspondence between the mathematical notation and the call to sum COMMENT
COMMENT note the correspondence between the mathematical notation and the call to sum COMMENT
print (sum (i, 1, 100, REAL: 1/i))
print (sum (i, 1, 100, REAL: 1/i))
END</lang>
END</syntaxhighlight>
Output: +5.18737751763962e +0
Output: +5.18737751763962e +0


Line 131: Line 131:
<br>This version uses call by name for the i parameter but uses a procedure parameter for the summed expression.
<br>This version uses call by name for the i parameter but uses a procedure parameter for the summed expression.
<br>The expression supplied in the call is automatically converted to a procedure by the compiler.
<br>The expression supplied in the call is automatically converted to a procedure by the compiler.
<lang algolw>begin
<syntaxhighlight lang="algolw">begin
integer i;
integer i;
real procedure sum ( integer %name% i; integer value lo, hi; real procedure term );
real procedure sum ( integer %name% i; integer value lo, hi; real procedure term );
Line 147: Line 147:
% note the correspondence between the mathematical notation and the call to sum %
% note the correspondence between the mathematical notation and the call to sum %
write( sum( i, 1, 100, 1/i ) )
write( sum( i, 1, 100, 1/i ) )
end.</lang>
end.</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 153: Line 153:


=={{header|AppleScript}}==
=={{header|AppleScript}}==
<lang AppleScript>set i to 0
<syntaxhighlight lang="applescript">set i to 0


on jsum(i, lo, hi, term)
on jsum(i, lo, hi, term)
Line 169: Line 169:
end script
end script


return jsum(a reference to i, 1, 100, term_func)</lang>
return jsum(a reference to i, 1, 100, term_func)</syntaxhighlight>
Output: 5.18737751764
Output: 5.18737751764


=={{header|ARM Assembly}}==
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>


/* ARM assembly Raspberry PI */
/* ARM assembly Raspberry PI */
Line 259: Line 259:
fUn: .float 1
fUn: .float 1


</syntaxhighlight>
</lang>
=={{header|Arturo}}==
=={{header|Arturo}}==
{{trans|Ruby}}
{{trans|Ruby}}
<lang rebol>harmonicSum: function [variable, lo, hi, term][
<syntaxhighlight lang="rebol">harmonicSum: function [variable, lo, hi, term][
result: new 0.0
result: new 0.0
loop lo..hi 'n ->
loop lo..hi 'n ->
Line 268: Line 268:
result
result
]
]
print ["harmonicSum 1->100:" harmonicSum 'i 1 100 {1.0 / i}]</lang>
print ["harmonicSum 1->100:" harmonicSum 'i 1 100 {1.0 / i}]</syntaxhighlight>


{{out}}
{{out}}
Line 275: Line 275:


=={{header|AWK}}==
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f JENSENS_DEVICE.AWK
# syntax: GAWK -f JENSENS_DEVICE.AWK
# converted from FreeBASIC
# converted from FreeBASIC
Line 290: Line 290:
printf("%.15f\n",tmp)
printf("%.15f\n",tmp)
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 298: Line 298:
=={{header|BASIC256}}==
=={{header|BASIC256}}==
{{trans|FreeBASIC}}
{{trans|FreeBASIC}}
<lang BASIC256>subroutine Evaluation()
<syntaxhighlight lang="basic256">subroutine Evaluation()
lo = 1 : hi = 100 : temp = 0
lo = 1 : hi = 100 : temp = 0
for i = lo to hi
for i = lo to hi
Line 307: Line 307:


call Evaluation()
call Evaluation()
end</lang>
end</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 316: Line 316:
=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
<lang bbcbasic> PRINT FNsum(j, 1, 100, FNreciprocal)
<syntaxhighlight lang="bbcbasic"> PRINT FNsum(j, 1, 100, FNreciprocal)
END
END
Line 326: Line 326:
= temp
= temp
DEF FNreciprocal = 1/i</lang>
DEF FNreciprocal = 1/i</syntaxhighlight>
Output:
Output:
<pre>
<pre>
Line 333: Line 333:


=={{header|Bracmat}}==
=={{header|Bracmat}}==
<lang bracmat>( ( sum
<syntaxhighlight lang="bracmat">( ( sum
= I lo hi Term temp
= I lo hi Term temp
. !arg:((=?I),?lo,?hi,(=?Term))
. !arg:((=?I),?lo,?hi,(=?Term))
Line 346: Line 346:
)
)
& sum$((=i),1,100,(=!i^-1))
& sum$((=i),1,100,(=!i^-1))
);</lang>
);</syntaxhighlight>
Output:
Output:
<pre>14466636279520351160221518043104131447711/2788815009188499086581352357412492142272</pre>
<pre>14466636279520351160221518043104131447711/2788815009188499086581352357412492142272</pre>


=={{header|C}}==
=={{header|C}}==
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>


int i;
int i;
Line 366: Line 366:
printf("%f\n", sum(&i, 1, 100, term_func));
printf("%f\n", sum(&i, 1, 100, term_func));
return 0;
return 0;
}</lang>
}</syntaxhighlight>
Output: 5.18738
Output: 5.18738


{{works with|gcc}}
{{works with|gcc}}
Alternatively, C's macros provide a closer imitation of ALGOL's call-by-name semantics:
Alternatively, C's macros provide a closer imitation of ALGOL's call-by-name semantics:
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
int i;
int i;
Line 389: Line 389:
printf("%f\n", sum(i, 1, 100, 1.0 / i));
printf("%f\n", sum(i, 1, 100, 1.0 / i));
return 0;
return 0;
}</lang>
}</syntaxhighlight>
Output: 5.187378
Output: 5.187378


=={{header|C sharp}}==
=={{header|C sharp}}==
Can be simulated via lambda expressions:
Can be simulated via lambda expressions:
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


class JensensDevice
class JensensDevice
Line 413: Line 413:
Console.WriteLine(Sum(ref i, 1, 100, () => 1.0 / i));
Console.WriteLine(Sum(ref i, 1, 100, () => 1.0 / i));
}
}
}</lang>
}</syntaxhighlight>


=={{header|C++}}==
=={{header|C++}}==
<lang cpp>
<syntaxhighlight lang="cpp">
#include <iostream>
#include <iostream>


Line 439: Line 439:
std::cout << SUM(i,1,100,1.0/i) << "\n";
std::cout << SUM(i,1,100,1.0/i) << "\n";
return 0;
return 0;
}</lang>
}</syntaxhighlight>
Output: 5.18738
Output: 5.18738
5.18738
5.18738
Line 445: Line 445:
=={{header|Clipper}}==
=={{header|Clipper}}==
With hindsight Algol60 provided this feature in a way that is terrible for program maintenance, because the calling code looks innocuous.
With hindsight Algol60 provided this feature in a way that is terrible for program maintenance, because the calling code looks innocuous.
<lang Clipper>// Jensen's device in Clipper (or Harbour)
<syntaxhighlight lang="clipper">// Jensen's device in Clipper (or Harbour)
// A fairly direct translation of the Algol 60
// A fairly direct translation of the Algol 60
// John M Skelton 11-Feb-2012
// John M Skelton 11-Feb-2012
Line 465: Line 465:
next i
next i
return temp
return temp
</syntaxhighlight>
</lang>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
Line 471: Line 471:
Common Lisp does not have call-by-name for functions; however, it can be directly simulated by a macro wrapping selected parameters in lambdas.
Common Lisp does not have call-by-name for functions; however, it can be directly simulated by a macro wrapping selected parameters in lambdas.


<lang lisp>(declaim (inline %sum))
<syntaxhighlight lang="lisp">(declaim (inline %sum))


(defun %sum (lo hi func)
(defun %sum (lo hi func)
Line 477: Line 477:


(defmacro sum (i lo hi term)
(defmacro sum (i lo hi term)
`(%sum ,lo ,hi (lambda (,i) ,term)))</lang>
`(%sum ,lo ,hi (lambda (,i) ,term)))</syntaxhighlight>


<lang lisp>CL-USER> (sum i 1 100 (/ 1 i))
<syntaxhighlight lang="lisp">CL-USER> (sum i 1 100 (/ 1 i))
14466636279520351160221518043104131447711/2788815009188499086581352357412492142272
14466636279520351160221518043104131447711/2788815009188499086581352357412492142272
CL-USER> (float (sum i 1 100 (/ 1 i)))
CL-USER> (float (sum i 1 100 (/ 1 i)))
5.1873775</lang>
5.1873775</syntaxhighlight>


=={{header|D}}==
=={{header|D}}==
There are better ways to do this in D, but this is closer to the original Algol version:
There are better ways to do this in D, but this is closer to the original Algol version:
<lang d>double sum(ref int i, in int lo, in int hi, lazy double term)
<syntaxhighlight lang="d">double sum(ref int i, in int lo, in int hi, lazy double term)
pure @safe /*nothrow @nogc*/ {
pure @safe /*nothrow @nogc*/ {
double result = 0.0;
double result = 0.0;
Line 499: Line 499:
int i;
int i;
sum(i, 1, 100, 1.0/i).writeln;
sum(i, 1, 100, 1.0/i).writeln;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 506: Line 506:
=={{header|DWScript}}==
=={{header|DWScript}}==
Must use a "while" loop, as "for" loop variables are restricted to local variable for code clarity, and this indeed a case where any kind of extra clarity helps.
Must use a "while" loop, as "for" loop variables are restricted to local variable for code clarity, and this indeed a case where any kind of extra clarity helps.
<lang delphi>function sum(var i : Integer; lo, hi : Integer; lazy term : Float) : Float;
<syntaxhighlight lang="delphi">function sum(var i : Integer; lo, hi : Integer; lazy term : Float) : Float;
begin
begin
i:=lo;
i:=lo;
Line 517: Line 517:
var i : Integer;
var i : Integer;


PrintLn(sum(i, 1, 100, 1.0/i));</lang>
PrintLn(sum(i, 1, 100, 1.0/i));</syntaxhighlight>
Output: 5.187...
Output: 5.187...


Line 526: Line 526:
(The definition of the outer <var>i</var> has been moved down to emphasize that it is unrelated to the <var>i</var> inside of <var>sum</var>.)
(The definition of the outer <var>i</var> has been moved down to emphasize that it is unrelated to the <var>i</var> inside of <var>sum</var>.)


<lang e>pragma.enable("one-method-object") # "def _.get" is experimental shorthand
<syntaxhighlight lang="e">pragma.enable("one-method-object") # "def _.get" is experimental shorthand
def sum(&i, lo, hi, &term) { # bind i and term to passed slots
def sum(&i, lo, hi, &term) { # bind i and term to passed slots
var temp := 0
var temp := 0
Line 539: Line 539:
var i := null
var i := null
sum(&i, 1, 100, def _.get() { return 1/i })
sum(&i, 1, 100, def _.get() { return 1/i })
}</lang>
}</syntaxhighlight>


<tt>1/i</tt> is not a noun, so there is no slot associated with it; so we use <tt>def _.get() { return 1/i }</tt> to define a slot object which does the computation when it is read as a slot.
<tt>1/i</tt> is not a noun, so there is no slot associated with it; so we use <tt>def _.get() { return 1/i }</tt> to define a slot object which does the computation when it is read as a slot.
Line 547: Line 547:
This emulation of the original call-by-name is of course unidiomatic; a natural version of the same computation would be:
This emulation of the original call-by-name is of course unidiomatic; a natural version of the same computation would be:


<lang e>def sum(lo, hi, f) {
<syntaxhighlight lang="e">def sum(lo, hi, f) {
var temp := 0
var temp := 0
for i in lo..hi { temp += f(i) }
for i in lo..hi { temp += f(i) }
return temp
return temp
}
}
sum(1, 100, fn i { 1/i })</lang>
sum(1, 100, fn i { 1/i })</syntaxhighlight>


=={{header|Elixir}}==
=={{header|Elixir}}==
{{trans|Erlang}}
{{trans|Erlang}}
<lang elixir>defmodule JensenDevice do
<syntaxhighlight lang="elixir">defmodule JensenDevice do
def task, do: sum( 1, 100, fn i -> 1 / i end )
def task, do: sum( 1, 100, fn i -> 1 / i end )
Line 566: Line 566:
end
end


IO.puts JensenDevice.task</lang>
IO.puts JensenDevice.task</syntaxhighlight>


{{out}}
{{out}}
Line 576: Line 576:
No call by name, no macros, so I use a fun(ction). Actually, the the macro part is a lie. Somebody else, that knows how, could do a parse transform.
No call by name, no macros, so I use a fun(ction). Actually, the the macro part is a lie. Somebody else, that knows how, could do a parse transform.


<syntaxhighlight lang="erlang">
<lang Erlang>
-module( jensens_device ).
-module( jensens_device ).


Line 588: Line 588:
Temp = Term( I ),
Temp = Term( I ),
Temp + sum( I + 1, High, Term ).
Temp + sum( I + 1, High, Term ).
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 597: Line 597:


=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
<lang fsharp>
<syntaxhighlight lang="fsharp">
printfn "%.14f" (List.fold(fun n g->n+1.0/g) 0.0 [1.0..100.0]);;
printfn "%.14f" (List.fold(fun n g->n+1.0/g) 0.0 [1.0..100.0]);;
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 606: Line 606:
=={{header|Factor}}==
=={{header|Factor}}==
Similar to the Java and Kotlin examples:
Similar to the Java and Kotlin examples:
<lang factor>: sum ( lo hi term -- x ) [ [a,b] ] dip map-sum ; inline
<syntaxhighlight lang="factor">: sum ( lo hi term -- x ) [ [a,b] ] dip map-sum ; inline


1 100 [ recip ] sum .</lang>
1 100 [ recip ] sum .</syntaxhighlight>


This version is a bit closer to the original, as it increments <code>i</code> in the caller's namespace.
This version is a bit closer to the original, as it increments <code>i</code> in the caller's namespace.
<lang factor>SYMBOL: i
<syntaxhighlight lang="factor">SYMBOL: i


: sum ( i lo hi term -- x )
: sum ( i lo hi term -- x )
Line 617: Line 617:
inline
inline


i 1 100 [ recip ] sum .</lang>
i 1 100 [ recip ] sum .</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 626: Line 626:
This version passes i on the stack:
This version passes i on the stack:


<lang forth>: sum 0 s>f 1+ swap ?do i over execute f+ loop drop ;
<syntaxhighlight lang="forth">: sum 0 s>f 1+ swap ?do i over execute f+ loop drop ;
:noname s>f 1 s>f fswap f/ ; 1 100 sum f.</lang>
:noname s>f 1 s>f fswap f/ ; 1 100 sum f.</syntaxhighlight>
Output: 5.18737751763962
Output: 5.18737751763962


The following version passes i and 1/i as execution tokens and is thus closer to the original, but less idiomatic:
The following version passes i and 1/i as execution tokens and is thus closer to the original, but less idiomatic:


<lang forth>fvariable ii \ i is a Forth word that we need
<syntaxhighlight lang="forth">fvariable ii \ i is a Forth word that we need
: sum ( xt1 lo hi xt2 -- r )
: sum ( xt1 lo hi xt2 -- r )
0e swap 1+ rot ?do ( addr xt r1 )
0e swap 1+ rot ?do ( addr xt r1 )
i s>f over execute f! dup execute f+
i s>f over execute f! dup execute f+
loop 2drop ;
loop 2drop ;
' ii 1 100 :noname 1e ii f@ f/ ; sum f.</lang>
' ii 1 100 :noname 1e ii f@ f/ ; sum f.</syntaxhighlight>


=={{header|Fortran}}==
=={{header|Fortran}}==
Fortran does not offer call-by-name in the manner of the Algol language. It passes parameters by reference (i.e. by passing the storage address) and alternatively uses copy-in, copy-out to give the same effect, approximately, as by reference. If a parameter is an arithmetic expression, it will be evaluated and its value stored in a temporary storage area, whose address will be passed to the routine. This evaluation is done once only for each call, thus vitiating the repeated re-evaluation required by Jensen's device every time within the routine that the parameter is accessed. So, this will ''not'' work<lang Fortran> FUNCTION SUM(I,LO,HI,TERM)
Fortran does not offer call-by-name in the manner of the Algol language. It passes parameters by reference (i.e. by passing the storage address) and alternatively uses copy-in, copy-out to give the same effect, approximately, as by reference. If a parameter is an arithmetic expression, it will be evaluated and its value stored in a temporary storage area, whose address will be passed to the routine. This evaluation is done once only for each call, thus vitiating the repeated re-evaluation required by Jensen's device every time within the routine that the parameter is accessed. So, this will ''not'' work<syntaxhighlight lang="fortran"> FUNCTION SUM(I,LO,HI,TERM)
SUM = 0
SUM = 0
DO I = LO,HI
DO I = LO,HI
Line 647: Line 647:
END FUNCTION SUM
END FUNCTION SUM
WRITE (6,*) SUM(I,1,100,1.0/I)
WRITE (6,*) SUM(I,1,100,1.0/I)
END</lang>
END</syntaxhighlight>
Here, type declarations have been omitted to save space because they won't help - until there appears a "BY NAME" or some such phrasing. Although variable <code>I</code> in the calling routine will have its value adjusted as the DO-loop in SUM proceeds (the parameter being passed by reference), this won't affect the evaluation of 1.0/I, which will be performed once using whatever value is in the caller's variable (it is uninitialised, indeed, undeclared also and so by default an integer) then the function is invoked with the address of the location containing that result. The function will make many references to that result, obtaining the same value each time. The fact that the caller's <code>I</code> will be changed each time doesn't matter.
Here, type declarations have been omitted to save space because they won't help - until there appears a "BY NAME" or some such phrasing. Although variable <code>I</code> in the calling routine will have its value adjusted as the DO-loop in SUM proceeds (the parameter being passed by reference), this won't affect the evaluation of 1.0/I, which will be performed once using whatever value is in the caller's variable (it is uninitialised, indeed, undeclared also and so by default an integer) then the function is invoked with the address of the location containing that result. The function will make many references to that result, obtaining the same value each time. The fact that the caller's <code>I</code> will be changed each time doesn't matter.


Fortran does offer a facility to pass a function as a parameter using the EXTERNAL declaration, as follows - SUM is a F90 library function, so a name change to SUMJ: <lang Fortran> FUNCTION SUMJ(I,LO,HI,TERM) !Attempt to follow Jensen's Device...
Fortran does offer a facility to pass a function as a parameter using the EXTERNAL declaration, as follows - SUM is a F90 library function, so a name change to SUMJ: <syntaxhighlight lang="fortran"> FUNCTION SUMJ(I,LO,HI,TERM) !Attempt to follow Jensen's Device...
INTEGER I !Being by reference is workable.
INTEGER I !Being by reference is workable.
INTEGER LO,HI !Just as any other parameters.
INTEGER LO,HI !Just as any other parameters.
Line 670: Line 670:


WRITE (6,*) SUMJ(I,1,100,THIS) !No statement as to the parameters of THIS.
WRITE (6,*) SUMJ(I,1,100,THIS) !No statement as to the parameters of THIS.
END</lang>
END</syntaxhighlight>
The result of this is 5.187378, however it does not follow the formalism of Jensen's Device. The invocation statement SUMJ(I,1,100,THIS) does not contain the form of the function but only its name, and the function itself is defined separately. This means that the convenience of different functions via the likes of SUM(I,1,100,1.0/I**2) is unavailable, a separately-defined function with its own name must be defined for each such function. Further, the SUM routine must invoke TERM(I) itself, explicitly supplying the appropriate parameter. And the fact that variable <code>I</code> is a parameter to SUM is an irrelevance, and might as well be omitted from SUMJ.
The result of this is 5.187378, however it does not follow the formalism of Jensen's Device. The invocation statement SUMJ(I,1,100,THIS) does not contain the form of the function but only its name, and the function itself is defined separately. This means that the convenience of different functions via the likes of SUM(I,1,100,1.0/I**2) is unavailable, a separately-defined function with its own name must be defined for each such function. Further, the SUM routine must invoke TERM(I) itself, explicitly supplying the appropriate parameter. And the fact that variable <code>I</code> is a parameter to SUM is an irrelevance, and might as well be omitted from SUMJ.


Line 677: Line 677:


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>Sub Evaluation
<syntaxhighlight lang="freebasic">Sub Evaluation
Dim As Integer i, lo = 1, hi = 100
Dim As Integer i, lo = 1, hi = 100
Dim As Double temp = 0
Dim As Double temp = 0
Line 687: Line 687:


Evaluation
Evaluation
Sleep</lang>
Sleep</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 695: Line 695:


=={{header|Go}}==
=={{header|Go}}==
<lang go>package main
<syntaxhighlight lang="go">package main


import "fmt"
import "fmt"
Line 711: Line 711:
func main() {
func main() {
fmt.Printf("%f\n", sum(&i, 1, 100, func() float64 { return 1.0 / float64(i) }))
fmt.Printf("%f\n", sum(&i, 1, 100, func() float64 { return 1.0 / float64(i) }))
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 721: Line 721:
{{trans|JavaScript}}
{{trans|JavaScript}}
Solution:
Solution:
<lang groovy>def sum = { i, lo, hi, term ->
<syntaxhighlight lang="groovy">def sum = { i, lo, hi, term ->
(lo..hi).sum { i.value = it; term() }
(lo..hi).sum { i.value = it; term() }
}
}
def obj = [:]
def obj = [:]
println (sum(obj, 1, 100, { 1 / obj.value }))</lang>
println (sum(obj, 1, 100, { 1 / obj.value }))</syntaxhighlight>


Output:
Output:
Line 731: Line 731:


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang haskell>import Control.Monad.ST
<syntaxhighlight lang="haskell">import Control.Monad.ST
import Data.STRef
import Data.STRef


Line 744: Line 744:


main :: IO ()
main :: IO ()
main = print foo</lang>
main = print foo</syntaxhighlight>
{{Out}}
{{Out}}
<pre>5.187377517639621</pre>
<pre>5.187377517639621</pre>


=={{header|Huginn}}==
=={{header|Huginn}}==
<lang huginn>harmonic_sum( i, lo, hi, term ) {
<syntaxhighlight lang="huginn">harmonic_sum( i, lo, hi, term ) {
temp = 0.0;
temp = 0.0;
i *= 0.0;
i *= 0.0;
Line 763: Line 763:
i = 0.0;
i = 0.0;
print( "{}\n".format( harmonic_sum( i, 1.0, 100.0, @[i](){ 1.0 / i; } ) ) );
print( "{}\n".format( harmonic_sum( i, 1.0, 100.0, @[i](){ 1.0 / i; } ) ) );
}</lang>
}</syntaxhighlight>
{{Output}}<pre>5.18737751764</pre>
{{Output}}<pre>5.18737751764</pre>


Line 769: Line 769:
Traditional call by name and reference are not features of Icon/Unicon. Procedures parameters are passed by value (immutable types) and reference (mutable types). However, a similar effect may be accomplished by means of co-expressions. The example below was selected for cleanliness of calling.
Traditional call by name and reference are not features of Icon/Unicon. Procedures parameters are passed by value (immutable types) and reference (mutable types). However, a similar effect may be accomplished by means of co-expressions. The example below was selected for cleanliness of calling.


<lang Icon>record mutable(value) # record wrapper to provide mutable access to immutable types
<syntaxhighlight lang="icon">record mutable(value) # record wrapper to provide mutable access to immutable types


procedure main()
procedure main()
Line 781: Line 781:
temp +:= @^term
temp +:= @^term
return temp
return temp
end</lang>
end</syntaxhighlight>


Refreshing the co-expression above is more expensive to process but to avoid it requires unary alternation in the call.
Refreshing the co-expression above is more expensive to process but to avoid it requires unary alternation in the call.
<lang Icon> write( sum(A, 1, 100, create |1.0/A.value) )
<syntaxhighlight lang="icon"> write( sum(A, 1, 100, create |1.0/A.value) )
...
...
temp +:= @term</lang>
temp +:= @term</syntaxhighlight>


Alternately, we can use a programmer defined control operator (PDCO) approach that passes every argument as a co-expression. Again the refresh co-expression/unary iteration trade-off can be made. The call is cleaner looking but the procedure code is less clear. Additionally all the parameters are passed as individual co-expressions.
Alternately, we can use a programmer defined control operator (PDCO) approach that passes every argument as a co-expression. Again the refresh co-expression/unary iteration trade-off can be made. The call is cleaner looking but the procedure code is less clear. Additionally all the parameters are passed as individual co-expressions.
<lang Icon> write( sum{A.value, 1, 100, 1.0/A.value} )
<syntaxhighlight lang="icon"> write( sum{A.value, 1, 100, 1.0/A.value} )
...
...
procedure sum(X)
procedure sum(X)
...
...
every @X[1] := @X[2] to @X[3] do
every @X[1] := @X[2] to @X[3] do
temp +:= @^X[4]</lang>
temp +:= @^X[4]</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==
'''Solution:'''
'''Solution:'''
<lang j>jensen=: monad define
<syntaxhighlight lang="j">jensen=: monad define
'name lo hi expression'=. y
'name lo hi expression'=. y
temp=. 0
temp=. 0
Line 805: Line 805:
temp=. temp + ".expression
temp=. temp + ".expression
end.
end.
)</lang>
)</syntaxhighlight>
'''Example:'''
'''Example:'''
<lang j> jensen 'i';1;100;'1%i'
<syntaxhighlight lang="j"> jensen 'i';1;100;'1%i'
5.18738</lang>
5.18738</syntaxhighlight>


Note, however, that in J it is reasonably likely that the expression (or an obvious variation on the expression) can deal with the looping itself. And in typical use this often simplifies to entering the expression and data directly on the command line.
Note, however, that in J it is reasonably likely that the expression (or an obvious variation on the expression) can deal with the looping itself. And in typical use this often simplifies to entering the expression and data directly on the command line.
Line 817: Line 817:
This is Java 8.
This is Java 8.


<lang java>import java.util.function.*;
<syntaxhighlight lang="java">import java.util.function.*;
import java.util.stream.*;
import java.util.stream.*;


Line 829: Line 829:
}
}
}
}
</syntaxhighlight>
</lang>
The program prints '5.187377517639621'.
The program prints '5.187377517639621'.


Java 7 is more verbose, but under the hood does essentially the same thing:
Java 7 is more verbose, but under the hood does essentially the same thing:


<lang java>public class Jensen2 {
<syntaxhighlight lang="java">public class Jensen2 {


interface IntToDoubleFunction {
interface IntToDoubleFunction {
Line 855: Line 855:
}
}
}
}
</syntaxhighlight>
</lang>


=={{header|JavaScript}}==
=={{header|JavaScript}}==
Line 862: Line 862:
Uses an object ''o'' instead of integer pointer ''i'', as the C example does.
Uses an object ''o'' instead of integer pointer ''i'', as the C example does.


<lang javascript>var obj;
<syntaxhighlight lang="javascript">var obj;


function sum(o, lo, hi, term) {
function sum(o, lo, hi, term) {
Line 872: Line 872:


obj = {val: 0};
obj = {val: 0};
alert(sum(obj, 1, 100, function() {return 1 / obj.val}));</lang>
alert(sum(obj, 1, 100, function() {return 1 / obj.val}));</syntaxhighlight>
The alert shows us '5.187377517639621'.
The alert shows us '5.187377517639621'.


=={{header|Joy}}==
=={{header|Joy}}==
<syntaxhighlight lang=Joy>100 [0] [[1.0 swap /] dip +] primrec.</syntaxhighlight>
<syntaxhighlight lang="joy">100 [0] [[1.0 swap /] dip +] primrec.</syntaxhighlight>
Joy does not have named parameters.
Joy does not have named parameters.
Neither i nor 1/i are visible in the program.
Neither i nor 1/i are visible in the program.
Line 882: Line 882:
=={{header|jq}}==
=={{header|jq}}==
The technique used in the Javascript example can also be used in jq, but in jq it is more idiomatic to use "." to refer to the current term. For example, using sum/3 defined below, we can write: sum(1; 100; 1/.) to perform the task.
The technique used in the Javascript example can also be used in jq, but in jq it is more idiomatic to use "." to refer to the current term. For example, using sum/3 defined below, we can write: sum(1; 100; 1/.) to perform the task.
<lang jq>def sum(lo; hi; term):
<syntaxhighlight lang="jq">def sum(lo; hi; term):
reduce range(lo; hi+1) as $i (0; . + ($i|term));
reduce range(lo; hi+1) as $i (0; . + ($i|term));


# The task:
# The task:
sum(1;100;1/.)</lang>
sum(1;100;1/.)</syntaxhighlight>
{{Out}}
{{Out}}
$ jq -n -f jensen.jq
$ jq -n -f jensen.jq
Line 895: Line 895:
{{trans|C}}
{{trans|C}}


<lang julia>macro sum(i, loname, hiname, term)
<syntaxhighlight lang="julia">macro sum(i, loname, hiname, term)
return quote
return quote
lo = $loname
lo = $loname
Line 908: Line 908:


i = 0
i = 0
@sum(i, 1, 100, 1.0 / i)</lang>
@sum(i, 1, 100, 1.0 / i)</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
<lang scala>fun sum(lo: Int, hi: Int, f: (Int) -> Double) = (lo..hi).sumByDouble(f)
<syntaxhighlight lang="scala">fun sum(lo: Int, hi: Int, f: (Int) -> Double) = (lo..hi).sumByDouble(f)


fun main(args: Array<String>) = println(sum(1, 100, { 1.0 / it }))</lang>
fun main(args: Array<String>) = println(sum(1, 100, { 1.0 / it }))</syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==


<syntaxhighlight lang="lua">
<lang Lua>
function sum(var, a, b, str)
function sum(var, a, b, str)
local ret = 0
local ret = 0
Line 926: Line 926:
end
end
print(sum("i", 1, 100, "1/i"))
print(sum("i", 1, 100, "1/i"))
</syntaxhighlight>
</lang>


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
The definition of the lazy function has two statements. First statement is a Module with one argument, the actual name of Jensen`s_Device, which make the function to get the same scope as module Jensen`s_Device, and the second statement is =1/i which return the expression.
The definition of the lazy function has two statements. First statement is a Module with one argument, the actual name of Jensen`s_Device, which make the function to get the same scope as module Jensen`s_Device, and the second statement is =1/i which return the expression.


<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Jensen`s_Device {
Module Jensen`s_Device {
Def double i
Def double i
Line 946: Line 946:
}
}
Jensen`s_Device
Jensen`s_Device
</syntaxhighlight>
</lang>


Using Decimal for better accuracy. change &i to &any to show that: when any change, change i, so f() use this i.
Using Decimal for better accuracy. change &i to &any to show that: when any change, change i, so f() use this i.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Jensen`s_Device {
Module Jensen`s_Device {
Def decimal i
Def decimal i
Line 963: Line 963:
}
}
Jensen`s_Device
Jensen`s_Device
</syntaxhighlight>
</lang>


Many other examples use single float. So this is one for single.
Many other examples use single float. So this is one for single.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Jensen`s_Device {
Module Jensen`s_Device {
Def single i
Def single i
Line 980: Line 980:
}
}
Jensen`s_Device
Jensen`s_Device
</syntaxhighlight>
</lang>


=={{header|M4}}==
=={{header|M4}}==
<lang M4>define(`for',
<syntaxhighlight lang="m4">define(`for',
`ifelse($#,0,``$0'',
`ifelse($#,0,``$0'',
`ifelse(eval($2<=$3),1,
`ifelse(eval($2<=$3),1,
Line 990: Line 990:
`pushdef(`temp',0)`'for(`$1',$2,$3,
`pushdef(`temp',0)`'for(`$1',$2,$3,
`define(`temp',eval(temp+$4))')`'temp`'popdef(`temp')')
`define(`temp',eval(temp+$4))')`'temp`'popdef(`temp')')
sum(`i',1,100,`1000/i')</lang>
sum(`i',1,100,`1000/i')</syntaxhighlight>


Output:
Output:
Line 999: Line 999:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
=={{header|Mathematica}} / {{header|Wolfram Language}}==


<lang Mathematica>sum[term_, i_, lo_, hi_] := Block[{temp = 0},
<syntaxhighlight lang="mathematica">sum[term_, i_, lo_, hi_] := Block[{temp = 0},
Do[temp = temp + term, {i, lo, hi}];
Do[temp = temp + term, {i, lo, hi}];
temp];
temp];
SetAttributes[sum, HoldFirst];</lang>
SetAttributes[sum, HoldFirst];</syntaxhighlight>


Output:
Output:
Line 1,013: Line 1,013:


=={{header|Maxima}}==
=={{header|Maxima}}==
<lang maxima>mysum(e, v, lo, hi) := block([s: 0], for i from lo thru hi do s: s + subst(v=i, e), s)$
<syntaxhighlight lang="maxima">mysum(e, v, lo, hi) := block([s: 0], for i from lo thru hi do s: s + subst(v=i, e), s)$


mysum(1/n, n, 1, 10);
mysum(1/n, n, 1, 10);
Line 1,027: Line 1,027:
/* still works */
/* still works */
mysum(1/n, n, 1, 10);
mysum(1/n, n, 1, 10);
7381/2520</lang>
7381/2520</syntaxhighlight>


=={{header|NetRexx}}==
=={{header|NetRexx}}==
<lang netrexx>
<syntaxhighlight lang="netrexx">
import COM.ibm.netrexx.process.
import COM.ibm.netrexx.process.


Line 1,068: Line 1,068:
return Rexx termMethod.invoke(null,[iv])
return Rexx termMethod.invoke(null,[iv])
</syntaxhighlight>
</lang>


=={{header|Nim}}==
=={{header|Nim}}==
<lang nim>var i: int
<syntaxhighlight lang="nim">var i: int


proc harmonicSum(i: var int; lo, hi: int; term: proc: float): float =
proc harmonicSum(i: var int; lo, hi: int; term: proc: float): float =
Line 1,079: Line 1,079:
inc i
inc i


echo harmonicSum(i, 1, 100, proc: float = 1 / i)</lang>
echo harmonicSum(i, 1, 100, proc: float = 1 / i)</syntaxhighlight>


{{out}}
{{out}}
Line 1,085: Line 1,085:


=={{header|Objeck}}==
=={{header|Objeck}}==
<lang objeck>
<syntaxhighlight lang="objeck">
bundle Default {
bundle Default {
class Jensens {
class Jensens {
Line 1,109: Line 1,109:
}
}
}
}
</syntaxhighlight>
</lang>


Output: 5.18738
Output: 5.18738


=={{header|OCaml}}==
=={{header|OCaml}}==
<lang ocaml>let i = ref 42 (* initial value doesn't matter *)
<syntaxhighlight lang="ocaml">let i = ref 42 (* initial value doesn't matter *)


let sum' i lo hi term =
let sum' i lo hi term =
Line 1,126: Line 1,126:


let () =
let () =
Printf.printf "%f\n" (sum' i 1 100 (fun () -> 1. /. float !i))</lang>
Printf.printf "%f\n" (sum' i 1 100 (fun () -> 1. /. float !i))</syntaxhighlight>
Output: 5.187378
Output: 5.187378


=={{header|Oforth}}==
=={{header|Oforth}}==


<lang Oforth>: mysum(lo, hi, term) | i | 0 lo hi for: i [ i term perform + ] ;</lang>
<syntaxhighlight lang="oforth">: mysum(lo, hi, term) | i | 0 lo hi for: i [ i term perform + ] ;</syntaxhighlight>


{{out}}
{{out}}
Line 1,144: Line 1,144:
=={{header|Oz}}==
=={{header|Oz}}==
Translation using mutable references and an anonymous function:
Translation using mutable references and an anonymous function:
<lang oz>declare
<syntaxhighlight lang="oz">declare
fun {Sum I Lo Hi Term}
fun {Sum I Lo Hi Term}
Temp = {NewCell 0.0}
Temp = {NewCell 0.0}
Line 1,157: Line 1,157:
I = {NewCell unit}
I = {NewCell unit}
in
in
{Show {Sum I 1 100 fun {$} 1.0 / {Int.toFloat @I} end}}</lang>
{Show {Sum I 1 100 fun {$} 1.0 / {Int.toFloat @I} end}}</syntaxhighlight>


Idiomatic code:
Idiomatic code:
<lang oz>declare
<syntaxhighlight lang="oz">declare
fun {Sum Lo Hi F}
fun {Sum Lo Hi F}
{FoldL {Map {List.number Lo Hi 1} F} Number.'+' 0.0}
{FoldL {Map {List.number Lo Hi 1} F} Number.'+' 0.0}
end
end
in
in
{Show {Sum 1 100 fun {$ I} 1.0/{Int.toFloat I} end}}</lang>
{Show {Sum 1 100 fun {$ I} 1.0/{Int.toFloat I} end}}</syntaxhighlight>


=={{header|PARI/GP}}==
=={{header|PARI/GP}}==
Line 1,171: Line 1,171:


=={{header|Pascal}}==
=={{header|Pascal}}==
<lang pascal>program Jensens_Device;
<syntaxhighlight lang="pascal">program Jensens_Device;


{$IFDEF FPC}
{$IFDEF FPC}
Line 1,202: Line 1,202:
writeln(sum(i, 1, 100, @term));
writeln(sum(i, 1, 100, @term));
{$IFNDEF UNIX} readln; {$ENDIF}
{$IFNDEF UNIX} readln; {$ENDIF}
end.</lang>
end.</syntaxhighlight>
Out
Out
<pre> 5.1873775176396206E+000</pre>
<pre> 5.1873775176396206E+000</pre>


=={{header|Perl}}==
=={{header|Perl}}==
<lang perl>my $i;
<syntaxhighlight lang="perl">my $i;
sub sum {
sub sum {
my ($i, $lo, $hi, $term) = @_;
my ($i, $lo, $hi, $term) = @_;
Line 1,217: Line 1,217:
}
}


print sum(\$i, 1, 100, sub { 1 / $i }), "\n";</lang>
print sum(\$i, 1, 100, sub { 1 / $i }), "\n";</syntaxhighlight>
Output: 5.18737751763962
Output: 5.18737751763962


Or you can take advantage of the fact that elements of the @_ are aliases of the original:
Or you can take advantage of the fact that elements of the @_ are aliases of the original:
<lang perl>my $i;
<syntaxhighlight lang="perl">my $i;
sub sum {
sub sum {
my (undef, $lo, $hi, $term) = @_;
my (undef, $lo, $hi, $term) = @_;
Line 1,231: Line 1,231:
}
}


print sum($i, 1, 100, sub { 1 / $i }), "\n";</lang>
print sum($i, 1, 100, sub { 1 / $i }), "\n";</syntaxhighlight>
Output: 5.18737751763962
Output: 5.18737751763962


Line 1,238: Line 1,238:
I could also have done what C and PHP are doing, though in Phix I'd have to explicitly assign the static var within the loop.<br>
I could also have done what C and PHP are doing, though in Phix I'd have to explicitly assign the static var within the loop.<br>
I wholeheartedly agree with the comment on the Clipper example.
I wholeheartedly agree with the comment on the Clipper example.
<!--<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;">sumr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">lo</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hi</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">sumr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">lo</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hi</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">)</span>
Line 1,251: Line 1,251:
<span style="color: #0000FF;">?</span><span style="color: #000000;">sumr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">reciprocal</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">sumr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">reciprocal</span><span style="color: #0000FF;">)</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 1,258: Line 1,258:


=={{header|PHP}}==
=={{header|PHP}}==
<lang php>$i;
<syntaxhighlight lang="php">$i;
function sum (&$i, $lo, $hi, $term) {
function sum (&$i, $lo, $hi, $term) {
$temp = 0;
$temp = 0;
Line 1,282: Line 1,282:


//Output: 5.1873775176396
//Output: 5.1873775176396
</syntaxhighlight>
</lang>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<lang PicoLisp>(scl 6)
<syntaxhighlight lang="picolisp">(scl 6)


(de jensen (I Lo Hi Term)
(de jensen (I Lo Hi Term)
Line 1,298: Line 1,298:
(format
(format
(jensen I 1 100 '(() (*/ 1.0 (val I))))
(jensen I 1 100 '(() (*/ 1.0 (val I))))
*Scl ) )</lang>
*Scl ) )</syntaxhighlight>
Output:
Output:
<pre>-> "5.187383"</pre>
<pre>-> "5.187383"</pre>
Line 1,304: Line 1,304:
=={{header|PureBasic}}==
=={{header|PureBasic}}==
{{trans|C}}
{{trans|C}}
<lang PureBasic>Prototype.d func()
<syntaxhighlight lang="purebasic">Prototype.d func()


Global i
Global i
Line 1,320: Line 1,320:
EndProcedure
EndProcedure


Answer.d = Sum(@i, 1, 100, @term_func())</lang>
Answer.d = Sum(@i, 1, 100, @term_func())</syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
<lang python>class Ref(object):
<syntaxhighlight lang="python">class Ref(object):
def __init__(self, value=None):
def __init__(self, value=None):
self.value = value
self.value = value
Line 1,340: Line 1,340:
# note the correspondence between the mathematical notation and the
# note the correspondence between the mathematical notation and the
# call to sum it's almost as good as sum(1/i for i in range(1,101))
# call to sum it's almost as good as sum(1/i for i in range(1,101))
print harmonic_sum(i, 1, 100, lambda: 1.0/i.value)</lang>
print harmonic_sum(i, 1, 100, lambda: 1.0/i.value)</syntaxhighlight>


or
or


<lang python>
<syntaxhighlight lang="python">
def harmonic_sum(i, lo, hi, term):
def harmonic_sum(i, lo, hi, term):
return sum(term() for i[0] in range(lo, hi + 1))
return sum(term() for i[0] in range(lo, hi + 1))
Line 1,350: Line 1,350:
i = [0]
i = [0]
print(harmonic_sum(i, 1, 100, lambda: 1.0 / i[0]))
print(harmonic_sum(i, 1, 100, lambda: 1.0 / i[0]))
</syntaxhighlight>
</lang>


or
or


<lang python>
<syntaxhighlight lang="python">
def harmonic_sum(i, lo, hi, term):
def harmonic_sum(i, lo, hi, term):
return sum(eval(term) for i[0] in range(lo, hi + 1))
return sum(eval(term) for i[0] in range(lo, hi + 1))
Line 1,360: Line 1,360:
i = [0]
i = [0]
print(harmonic_sum(i, 1, 100, "1.0 / i[0]"))
print(harmonic_sum(i, 1, 100, "1.0 / i[0]"))
</syntaxhighlight>
</lang>


Output: 5.18737751764
Output: 5.18737751764
Line 1,370: Line 1,370:
of a function; however, ignoring conventions we can come disturbingly close to the ALGOL call-by-name semantics.
of a function; however, ignoring conventions we can come disturbingly close to the ALGOL call-by-name semantics.


<lang R>sum <- function(var, lo, hi, term)
<syntaxhighlight lang="r">sum <- function(var, lo, hi, term)
eval(substitute({
eval(substitute({
.temp <- 0;
.temp <- 0;
Line 1,384: Line 1,384:
##and because of enclos=parent.frame(), the term can involve variables in the caller's scope:
##and because of enclos=parent.frame(), the term can involve variables in the caller's scope:
x <- -1
x <- -1
sum(i, 1, 100, i^x) #5.187378</lang>
sum(i, 1, 100, i^x) #5.187378</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==
Line 1,390: Line 1,390:
be written just as Jørn Jensen did at Regnecentralen.
be written just as Jørn Jensen did at Regnecentralen.


<lang racket>
<syntaxhighlight lang="racket">
#lang algol60
#lang algol60
begin
begin
Line 1,409: Line 1,409:
printnln (sum (i, 1, 100, 1/i))
printnln (sum (i, 1, 100, 1/i))
end
end
</syntaxhighlight>
</lang>


But of course you can also use the more boring popular alternative of first class functions:
But of course you can also use the more boring popular alternative of first class functions:


<lang racket>
<syntaxhighlight lang="racket">
#lang racket/base
#lang racket/base
(define (sum lo hi f)
(define (sum lo hi f)
(for/sum ([i (in-range lo (add1 hi))]) (f i)))
(for/sum ([i (in-range lo (add1 hi))]) (f i)))
(sum 1 100 (λ(i) (/ 1.0 i)))
(sum 1 100 (λ(i) (/ 1.0 i)))
</syntaxhighlight>
</lang>


=={{header|Raku}}==
=={{header|Raku}}==
Line 1,424: Line 1,424:


Rather than playing tricks like Perl&nbsp;5 does, the declarations of the formal parameters are quite straightforward in Raku:
Rather than playing tricks like Perl&nbsp;5 does, the declarations of the formal parameters are quite straightforward in Raku:
<lang perl6>sub sum($i is rw, $lo, $hi, &term) {
<syntaxhighlight lang="raku" line>sub sum($i is rw, $lo, $hi, &term) {
my $temp = 0;
my $temp = 0;
loop ($i = $lo; $i <= $hi; $i++) {
loop ($i = $lo; $i <= $hi; $i++) {
Line 1,433: Line 1,433:


my $i;
my $i;
say sum $i, 1, 100, { 1 / $i };</lang>
say sum $i, 1, 100, { 1 / $i };</syntaxhighlight>
Note that the C-style "for" loop is pronounced "loop" in Raku, and is the only loop statement that actually requires parens.
Note that the C-style "for" loop is pronounced "loop" in Raku, and is the only loop statement that actually requires parens.


=={{header|Rascal}}==
=={{header|Rascal}}==
<lang rascal>public num Jenssen(int lo, int hi, num (int i) term){
<syntaxhighlight lang="rascal">public num Jenssen(int lo, int hi, num (int i) term){
temp = 0;
temp = 0;
while (lo <= hi){
while (lo <= hi){
Line 1,443: Line 1,443:
lo += 1;}
lo += 1;}
return temp;
return temp;
}</lang>
}</syntaxhighlight>


With as output:
With as output:


<lang rascal>rascal>Jenssen(1, 100, num(int i){return 1.0/i;})
<syntaxhighlight lang="rascal">rascal>Jenssen(1, 100, num(int i){return 1.0/i;})
num: 5.18737751763962026080511767565825315790897212670845165317653395662</lang>
num: 5.18737751763962026080511767565825315790897212670845165317653395662</syntaxhighlight>


=={{header|REXX}}==
=={{header|REXX}}==
<lang rexx>/*REXX program demonstrates Jensen's device (via call subroutine, and args by name). */
<syntaxhighlight lang="rexx">/*REXX program demonstrates Jensen's device (via call subroutine, and args by name). */
parse arg d . /*obtain optional argument from the CL.*/
parse arg d . /*obtain optional argument from the CL.*/
if d=='' | d=="," then d= 100 /*Not specified? Then use the default.*/
if d=='' | d=="," then d= 100 /*Not specified? Then use the default.*/
Line 1,467: Line 1,467:
/*comment lit var lit var lit var literal var literal */
/*comment lit var lit var lit var literal var literal */


return $</lang>
return $</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
{{out|output|text=&nbsp; when using the default input:}}
<pre>
<pre>
Line 1,488: Line 1,488:


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
# Project : Jensen's Device
# Project : Jensen's Device


Line 1,502: Line 1,502:
next
next
return temp
return temp
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 1,510: Line 1,510:
=={{header|Ruby}}==
=={{header|Ruby}}==
Here, setting the variable and evaluating the term are truly executed in the "outer" context:
Here, setting the variable and evaluating the term are truly executed in the "outer" context:
<lang ruby>def sum(var, lo, hi, term, context)
<syntaxhighlight lang="ruby">def sum(var, lo, hi, term, context)
sum = 0.0
sum = 0.0
lo.upto(hi) do |n|
lo.upto(hi) do |n|
Line 1,517: Line 1,517:
sum
sum
end
end
p sum "i", 1, 100, "1.0 / i", binding # => 5.18737751763962</lang>
p sum "i", 1, 100, "1.0 / i", binding # => 5.18737751763962</syntaxhighlight>


But here is the Ruby way to do it:
But here is the Ruby way to do it:
<lang ruby>def sum2(lo, hi)
<syntaxhighlight lang="ruby">def sum2(lo, hi)
lo.upto(hi).inject(0.0) {|sum, n| sum += yield n}
lo.upto(hi).inject(0.0) {|sum, n| sum += yield n}
end
end
p sum2(1, 100) {|i| 1.0/i} # => 5.18737751763962</lang>
p sum2(1, 100) {|i| 1.0/i} # => 5.18737751763962</syntaxhighlight>


Even more concise: (requires ruby >= 2.4)
Even more concise: (requires ruby >= 2.4)
<lang ruby>
<syntaxhighlight lang="ruby">
def sum lo, hi, &term
def sum lo, hi, &term
(lo..hi).sum(&term)
(lo..hi).sum(&term)
Line 1,533: Line 1,533:
# or using Rational:
# or using Rational:
p sum(1,100){|i| Rational(1,i)} # => 14466636279520351160221518043104131447711 / 2788815009188499086581352357412492142272
p sum(1,100){|i| Rational(1,i)} # => 14466636279520351160221518043104131447711 / 2788815009188499086581352357412492142272
</syntaxhighlight>
</lang>


=={{header|Rust}}==
=={{header|Rust}}==
<lang rust>
<syntaxhighlight lang="rust">
use std::f32;
use std::f32;


Line 1,550: Line 1,550:
}
}


</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,563: Line 1,563:
class, which is effectively the same as passing by reference.
class, which is effectively the same as passing by reference.


<lang scala>class MyInt { var i: Int = _ }
<syntaxhighlight lang="scala">class MyInt { var i: Int = _ }
val i = new MyInt
val i = new MyInt
def sum(i: MyInt, lo: Int, hi: Int, term: => Double) = {
def sum(i: MyInt, lo: Int, hi: Int, term: => Double) = {
Line 1,574: Line 1,574:
temp
temp
}
}
sum(i, 1, 100, 1.0 / i.i)</lang>
sum(i, 1, 100, 1.0 / i.i)</syntaxhighlight>


Result:
Result:
Line 1,585: Line 1,585:
Scheme procedures do not support call-by-name. Scheme macros, however, do:
Scheme procedures do not support call-by-name. Scheme macros, however, do:


<lang scheme>
<syntaxhighlight lang="scheme">
(define-syntax sum
(define-syntax sum
(syntax-rules ()
(syntax-rules ()
Line 1,595: Line 1,595:
(loop (+ var 1)
(loop (+ var 1)
(+ result . body)))))))
(+ result . body)))))))
</syntaxhighlight>
</lang>


<pre>
<pre>
Line 1,605: Line 1,605:
Seed7 supports call-by-name with function parameters:
Seed7 supports call-by-name with function parameters:


<lang seed7>
<syntaxhighlight lang="seed7">
$ include "seed7_05.s7i";
$ include "seed7_05.s7i";
include "float.s7i";
include "float.s7i";
Line 1,625: Line 1,625:
writeln(sum(i, 1, 100, 1.0/flt(i)) digits 6);
writeln(sum(i, 1, 100, 1.0/flt(i)) digits 6);
end func;
end func;
</syntaxhighlight>
</lang>


Output:
Output:
Line 1,633: Line 1,633:


=={{header|Sidef}}==
=={{header|Sidef}}==
<lang ruby>var i;
<syntaxhighlight lang="ruby">var i;
func sum (i, lo, hi, term) {
func sum (i, lo, hi, term) {
var temp = 0;
var temp = 0;
Line 1,641: Line 1,641:
return temp;
return temp;
};
};
say sum(\i, 1, 100, { 1 / i });</lang>
say sum(\i, 1, 100, { 1 / i });</syntaxhighlight>
{{out}}
{{out}}
<pre>5.18737751763962026080511767565825315790899</pre>
<pre>5.18737751763962026080511767565825315790899</pre>
Line 1,648: Line 1,648:
{{trans|algol60}}
{{trans|algol60}}
{{works with|SIMULA-67}}
{{works with|SIMULA-67}}
Compare with Algol 60, in Simula 67 'call by name' is specified with '''name'''. It is a true 'call by name' evaluation not a 'procedure parameter' emulation.<lang simula>comment Jensen's Device;
Compare with Algol 60, in Simula 67 'call by name' is specified with '''name'''. It is a true 'call by name' evaluation not a 'procedure parameter' emulation.<syntaxhighlight lang="simula">comment Jensen's Device;
begin
begin
integer i;
integer i;
Line 1,670: Line 1,670:
comment note the correspondence between the mathematical notation and the call to sum;
comment note the correspondence between the mathematical notation and the call to sum;
outreal (sum (i, 1, 100, 1/i), 7, 14)
outreal (sum (i, 1, 100, 1/i), 7, 14)
end</lang>
end</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,677: Line 1,677:


=={{header|Standard ML}}==
=={{header|Standard ML}}==
<lang sml>val i = ref 42 (* initial value doesn't matter *)
<syntaxhighlight lang="sml">val i = ref 42 (* initial value doesn't matter *)


fun sum' (i, lo, hi, term) = let
fun sum' (i, lo, hi, term) = let
Line 1,691: Line 1,691:


val () =
val () =
print (Real.toString (sum' (i, 1, 100, fn () => 1.0 / real (!i))) ^ "\n")</lang>
print (Real.toString (sum' (i, 1, 100, fn () => 1.0 / real (!i))) ^ "\n")</syntaxhighlight>
Output: 5.18737751764
Output: 5.18737751764


=={{header|Swift}}==
=={{header|Swift}}==
<lang swift>var i = 42 // initial value doesn't matter
<syntaxhighlight lang="swift">var i = 42 // initial value doesn't matter


func sum(inout i: Int, lo: Int, hi: Int, @autoclosure term: () -> Double) -> Double {
func sum(inout i: Int, lo: Int, hi: Int, @autoclosure term: () -> Double) -> Double {
Line 1,705: Line 1,705:
}
}


println(sum(&i, 1, 100, 1 / Double(i)))</lang>
println(sum(&i, 1, 100, 1 / Double(i)))</syntaxhighlight>
(Prior to Swift 1.2, replace <code>@autoclosure term: () -> Double</code> with <code>term: @autoclosure () -> Double</code>.)
(Prior to Swift 1.2, replace <code>@autoclosure term: () -> Double</code> with <code>term: @autoclosure () -> Double</code>.)
{{out}}
{{out}}
Line 1,712: Line 1,712:
=={{header|Tcl}}==
=={{header|Tcl}}==
Here, we set the value of the passed variable in the caller's frame. We then evaluate the passed term there too.
Here, we set the value of the passed variable in the caller's frame. We then evaluate the passed term there too.
<lang tcl>proc sum {var lo hi term} {
<syntaxhighlight lang="tcl">proc sum {var lo hi term} {
upvar 1 $var x
upvar 1 $var x
set sum 0.0
set sum 0.0
Line 1,720: Line 1,720:
return $sum
return $sum
}
}
puts [sum i 1 100 {1.0/$i}] ;# 5.177377517639621</lang>
puts [sum i 1 100 {1.0/$i}] ;# 5.177377517639621</syntaxhighlight>
However, the solution is expressed more simply like this
However, the solution is expressed more simply like this
<lang tcl>proc sum2 {lo hi lambda} {
<syntaxhighlight lang="tcl">proc sum2 {lo hi lambda} {
set sum 0.0
set sum 0.0
for {set n $lo} {$n < $hi} {incr n} {
for {set n $lo} {$n < $hi} {incr n} {
Line 1,729: Line 1,729:
return $sum
return $sum
}
}
puts [sum2 1 100 {i {expr {1.0/$i}}}] ;# 5.177377517639621</lang>
puts [sum2 1 100 {i {expr {1.0/$i}}}] ;# 5.177377517639621</syntaxhighlight>


=={{header|VBA}}==
=={{header|VBA}}==
<syntaxhighlight lang="vb">
<lang vb>
Private Function sum(i As String, ByVal lo As Integer, ByVal hi As Integer, term As String) As Double
Private Function sum(i As String, ByVal lo As Integer, ByVal hi As Integer, term As String) As Double
Dim temp As Double
Dim temp As Double
Line 1,745: Line 1,745:
Debug.Print sum("j", 1, 100, "sin(j)")
Debug.Print sum("j", 1, 100, "sin(j)")
End Sub
End Sub
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,755: Line 1,755:
=={{header|Wren}}==
=={{header|Wren}}==
As Wren doesn't support call by name, call by reference nor pointers we need to 'box' the global numeric variable 'i' and use a function for 'term' to simulate Jensen's device. This works because all user defined types are reference types and functions can capture external variables.
As Wren doesn't support call by name, call by reference nor pointers we need to 'box' the global numeric variable 'i' and use a function for 'term' to simulate Jensen's device. This works because all user defined types are reference types and functions can capture external variables.
<lang ecmascript>class Box {
<syntaxhighlight lang="ecmascript">class Box {
construct new(v) { _v = v }
construct new(v) { _v = v }
v { _v }
v { _v }
Line 1,774: Line 1,774:


var s = sum.call(i, 1, 100, Fn.new { 1/i.v })
var s = sum.call(i, 1, 100, Fn.new { 1/i.v })
System.print(s)</lang>
System.print(s)</syntaxhighlight>


{{out}}
{{out}}
Line 1,784: Line 1,784:
=={{header|Yabasic}}==
=={{header|Yabasic}}==
{{trans|FreeBASIC}}
{{trans|FreeBASIC}}
<lang Yabasic>sub Evaluation()
<syntaxhighlight lang="yabasic">sub Evaluation()
lo = 1 : hi = 100 : temp = 0
lo = 1 : hi = 100 : temp = 0
for i = lo to hi
for i = lo to hi
Line 1,792: Line 1,792:
end sub
end sub


Evaluation()</lang>
Evaluation()</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,801: Line 1,801:
=={{header|zkl}}==
=={{header|zkl}}==
zkl doesn't support call by name/address but does have reference objects. Using an explicit call to term:
zkl doesn't support call by name/address but does have reference objects. Using an explicit call to term:
<lang zkl>fcn sum(ri, lo,hi, term){
<syntaxhighlight lang="zkl">fcn sum(ri, lo,hi, term){
temp:=0.0; ri.set(lo);
temp:=0.0; ri.set(lo);
do{ temp+=term(ri); } while(ri.inc()<hi); // inc return previous value
do{ temp+=term(ri); } while(ri.inc()<hi); // inc return previous value
return(temp);
return(temp);
}
}
sum(Ref(0), 1,100, fcn(ri){ 1.0/ri.value }).println();</lang>
sum(Ref(0), 1,100, fcn(ri){ 1.0/ri.value }).println();</syntaxhighlight>
Using function application/deferred(lazy) objects, we can make the function call implicit (addition forces evaluation of the LHS):
Using function application/deferred(lazy) objects, we can make the function call implicit (addition forces evaluation of the LHS):
<lang zkl>fcn sum2(ri, lo,hi, term){
<syntaxhighlight lang="zkl">fcn sum2(ri, lo,hi, term){
temp:=0.0; ri.set(lo);
temp:=0.0; ri.set(lo);
do{ temp=term + temp; } while(ri.inc()<hi); // inc return previous value
do{ temp=term + temp; } while(ri.inc()<hi); // inc return previous value
Line 1,814: Line 1,814:
}
}
ri:=Ref(0);
ri:=Ref(0);
sum2(ri, 1,100, 'wrap(){ 1.0/ri.value }).println();</lang>
sum2(ri, 1,100, 'wrap(){ 1.0/ri.value }).println();</syntaxhighlight>
In this case, we can call sum or sum2 and it does the same thing (the ri parameter will be ignored).
In this case, we can call sum or sum2 and it does the same thing (the ri parameter will be ignored).


Of course, as others have pointed out, this can be expressed very simply:
Of course, as others have pointed out, this can be expressed very simply:
<lang zkl>fcn sum3(lo,hi, term){ [lo..hi].reduce('wrap(sum,i){ sum + term(i) },0.0) }
<syntaxhighlight lang="zkl">fcn sum3(lo,hi, term){ [lo..hi].reduce('wrap(sum,i){ sum + term(i) },0.0) }
sum3(1,100, fcn(i){ 1.0/i }).println();</lang>
sum3(1,100, fcn(i){ 1.0/i }).println();</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,828: Line 1,828:


=={{header|ZX Spectrum Basic}}==
=={{header|ZX Spectrum Basic}}==
<lang zxbasic>10 DEF FN r(x)=1/x
<syntaxhighlight lang="zxbasic">10 DEF FN r(x)=1/x
20 LET f$="FN r(i)"
20 LET f$="FN r(i)"
30 LET lo=1: LET hi=100
30 LET lo=1: LET hi=100
Line 1,840: Line 1,840:
1040 NEXT i
1040 NEXT i
1050 RETURN
1050 RETURN
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>