First-class functions: Difference between revisions

m
imported>Arakov
(8 intermediate revisions by 6 users not shown)
Line 1,135:
 
=={{header|Elena}}==
ELENA 56.0x :
<syntaxhighlight lang="elena">import system'routines;
import system'math;
Line 1,153:
fs.zipBy(gs, (f,g => 0.5r.compose(f,g)))
.forEach:(printingLn)
}</syntaxhighlight>
{{out}}
Line 1,750:
jq does not support functions as "first class objects" in the sense specified in the task description
but it does give near-first-class status to functions and functional expressions, which can
for example, be passed as arguments to functions. In fact, it is quite straightforward, though possibly misleading,
to transcribe the [[#Wren|Wren]] entry to jq, as follows:
<syntaxhighlight lang=jq>
Line 1,798:
 
=={{header|Kotlin}}==
 
<syntaxhighlight lang="scala">// version 1.0.6
<syntaxhighlight lang="kotlin">
import kotlin.math.*
 
fun compose(f: (Double) -> Double, g: (Double) -> Double ): (Double) -> Double = { f(g(it)) }
Line 1,804 ⟶ 1,806:
fun cube(d: Double) = d * d * d
 
fun main(args: Array<String>) {
val listA = listOf(Math::sin, Math::cos, ::cube)
val listB = listOf(Math::asin, Math::acos, Math::cbrt)
val x = 0.5
for (i in 0..2) println(compose(listA[i], listB[i])(x))
Line 1,835 ⟶ 1,837:
0.49999999999999994
0.5000000000000001
</syntaxhighlight>
 
=={{header|Lang}}==
<syntaxhighlight lang="lang">
fp.cube = ($x) -> return parser.op($x ** 3)
 
fp.cuberoot = ($x) -> return parser.op($x ** (1/3))
 
# fn.concat can be used as compose
 
&funcs $= [fn.sin, fn.cos, fp.cube]
&invFuncs $= [fn.asin, fn.acos, fp.cuberoot]
 
$pair
foreach($[pair], fn.arrayZip(&funcs, &invFuncs)) {
parser.op(fn.println(($pair[0] ||| $pair[1])(.5)))
}
</syntaxhighlight>
 
Line 2,538 ⟶ 2,557:
{{Out}}
<pre>[0.49999999999999994, 0.5000000000000001, 0.5000000000000001]</pre>
 
=={{header|Quackery}}==
 
Preamble. Quackery has first class functions, but it doesn't have floating point numbers.
 
However, as it is implemented in Python, we can drop down into Python for that functionality, and represent floating point numbers as strings in Quackery. This code implements that, with a light sprinkle of syntactic sugar for the compiler so we can use <code>f 0.5</code> rather than <code>$ "0.5"</code> to represent the floating point number <code>0.5</code>
 
<syntaxhighlight lang="Quackery"> [ $ \
try:
float(string_from_stack())
except:
to_stack(False)
else:
to_stack(True)
\ python ] is isfloat ( $ --> b )
 
[ nextword
dup isfloat not if
[ $ '"f" needs to be followed by a number.'
message put bail ]
' [ ' ] swap nested join
nested swap dip join ] builds f ( [ $ --> [ $ )
 
[ $ \
import math
a = string_from_stack()
a = str(math.sin(float(a)))
string_to_stack(a) \ python ] is sin ( $ --> $ )
 
[ $ \
import math
a = string_from_stack()
a = str(math.asin(float(a)))
string_to_stack(a) \ python ] is asin ( $ --> $ )
 
[ $ \
import math
a = string_from_stack()
a = str(math.cos(float(a)))
string_to_stack(a) \ python ] is cos ( $ --> $ )
 
[ $ \
import math
a = string_from_stack()
a = str(math.acos(float(a)))
string_to_stack(a) \ python ] is acos ( $ --> $ )
 
[ $ \
a = string_from_stack()
b = string_from_stack()
c = str(float(b) * float(a))
string_to_stack(c) \ python ] is f* ( $ $ --> $ )
 
[ $ \
a = string_from_stack()
b = string_from_stack()
c = str(float(b) / float(a))
string_to_stack(c) \ python ] is f/ ( $ $ --> $ )
 
[ $ \
a = string_from_stack()
b = string_from_stack()
c = str(float(b) ** float(a))
string_to_stack(c) \ python ] is f** ( $ $ --> $ )</syntaxhighlight>
 
…and now the task…
 
<syntaxhighlight lang="Quackery"> [ dup dup f* f* ] is cubed ( $ --> $ )
 
[ f 1 f 3 f/ f** ] is cuberoot ( $ --> $ )
 
[ table sin cos cubed ] is A ( n --> [ )
 
[ table asin acos cuberoot ] is B ( n --> [ )
 
[ dip nested nested join ] is compose ( x x --> [ )
 
[ dup dip A B compose do ] is ->A->B-> ( f n --> f )
 
' [ f 0.5 f 1.234567 ]
witheach
[ do 3 times
[ dup echo$
say " -> "
i^ A echo
say " -> "
i^ B echo
say " -> "
dup i^ ->A->B-> echo$
cr ]
drop cr ]</syntaxhighlight>
 
{{out}}
 
<pre>0.5 -> sin -> asin -> 0.5
0.5 -> cos -> acos -> 0.4999999999999999
0.5 -> cubed -> cuberoot -> 0.5
 
1.234567 -> sin -> asin -> 1.234567
1.234567 -> cos -> acos -> 1.234567
1.234567 -> cubed -> cuberoot -> 1.234567</pre>
 
=={{header|R}}==
Line 2,584 ⟶ 2,704:
=={{header|Raku}}==
(formerly Perl 6)
Here we use the <tt>Z</tt> ("zipwith") metaoperator to zip the 𝐴 and 𝐵 lists with abuiltin user-definedcomposition compose functionoperator, expressed<tt>∘</tt> as(or an infix operator,just <tt>o</tt>). The <tt>.()</tt> construct invokes the function contained in the <tt>$_</tt> (current topic) variable.
<syntaxhighlight lang="raku" line>sub infix:<∘> (&𝑔, &𝑓) { -> \x { 𝑔 𝑓 x } }
 
<syntaxhighlight lang="raku" line>my \𝐴 = &sin, &cos, { $_ ** <3/1> }
my \𝐵 = &asin, &acos, { $_ ** <1/3> }
 
say .(.5) for 𝐴 Z∘ 𝐵</syntaxhighlight>
 
Output:
{{output}}
<pre>0.5
0.4999999999999999
0.5
0.5000000000000001
0.5</pre>
</pre>
 
It is not clear why we don't get exactly 0.5, here.
 
Operators, both buildinbuiltin and user-defined, are first class too.
 
<syntaxhighlight lang="raku" line>my @a = 1,2,3;
Line 3,118 ⟶ 3,241:
=={{header|Wren}}==
In Wren, there is a distinction between functions and methods. Essentially, the former are independent objects which can do all the things required of 'first class functions' and the latter are subroutines which are tied to a particular class. As sin, cos etc. are instance methods of the Num class, we need to wrap them in functions to complete this task.
<syntaxhighlight lang="ecmascriptwren">var compose = Fn.new { |f, g| Fn.new { |x| f.call(g.call(x)) } }
 
var A = [
Anonymous user