Using Swift struct Constructor as Function - function

Given a struct S defined in this way
struct S {
let a : String
let b : Int
let c : Bool
}
and a function sConstructorFun
func sConstructorFun(#a:String, #b:Int, #c:Bool) -> S {
return S(a:a, b:b, c:c)
}
I can use both sConstructorFun(a:"", b:1, c:false) and S(a:"", b:1, c:false) to get the following S value (as the REPL outputs it)
S = {
a = ""
b = 1
c = false
}
So S and sConstructorFun have the very same interface and unsurprisingly return the same result.
However, a sFactory function defined as follows
func sFactory(f:(String, Int, Bool) -> S) -> S {
return f("foo", 42, false)
}
can only be used with the sConstructorFun but not with S directly:
REPL> sFactory(sConstructorFun)
$R2: S = {
a = "foo"
b = 42
c = false
}
and
REPL> sFactory(S)
repl.swift:18:1: error: cannot invoke 'sFactory' with no arguments
sFactory(S)
^
repl.swift:18:9: note: expected an argument list of type '((String, Int, Bool) -> S)'
sFactory(S)
^
Is there any way of using the default constructor of a struct (S in this example) as a function (without defining a new function/closure to do so)?

You just need to put the default constructor inside of a closure and pass that to the sFactory function. Try this:
let f = { S(a: $0, b: $1, c: $2) }
func sFactory(f:(String, Int, Bool) -> S) -> S {
return f("foo", 42, false)
}
let s = sFactory(f)
println("s = (a: \(s.a), b: \(s.b), c: \(s.c))") // S = (a: foo, b: 42, c: false)

Not very clear to me your intent, but maybe you are looking for constructors like these:
extension S {
init (f: (a: String, b: Int, c: Bool) -> S) {
self = f(a: "foo", b: 1, c: true)
}
init(f: () -> S) {
self = f()
}
}

Related

Kotlin - Pass a function and its arguments to a reusable handler function

My problem comes from an error handler that I need to write. The handler is meant to catch an error, do an action 'A', and then proceed to retry the original function that failed in the first place. The blocker comes when I need to generalise the handler to be able to accept any function definition.
For example:
fun foo(a: Any) {
// Do something and return null if unsuccessful
}
fun bar(b: Any, c: Any) {
// Do something else and return false if unsuccessful
}
fun handler(fn: Function???, args: Array[arguments???]) {
log.warn("Error has been caught at <${functionName}>, doing action A and retrying")
// Do action A
log.warn("Retrying <${functionName}>")
fn(args)
}
fun main() {
val resultFoo = foo('bar')
if (resultFoo == null) {
handler(foo, ['bar'])
}
val resultBar = bar('foo', { 'foo': 'bar' })
if (!resultBar) {
handler(bar, ['foo', { 'foo': 'bar' }])
}
}
As you can see, I have two functions foo and bar with different definitions which I would like to be able to call from handler. Otherwise I would need to copy-paste the body inside handler to each individual function and handle the error inside there. I was hoping to be able to generalise this and be able to reuse it.
If you want to avoid reflection, which would provide no compile-time error checking, you should overload your function to have variants with different numbers of variables. Then you can use generics, and you'll get compile-time checking.
There's not a clean way to pass functions along with their names, so I made the name for logging a separate argument in this example.
// zero args handler
inline fun <R> handler(loggedFunctionName: String?, fn: ()->R): R {
val functionName = "<$loggedFunctionName>" ?: "function"
log.warn("Error has been caught at $functionName, doing action A and retrying")
// Do action A
log.warn("Retrying $functionName")
return fn()
}
// one arg handler
inline fun <A, R> handler(loggedFunctionName: String?, fn: (A)->R, argA: A): R
= handler(loggedFunctionName) { fn(argA) }
// two args handler
inline fun <A, B, R> handler(loggedFunctionName: String?, fn: (A, B)->R, argA: A, argB: B): R
= handler(loggedFunctionName) { fn(argA, argB) }
fun main() {
val resultFoo = foo("bar")
if (resultFoo == null) {
handler("foo", ::foo, "arg")
}
val resultBar = bar("arg1", "arg2")
if (!resultBar) {
handler("bar", ::bar, "arg1", "arg2")
}
}
However, it seems you could reduce boilerplate further by incorporating your logical test of the result as another argument:
// zero args handler
inline fun <R> handler(loggedFunctionName: String?, fn: ()->R, verifyResult: (R)->Boolean): R {
val firstResult = fn()
if (verifyResult(firstResult)){
return firstResult
}
val functionName = "<$loggedFunctionName>" ?: "function"
log.warn("Error has been caught at $functionName, doing action A and retrying")
// Do action A
log.warn("Retrying $functionName")
return fn()
}
// one arg handler
inline fun <A, R> handler(loggedFunctionName: String?, fn: (A)->R, verifyResult: (R)->Boolean, argA: A): R
= handler(loggedFunctionName, { fn(argA) }, verifyResult)
// two args handler
inline fun <A, B, R> handler(loggedFunctionName: String?, fn: (A, B)->R, verifyResult: (R)->Boolean, argA: A, argB: B): R
= handler(loggedFunctionName, { fn(argA, argB) }, verifyResult)
fun main() {
handler("foo", ::foo, { it != null }, "arg")
handler("bar", ::bar, { it }, "arg1", "arg2")
}
First of all you need to know, what exactly you want to generalize.
As I can see from your example, you want to repeat function call with same arguments. So instead all this messing with argument-arrays you can wrap payload (function call with arguments) into lambda and call it twice.
Second question is repeat condition. In foo it's result == null, in bar it's result == false. So condition is different for different functions. You can calculate condition in separate lambda.
So you can write something like this:
fun <T, F: KFunction<*>> F.callAndRepeatOnCondition (
payload: (F) -> T,
condition: (T) -> Boolean,
): T {
var result = payload(this)
if (condition(result)) {
println("log: doing something and repeat function ${this.name} ")
println("some super logic before repeat")
result = payload(this)
}
return result
}
fun foo(a: Int, b: String): String? { return null }
fun bar(c: Int): Boolean { return false }
fun main() {
val resultFoo = ::foo.callAndRepeatOnCondition({ it(1, "a") }, { it == null })
val resultBar = ::bar.callAndRepeatOnCondition({ it(2) }, { !it })
}
PS. If you don't need to log function name or can pass it explicitly, here is a little less ugly solution:
fun foo(a: Int, b: String): String? { return null }
fun bar(c: Int): Boolean { return false }
fun <T> (() -> T).repeatIf(condition: (T) -> Boolean): T {
val result = this()
if (!condition(result)) return result
println("some super logic before repeat")
return this()
}
fun <T> (() -> T).repeatWithLoggingIf(logName: String, condition: (T) -> Boolean): T {
val result = this()
if (!condition(result)) return result
println("log: repeating $logName")
println("some super logic before repeat")
return this()
}
fun main() {
run { // without logName
val resultFoo = { foo(1, "a") }.repeatIf { it == null }
val resultBar = { bar(2) }.repeatIf { !it }
}
run { // with logName
val resultFoo = { foo(1, "a") }.repeatWithLoggingIf("foo") { it == null }
val resultBar = { bar(2) }.repeatWithLoggingIf("bar") { !it }
}
}

Programatically creating an iterator from mapping functions in Rust

I'm trying to write code like the following, but where I apply f1 and f2 some variable number of times:
#![feature(impl_trait_in_bindings)]
fn f1(c: char) -> impl IntoIterator<Item = char> {
vec!['A', c]
}
fn f2(c: char) -> impl IntoIterator<Item = char> {
vec!['C', 'D', c]
}
fn main() {
let x = vec!['X', 'X', 'X'];
let v: impl Iterator<Item = char> = x.into_iter();
let v = v.flat_map(f1);
let v = v.flat_map(f2);
println!("Force evaluation of five elements: {:?}", v.take(5).collect::<Vec<_>>());
}
I'd like to replace the let v = ... lines with a loop that iteratively reassigns v, like
let mut v: impl Iterator<Item = char> = x.into_iter();
for i in 0..f1Times {
v = v.flat_map(f1);
}
for i in 0..f2Times {
v = v.flat_map(f2);
}
... e.g. for my use case I may have several functions and I won't know which ones (or how many times) to apply ahead of time. I'd like the result to be an iterator that I can take only a limited number of items from, and I'd like to avoid invoking any functions that aren't needed to generate those items.
I can't get the types to work. For instance with the let mut block I proposed above I get:
mismatched types
expected opaque type `impl Iterator`
found struct `FlatMap<impl Iterator, impl IntoIterator, fn(char) -> impl IntoIterator {f1}>`
Is there a good way to build up this sort of iterator programatically?
I've found this pattern works, but still don't know if it's idiomatic or recommended...
#![feature(impl_trait_in_bindings)]
fn f1(c: char) -> impl Iterator<Item = char> {
Box::new(vec!['A', c].into_iter())
}
fn f2(c: char) -> impl Iterator<Item = char> {
Box::new(vec!['C', 'D', c].into_iter())
}
fn main() {
let x = vec!['X', 'X', 'X'];
let mut v: Box<dyn Iterator<Item = char>> = Box::new(x.into_iter());
let f1_ntimes = 2;
for _i in 0..f1NTimes {
v = Box::new(v.into_iter().flat_map(f1));
}
let f2_ntimes = 2;
for _i in 0..f2_ntimes {
v = Box::new(v.into_iter().flat_map(f2));
}
println!("Force evaluation of five elements: {:?}", v.take(5).collect::<Vec<_>>());
}

How do I write a function that returns itself?

What I want to make is a function, that returns itself, so I can call it like this:
foo()()...()
In C# it would be done via delegates:
delegate SelfFunc SelfFunc();
static void Main() {
SelfFunc foo = null;
foo = () => {
return foo;
};
foo()()...();
}
Anticipating questions like "why implement such silly behavior?": I want to sum numbers in a very strange way using single function continues calls: foo(1)(2)(3)() = 6, but in this question I just want to know how to return function itself. Example realization of this method that I made in C#. This is all just for fun and to learn Rust:
static int sum = 0;
delegate dynamic InfFunc(int i = int.MaxValue);
static void InfFuncTest() {
InfFunc f = null;
f = (int i) => {
if(i == int.MaxValue) {
return sum;
}
sum += i;
return f;
};
var g = f;
var value = g(1)(2)(3)();
Console.WriteLine(value);
}
A function that returns itself is possible on nightly.
First you need to enable the features unboxed_closures and fn_traits.
Then you can define a struct which, when called, returns self. The full code looks something like this:
#![feature(unboxed_closures, fn_traits)]
struct SelfFunc;
impl FnOnce<()> for SelfFunc {
type Output = SelfFunc;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self
}
}
Then you can call the function as many times as you want:
fn main() {
let f = SelfFunc;
f()()()()()();
}
Based on #cameron1024's answer, you can "overload" using traits, but you will need 2 structs to handle the empty case properly of foo() (here called Add) without any arguments returning 0.
#![feature(unboxed_closures, fn_traits)]
struct Add;
impl FnOnce<(u32,)> for Add {
type Output = AddImpl;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
AddImpl(args.0)
}
}
impl FnOnce<()> for Add {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
0
}
}
struct AddImpl(u32);
impl FnOnce<()> for AddImpl {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self.0
}
}
impl FnOnce<(u32,)> for AddImpl {
type Output = AddImpl;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
Self(self.0 + args.0)
}
}
fn main() {
dbg!( Add(1)(2)(3)() );
dbg!( Add() );
}
Playground
If you do not care about the no-args foo() requirement, you can make Add a tuple struct instead and remove AddImpl:
#![feature(unboxed_closures, fn_traits)]
struct Add(u32);
impl FnOnce<(u32,)> for Add {
type Output = Add;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
Add(self.0 + args.0)
}
}
impl FnOnce<()> for Add {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self.0
}
}
fn main() {
dbg!( Add(1)(2)(3)() );
//dbg!( Add() ); // doesn't compile
}
Playground
Although I should note that this likely isn't such a great idea, using an slice/iterator would likely result in cleaner code:
fn main() {
dbg!([1, 2, 3].iter().copied().sum::<u32>());
}
Playground

Swift - Make the labels on constructor parameters optional?

Let's say, for instance, you have the following code:
struct SomeStruct {
init (arg1: String, arg2: Int){
// Does Stuff with Variables
}
}
// Some Point Later
var str = "fasfsad"
var integer = 343
let smth = SomeStruct(arg1: str, arg2: integer)
Is it possible to modify the SomeStruct struct to make the following line of code legal?
let smth = SomeStruct(str, integer)
Yes, you can make the parameters anonymous by using an underscore for the external parameter name:
struct SomeStruct {
init (_ arg1: String, _ arg2: Int){
// Does Stuff with Variables
}
}
Here is how you can do this:
struct A {
var a: String
var b: String
init(_ a: String,_ b: String) {
self.a = a
self.b = b
}
}
var x = A("S", "B")

Can functions be passed as parameters?

In Java I can do something like
derp(new Runnable { public void run () { /* run this sometime later */ } })
and "run" the code in the method later. It's a pain to handle (anonymous inner class), but it can be done.
Does Go have something that can facilitate a function/callback being passed in as a parameter?
Yes, consider some of these examples:
package main
import "fmt"
// convert types take an int and return a string value.
type convert func(int) string
// value implements convert, returning x as string.
func value(x int) string {
return fmt.Sprintf("%v", x)
}
// quote123 passes 123 to convert func and returns quoted string.
func quote123(fn convert) string {
return fmt.Sprintf("%q", fn(123))
}
func main() {
var result string
result = value(123)
fmt.Println(result)
// Output: 123
result = quote123(value)
fmt.Println(result)
// Output: "123"
result = quote123(func(x int) string { return fmt.Sprintf("%b", x) })
fmt.Println(result)
// Output: "1111011"
foo := func(x int) string { return "foo" }
result = quote123(foo)
fmt.Println(result)
// Output: "foo"
_ = convert(foo) // confirm foo satisfies convert at runtime
// fails due to argument type
// _ = convert(func(x float64) string { return "" })
}
Play: http://play.golang.org/p/XNMtrDUDS0
Tour: https://tour.golang.org/moretypes/25 (Function Closures)
You can pass function as parameter to a Go function. Here is an example of passing function as parameter to another Go function:
package main
import "fmt"
type fn func(int)
func myfn1(i int) {
fmt.Printf("\ni is %v", i)
}
func myfn2(i int) {
fmt.Printf("\ni is %v", i)
}
func test(f fn, val int) {
f(val)
}
func main() {
test(myfn1, 123)
test(myfn2, 321)
}
You can try this out at: https://play.golang.org/p/9mAOUWGp0k
Here is the sample "Map" implementation in Go. Hope this helps!!
func square(num int) int {
return num * num
}
func mapper(f func(int) int, alist []int) []int {
var a = make([]int, len(alist), len(alist))
for index, val := range alist {
a[index] = f(val)
}
return a
}
func main() {
alist := []int{4, 5, 6, 7}
result := mapper(square, alist)
fmt.Println(result)
}
Here is a simple example:
package main
import "fmt"
func plusTwo() (func(v int) (int)) {
return func(v int) (int) {
return v+2
}
}
func plusX(x int) (func(v int) (int)) {
return func(v int) (int) {
return v+x
}
}
func main() {
p := plusTwo()
fmt.Printf("3+2: %d\n", p(3))
px := plusX(3)
fmt.Printf("3+3: %d\n", px(3))
}
This is the simplest way I can come with.
package main
import "fmt"
func main() {
g := greeting
getFunc(g)
}
func getFunc(f func()) {
f()
}
func greeting() {
fmt.Println("Hello")
}
I hope the below example will provide more clarity.
package main
type EmployeeManager struct{
category string
city string
calculateSalary func() int64
}
func NewEmployeeManager() (*EmployeeManager,error){
return &EmployeeManager{
category : "MANAGEMENT",
city : "NY",
calculateSalary: func() int64 {
var calculatedSalary int64
// some formula
return calculatedSalary
},
},nil
}
func (self *EmployeeManager) emWithSalaryCalculation(){
self.calculateSalary = func() int64 {
var calculatedSalary int64
// some new formula
return calculatedSalary
}
}
func updateEmployeeInfo(em EmployeeManager){
// Some code
}
func processEmployee(){
updateEmployeeInfo(struct {
category string
city string
calculateSalary func() int64
}{category: "", city: "", calculateSalary: func() int64 {
var calculatedSalary int64
// some new formula
return calculatedSalary
}})
}
You can also pass the function of a struct, like:
package main
// define struct
type Apple struct {}
// return apple's color
func (Apple) GetColor() string {
return "Red"
}
func main () {
// instantiate
myApple := Apple{}
// put the func in a variable
theFunc := myApple.GetColor
// execute the variable as a function
color := theFunc()
print(color)
}
output will be "Red", check on the playground
Yes Go does accept first-class functions.
See the article "First Class Functions in Go" for useful links.