Arc Forumnew | comments | leaders | submitlogin
1 point by Pauan 4433 days ago | link | parent

A quick comparison. First, in Nulan:

  $def %foo (type)
  $def foo
    (%foo F) -> (F 10)
  $def foo-instance { %foo (X -> X + 20) }
  (foo foo-instance)
Now in Arc:

  (def foo (x)
    (x!foo 10))
  (= foo-instance (obj foo (fn (x) (+ x 20))))
  (foo foo-instance)
Now in Arc (hygienic):

  (= foo-t (uniq))
  (def foo (x)
    (x.foo-t 10))
  (= foo-instance (listtab:list
                    (list foo-t (fn (x) (+ x 20)))))
  (foo foo-instance)
Now in JS:

  function foo(x) {
    return x.foo(10)
  }
  var fooInstance = { foo: function (x) { return x + 20 } }
  foo(fooInstance)
Now in Python:

  def foo(x):
    return x["foo"](10)
  fooInstance = { "foo": lambda x: x + 20 }
  foo(fooInstance)
Interestingly enough, Arc and Python are shorter than Nulan by 1 line. But there's a HUGE benefit to the Nulan code: it's hygienic. Arc, JS, and Python use string/symbol keys, which means if you pass in an object that just so happens to have a "foo" key, but different behavior, things will break.

Nulan, however, uses types, which are unique identifiers, so it's impossible to accidentally add a %foo type to something: there's no collision.

As you can see, the hygienic version of the Arc code sucks, because Arc doesn't have a good way to create a hash table where the keys are evaluated. That would be easy to fix with a macro, putting it on par with Nulan. Unfortunately, Arc really isn't designed for this kind of type system, whereas Nulan is. But I can easily imagine a dialect of Arc that uses Nulan's type system.

There's a proposal for ECMAScript to add in Private Names, which are basically just gensyms: http://wiki.ecmascript.org/doku.php?id=strawman:private_name... That would give JS roughly the same capabilities of Nulan, albeit with worse syntax and much more complicated semantics.

Unfortunately, even if it gets added to JS (I sure hope so!) the existing language doesn't make use of it. For instance, arrays have a magical "length" property, where "length" is a string. Maybe that'll get fixed eventually.

---

Oh yeah, and it's possible to use the unhygienic version in Nulan too, by using string keys:

  $def foo
    ("foo" F) -> (F 10)
  $def foo-instance { "foo" (X -> X + 20) }
  (foo foo-instance)
But I don't recommend this. The one place where I'd consider it okay is to have an object as a value of a type:

  $def %foo (type)

  { %foo { "bar"   ...
           "qux"   ...
           "corge" ... } }