Arc Forumnew | comments | leaders | submitlogin
2 points by rocketnia 5251 days ago | link | parent

What do you like about having an object system, specifically? I wouldn't mind having one too, but I think object systems get complicated and arbitrary very quickly. I'd rather not have one monolithic abstraction where several highly-focused ones would do.

I do find myself switching to Groovy a lot thanks to its object system. I think what I mainly like is the ability to make an instance of FooSubclass and automatically have "foo in FooSuperclass" and "foo in FooInterface" be true.

Using Arc's built-in notion that the type of an object is the result of calling the 'type function on it (which is configurable via 'annotate), it's easy enough to achieve a form of inheritance that accomplishes what I just described:

  ; This is a table from type symbols to lists of their supertypes.
  ; Indirect supertypes are included in these lists, but no type is a
  ; member of its own list. There are no inheritance loops, either;
  ; inheritance here is a directed acyclic graph, and this is the
  ; transitive closure of that graph.
  (= indirect-inheritance* (table))
  
  (def inherits (subtype supertype)
    (~~mem supertype (cons subtype indirect-inheritance*.subtype)))
  
  (def fn-def-inherits (subtype . supertypes)
    (each supertype supertypes
      (when (~inherits subtype supertype)
        (when (inherits supertype subtype)
          (err "There was an inheritance loop."))
        (let supers (cons supertype indirect-inheritance*.supertype)
          (zap [union is supers _] indirect-inheritance*.subtype)
          (each (k v) indirect-inheritance*
            (when (mem subtype v)
              (zap [union is supers _] indirect-inheritance*.k)))))))
  
  (mac def-inherits (subtype . supertypes)
    `(fn-def-inherits ',subtype ,@(map [do `',_] supertypes)))
  
  (def isinstance (x test-type)
    (inherits type.x test-type))
  
  (def a- (test-type)
    [isinstance _ test-type])
Come to think of it, I can't think of anything else object-oriented I miss in Arc. (OO is good for dispatch too, but I've already made an Arc dispatch library I like better.) I'll make sure to try this out the next time I program something substantial in Arc.

So, I've talked a lot about me, but my question to you still stands. What features are you looking for in an object system?



3 points by ylando 5250 days ago | link

In my own opinion:

The most important feature of object oriented is name compressing. Imagine a program with a lot of different databases. Now you have to give names for functions that add element, You will have to give them names like:

  add-worker, add-statistic, add-html-text ...
Now you have to remember all those names.

-----

3 points by rocketnia 5249 days ago | link

That sounds like dispatch to me. ^_^ You'd like to use one name but give it multiple meanings based on the types involved. This thread (http://arclanguage.org/item?id=11779) has a couple of approaches to dispatch from akkartik and myself.

Hmm, I've been having trouble for a while, trying to figure out my favorite way to have inheritance and multiple dispatch at the same time. (Single dispatch with inheritance seems more straightforward, but I'd rather not bother with it if I could use multiple dispatch instead.) If one method signature is (A, B) -> C, and another is (B, A) -> C, and A is a subtype of B, then what happens if you call the method with (a, a)? That could just cause an error, or the first argument could take precedence, but I'm not sure which approach I like better.

-----

1 point by ylando 5249 days ago | link

I think that multi dispatch is good idea for strong type languages. If c++ encounters this problem it will solve it at compile time (I think it will try to find the solution that is best for the first variable then the second and so on). For a dynamic language like arc multi dispatch will have an efficiency cost. In my own opinion:

It is one of the "too smart to be useful" features of common lisp. It is one of the reason people hate clos.

I have a question for you: In what way a multi dispath is better then the alternatives? You can dispatch only on the first argument or hold a virtual table of functions for every object.

-----

1 point by rocketnia 5249 days ago | link

For a dynamic language like arc multi dispatch will have an efficiency cost.

I don't think the efficiency cost for dynamic dispatch on the first argument would be significantly different, and I'm not worried about either one. I think they're at worst as inefficient as a sequence of if statements, which is to say they would take constant time (given a constant number of methods to check and constant time for each check).

Constant time can still be painful in the right quantity, and making the decision at compile time would indeed help, but Arc doesn't have the necessary static type information to go on (as you know). So multiple dispatch and single dispatch alike have to suffer a bit.

It is one of the reasons people hate clos.

Well, I've heard nothing but good things about CLOS, but then I haven't heard that much. ^_^ Is there some good anti-CLOS reading material you can recommend? XD

In what way is multi dispatch better then the alternatives?

It's partly a matter of name compression. ^_-

  ; no dispatch
  (collide-spaceship-with-spaceship s s)
  (collide-spaceship-with-asteroid s a)
  (collide-asteroid-with-spaceship a s)
  (collide-asteroid-with-asteroid a a)
  
  ; single dispatch (on the first argument)
  (collide-with-spaceship s s)
  (collide-with-asteroid s a)
  (collide-with-spaceship a s)
  (collide-with-asteroid a a)
  
  ; double dispatch
  (collide a s)
  (collide s a)
  (collide a s)
  (collide a a)
Yeah, I stole Wikipedia's example here. Another example is a comparison function that needs to compare values of many different types. Yet another is a "write" function which has different behavior for each type of writer object and each type of object to be written.

When it comes right down to it, I just believe multiple dispatch ought to be a simpler concept than single dispatch, since it imposes fewer restrictions on the programmer. Unfortunately, it seems to replace one arbitrary restriction with a bunch of (what I see as) arbitrary design decisions. ^_^;

-----

0 points by ylando 5249 days ago | link

For every one of your examples, we can use double dispatch design pattern; For example:

  (collide o1 o2) call 
  (collide-with-spaceship o2 o1) if o1 is a spaceship
  or (collide-with-asteroid o2 o1) if o1 is an asteroid.
I think that you can even abstract this design pattern with a macro (but I did not try it). So you still did not convince me that multi dispatch is a good feature.

-----