Arc Forumnew | comments | leaders | submitlogin
Simple higher-order operations
4 points by fallintothis 4234 days ago | discuss
Higher-order functions have such aesthetic appeal, but I feel like we can never find enough spots to use them. I've been sitting some interesting ones of my own, but realized that I have no reason to keep them to myself. Anyone else want to share theirs? I'll start.

---

  (def has (property value)
    [(testify value) (property _)])

  (def hasnt (property value)
    [no ((testify value) (property _))])
E.g.,

  arc> (= xs (tokens "the quick brown fox jumped over the lazy red dog"))
  arc> (keep (has len 4) xs)
  ("over" "lazy")
  arc> (all (has type 'string) xs)
  t
  arc> (rem (hasnt len odd) xs)
  ("the" "quick" "brown" "fox" "the" "red" "dog")
---

  (mac not (f . xs)
    (if xs
        `(no (,f ,@xs))
        `(complement ,f)))
Thus

  arc> (mem 5 '(1 2 3))
  nil
  arc> (not mem 5 '(1 2 3))
  t
  arc> (keep (not even) '(1 2 3))
  (1 3)
Ssyntax makes this one useless, but I like it.

---

There are higher-order functions that work OK on their own...

  (def less (measure)
    (compare < measure))

  (def same (measure)
    (compare is measure))

  (def more (measure)
    (compare > measure))
...but could be made better with currying:

  ; Partial application hack
  (w/uniq missing
    (def less (measure (o x missing) (o y missing))
      (let f (compare < measure)
        (if (is x missing) (fn (a b) (f a b))
            (is y missing) (fn (a) (f a x))
                           (f x y))))

    (def same (measure (o x missing) (o y missing))
      (let f (compare is measure)
        (if (is x missing) (fn (a b) (f a b))
            (is y missing) (fn (b) (f x b))
                           (f x y))))

    (def more (measure (o x missing) (o y missing))
      (let f (compare > measure)
        (if (is x missing) (fn (a b) (f a b))
            (is y missing) (fn (a) (f a x))
                           (f x y))))
  )
Thus, all the following work.

  (def least (measure seq)
    (best (less measure) seq))

  (def most (measure seq)
    (best (more measure) seq))

  arc> (keep (less len "me") '("you" "I"))
  ("I")
  arc> (keep (more len "me") '("you" "I"))
  ("you")
  arc> (keep (same len "you") '("him" "her" "me" "myself" "I"))
  ("him" "her")
  arc> (less len "you" "me")
  nil
  arc> (more len "you" "me")
  t
  arc> (map (same len) '("a" "bb" "ccc") '("ccc" "bb" "a"))
  (nil t nil)
---

Simple and generally unnecessary, but they read nicely enough:

  (def both (f x y)
    (and (f x) (f y)))

  (def either (f x y)
    (or (f x) (f y)))