Arc Forumnew | comments | leaders | submitlogin
Arc suggestion
5 points by d0m 5357 days ago | 3 comments
It would be nice if [] could act as a currying function if _ isn't present.

For instance:

(map [+ 10 _] '(1 2 3))

could be rewritten as:

(map [+ 10] '(1 2 3))

Or, taken directly from the tutorial:

arc> (trues [if (odd _) (+ _ 10)] '(1 2 3 4 5))

could be rewritten as:

(trues [if [odd] [+ 10]] '(1 2 3 4 5))

which is arguably simpler and clearer.

And by the way, _ could also be usable as before such as:

(filter [> _ 10] (range 1 100)).

And last thing, I know it won't change but, I'd much more prefer x than _ as [] variable. I know _ has been a long time place-holder, but in maths, x is practically always used as temporary variable. i.e. I like way better: [> x 2] than [> _ 2].

:)



5 points by fallintothis 5357 days ago | link

  (trues [if [odd] [+ 10]] '(1 2 3 4 5))
The currying idea is sound, but I don't see how this example would work. That is, I can see that

  [+ 10]
maps to

  (fn _ (apply + 10 _))
But applying the same transformation to

  [if [odd] [+ 10]]
yields

  (fn _ (apply if [odd] [+ 10] _)) ; ?
You could use another function like Anarki's iff (http://github.com/nex3/arc/blob/master/lib/util.arc#L198):

  (trues (iff odd [+ 10]) '(1 2 3 4 5)) ; note that [odd] == odd
Except you'd need to make iff's else clause default to returning nil. (I'm not sure why it doesn't do this now, but I don't use Anarki.)

It's an interesting idea, though. Currying in Arc has traditionally been a belabored topic with no clear "winner". One potential sticking point is that sometimes [] is used without _ to simply ignore the argument:

  $ grep -P "^[^;]*\[[^\]_]*\]" *.arc
  arc.arc:                     (let argsyms (map [uniq] (cdr expr))
  arc.arc:  (with (vars (map [uniq] places)
  arc.arc:         gargs  (map [uniq] args)

  [7 false positives elided (stuff in strings): 1 from blog.arc, 6 from news.arc]

  news.arc:            (flink [submit-login-warning url title showtext text])
  news.arc:            (flink [submit-page user url title showtext text retry*])
  news.arc:            (flink [submit-page user url title showtext text toolong*])
  news.arc:            (flink [submit-page user url title showtext text bothblank*])
  news.arc:            (flink [msgpage user spammage*])
  news.arc:            (flink [msgpage user toofast*])
  news.arc:       (flink [newpoll-page user title text opts retry*])
  news.arc:       (flink [newpoll-page user title text opts toolong*])
  news.arc:       (flink [newpoll-page user title text opts fewopts*])
  news.arc:       (flink [comment-login-warning parent whence text])
  news.arc:       (flink [msgpage user toofast*])
And last thing, I know it won't change but, I'd much more prefer x than _ as [] variable.

You're right, it probably won't change, but I think it's for a good reason -- indeed, the reason you mention: x is a common variable, so it's used in regular functions a lot. For example, in arc.arc:

  (def testify (x)
    (if (isa x 'fn) x [is _ x]))

  (def adjoin (x xs (o test iso))
    (if (some [test x _] xs)
        xs
        (cons x xs)))

  (def intersperse (x ys)
    (and ys (cons (car ys)
                  (mappend [list x _] (cdr ys)))))
It would apply pressure to not use x as a variable name in normal functions, which is livable but unpleasant. Compare to _, which has the aesthetic appeal of a blank to fill in and doesn't conflict with common variables.

-----

2 points by d0m 5357 days ago | link

Thanks for answer. You are right, my example doesn't work :p However, I still think that currying is important as it simplifies nested code a lot.

Maybe:

(map {+ 10} '(1 2 3))

Or maybe, it should just be a convention in arc that when not enough parameters are given, a currying function is returned. So we could do:

(map (+ 10) '(1 2 3))

even if I know it may break a lot of things :p

-----

Also, I feel that, from a good coding perspective, x is great as a temporary variable in []. In fact, it might be a good thing that the programmer is forced to use a good variable name instead of x for normal arguments.

To take your example:

(def testify (x) (if (isa x 'fn) x [is _ x]))

(def testify (type) (if (isa type 'fn) type [is x type]))

-----

3 points by evanrmurphy 5357 days ago | link

ac.scm contains this comment about currying:

  ; Though graphically the right choice, can't use _ for currying
  ; because then _!foo becomes a function.  Maybe use <>.  For now
  ; leave this off and see how often it would have been useful.
And this other one:

  ; Non-fn constants in functional position are valuable real estate, so
  ; should figure out the best way to exploit it.  What could (1 foo) or 
  ; ('a foo) mean?  Maybe it should mean currying.

-----