1

I am trying to make a curry function like in Lodash http://lodash.com/docs#curry

Unfortunately I am getting two compile errors.

func curry(fun: (Any...)) -> ((Any...) -> (Any)) {
    let count = fun.0.count
    var resultArgs: Any[] = []
    func generator(newArgs: Any...) -> ((Any...) -> (Any))? {
        for (index, elem) in enumerate(newArgs) {
            if resultArgs.count >= count {
                break
            } else {
                resultArgs += elem
            }
        }

        if resultArgs.count >= count {
            // fun(resultArgs)
            // Commenting fun now cause that throws a compile error saying array cannot be passed in Variadic parameter function
            return nil
        } else {
            return generator
        }
    }
    return generator
}

There are two issues here:

  1. Segmentation faults for some reason on the generator function. Idea behind this function is to take parameters and return a new function or not return nothing at all and evaluate the function fun passed in the curry function
  2. Passing array of arguments to a function that accepts Variadic parameters. This should be a given in a language as we can do this using the performSelector in Objective-C

How can I solve these two problems?

I am getting the following error for the generator function which is a segmentation fault during compile time

1.  While emitting IR SIL function @_TTRXFt_oGSaP__oBolGSaP__dSioXFo_oGSaP___oGSqFtGSaP___P____oGSqFtGSaP___P___XFo_oGSaP___oGSqFtGSaP___P___ for 'generator'
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: swift frontend command failed due to signal (use -v to see invocation)
Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254
1
  • There are lots of bugs in the Swift compiler right now. Using a nested function inside itself like you're doing is one of the things that will crash the compiler. e.g. func foo() { func bar() { bar() } } Commented Jun 9, 2014 at 18:12

1 Answer 1

1

This is the closest I got at accepting multiple arguments. It looks like it treats arguments as tuples, according to the error message given for curry2...

func curry<T, U>(fun: (T) -> U) -> (T)->U {
    return fun
}

func curry2(fun: (Any...) -> Any) -> (Any...)->Any {
    return fun
}

func to_curry(a: Int, b: Int) -> Int { return a + b }

func test() {
    curry(to_curry)(3, 5) // returns 8
    curry2(to_curry)(3, 5)
    // tuple types '(Any...)' and '(Int, Int)' have a
    // different number of elements (1 vs. 2)
}

And I can't find any way to count tuples other than doing something like this:

let tuple = (1, 2)
let count = sizeofValue(tuple)/sizeof(Int)
Sign up to request clarification or add additional context in comments.

2 Comments

The solution you have is not a curry function. It only works if you pass both arguments then I would just call the function directly. What I want to do is let add3 = curry(to_curry)(3) and then you can call add3(5) and it will return 8
I just managed to accept a varying number of arguments, didn't get any further than that unfortunately.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.