Function composition: Difference between revisions

m
m (syntax hghlighting fixup automation)
 
(19 intermediate revisions by 13 users not shown)
Line 183:
F sin arc sin = compose(sin, arc sin);
print((sin arc sin(0.5), (sin O arc sin)(0.5), new line))</syntaxhighlight>
 
=={{header|Amazing Hopper}}==
VERSION 1:
<syntaxhighlight lang="c">
#defn Compose(_FX_,_FY_) _FX_,_FY_
 
main:
0.5,Compose(sin,arcsin)
"\n", print
{0}return
</syntaxhighlight>
{{out}}
<pre>
$ hopper3 basica/compose1.hop
0.500000
 
</pre>
VERSION 2:
<syntaxhighlight lang="c">
#define-a «(_X_) _X_ )
#define Compose(_FX_,_FY_) _FC_(_FX_,_FY_,
#define _FC_(_X_,_Y_,*) *,_X_,_Y_
 
main:
Compose(sin,arcsin)«( 0.5)
"\n", print
{0}return
</syntaxhighlight>
{{out}}
<pre>
$ hopper3 basica/compose2.hop
0.500000
 
</pre>
 
VERSION 3:
<syntaxhighlight lang="c">
#define «(_X_) _X_ )
#define Compose(_FX_,_FY_) _FC_(_FX_,_FY_,
#define _FC_(_X_,_Y_,*) *,_X_,_Y_
 
main:
Compose(sin,arcsin)«( 0.5, mul by '2' )
"\n", print
{0}return
</syntaxhighlight>
{{out}}
<pre>
$ hopper3 basica/compose2.hop
1.000000
 
</pre>
<p>The power of macro-substitution, by Hopper!</p>
 
=={{header|AntLang}}==
Line 550 ⟶ 603:
{{out}} on Android phone:
<syntaxhighlight lang="bori">0.500000000</syntaxhighlight>
 
=={{header|Binary Lambda Calculus}}==
 
In lambda calculus, the compose functions happens to coincide with multiplication on Church numerals, namely <code>compose = \f \g \x. f (g x)</code> which in BLC is
 
<pre>00 00 00 01 1110 01 110 10</pre>
 
=={{header|BQN}}==
Line 610 ⟶ 669:
b = compose(->double ->add1)
p b 1 #should print 4</syntaxhighlight>
 
=={{header|Bruijn}}==
Composition operators as defined in <code>std/Combinator</code>:
<syntaxhighlight lang="bruijn">
:import std/Number .
 
# 1x composition, bluebird combinator
…∘… [[[2 (1 0)]]]
 
:test (((inc ∘ (mul (+2))) (+3)) =? (+7)) ([[1]])
 
# 2x composition, blackbird combinator
…∘∘… [[[[3 (2 1 0)]]]]
 
:test (((inc ∘∘ mul) (+2) (+3)) =? (+7)) ([[1]])
 
# 3x composition, bunting combinator
…∘∘∘… [[[[[4 (3 2 1 0)]]]]]
 
:test (((inc ∘∘∘ (add ∘∘ mul)) (+1) (+2) (+4)) =? (+7)) ([[1]])
 
# reverse composition, queer bird combinator
…→… [[[1 (2 0)]]]
 
:test ((((mul (+2)) → inc) (+3)) =? (+7)) ([[1]])
</syntaxhighlight>
 
=={{header|C}}==
Line 1,044 ⟶ 1,129:
 
=={{header|Elena}}==
ELENA 46.x :
<syntaxhighlight lang="elena">import extensions;
Line 1,055 ⟶ 1,140:
public program()
{
var fg := (x => x + 1).compose::(x => x * x);
console.printLine(fg(3))
Line 1,335 ⟶ 1,420:
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Function_composition}}
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
'''Solution'''
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
[[File:Fōrmulæ - Function composition 01.png]]
In '''[https://formulae.org/?example=Function_composition this]''' page you can see the program(s) related to this task and their results.
 
The compose function returns a lambda expression, containing the actual composition of its arguments, and hence it can be called applied with its argument(s):
 
'''Test cases'''
 
[[File:Fōrmulæ - Function composition 02.png]]
 
[[File:Fōrmulæ - Function composition 03.png]]
 
Arguments of the functions to compose can be the same symbol, they are not "scrambled":
 
[[File:Fōrmulæ - Function composition 04.png]]
 
[[File:Fōrmulæ - Function composition 05.png]]
 
Because a function in Fōrmulæ is just a lambda expression, a lambda expression can be directly provided.
 
[[File:Fōrmulæ - Function composition 06.png]]
 
[[File:Fōrmulæ - Function composition 03.png]]
 
[[File:Fōrmulæ - Function composition 07.png]]
 
[[File:Fōrmulæ - Function composition 05.png]]
 
Since the composition function returns a lambda expression, it is not required to be applied:
 
[[File:Fōrmulæ - Function composition 08.png]]
 
[[File:Fōrmulæ - Function composition 09.png]]
 
[[File:Fōrmulæ - Function composition 10.png]]
 
[[File:Fōrmulæ - Function composition 11.png]]
 
=={{header|GAP}}==
Line 1,510 ⟶ 1,629:
 
Note: <code>1&o.</code> is sine (mnemonic: sine is an odd circular function), <code>2&o.</code> is cosine (cosine is an even circular function), <code>%:</code> is square root, <code>>.</code> is ceiling, <code>|</code> is absolute value and <code>1&+</code> adds 1.
 
=={{header|Janet}}==
 
Janet supports function composition with the [https://janet-lang.org/api/misc.html#comp <code>comp</code>] function.
 
<syntaxhighlight lang="janet">(defn fahrenheit->celsius [deg-f]
(/ (* (- deg-f 32) 5) 9))
 
(defn celsius->kelvin [deg-c]
(+ deg-c 273.15))
 
(def fahrenheit->kelvin (comp celsius->kelvin fahrenheit->celsius))
 
(fahrenheit->kelvin 72) // 295.372
</syntaxhighlight>
 
=={{header|Java}}==
Line 1,743 ⟶ 1,877:
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scalakotlin">// version 1.0.6
 
fun f(x: Int): Int = x * x
 
fun g(x: Int): Int = x + 2
 
fun <T, V, R> compose(f: (IntV) -> IntR, g: (IntT) -> IntV): (IntT) -> IntR = { f(g(it)) }
 
fun main(args: Array<String>) {
val x = 10
println(compose(::f, ::g)(x))
}</syntaxhighlight>
Line 1,779 ⟶ 1,912:
{{f} 3}
-> 80
</syntaxhighlight>
 
=={{header|Lang}}==
<syntaxhighlight lang="lang">
fp.f = ($x) -> return parser.op($x * 3)
fp.g = ($x) -> return parser.op($x + 2)
 
$x = 5
 
# In Lang this task can be achieved with the concat operator
fn.println(parser.op((fp.g ||| fp.f)($x))) # Prints 21 [Internal execution: fp.f(fp.g($x))]
 
# Creating a user-defined function doing the same thing is a bit more difficult
fp.compose = (fp.f, fp.g) -> {
fp.innerFunc = (fp.f, fp.g, $x) -> return fp.f(fp.g($x))
return fn.argCnt1(fn.combA3(fp.innerFunc, fp.f, fp.g)) # fn.combA3 must be used, because Lang does not support closures
}
 
fn.println(fp.compose(fp.f, fp.g)($x)) # Prints also 21
</syntaxhighlight>
 
Line 2,139 ⟶ 2,291:
<syntaxhighlight lang="nim">import sugar
 
proc compose[A,B,C](f: AB -> BC, g: BA -> CB): A -> C = (x: A) => f(g(x))
 
proc plustwo(x: int): int = x + 2
Line 2,799 ⟶ 2,951:
<pre>
11
</pre>
 
=={{header|RPL}}==
{{works with|HP|48G}}
« →STR SWAP →STR +
DUP "»«" POS " " REPL STR→
» '<span style="color:blue">FCOMP</span>' STO <span style="color:grey">@ ''( « f » « g » → « f o g » )''</span>
≪ ALOG ≫ ≪ COS ≫ <span style="color:blue">FCOMP</span>
≪ ALOG ≫ ≪ COS ≫ <span style="color:blue">FCOMP</span> 0 EVAL
≪ ALOG ≫ ≪ COS ≫ <span style="color:blue">FCOMP</span> 'x' EVAL
{{out}}
<pre>
3: ≪ COS ALOG ≫
2: 10
1: 'ALOG(COS(x))'
</pre>
 
Line 2,945 ⟶ 3,113:
{*}$sin_asin 0.5 ;# ==> 0.5
{*}[compose abs int] -3.14 ;# ==> 3</syntaxhighlight>
 
=={{header|Transd}}==
<syntaxhighlight lang="Scheme">#lang transd
 
MainModule: {
// Make a short alias for a function type that takes a string and
// returns a string. Call it 'Shader'.
 
Shader: typealias(Lambda<String String>),
 
// 'composer' function takes two Shaders, combines them into
// a single Shader, which is a capturing closure, аnd returns
// this closure to the caller.
// [[f1,f2]] is a list of captured variables
 
composer: (λ f1 Shader() f2 Shader()
(ret Shader(λ[[f1,f2]] s String() (exec f1 (exec f2 s))))),
 
_start: (λ
// create a combined shader as a local variable 'render'
 
locals: render (composer
Shader(λ s String() (ret (toupper s)))
Shader(λ s String() (ret (+ s "!"))))
// call this combined shader as a usual shader with passing
// a string to it, аnd receiving from it the combined result of
// its two captured shaders
 
(textout (exec render "hello")))
}</syntaxhighlight>
{{out}}
<pre>
HELLO!
</pre>
 
=={{header|TypeScript}}==
Line 3,270 ⟶ 3,473:
 
=={{header|Wren}}==
<syntaxhighlight lang="ecmascriptwren">var compose = Fn.new { |f, g| Fn.new { |x| f.call(g.call(x)) } }
 
var double = Fn.new { |x| 2 * x }
543

edits