ethereum / moon-lang

Minimal code-interchange format
MIT License
193 stars 20 forks source link

Feature: Variable number of arguments seems really powerful! #2

Closed AnthonyJacob closed 7 years ago

AnthonyJacob commented 7 years ago

I have not realized until now, how powerful actually that feature is

(andThen '(1 2 3)
  (map (add 1))
  (filter (lt 3))
  (take 10)
)
VictorTaelin commented 7 years ago

Not sure if this is a feature request or a comment, but variable number of arguments are expressible on the λ-calculus (and, thus, Moon)! Take this, for example:

sum: 
  roll: self. r. x.
    (if (eql x 0)
      r
      (self self (add x r))
    (self self 0))
  (roll roll)

(sum 1 2 3 4 5 0)

This keeps summing all arguments it receives until it receives 0. Note, though, that this style is often considered bad; it introduces non-termination, has no normal form and wouldn't be typeable in a total fragment of Moon. What you want, 99% of the cases, is to fold over a list. For example, the right way to implement your andThen is with:

with: val. fns.
  (for 0 (get fns "length") val i.result.
    (get fns (nts i) result))

(with 3 [
  (add 1)
  (mul 2)
  (add 100)
])

Notice how it looks basically the same, but now everything has a normal form. Your "multi-argument" map can be expressed the same way. For example, you could do this:

map: cons. matrix.
  w: (get matrix "length")
  h: (get (get matrix "0") "length")
  (arrayGenerate 0 h i.
    (for 0 w cons j. fn.
      (fn (get (get matrix (nts j)) (nts i)))))

add3: a. b. c. (add a (add b c))

(map add3 [[1 2 3 4 5] [1 1 1 1 1] [10 10 10 10 10]])

Which uses add3 and sucks, but this could, too, be avoided with folds:

map: cons. nil. matrix.
  w: (get matrix "length")
  h: (get (get matrix "0") "length")
  (arrayGenerate 0 h i.
    (for 0 w nil j. 
      (cons (get (get matrix (nts j)) (nts i)))))

(map (add) 0 [[1 2 3 4 5] [1 1 1 1 1] [10 10 10 10 10]])

Here, map performs a cross-column fold, you just need a 2 argument function and an initial value. No need to implement multiple-argument functions! In fact, that map is quite useful, so it is now added to moon-base under the name arrayCrossWith.