Partial function application: Difference between revisions

Added FreeBASIC
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
(Added FreeBASIC)
 
(17 intermediate revisions by 13 users not shown)
Line 32:
* This task is more about ''how'' results are generated rather than just getting results.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F partial(f, g)
F fg(x)
R @f(@g, x)
R fg
 
F main()
F ffs(f, x)
R x.map(a -> @f(a))
F f1(a) {R a * 2}
F f2(a) {R a * a}
 
V fsf1 = partial(ffs, f1)
V fsf2 = partial(ffs, f2)
 
print(fsf1([1, 2, 3, 4]))
print(fsf2([1, 2, 3, 4]))
 
main()</syntaxhighlight>
 
{{out}}
<pre>
[2, 4, 6, 8]
[1, 4, 9, 16]
</pre>
 
=={{header|Ada}}==
Line 37 ⟶ 65:
Ada allows to define generic functions with generic parameters, which are partially applicable.
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
 
procedure Partial_Function_Application is
Line 86 ⟶ 114:
Print(FSF1((2,4,6,8)));
Print(FSF2((2,4,6,8)));
end Partial_Function_Application;</langsyntaxhighlight>
 
Output:
Line 100 ⟶ 128:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
<langsyntaxhighlight lang="algol68">MODE SET = FLEX[0]INT;
 
MODE F = PROC(INT)INT,
Line 127 ⟶ 155:
printf((set fmt, fsf1((2, 4, 6, 8)))); # prints (4, 8, 12, 16) #
printf((set fmt, fsf2((2, 4, 6, 8)))) # prints (4, 16, 36, 64) #
</syntaxhighlight>
</lang>
Output:
<pre>
Line 139 ⟶ 167:
To derive first class functions in AppleScript, we have to lift ordinary handlers into script objects with lambda handlers.
 
<langsyntaxhighlight AppleScriptlang="applescript">-- PARTIAL APPLICATION --------------------------------------------
 
on f1(x)
Line 200 ⟶ 228:
end script
end if
end mReturn</langsyntaxhighlight>
{{Out}}
<pre>{{0, 2, 4, 6}, {0, 1, 4, 9}, {4, 8, 12, 16}, {4, 16, 36, 64}}</pre>
 
=={{header|BBC BASIC}}==
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> fsf1 = FNpartial(PROCfs(), FNf1())
fsf2 = FNpartial(PROCfs(), FNf2())
Line 244 ⟶ 273:
DEF FNf1(n) = n * 2
DEF FNf2(n) = n ^ 2</langsyntaxhighlight>
'''Output:'''
<pre>
Line 256 ⟶ 285:
4 16 36 64
</pre>
 
==={{header|FreeBASIC}}===
{{trans|Lua}}
<syntaxhighlight lang="vbnet">Sub map(f As Function(As Integer) As Integer, arr() As Integer, result() As Integer)
For i As Integer = Lbound(arr) To Ubound(arr)
result(i) = f(arr(i))
Next i
End Sub
 
Function timestwo(n As Integer) As Integer
Return n * 2
End Function
 
Function squared(n As Integer) As Integer
Return n ^ 2
End Function
 
Sub printArray(arr() As Integer)
For i As Integer = Lbound(arr) To Ubound(arr)
Print arr(i);
If i < Ubound(arr) Then Print ",";
Next i
Print
End Sub
 
Dim As Integer arr1(3) = {0, 1, 2, 3}
Dim As Integer arr2(3) = {2, 4, 6, 8}
Dim As Integer result(3)
 
map(@timestwo, arr1(), result())
printArray(result())
 
map(@squared, arr1(), result())
printArray(result())
 
map(@timestwo, arr2(), result())
printArray(result())
 
map(@squared, arr2(), result())
printArray(result())
 
Sleep</syntaxhighlight>
{{out}}
<pre>Same as Lua entry.</pre>
 
==={{header|Visual Basic .NET}}===
Functions are not curried in VB, and so this entry details the creation of functions that take a function and one or more arguments and returns a function that is the result of the partial application of the given function to those arguments.
 
This is done with two approaches: one that takes generic functions of fixed arity and returns a lambda that then calls the function, and a generalized one that allows arbitrary arity of function and arguments.
 
====First approach====
The "type-safe" approach, which has the disadvantage that a new overload of PartialApply must be created for every combination of function arity and applied argument arity.
 
<syntaxhighlight lang="vbnet">Module PartialApplication
Function fs(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
' This is exactly what Enumerable.Select does.
Return s.Select(f)
End Function
 
Function f1(x As Integer) As Integer
Return x * 2
End Function
 
Function f2(x As Integer) As Integer
Return x * x
End Function
 
' The overload that takes a binary function and partially applies to its first parameter.
Function PartialApply(Of T1, T2, TResult)(f As Func(Of T1, T2, TResult), arg As T1) As Func(Of T2, TResult)
Return Function(arg2) f(arg, arg2)
End Function
 
Sub Main()
Dim args1 As Integer() = {0, 1, 2, 3}
Dim args2 As Integer() = {2, 4, 6, 8}
 
Dim fsf1 = PartialApply(Of Func(Of Integer, Integer), IEnumerable(Of Integer), IEnumerable(Of Integer))(AddressOf fs, AddressOf f1)
Dim fsf2 = PartialApply(Of Func(Of Integer, Integer), IEnumerable(Of Integer), IEnumerable(Of Integer))(AddressOf fs, AddressOf f2)
 
Console.WriteLine("fsf1, 0-3: " & String.Join(", ", fsf1(args1)))
Console.WriteLine("fsf1, evens: " & String.Join(", ", fsf1(args2)))
Console.WriteLine("fsf2, 0-3: " & String.Join(", ", fsf2(args1)))
Console.WriteLine("fsf2, evens: " & String.Join(", ", fsf2(args2)))
End Sub
End Module</syntaxhighlight>
 
====Second approach====
f1 and f2 in the second approach will also be defined to use late binding in order to work with any argument that can be multiplied. In the interest of idiomatic VB.NET, a minimal amount of code is to have Option Strict off:
 
<syntaxhighlight lang="vbnet">Option Strict Off
 
Partial Module PartialApplicationDynamic
Function f1(x As Object) As Object
Return x * 2
End Function
 
Function f2(x As Object) As Object
Return x * x
End Function
End Module</syntaxhighlight>
 
and in a separate file,
 
<syntaxhighlight lang="vbnet">Option Strict On
 
Partial Module PartialApplicationDynamic
' Create a matching delegate type to simplify delegate creation.
Delegate Function fsDelegate(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
Function fs(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
' This is exactly what Enumerable.Select does.
Return s.Select(f)
End Function
 
Function ArrayConcat(Of T)(arr1 As T(), arr2 As T()) As T()
Dim result(arr1.Length + arr2.Length - 1) As T
Array.Copy(arr1, result, arr1.Length)
Array.Copy(arr2, 0, result, 1, arr2.Length)
Return result
End Function
 
' C# can define ParamArray delegates and VB can consume them, but VB cannot define them on its own.
' The argument list of calls to the resulting function thus must be wrapped in a coerced array literal.
' VB also doesn't allow Delegate as a type constraint. :(
' The function is generic solely to ease use for callers. In this case generics aren't providing any type-safety.
Function PartialApplyDynamic(Of TDelegate, TResult)(f As TDelegate, ParamArray args As Object()) As Func(Of Object(), TResult)
Dim del = CType(CObj(f), [Delegate])
Return Function(rest) CType(del.DynamicInvoke(ArrayConcat(args, rest).Cast(Of Object).ToArray()), TResult)
End Function
 
Sub Main()
Dim args1 As Object = New Object() {0, 1, 2, 3}
Dim args2 As Object = New Object() {2, 4, 6, 8}
 
Dim fsf1 = PartialApplyDynamic(Of fsDelegate(Of Object, Object), IEnumerable(Of Object))(AddressOf fs, New Func(Of Object, Object)(AddressOf f1))
Dim fsf2 = PartialApplyDynamic(Of fsDelegate(Of Object, Object), IEnumerable(Of Object))(AddressOf fs, New Func(Of Object, Object)(AddressOf f2))
 
' The braces are array literals.
Console.WriteLine("fsf1, 0-3: " & String.Join(", ", fsf1({args1})))
Console.WriteLine("fsf1, evens: " & String.Join(", ", fsf1({args2})))
Console.WriteLine("fsf2, 0-3: " & String.Join(", ", fsf2({args1})))
Console.WriteLine("fsf2, evens: " & String.Join(", ", fsf2({args2})))
End Sub
End Module</syntaxhighlight>
 
{{out|note=for both versions}}
<pre>fsf1, 0-3: 0, 2, 4, 6
fsf1, evens: 4, 8, 12, 16
fsf2, 0-3: 0, 1, 4, 9
fsf2, evens: 4, 16, 36, 64</pre>
 
=={{header|Bracmat}}==
Line 261 ⟶ 439:
The the function <code>fs</code> consists of a lambda abstraction inside a lambda abstraction. In that way <code>fs</code> can take two arguments. Similarly, the function <code>partial</code>, which also needs to take two arguments, is defined using lambda abstractions.
Currying takes place by applying a two-argument function to its first argument. This happens in <code>($x)$($y)</code>.
<langsyntaxhighlight lang="bracmat">( (fs=/('(x./('(y.map'($x.$y))))))
& (f1=/('(x.$x*2)))
& (f2=/('(x.$x^2)))
Line 271 ⟶ 449:
& out$(!fsf1$(2 4 6 8))
& out$(!fsf2$(2 4 6 8))
);</langsyntaxhighlight>
Output:
<pre>0 2 4 6
Line 280 ⟶ 458:
=={{header|C}}==
Nasty hack, but the partial does return a true C function pointer, which is otherwise hard to achieve. (In case you are wondering, no, this is not a good or serious solution.) Compiled with <code>gcc -Wall -ldl</code>.
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
Line 337 ⟶ 515:
 
return 0;
}</langsyntaxhighlight>output<syntaxhighlight lang="text">partial square:
1
4
Line 346 ⟶ 524:
4
6
8</langsyntaxhighlight>
 
=={{header|C sharp}}==
Line 354 ⟶ 532:
A partial application function for binary functions.
 
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 381 ⟶ 559:
Console.WriteLine(string.Join(", ", fsf2(s)));
}
}</langsyntaxhighlight>
 
{{out}}
Line 395 ⟶ 573:
A partial application function that accepts arbitrary function and applied function arity. f1 and f2 also use late binding in this example to work with any argument that can be multiplied.
 
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 439 ⟶ 617:
Console.WriteLine("fsf2, evens: " + string.Join(", ", fsf2(args2)));
}
}</langsyntaxhighlight>
 
{{out}}
Line 448 ⟶ 626:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <utility> // For declval.
#include <algorithm>
#include <array>
Line 518 ⟶ 696:
<< "\tfsf1: " << fsf1(ys) << '\n'
<< "\tfsf2: " << fsf2(ys) << '\n';
}</langsyntaxhighlight>
 
=={{header|Ceylon}}==
<langsyntaxhighlight lang="ceylon">shared void run() {
function fs(Integer f(Integer n), {Integer*} s) => s.map(f);
Line 537 ⟶ 715:
value evens = (2..8).by(2);
print("fsf1(``evens``) is ``fsf1(evens)`` and fsf2(``evens``) is ``fsf2(evens)``");
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight Clojurelang="clojure">(defn fs [f s] (map f s))
(defn f1 [x] (* 2 x))
(defn f2 [x] (* x x))
Line 549 ⟶ 727:
(println "seq: " s)
(println " fsf1: " (fsf1 s))
(println " fsf2: " (fsf2 s)))</langsyntaxhighlight>
Output:
<pre>seq: (0 1 2 3)
Line 559 ⟶ 737:
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">
partial = (f, g) ->
(s) -> f(g, s)
Line 573 ⟶ 751:
console.log fsf1 seq
console.log fsf2 seq
</syntaxhighlight>
</lang>
output
<syntaxhighlight lang="text">
> coffee partials.coffee
[ 0, 2, 4, 6 ]
Line 581 ⟶ 759:
[ 4, 8, 12, 16 ]
[ 4, 16, 36, 64 ]
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun fs (f s)
(mapcar f s))
(defun f1 (i)
Line 604 ⟶ 782:
(fsf1 seq)
(fsf2 seq)))
</syntaxhighlight>
</lang>
 
Output: <pre>seq: (0 1 2 3)
Line 615 ⟶ 793:
=={{header|D}}==
fs has a static template argument f and the runtime argument s. The template constraints of fs statically require f to be a callable with just one argument, as requested by the task.
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.traits;
 
auto fs(alias f)(in int[] s) pure nothrow
Line 633 ⟶ 811:
d.fsf2.writeln;
}
}</langsyntaxhighlight>
{{out}}
<pre>[0, 2, 4, 6]
Line 642 ⟶ 820:
=={{header|E}}==
 
<langsyntaxhighlight lang="e">def pa(f, args1) {
return def partial {
match [`run`, args2] {
Line 667 ⟶ 845:
println(f(s))
}
}</langsyntaxhighlight>
 
=={{header|Egison}}==
 
<langsyntaxhighlight lang="egison">
(define $fs (map $1 $2))
 
Line 684 ⟶ 862:
(test (fsf1 {2 4 6 8}))
(test (fsf2 {2 4 6 8}))
</syntaxhighlight>
</lang>
'''Output:'''
<langsyntaxhighlight lang="egison">
{0 2 4 6}
{0 1 4 9}
{4 8 12 16}
{4 16 36 64}
</syntaxhighlight>
</lang>
 
=={{header|Elena}}==
{{trans|Smalltalk}}
ELENA 56.0x :
<langsyntaxhighlight lang="elena">import system'collections;
import system'routines;
import extensions;
Line 704 ⟶ 882:
var partial := (afs,af => (s => afs(af, s)));
var fs := (f,s => s.selectBy::(x => f(x)).summarize(new ArrayList()).toArray());
var f1 := (x => x * 2);
var f2 := (x => x * x);
Line 713 ⟶ 891:
console.printLine(fsf1(new int[]{2,4,6,8}).toString());
console.printLine(fsf2(new int[]{2,4,6,8}).toString())
}</langsyntaxhighlight>
{{out}}
<pre>
Line 723 ⟶ 901:
Translation of Racket
 
<langsyntaxhighlight lang="fsharp">
let fs f s = List.map f s
let f1 n = n * 2
Line 735 ⟶ 913:
printfn "%A" (fsf2 [0; 1; 2; 3])
printfn "%A" (fsf2 [2; 4; 6; 8])
</syntaxhighlight>
</lang>
Output:
<pre>
Line 745 ⟶ 923:
 
=={{header|Factor}}==
<syntaxhighlight lang="text">USING: kernel math prettyprint sequences ;
IN: rosetta-code.partial-function-application
 
Line 755 ⟶ 933:
 
{ 0 1 2 3 } [ fsf1 . ] [ fsf2 . ] bi
{ 2 4 6 8 } [ fsf1 . ] [ fsf2 . ] bi</langsyntaxhighlight>
{{out}}
<pre>
Line 765 ⟶ 943:
 
=={{header|FunL}}==
<langsyntaxhighlight lang="funl">fs = map
f1 = (* 2)
f2 = (^ 2)
Line 775 ⟶ 953:
println( fsf2(0..3) )
println( fsf1(2..8 by 2) )
println( fsf2(2..8 by 2) )</langsyntaxhighlight>
 
{{out}}
Line 789 ⟶ 967:
{{works with|Go|1.1}} (The first way shown uses [http://golang.org/ref/spec#Method_values Method values] which were added in Go 1.1. The second uses a function returning a function which was always possible.)
[http://play.golang.org/p/fbmK4qfFZr Run this in the Go playground].
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 843 ⟶ 1,021:
fmt.Println(" fsf3:", fsf3(s...))
fmt.Println(" fsf3(fsf1):", fsf3(fsf1(s...)...))
}</langsyntaxhighlight>
{{out}}
<pre>For s = [0 1 2 3]
Line 857 ⟶ 1,035:
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">def fs = { fn, values -> values.collect { fn(it) } }
def f1 = { v -> v * 2 }
def f2 = { v -> v ** 2 }
def fsf1 = fs.curry(f1)
def fsf2 = fs.curry(f2)</langsyntaxhighlight>
Testing:
<langsyntaxhighlight lang="groovy">[(0..3), (2..8).step(2)].each { seq ->
println "fsf1$seq = ${fsf1(seq)}"
println "fsf2$seq = ${fsf2(seq)}"
}</langsyntaxhighlight>
Output:
<pre>fsf1[0, 1, 2, 3] = [0, 2, 4, 6]
Line 875 ⟶ 1,053:
=={{header|Haskell}}==
Haskell functions are curried. i.e. All functions actually take exactly one argument. Functions of multiple arguments are simply functions that take the first argument, which returns another function to take the remaining arguments, etc. Therefore, partial function application is trivial. Not giving a multi-argument function all of its arguments will simply return a function that takes the remaining arguments.
<langsyntaxhighlight lang="haskell">fs = map
f1 = (* 2)
f2 = (^ 2)
Line 887 ⟶ 1,065:
print $ fsf2 [0, 1, 2, 3] -- prints [0, 1, 4, 9]
print $ fsf1 [2, 4, 6, 8] -- prints [4, 8, 12, 16]
print $ fsf2 [2, 4, 6, 8] -- prints [4, 16, 36, 64]</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">link printf
 
procedure main()
Line 928 ⟶ 1,106:
every (s := "[ ") ||:= !L || " "
return s || "]"
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 945 ⟶ 1,123:
Given:
 
<langsyntaxhighlight lang="j">fs=:1 :'u"0 y'
f1=:*&2
f2=:^&2
fsf1=:f1 fs
fsf2=:f2 fs</langsyntaxhighlight>
 
The required examples might look like this:
 
<langsyntaxhighlight lang="j"> fsf1 i.4
0 2 4 6
fsf2 i.4
Line 960 ⟶ 1,138:
4 8 12 16
fsf2 fsf1 1+i.4
4 16 36 64</langsyntaxhighlight>
 
That said, note that much of this is unnecessary, since f1 and f2 already work the same way on list arguments.
 
<langsyntaxhighlight lang="j"> f1 i.4
0 2 4 6
f2 i.4
Line 971 ⟶ 1,149:
2 4 6 8
f2 f1 1+i.4
4 16 36 64</langsyntaxhighlight>
 
That said, note that if we complicated the definitions of f1 and f2, so that they would not work on lists, the fs approach would still work:
Line 977 ⟶ 1,155:
In other words, given:
 
<langsyntaxhighlight lang="j">crippled=:1 :0
assert.1=#y
u y
Line 985 ⟶ 1,163:
F2=: f2 crippled
fsF1=: F1 fs
fsF2=: F2 fs</langsyntaxhighlight>
 
the system behaves like this:
 
<langsyntaxhighlight lang="j"> F1 i.4
|assertion failure: F1
| 1=#y
fsF1 i.4
0 2 4 6
NB. and so on...</langsyntaxhighlight>
 
=={{header|Java}}==
To solve this task, I wrote <tt>fs()</tt> as a curried method. I changed the syntax from <tt>fs(arg1, arg2)</tt> to <tt>fs(arg1).call(arg2)</tt>. Now I can use <tt>fs(arg1)</tt> as partial application.
 
<langsyntaxhighlight lang="java">import java.util.Arrays;
 
public class PartialApplication {
Line 1,061 ⟶ 1,239:
}
}
}</langsyntaxhighlight>
 
The aforementioned code, lambda-ized in Java 8.
 
<langsyntaxhighlight lang="java5">import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;
Line 1,132 ⟶ 1,310:
;
}
}</langsyntaxhighlight>
 
Compilation and output for both versions: <pre>$ javac PartialApplication.java
Line 1,149 ⟶ 1,327:
(No special libraries are required for the creation or application of partial functions)
 
<langsyntaxhighlight JavaScriptlang="javascript">var f1 = function (x) { return x * 2; },
f2 = function (x) { return x * x; },
 
Line 1,168 ⟶ 1,346:
fsf1([2, 4, 6, 8]),
fsf2([2, 4, 6, 8])
]</langsyntaxhighlight>
 
Output:
Line 1,176 ⟶ 1,354:
For additional flexibility ( allowing for an arbitrary number of arguments in applications of a partially applied function, and dropping the square brackets from the function calls in the tests above ) we can make use of the array-like ''arguments'' object, which is a property of any JavaScript function.
 
<langsyntaxhighlight JavaScriptlang="javascript">var f1 = function (x) { return x * 2; },
f2 = function (x) { return x * x; },
 
Line 1,196 ⟶ 1,374:
fsf1(2, 4, 6, 8, 10, 12),
fsf2(2, 4, 6, 8)
]</langsyntaxhighlight>
 
Output:
Line 1,204 ⟶ 1,382:
===ES6===
====Simple curry====
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
'use strict';
 
Line 1,235 ⟶ 1,413:
fsf2([2, 4, 6, 8])
];
})();</langsyntaxhighlight>
{{Out}}
<pre>[[0, 2, 4, 6], [0, 1, 4, 9], [4, 8, 12, 16], [4, 16, 36, 64]]</pre>
Line 1,241 ⟶ 1,419:
The simple version of the higher-order '''curry''' function above works only on functions with two arguments. For more flexibility, we can generalise it to a form which curries functions with an arbitrary number of arguments:
 
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
'use strict';
 
Line 1,277 ⟶ 1,455:
fsf2([2, 4, 6, 8])
];
})();</langsyntaxhighlight>
{{Out}}
<pre>[[0, 2, 4, 6], [0, 1, 4, 9], [4, 8, 12, 16], [4, 16, 36, 64]]</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<syntaxhighlight lang="jq"># fs(f, s) takes a function, f, of one value and a sequence of values s,
# and returns an ordered sequence of the result of applying function f to every value of s in turn.
 
def fs(f; s): s | f;
 
# f1 takes a value and returns it multiplied by 2:
def f1: 2 * .;
 
# f2 takes a value and returns it squared:
def f2: . * .;
 
# Partially apply f1 to fs to form function fsf1(s):
def fsf1(s): fs(f1;s);
 
# Partially apply f2 to fs to form function fsf2(s)
def fsf2(s): fs(f2; s);
 
# Test fsf1 and fsf2 by evaluating them with s being the sequence of integers from 0 to 3 inclusive ...
 
"fsf1",
[fsf1(range(0;4))],
"fsf2",
[fsf2(range(0;4))],
 
# and then the sequence of even integers from 2 to 8 inclusive:
 
"fsf1",
[fsf1(range(2;9;2))],
"fsf2",
[fsf2(range(2;9;2))]</syntaxhighlight>
{{out}}
<pre>
fsf1
[0,2,4,6]
fsf2
[0,1,4,9]
fsf1
[4,8,12,16]
fsf2
[4,16,36,64]
</pre>
 
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">
fs(f, s) = map(f, s)
f1(x) = 2x
Line 1,295 ⟶ 1,519:
println("fsf1 of s2 is $(fsf1(s2))")
println("fsf2 of s2 is $(fsf2(s2))")
</syntaxhighlight>
</lang>
{{output}}<pre>
fsf1 of s1 is [0, 2, 4, 6]
Line 1,304 ⟶ 1,528:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
typealias Func = (Int) -> Int
Line 1,331 ⟶ 1,555:
println()
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,349 ⟶ 1,573:
 
{lambda talk} doesn't know closures but accepts de facto partial application. Not giving a multi-argument function all of its arguments will simply return a function that takes the remaining arguments.
<syntaxhighlight lang="scheme">
<lang Scheme>
1) just define function as usual:
{def add {lambda {:a :b :c} {+ :a :b :c}}} -> add
Line 1,376 ⟶ 1,600:
4 8 12 16
4 16 36 64
</syntaxhighlight>
</lang>
 
=={{header|LFE}}==
Line 1,383 ⟶ 1,607:
 
Here is the code, made more general to account for different arrities (note that to copy and paste into the LFE REPL, you'll need to leave out the docstring):
<langsyntaxhighlight lang="lisp">
(defun partial
"The partial function is arity 2 where the first parameter must be a
Line 1,404 ⟶ 1,628:
((arg-2)
(funcall func arg-1 arg-2)))))
</syntaxhighlight>
</lang>
 
Here is the problem set:
<langsyntaxhighlight lang="lisp">
(defun fs (f s) (lists:map f s))
(defun f1 (i) (* i 2))
Line 1,426 ⟶ 1,650:
(4.0 16.0 36.0 64.0)
 
</syntaxhighlight>
</lang>
 
=={{header|Logtalk}}==
Using Logtalk's built-in and library meta-predicates:
<langsyntaxhighlight lang="logtalk">
:- object(partial_functions).
 
Line 1,462 ⟶ 1,686:
 
:- end_object.
</syntaxhighlight>
</lang>
Output:
<langsyntaxhighlight lang="text">
| ?- partial_functions::show.
[0,1,2,3] -> fs(f1) -> [0,2,4,6]
Line 1,471 ⟶ 1,695:
[2,4,6,8] -> fs(f2) -> [4,16,36,64]
yes
</syntaxhighlight>
</lang>
 
=={{header|Lua}}==
 
<langsyntaxhighlight lang="lua">function map(f, ...)
local t = {}
for k, v in ipairs(...) do
Line 1,503 ⟶ 1,727:
print(table.concat(squared_s{0, 1, 2, 3}, ', '))
print(table.concat(timestwo_s{2, 4, 6, 8}, ', '))
print(table.concat(squared_s{2, 4, 6, 8}, ', '))</langsyntaxhighlight>
 
'''Output:'''
Line 1,512 ⟶ 1,736:
4, 16, 36, 64
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">fs[f_, s_] := Map[f, s]
f1 [n_] := n*2
f2 [n_] := n^2
fsf1[s_] := fs[f1, s]
fsf2[s_] := fs[f2, s]</langsyntaxhighlight>
Example usage:
<pre>fsf1[{0, 1, 2, 3}]
Line 1,529 ⟶ 1,753:
 
=={{header|Mercury}}==
<langsyntaxhighlight lang="mercury">:- module partial_function_application.
:- interface.
 
Line 1,564 ⟶ 1,788:
:- func fsf2 = (func(list(int)) = list(int)).
 
fsf2 = fs(f2).</langsyntaxhighlight>
 
=={{header|min}}==
{{works with|min|0.19.3}}
<langsyntaxhighlight lang="min">'map :fs
(dup +) :f1
(dup *) :f2
Line 1,577 ⟶ 1,801:
(0 1 2 3) fsf2 puts!
(2 4 6 8) fsf1 puts!
(2 4 6 8) fsf2 puts!</langsyntaxhighlight>
{{out}}
<pre>
Line 1,587 ⟶ 1,811:
 
=={{header|Nemerle}}==
<langsyntaxhighlight Nemerlelang="nemerle">using System;
using System.Console;
 
Line 1,631 ⟶ 1,855:
}
}</langsyntaxhighlight>
 
=={{header|Nim}}==
{{trans|Kotlin}}
<syntaxhighlight lang="nim">import sequtils
 
type
 
Func = proc(n: int): int
FuncS = proc(f: Func; s: seq[int]): seq[int]
 
proc fs(f: Func; s: seq[int]): seq[int] = s.map(f)
 
proc partial(fs: FuncS; f: Func): auto =
result = proc(s: seq[int]): seq[int] = fs(f, s)
 
proc f1(n: int): int = 2 * n
proc f2(n: int): int = n * n
 
when isMainModule:
 
const Seqs = @[@[0, 1, 2, 3], @[2, 4, 6, 8]]
 
let fsf1 = partial(fs, f1)
let fsf2 = partial(fs, f2)
 
for s in Seqs:
echo fs(f1, s) # Normal.
echo fsf1(s) # Partial.
echo fs(f2, s) # Normal.
echo fsf2(s) # Partial.
echo ""</syntaxhighlight>
 
{{out}}
<pre>@[0, 2, 4, 6]
@[0, 2, 4, 6]
@[0, 1, 4, 9]
@[0, 1, 4, 9]
 
@[4, 8, 12, 16]
@[4, 8, 12, 16]
@[4, 16, 36, 64]
@[4, 16, 36, 64]</pre>
 
=={{header|OCaml}}==
OCaml functions are curried. i.e. All functions actually take exactly one argument. Functions of multiple arguments are simply functions that take the first argument, which returns another function to take the remaining arguments, etc. Therefore, partial function application is trivial. Not giving a multi-argument function all of its arguments will simply return a function that takes the remaining arguments.
<langsyntaxhighlight lang="ocaml">#
let fs f s = List.map f s
let f1 value = value * 2
Line 1,656 ⟶ 1,922:
- : int list = [4; 8; 12; 16]
# fsf2 [2; 4; 6; 8];;
- : int list = [4; 16; 36; 64]</langsyntaxhighlight>
 
=={{header|Oforth}}==
 
<langsyntaxhighlight Oforthlang="oforth">: fs(s, f) f s map ;
: f1 2 * ;
: f2 sq ;
 
#f1 #fs curry => fsf1
#f2 #fs curry => fsf2</langsyntaxhighlight>
 
{{out}}
Line 1,681 ⟶ 1,947:
=={{header|Order}}==
Much like Haskell and ML, not giving a multi-argument function all of its arguments returns a function that will accept the rest.
<langsyntaxhighlight lang="c">#include <order/interpreter.h>
 
#define ORDER_PP_DEF_8fs ORDER_PP_FN( 8fn(8F, 8S, 8seq_map(8F, 8S)) )
Line 1,696 ⟶ 1,962:
8print(8ap(8G, 8seq(0, 1, 2, 3)) 8comma 8space),
8print(8ap(8F, 8seq(2, 4, 6, 8)) 8comma 8space),
8print(8ap(8G, 8seq(2, 4, 6, 8))))) )</langsyntaxhighlight>
{{out}}
<pre>(0)(2)(4)(6), (0)(1)(4)(9), (4)(8)(12)(16), (4)(16)(36)(64)</pre>
Line 1,703 ⟶ 1,969:
=={{header|PARI/GP}}==
This pure-GP solution cheats slightly, since GP lacks variadic arguments and reflection.
<langsyntaxhighlight lang="parigp">fs=apply;
f1(x)=2*x;
f2(x)=x^2;
Line 1,711 ⟶ 1,977:
fsf1(2([1..4])
fsf2([0..3])
fsf2(2([1..4])</langsyntaxhighlight>
 
PARI can do true partial function application, along the lines of [[#C|C]]; see also the <code>E*</code> parser code.
Line 1,717 ⟶ 1,983:
=={{header|Perl}}==
Note: this is written according to my understanding of the task spec and the discussion page; it doesn't seem a consensus was reached regarding what counts as a "partial" yet.
<langsyntaxhighlight Perllang="perl">sub fs :prototype(&) {
my $func = shift;
sub { map $func->($_), @_ }
}
 
sub double :prototype($) { shift() * 2 }
sub square :prototype($) { shift() ** 2 }
 
my $fs_double = fs(\&double);
Line 1,734 ⟶ 2,000:
@s = (2, 4, 6, 8);
print "fs_double(@s): @{[ $fs_double->(@s) ]}\n";
print "fs_square(@s): @{[ $fs_square->(@s) ]}\n";</langsyntaxhighlight>
Output: <pre>fs_double(0 1 2 3): 0 2 4 6
fs_square(0 1 2 3): 0 1 4 9
Line 1,741 ⟶ 2,007:
 
=={{header|Phix}}==
Phix does not explicitly support this, but you can easily emulate it with routine_id<br>
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function fs(integer rid, sequence s)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
for i=1 to length(s) do
<span style="color: #008080;">function</span> <span style="color: #000000;">fs</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
s[i] = call_func(rid,{s[i]})
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">))</span>
end for
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
return s
<span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
function p_apply(sequence f, sequence args)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return call_func(f[1],{f[2],args})
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">p_apply</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
 
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">f1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">f</span>
function f1(integer i)
<span style="color: #008080;">return</span> <span style="color: #000000;">f1</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
return i+i
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end function
 
<span style="color: #008080;">function</span> <span style="color: #000000;">f1</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
function f2(integer i)
<span style="color: #008080;">return</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span>
return i*i
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end function
 
<span style="color: #008080;">function</span> <span style="color: #000000;">f2</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
constant fsf1 = {routine_id("fs"),routine_id("f1")},
<span style="color: #008080;">return</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">i</span>
fsf2 = {routine_id("fs"),routine_id("f2")}
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
?p_apply(fsf1,{0,1,2,3})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p_apply</span><span style="color: #0000FF;">({</span><span style="color: #000000;">fs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})})</span>
?p_apply(fsf2,{2,4,6,8})</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p_apply</span><span style="color: #0000FF;">({</span><span style="color: #000000;">fs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
{0,2,4,6}
{40,161,364,649}
</pre>
Should you want to supply partial arguments:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">fs</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">p_apply</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">ffa</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">f1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ffa</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">f1</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">f3</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p_apply</span><span style="color: #0000FF;">({</span><span style="color: #000000;">fs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
{1,2,3,4}
</pre>
Should you want the first few arguments set as part of fsf1/2 [ie as a 3rd sequence element], then obviously p_apply might be more like
<lang Phix>function p_apply(sequence ffsa, sequence extra_args)
object {fa,fx,set_args} = ffsa
return call_func(fa,{fx,set_args&extra_args})
end function</lang>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(def 'fs mapcar)
(de f1 (N) (* 2 N))
(de f2 (N) (* N N))
Line 1,791 ⟶ 2,080:
(for S '((0 1 2 3) (2 4 6 8))
(println (fsf1 S))
(println (fsf2 S)) )</langsyntaxhighlight>
Output:
<pre>(0 2 4 6)
Line 1,800 ⟶ 2,089:
=={{header|Prolog}}==
Works with SWI-Prolog.
<langsyntaxhighlight Prologlang="prolog">fs(P, S, S1) :-
maplist(P, S, S1).
 
Line 1,825 ⟶ 2,114:
call(FSF1,S2, S21), format('~w : ~w ==> ~w~n',[FSF2, S2, S21]),
call(FSF2,S2, S22), format('~w : ~w ==> ~w~n',[FSF1, S2, S22]).
</syntaxhighlight>
</lang>
Output :
<pre>?- fs.
Line 1,835 ⟶ 2,124:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">from functools import partial
 
def fs(f, s): return [f(value) for value in s]
Line 1,852 ⟶ 2,141:
s = [2, 4, 6, 8]
assert fs(f1, s) == fsf1(s) # == [4, 8, 12, 16]
assert fs(f2, s) == fsf2(s) # == [4, 16, 36, 64]</langsyntaxhighlight>
 
The program runs without triggering the assertions.
 
Explicitly spelling out the partial function without hiding behind a library:<langsyntaxhighlight Pythonlang="python">def partial(f, g):
def fg(*x): return f(g, *x)
return fg
Line 1,868 ⟶ 2,157:
 
print fsf1(1, 2, 3, 4)
print fsf2(1, 2, 3, 4)</langsyntaxhighlight>
 
=={{header|Quackery}}==
 
(It would be more natural in Quackery to take the arguments to ''fs'' in the order ''s f''. This code complies with the requirements of the task. To make it idiomatic, omit all but the second ''swap''.)
<syntaxhighlight lang="quackery"> [ [] unrot
swap nested
' join nested
join nested
' witheach nested
swap join
do ] is fs ( f s --> [ )
[ 2 * ] is f1 ( n --> n )
[ 2 ** ] is f2 ( n --> n )
[ ' f1 swap fs ] is fsf1 ( s --> [ )
[ ' f2 swap fs ] is fsf2 ( s --> [ )
' [ 0 1 2 3 ] fsf1 echo cr
' [ 0 1 2 3 ] fsf2 echo cr
' [ 2 4 6 8 ] fsf1 echo cr
' [ 2 4 6 8 ] fsf2 echo cr
( ... or, using Quackery's partial applicator "witheach",
which applies the word or nest following it to each
item in a nest on the top of the stack ... )
cr
' [ [ 0 1 2 3 ] [ 2 4 6 8 ] ]
witheach
[ dup ' [ fsf1 fsf2 ]
witheach [ do echo cr ] ]</syntaxhighlight>
 
{{Out}}
 
<pre>[ 0 2 4 6 ]
[ 0 1 4 9 ]
[ 4 8 12 16 ]
[ 4 16 36 64 ]
 
[ 0 2 4 6 ]
[ 0 1 4 9 ]
[ 4 8 12 16 ]
[ 4 16 36 64 ]</pre>
 
=={{header|R}}==
 
<langsyntaxhighlight Rlang="r">partially.apply <- function(f, ...) {
capture <- list(...)
function(...) {
Line 1,889 ⟶ 2,225:
fsf2(0:3)
fsf1(seq(2,8,2))
fsf2(seq(2,8,2))</langsyntaxhighlight>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 1,907 ⟶ 2,243:
(fsf2 '(0 1 2 3))
(fsf2 '(2 4 6 8))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 1,913 ⟶ 2,249:
{{works with|rakudo|2015-09-25}}
All Code objects have the .assuming method, which partially applies its arguments. For both type safety reasons and parsing sanity reasons we do not believe in implicit partial application by leaving out arguments. Also, people can understand "assuming" without being steeped in FP culture.
<syntaxhighlight lang="raku" perl6line>sub fs ( Code $f, @s ) { @s.map: { .$f } }
sub f1 ( $n ) { $n * 2 }
Line 1,923 ⟶ 2,259:
for [1..3], [2, 4 ... 8] X &fsf1, &fsf2 -> ($s, $f) {
say $f.($s);
}</langsyntaxhighlight>
 
Output:<pre>(2 4 6)
Line 1,929 ⟶ 2,265:
(4 8 12 16)
(4 16 36 64)</pre>
The <tt>*+2</tt> is also a form of partial application in Perl&nbsp;6Raku. In this case we partially apply the <tt>infix:<+></tt> function with a second argument of 2. That is, the star (known as the "whatever" star) indicates which argument <em>not</em> to apply. In contrast to languages that keep some arguments unbound by leaving holes, the explicit star in Perl&nbsp;6Raku allows us to avoid syntactic ambiguity in whether to expect a term or an infix operator; such self-clocking code contributes to better error messages when things go wrong.
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program demonstrates a method of a partial function application. */
s=; do a=0 to 3 /*build 1st series of some low integers*/
s=strip(s a) /*append to the integer to the S list*/
Line 1,954 ⟶ 2,290:
interpret '$=$' f"("z')'
end /*j*/
return strip($)</langsyntaxhighlight>
'''output'''
<pre>
Line 1,961 ⟶ 2,297:
for f1, series= 2 4 6 8, result= 4 8 12 16
for f2, series= 2 4 6 8, result= 4 16 36 64
</pre>
 
=={{header|RPL}}==
<code>fs(f,s)</code> is a built-in function in RPL named <code>DOLIST </code>
« 2 * » '<span style="color:blue">F1</span>' STO
« SQ » '<span style="color:blue">F2</span>' STO
« 1 '<span style="color:blue">F1</span>' DOLIST » '<span style="color:blue">FSF1</span>' STO
« 1 '<span style="color:blue">F2</span>' DOLIST » '<span style="color:blue">FSF2</span>' STO
 
{ 0 1 2 3 } <span style="color:blue">FSF1</span>
{ 0 1 2 3 } <span style="color:blue">FSF2</span>
{ 2 4 6 8 } <span style="color:blue">FSF1</span>
{ 2 4 6 8 } <span style="color:blue">FSF2</span>
{{out}}
<pre>
4: { 0 2 4 6 }
3! { 0 1 4 9 }
2: { 4 8 12 16 }
1: { 4 16 36 64 }
</pre>
 
Line 1,967 ⟶ 2,325:
 
{{works with|Ruby|1.9}}
<langsyntaxhighlight lang="ruby">fs = proc { |f, s| s.map &f }
f1 = proc { |n| n * 2 }
f2 = proc { |n| n ** 2 }
Line 1,976 ⟶ 2,334:
p fsf1[e]
p fsf2[e]
end</langsyntaxhighlight>
 
Output
Line 1,985 ⟶ 2,343:
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">def fs[X](f:X=>X)(s:Seq[X]) = s map f
def f1(x:Int) = x * 2
def f2(x:Int) = x * x
Line 1,994 ⟶ 2,352:
 
assert(fsf1(List(0,1,2,3)) == List(0,2,4,6))
assert(fsf2(List(0,1,2,3)) == List(0,1,4,9))</langsyntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">func fs(f) {
func(*args) {
args.map {f(_)}
Line 2,016 ⟶ 2,374:
s = [2, 4, 6, 8];
say "fs_double(#{s}): #{fs_double(s...)}";
say "fs_square(#{s}): #{fs_square(s...)}";</langsyntaxhighlight>
{{out}}
<pre>
Line 2,027 ⟶ 2,385:
=={{header|Smalltalk}}==
{{works with|Pharo|1.3-13315}}
<langsyntaxhighlight lang="smalltalk">
| f1 f2 fs fsf1 fsf2 partial |
 
Line 2,047 ⟶ 2,405:
fsf2 value: #(2 4 6 8).
" #(4 16 36 64)"
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
proc partial {f1 f2} {
variable ctr
Line 2,059 ⟶ 2,417:
}
}} $f1 $f2
}</langsyntaxhighlight>
Demonstration:
<langsyntaxhighlight lang="tcl">proc fs {f s} {
set r {}
foreach n $s {
Line 2,075 ⟶ 2,433:
puts "$s ==f1==> [$fsf1 $s]"
puts "$s ==f2==> [$fsf2 $s]"
}</langsyntaxhighlight>
Output:
<pre>
Line 2,090 ⟶ 2,448:
Indeed, functional language purists would probably say that even the explicit <code>op</code> operator spoils it, somewhat.
 
<langsyntaxhighlight lang="sh">$ txr -p "(mapcar (op mapcar (op * 2)) (list (range 0 3) (range 2 8 2)))"
((0 2 4 6) (4 8 12 16))
 
$ txr -p "(mapcar (op mapcar (op * @1 @1)) (list (range 0 3) (range 2 8 2)))"
((0 1 4 9) (4 16 36 64))</langsyntaxhighlight>
 
Note how in the above, '''no''' function arguments are explicitly mentioned at all except the necessary reference <code>@1</code> to an argument whose existence is implicit.
Line 2,100 ⟶ 2,458:
Now, without further ado, we surrender the concept of partial application to meet the task requirements:
 
<langsyntaxhighlight lang="sh">$ txr -e "(progn
(defun fs (fun seq) (mapcar fun seq))
(defun f1 (num) (* 2 num))
Line 2,110 ⟶ 2,468:
(print [fs fsf2 '((0 1 2 3) (2 4 6 8))]) (put-line \"\"))"
((0 2 4 6) (4 8 12 16))
((0 1 4 9) (4 16 36 64))</langsyntaxhighlight>
 
=={{header|Visual Basic .NETWren}}==
<syntaxhighlight lang="wren">var fs = Fn.new { |f, s| s.map { |e| f.call(e) }.toList }
var f1 = Fn.new { |n| 2 * n }
var f2 = Fn.new { |n| n * n }
 
var partial = Fn.new { |f, g| Fn.new { |x| f.call(g, x) } }
Functions are not curried in VB, and so this entry details the creation of functions that take a function and one or more arguments and returns a function that is the result of the partial application of the given function to those arguments.
 
var ss = [[0, 1, 2, 3], [2, 4, 6, 8]]
This is done with two approaches: one that takes generic functions of fixed arity and returns a lambda that then calls the function, and a generalized one that allows arbitrary arity of function and arguments.
for (s in ss) {
var fsf1 = partial.call(fs, f1)
var fsf2 = partial.call(fs, f2)
System.print(fsf1.call(s))
System.print(fsf2.call(s))
System.print()
}</syntaxhighlight>
 
{{out}}
===First approach===
<pre>
[0, 2, 4, 6]
[0, 1, 4, 9]
 
[4, 8, 12, 16]
The "type-safe" approach, which has the disadvantage that a new overload of PartialApply must be created for every combination of function arity and applied argument arity.
[4, 16, 36, 64]
</pre>
 
=={{header|zkl}}==
<lang vbnet>Module PartialApplication
<syntaxhighlight lang="zkl">fcn fs(f,s){s.apply(f)} fcn f1(n){n*2} fcn f2(n){n*n}
Function fs(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
var fsf1=fs.fp(f1), fsf2=fs.fp(f2);
' This is exactly what Enumerable.Select does.
fsf1([0..3]); //-->L(0,2,4,6)
Return s.Select(f)
fsf2([2..8,2]); //-->L(4,16,36,64)</syntaxhighlight>
End Function
 
Function f1(x As Integer) As Integer
Return x * 2
End Function
 
=={{header|Z80 Assembly}}==
Function f2(x As Integer) As Integer
First, the implementation of the functions.
Return x * x
<syntaxhighlight lang="z80">func_fs:
End Function
;input
;hl = function to call
;ix = data range to operate over
;de = output area
;b = length of data range
 
push bc
' The overload that takes a binary function and partially applies to its first parameter.
ld (smc_fs+1),hl
Function PartialApply(Of T1, T2, TResult)(f As Func(Of T1, T2, TResult), arg As T1) As Func(Of T2, TResult)
ld a,(ix+0)
Return Function(arg2) f(arg, arg2)
smc_fs:
End Function
call 0 ;overwritten with the function address passed in HL
 
ld (de),a
Sub Main()
inc ix
Dim args1 As Integer() = {0, 1, 2, 3}
inc de
Dim args2 As Integer() = {2, 4, 6, 8}
pop bc
djnz func_fs
ret
 
f: ;dummy function - returns input as-is
Dim fsf1 = PartialApply(Of Func(Of Integer, Integer), IEnumerable(Of Integer), IEnumerable(Of Integer))(AddressOf fs, AddressOf f1)
ret
Dim fsf2 = PartialApply(Of Func(Of Integer, Integer), IEnumerable(Of Integer), IEnumerable(Of Integer))(AddressOf fs, AddressOf f2)
 
f1:
Console.WriteLine("fsf1, 0-3: " & String.Join(", ", fsf1(args1)))
;returns A times 2
Console.WriteLine("fsf1, evens: " & String.Join(", ", fsf1(args2)))
sla a
Console.WriteLine("fsf2, 0-3: " & String.Join(", ", fsf2(args1)))
ret
Console.WriteLine("fsf2, evens: " & String.Join(", ", fsf2(args2)))
End Sub
End Module</lang>
 
f2:
===Second approach===
;returns A squared
ld b,a
jp square_small
;ret
 
data1:
f1 and f2 in the second approach will also be defined to use late binding in order to work with any argument that can be multiplied. In the interest of idiomatic VB.NET, a minimal amount of code is to have Option Strict off:
db 0,1,2,3
 
data2
<lang vbnet>Option Strict Off
db 2,4,6,8
 
output:
Partial Module PartialApplicationDynamic
ds 4
Function f1(x As Object) As Object
Return x * 2
End Function
 
;these libraries allow us to write the output to the screen
Function f2(x As Object) As Object
read "\SrcCPC\winape_monitor.asm"
Return x * x
read "\SrcCPC\winape_stringop.asm"
End Function
read "\SrcCPC\winape_showhex.asm"
End Module</lang>
 
square_small:
and in a separate file,
;returns a*a into a
LD C,B
mul8_small:
;multiplies two 8-bit regs, product is also 8 bit.
;no overflow protection!
;computes A = c * b
ld a,c
or a
ret z
djnz skip_return_C
;ADVANCED TRICKERY:
; we need to decrement B anyway.
; also if B = 1, then A = C.
; C is already in A, which we need for the multiplication regardless.
; This does the job for us in one instruction!
; Most DJNZs are backward but this one is FORWARD!
ret
skip_return_C:
add C
djnz skip_return_C
ret</syntaxhighlight>
 
{{out}}
<lang vbnet>Option Strict On
 
And this is the unit test showing the results. Output is in hexadecimal but is otherwise correct.
Partial Module PartialApplicationDynamic
<syntaxhighlight lang="z80">;;;;;;;;;;;;;;;;;;; HEADER ;;;;;;;;;;;;;;;;;;;
' Create a matching delegate type to simplify delegate creation.
read "\SrcCPC\winape_macros.asm"
Delegate Function fsDelegate(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
read "\SrcCPC\MemoryMap.asm"
Function fs(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
read "\SrcALL\winapeBuildCompat.asm"
' This is exactly what Enumerable.Select does.
;;;;;;;;;;;;;;;;;;; PROGRAM ;;;;;;;;;;;;;;;;;;;
Return s.Select(f)
End Function
 
org &1000
Function ArrayConcat(Of T)(arr1 As T(), arr2 As T()) As T()
Dim result(arr1.Length + arr2.Length - 1) As T
Array.Copy(arr1, result, arr1.Length)
Array.Copy(arr2, 0, result, 1, arr2.Length)
Return result
End Function
 
ld hl,f1
' C# can define ParamArray delegates and VB can consume them, but VB cannot define them on its own.
ld ix,data1
' The argument list of calls to the resulting function thus must be wrapped in a coerced array literal.
ld de,output
' VB also doesn't allow Delegate as a type constraint. :(
ld b,4
' The function is generic solely to ease use for callers. In this case generics aren't providing any type-safety.
call func_fs ;execute f1f(s) on data set 1
Function PartialApplyDynamic(Of TDelegate, TResult)(f As TDelegate, ParamArray args As Object()) As Func(Of Object(), TResult)
Dim del = CType(CObj(f), [Delegate])
Return Function(rest) CType(del.DynamicInvoke(ArrayConcat(args, rest).Cast(Of Object).ToArray()), TResult)
End Function
 
Sub Main()
Dim args1 As Object = New Object() {0, 1, 2, 3}
Dim args2 As Object = New Object() {2, 4, 6, 8}
 
call monitor_memdump ;display the output
Dim fsf1 = PartialApplyDynamic(Of fsDelegate(Of Object, Object), IEnumerable(Of Object))(AddressOf fs, New Func(Of Object, Object)(AddressOf f1))
db 4
Dim fsf2 = PartialApplyDynamic(Of fsDelegate(Of Object, Object), IEnumerable(Of Object))(AddressOf fs, New Func(Of Object, Object)(AddressOf f2))
dw output
 
call newline
' The braces are array literals.
 
Console.WriteLine("fsf1, 0-3: " & String.Join(", ", fsf1({args1})))
ld hl,f1
Console.WriteLine("fsf1, evens: " & String.Join(", ", fsf1({args2})))
ld ix,data2
Console.WriteLine("fsf2, 0-3: " & String.Join(", ", fsf2({args1})))
ld de,output
Console.WriteLine("fsf2, evens: " & String.Join(", ", fsf2({args2})))
ld b,4
End Sub
call func_fs ;;execute f1f(s) on data set 2
End Module</lang>
 
{{out|note=for both versions}}
<pre>fsf1, 0-3: 0, 2, 4, 6
fsf1, evens: 4, 8, 12, 16
fsf2, 0-3: 0, 1, 4, 9
fsf2, evens: 4, 16, 36, 64</pre>
 
call monitor_memdump ;display the output
=={{header|zkl}}==
db 4
<lang zkl>fcn fs(f,s){s.apply(f)} fcn f1(n){n*2} fcn f2(n){n*n}
dw output
var fsf1=fs.fp(f1), fsf2=fs.fp(f2);
 
fsf1([0..3]); //-->L(0,2,4,6)
call newline
fsf2([2..8,2]); //-->L(4,16,36,64)</lang>
 
ld hl,f2
ld ix,data1
ld de,output
ld b,4
call func_fs
 
 
call monitor_memdump
db 4
dw output
 
call newline
 
ld hl,f2
ld ix,data2
ld de,output
ld b,4
call func_fs
 
 
call monitor_memdump
db 4
dw output
 
ret ;return to basic</syntaxhighlight>
 
<pre>;107D = address of output data buffer
107D:
00 02 04 06 ....
 
107D:
04 08 0C 10 ....
 
107D:
00 01 04 09 ....
 
107D:
04 10 24 40 ..$@</pre>
 
{{omit from|Euphoria}}
2,130

edits