Arc Forumnew | comments | leaders | submitlogin
2 points by cchooper 5639 days ago | link | parent

And here's a function that performs true currying on a function:

  (def curry (f n (o args nil))
    (if (is 0 n) (apply f (rev args))
        (fn (x) (curry f (- n 1) (cons x args)))))
An example of usage:

  (subst "bar" "foo" "catfood")
  => "catbard"

  (= curried-subst (curry subst 3))

  (((curried-subst "bar") "foo") "catfood")
  => "catbard"


1 point by shader 5639 days ago | link

What if you wanted to curry the function in a different order? :)

I suppose you would just curry a shadow function? Or could a utility/macro be made to easily map one order of parameters to another?

-----

1 point by cchooper 5639 days ago | link

The problem is: what's a concise way of expressing the new order? Perhaps something like this:

  ((reorder foo (x y z) (z x y)) 1 2 3)
but it's so clunky it's not really worth it. If you could reflect on functions to see their parameter list, then you could do this:

  (def foo (x y z) ...stuff...)

  ((reorder foo (z x y)) 1 2 3)
A little better.

-----

2 points by Darmani 5639 days ago | link

May give you a few ideas: http://en.wikipedia.org/wiki/Permutation_group

-----

1 point by cchooper 5639 days ago | link

Ah yes, cycle notation!

  ; convert a cycle into transpositions
  (def trans (cycle (o first nil))
    (if (no cycle) nil
        (~cdr cycle) (list:list cycle.0 first)
        (cons (list cycle.0 cycle.1)
              (trans (cdr cycle) 
                     (if first first cycle.0)))))

  ; permute a list using a list of disjoint cycles
  (def permute (cycles l)
    (with (ts (apply join (map trans cycles))
           ret (copy l))
      (map [= (ret (- _.1 1)) (l (- _.0 1))] ts)
      ret))

  (permute '((1 2 3) (4 5)) '(a b c d e))
  => (c a b e d)

-----

2 points by shader 5638 days ago | link

hmm. I think that cycle notation is sometimes shorter than just stating the final positions, but only rarely.

How about a function that does:

  >(reorder '(2 5 4 1 3) '(a b c d e))
  '(b e d a c)
That makes more sense in many cases. But having a function that does permutations using cycle notation is probably also useful.

-----