From: Greg McIntyre Date: 2003-11-21T11:07:17+09:00 Subject: Re: New Type Checking System Idea "Sean O'Dell" wrote: > On Thursday 20 November 2003 04:37 pm, Greg McIntyre wrote: > > I like your idea, Sean, but it's too much effort! If it is onerous > > then it won't be used. Perhaps if we based it upon method name and > > arity(essentially replacing a bunch of respond_to?() calls with > > arity checks added in as a bonus). This is because it requires no > > extra effort on the programmer's part, so it fits into the existing > > Ruby syntax. > > Very funny. =) Gee, I wasn't trying to be funny. I really would be annoyed if I had to write as much as you did to have interfaces. A lot of what you would end up writing would be repeditive, in the same way that with C++, writing .h and.cpp files repeats a lot of information (i.e. the type signatures). > Actually, I sort of meant my proposal to require a very minimal effort > for both sides. On Matz' end (save for syntax sugar) it's not a heck > of a lot to code, and it doesn't screech hard against the existing > code (at least not from what I've seen, could be wrong), and on our > side it's just a short block of interface description to write. It > really couldn't get a heck of a lot easier except to just not do it, > or to do some sort of interface id tagging thing like my first > proposal, where no enforcement was performed at all. The main problem I see, with both versions, is that they put the onus on the class provider to define all supported interfaces, whereas use of respond_to? puts the onus on the class client to assert the object supports the minimally required interface. Where _should_ the responsibility be? If it's up to the provider then the client may end up with an object which does not promise to support an interface it could because it is ignorant of it: i.e. it may restrict duck typing. If it's up to the class consumer then all that checking becomes a pain (and inefficient). Hmm... Can you clarify your idea in the following regard? Can I check one object against another's interface at run-time if I desire it? def read_from(object) if object.complies(IO::InputStream.interface) # ... end end > > I took your code and rewrote it a bit... > > Ha. Ha. =) > > It looks like too much happens at run-time, always checking and > querying for certain methods, etc. At "definition" time, yes (when the class is defined). Isn't that what your code does? Ruby has no "compile" time, after all... > Also, the concept of a whole > interface, rather than querying for a set of required methods, I > always think is easier to grasp. Yes, I'm all for grouping these queries into identifiable interfaces. I think that's a Good Thing. > I mean, there will always be respond_to? and for those people who see > no use in interface checking, they can, as always, keep just asking > respond_to? or not asking anything at all. Your changes seemed to be > sort of a souped-up respond_to? engine. Yes, that's a good way to describe it... which is interface checking. :) It's just that the interface contains a little less information than the type signatures of statically typed languages. In practice (and we've had a decade of it), Guido and matz have shown us that we don't really need such strong type safety -- it's a frictional force while programming and the difference it makes in practice is minimal. > Not to mention, no information about required parameter types. Exactly, that's what it leaves out. Then you could, optionally, ask Ruby whether object X fulfils interface Y and it would tell you without any respond_to? action. It's like... precalculated respond_to? :-) I think it could work because of inheritance (wow, it comes in handy after all) -- more general classes like IO::Stream can define fewer or more abstract methods and create abstract interfaces *at the same time* without the effort of defining the interface explicitly, separately. You'd probably want to allow explicit interface definitions too, I just think you're creating more work for yourself if you ingore what you already have... > My feeling is, a short run of overhead at compile-time is better than > constant overhead at run-time. I agree, except yoursentence.gsub!(/compile/, 'definition'), or whatever the more accepted term is for that stage of execution. > My proposal does all the interface fulfillment checking at > compile-time, then conformance checks are done with a simple flag test > internally. I thought my suggestion would too. It's based closely upon your suggestion after all... I just "Rubied" the information you keep in your interface so it did not tread on the pretty ducks. ;) -- Greg McIntyre ======[ greg@puyo.cjb.net ]===[ http://puyo.cjb.net ]===