Naw, it's not needed on the right column. `each` works out-of-the-box with my object.arc library. Though you could probably do the same thing with wart, if you wanted to.
Basically, if the object has a `keys` attribute, it uses that, otherwise it iterates over the object's attributes. So by extending maptable, my library gets keys, vals, and each, all for free.
This lovely property is because of Arc, though, not my library.
---
However, it does demonstrate that it's more convenient to simply create an object, rather than having to create a new type (like 'heir) and then use defcall, defcoerce, etc.
So the real point isn't that my library is perfect, the point is that our current way of thinking of types is flawed. We should either try to improve it (which my library does), or dump it entirely and use something completely different (rocketnia seems to prefer this approach).
Ultimately, I think the reason dealing with data types is clunky is because our type model is clunky. extend vs. objects is an interesting debate, but as you pointed out, with proper support, extend is more-or-less just as concise as objects in most circumstances.
So the real question is about dealing with types. How do we differentiate different things? My object.arc library provides one possible way. Using extend provides a slightly different way.
Because really, that's what my library is all about. If it's shorter than using extend, that's a nice bonus, but the reason I made it is so I can easily create an object that has a type of 'table and behaves like a table.
So, I would like to take the time to apologize for the massive thread earlier, and all the arguing. You were right, akkartik, I should just go and do it and not worry about what you guys think. I wasted a lot of time and emotions on something that ultimately didn't matter a lot. Yes, using objects is better in some circumstances, and I still think there's some interesting stuff to explore here, but it's not worth arguing about.
I would also like to apologize for making it appear that message passing (with or without objects) was drastically better than wart. I was not trying to deceive, I really did think that things were that verbose, in large part because I was ignorant. Nonetheless, that's not an excuse for the things I said, or the way I said them.
That's very classy of you! This thread helps me understand where you were coming from in that thread. And it helps me to know that there isn't something about message passing that I totally missed :)
Indeed. I think I prefer creating new types because I don't like something that looks like a string but isn't. Rails, for example, has these things called scopes that encapsulate sql queries. If you try to print a scope you see an array. But if you treat it like an array you can end up in sixteen different subtle kinds of trouble.
So I'd rather have new types that coerce transparently to tables rather than have a non-table claim to be a table. But I can absolutely imagine being equally productive with a programming style that plays more fast-and-loose with prototypes so that different tables have subtly different behaviors.
Yeah, but my idea is that types are interfaces. So if a scope is pretending to be an array, then by golly it better act like an array too. If it doesn't, then it's breaking the interface contract, so shame on it.
Then again, the current interfaces in Arc are fairly lax... conses mostly just need to support car, cdr, call, and set... tables need to support call, set, and keys.
So for making things that behave like tables, it just makes sense to give them a type of table, since the interface is so easy to adhere to. Like namespaces in import.arc, for instance. It makes sense to give them a type of table.
---
However, you're right that sometimes you might want something that's similar to, but slightly different than an existing type... in which case you'll probably want something else. On the OOP side you have subclasses and prototypes. On the Arc side you have... uh... extend, I guess, which is more general.
So let's imagine that object.arc is basically a thin skin over extend... in which case we might as well treat objects and extend as equivalent, since anything objects can do, extend can too.
With my types-are-interfaces idea, you could either give your new data a new type, or you could give it multiple types, or you could go rocketnia's approach and use `table?` predicates, or similar. I'd be interested in hearing about other approaches.
I remember being sorta-vaguely interested in it a long while ago, but never tried it. Now that I've learned Arc, all I can see is that the examples would be half as short (or shorter!) with macros. :P
If I were to strictly translate the example on their home page, it might look like this:
Okay, not quite half as short, but even so. From what I can tell, traits seems to be an interesting way to combine objects together, according to a contract. Not saying this is "The Way", but it might be interesting to write a traits.arc library to play around with it.
---
Also, apparently traits were invented in Self... which also invented prototypes (!):
Yes I remember noticing that word 'interfaces' in the old thread but not recent ones :) Interfaces seem useful in java and Go because there's some type-checking attached to it. If you're planning to add type-checking - so that objects claiming to be tables have to implement certain methods, or the object call immediately errors (gets _called_ on it ^-^) - that's an interesting direction. I won't immediately follow you but I'll watch to see where you end up :) But without type-checking there can be no notion of an interface. 'Duck-typed interfaces' is an oxymoron, I think.
"If you're planning to add type-checking - so that objects claiming to be tables have to implement certain methods, or the object call immediately errors (gets _called_ on it ^-^) - that's an interesting direction."
I wasn't planning on it, no, and I think we can still gain uses out of types-as-interfaces even without type checking. However, Traits.js might just change my mind. But that would be more complicated than my simple object.arc library.
I would personally treat a type like "table" to be an interface. So anything could be a table, as long as you could use it like a table.
Your example of something that claims to be an array but gives you trouble if you treat it like an array strikes me as more an issue with that particular bad implementation...
Interesting question though: what would treating types like interfaces look like from an Arc point of view? I'll have to think about that one :)
Update: I wrote this before I saw Pauan's comment :)
:) In that rails example scopes don't claim to be arrays. Hmm, perhaps it's just that printing them on the console is confusing. Perhaps other forms of overloading aren't so bad, and perhaps I can even handle the console with a slightly different mindset - not judging values by how they print.