Arc Forumnew | comments | leaders | submitlogin
3 points by Pauan 4177 days ago | link | parent

"What do y'all think?"

I think conses are silly and Lisps should use objects instead!

If you insist on using cons, at least make everything immutable, in which case you don't even need copy at all. Yup. That's my stance: accidentally immutable all the things.

---

"The drawback of a deeper copy is that the above function needs to be inlined into arc's list function, which is currently [...]"

pg actually says in the arc.arc source code:

  ; Can return to this def once Rtm gets ac to make all rest args
  ; nil-terminated lists.

  ; (def list args args)
That definition works just fine in Arc/Nu. If it doesn't work right in Anarki, I'd say that's a bug with their compiler that should be fixed. As an added bonus, in Arc/Nu, the above is over 3 times faster than Arc's definition of copylist.

---

"I just noticed today that arc's copy had that additional semantic of merging in new args, and it turned out to be easy to add. Can Nulan add it cleanly? :)"

I'm not sure what you're talking about. Could you clarify please?



1 point by akkartik 4177 days ago | link

I meant the last definition:

  def (copy x ... merge_args) :case merge_args
    ret result copy.x
      each (k v) pair.merge_args
        result.k <- v
I assume Nulan's way of doing extensible copy would be to call an object's %copy method or something like that. But would it be able to handle if the signature for copy changed, or would you have to go update all the %copy methods?

-----

3 points by Pauan 4177 days ago | link

"I assume Nulan's way of doing extensible copy would be to call an object's %copy method or something like that. But would it be able to handle if the signature for copy changed, or would you have to go update all the %copy methods?"

Well, there's no need for copy since everything's immutable in Nulan... but assuming I did want copy, yes there would be a %copy method for objects. And yes, if you changed the signature for the %copy method you'd need to change all the objects.

That's because methods form an interface: if you fulfill the interface, you get the functionality. So naturally if the interface changes, any code that uses that interface will need to change. If you're really worried about backwards compat, you could instead create a new %copy2 interface, etc.

But the copy function itself is not the same as the %copy method. So even if the copy function changed, it might not require changes in the %copy method. It depends on what the changes are.

Looking at that function... it looks like you're saying that this:

  (copy x 'a 5 'b 10)
Would copy "x", and then assign "a" to 5 and "b" to 10, correct? That change would be trivial to do in Nulan, without affecting the %copy method at all. I guess it'd look something like this:

  (def copy -> (let x [ %copy f ]) @r
    (let x (f x)
      (each (pair r) -> [k v]
        (set! x k v))
      x))
Not so different from in wart, eh? Though I'd prefer to use an immutable version that doesn't use set! and boxes. Maybe something like this instead:

  (def copy -> (let x [ %copy f ]) @r
    (foldl (f x) (pair r) -> x [k v]
      (set x k v)))

-----

2 points by Pauan 4177 days ago | link

By the way, in case you're wondering... the %copy signature is this here:

  (f x)
Yeah, that tiny little thing. What that does is it takes the %copy method and calls it with the object as its first argument. That's it. As long as that doesn't change, then there's no need to update the objects.

So, if we wanted to add in some new copy functionality that required us to pass more information to the %copy method, we'd need to change the copy function to pass more arguments to the %copy method, which would require changes to all the objects that use the %copy method.

But in this case, we don't need to pass any more arguments to the %copy method so nothing changes except the copy function itself.

And the copy function uses @r which means "0 or more extra arguments", so it works just fine in the 1-argument case. Thus, this change is backwards compatible in every way (that I care about).

-----

1 point by akkartik 4177 days ago | link

> (def list args args)

Ah, thanks! I'd considered that but desisted out of a vague fear that the quoted-list gotcha might apply here: http://arclanguage.org/item?id=10248

-----

2 points by Pauan 4177 days ago | link

  > (def foo (s) (let a '(3) (= (car a) (cons s (car a)))))
  (3 . 3)
  (3 3 . 3)
  
  > (def foo (s) (let a (list 3) (= (car a) (cons s (car a)))))
  (3 . 3)
  (3 . 3)
  
  > (def foo (s) (let a ((fn args args) 3) (= (car a) (cons s (car a)))))
  (3 . 3)
  (3 . 3)
Yes, this change is fine.

-----