Arc Forumnew | comments | leaders | submit | Loup's commentslogin
2 points by Loup 6112 days ago | link | parent | on: could currying be introduced in Arc?

Ahhhrg, too bad. I searched for the topic before posting, but I didn't found anything on it. Well, better live with [+ x _], I suppose. At least, it is compatible with variadic functions.

-----

1 point by absz 6112 days ago | link

You can also have a par function to curry a function:

  (def par (f . args)
    " Partially apply `f' to `args'; i.e., return a function which, when called,
      calls `f' with `args' and the arguments to the new function. "
    (fn newargs (apply f (join args newargs))))
so (par + 42) will do what you want. Also, a generalized swap (which I called flip):

  (def flip (fun)
    " Returns a function which is the same as `fun', but takes its arguments in
      the opposite order. "
    (fn args (apply fun (rev args))))
This works for n-ary functions, but is still probably most useful for functions of two arguments: (par (flip -) 42).

-----

2 points by Loup 6108 days ago | link

Didn't think of "par", cool idea. It could even be turned into a macro, like that:

(par foo x) => [foo x] ; Well maybe too much.

About flip, I'd rather rotate the arguments instead of reverse them. That way, you have access to more arguments orders by composing flip. You could also define flip2, flip3... in the library if they're used often.

-----

1 point by absz 6108 days ago | link

Don't you mean [foo x] => (par foo x)? []s aren't fundamental, they're sugar.

I'm not sure there is a sensible way to extend flip to functions taking more than two arguments. Reverse is one, rotate is another; you might as well have two functions for that. It seems like six of one, half a dozen of the other to me.

-----

1 point by Loup 6112 days ago | link | parent | on: could currying be introduced in Arc?

Optional arguments in Ocaml are labelled (if I remember correctly). They're not used much.

About "rest" arguments, take a look at this (incomplete) definition of +, where prim+ is the primitive definition of +.

(def + (x y @rest) (foldl (prim+) (prim+ x y) rest))

(Is the "@" to denote "rest"?)

Then: (+) => +

(+ 42) => (fn (x) (foldl (prim+) (prim+ 42 x) ())) => (fn (x) (prim+ 42 x))

(+ 42 24) => (foldl (prim+) (prim+ 42 24) ()) => 66

(+ 42 24 34) => (foldl (prim+) (prim+ 42 24) '(66)) => 100

This principle can be generalized to any function with a "rest", and to any function with optional arguments (provided they are at the end of the argument list).

Yes, currying should be disabled with macros. But they already are. Macro aren't plain functions. They can't be, with their special evaluation scheme. What is true is that macros and functions from list to lists are isomorphic. So, if I define a macro whose result is an integer, I bet the compiler will kindly notify my blunder when trying to make a list from this integer (right?). Same thing if the macro yields a function. So, any partial application in macro will automatically result in an error, and that particular error should be caught at parse/compile time by any descent Arc compiler.

-----

3 points by absz 6112 days ago | link

Except the primitive definition of + is still variadic. Any function declared as

  (def foo args
    (munge (frob args)))
will be uncurriable, which is the problem.

-----

1 point by almkglor 6112 days ago | link

> So, if I define a macro whose result is an integer, I bet the compiler will kindly notify my blunder when trying to make a list from this integer (right?). Same thing if the macro yields a function.

No, it won't. Because a macro returns an object which is inserted into the code. It's usually a list, but not always. It can be an integer, it can be a function object, and unfortunately the underlying mzscheme doesn't allow tables.

-----