title: Partial application in LLVM
body: <p>I am trying to create a function "add" that can be applied to a single argument, and subsequently another. I can't figure out how to represent this with LLVM IR, as I don't understand how to call a function with a single value, then save the value somewhere in memory and return another function that is applied to that val. I would need some sort of closure mechanism in LLVM.</p>
  
  <p>I have searched for implementations of this in C so that I could view the emitted LLVM through clang, but the solutions I found were wildly complex, so I thought I might just investigate LLVM directly.</p>
  
  <p>This would be the uncurried version</p>
  
  <pre><code>define i8 @add(i8 %a, i8 %b) {
  entry:
    %res = add i8 %a, %b
    ret i8 %res
  }
  </code></pre>
  
  <p>And somehow I'd like for <code>add(1)</code> to return an <code>i8 (i8)</code> type. I figure I'll have to split the function up somehow.</p>
  
  <p>ps. I am looking into this because I'm working on a compiler for a small functional language, so I'm looking for any advice concering the implementation of partial application/currying in compiler design in general.</p>
  
  <p>Update:
  I now have the following code working, but it's a quite complicated and I don't think it'll be easy to generate automatically</p>
  
  <pre><code>declare i32 @printf(i8* noalias nocapture, ...)
  
  define { i8, i8 (i8, i8) * } @add1(i8 %a) {
    ; allocate the struct containing the supplied argument 
    ; and a function ptr to the actual function
    %nextPtr = alloca { i8, i8 (i8, i8) * }
    store { i8, i8 (i8, i8) * } { i8 undef, i8 (i8, i8) * @add2 }, { i8, i8 (i8, i8) * } * %nextPtr
    %next0 = load { i8, i8 (i8, i8) * } * %nextPtr
  
    ; insert the supplied arg into the struct
    %next1 = insertvalue { i8, i8 (i8, i8) * } %next0, i8 %a, 0
    ret { i8, i8 (i8, i8) * } %next1
  }
  
  define i8 @add2(i8 %a, i8 %b) {
    %res = add i8 %a, %b
    ret i8 %res
  }
  
  define i8 @main() {
    ; call add(35) resulting in 'fn' of type {35, &amp;add2}
    %res1 = call { i8, i8 (i8, i8) * } @add1(i8 35)
  
    ; get the arg of the first call, ie element 0 of the resulting struct
    %arg = extractvalue { i8, i8 (i8, i8) * } %res1, 0
    ; similarily get the function ptr
    %fn = extractvalue { i8, i8 (i8, i8) * } %res1, 1
  
    ; apply the argument to the function
    %res = call i8 %fn(i8 %arg, i8 30)
  
    ; print result  
    %ptr = alloca i8
    store i8 %res, i8* %ptr
    call i32 (i8*, ...)* @printf(i8* %ptr)
  
    ret i8 0
  }
  </code></pre>