Re: why generative? will@xxxxxx 31 Aug 2009 14:55 UTC
Shiro Kawai wrote: > > > In other words, we make make-rtd behave > > > functionally, meaning it returns eqv? objects for equivalent > > > set of arguments. > > > > That could be done, but it's more complicated. > > Not necessarily. If simplicity is important, you can > just return a new structure from make-rtd. When comparing > rtds, the simplest way is to compare element-by-element > (just like comparing complex numbers, for example. that's > how "functional" objects should be compared, semantically.) Element-by-element comparisons are more complicated than pointer comparisons, even if you ignore performance. If the comparison involves equality of the parent record type, then the comparison involves recursion. > If performance is important, complexity generally increases. The performance of records is important. If programmers can't rely on record accesses to be reasonably fast, then they'll start to use vectors instead of records even when records would otherwise be more appropriate. > Using tables is one way to optimize comparison. If an > implementation wish to use the table, I suppose it already > has tables with weak references, hence inadvertent retention > won't occur. Hash tables with weak references aren't universal, and may have drawbacks even in systems that have them. > Another optimization strategy may be that the implementation > calculates a hash value from rtd fields and cache it in an rtd. Even when an integer hash matches, you'd still have to perform the complicated comparison to confirm the match. > Either way, it is an implementation detail. Agreed. > Do you still see disadvantages? Yes. Using the "sufficiently clever implementation" idea to pretend that performance and implementation complexity don't matter has gotten language designers into a lot of trouble in the past, and it did some harm even to the R6RS. > What I think as an advantage is: I assume nongenerative rtds > are the norm, and generative ones are exceptional. Putting > the burden of specfying extra information (uid) to the > rarer use case certainly has an advantage. Okay, I'll admit that advantage. On the other hand, I'm going to appeal to the "sufficiently clever implementation" to this extent: Most record types are likely to be defined at the top level of a library or top-level program by straightforward, easy-to-recognize code. Implementations that invoke each library only once (which has other advantages as well) can treat that common special case as though the definitions were non-generative. That's just a simple source transformation. To programmers, generative record types defined at top level are equivalent to a non-generative record type defined at top level, so neither default adds any extra burden for that common case. For record types that are not defined at top level, it is unclear whether generative or non-generative definitions are more common. My intuition says it's likely to depend upon individual programmers' preferred styles, so no general rule applies generally. Will