From: Christoph Rippel Date: 2001-03-10T20:00:51+09:00 Subject: [ruby-talk:12379] Re: Q re looping structures > From: Benjamin J. Tilly [mailto:ben_tilly@operamail.com] [..] > [...] > >Right now at least the interpreter is crashing - > >if a dubious equality notion is introduced some > >scriot will produce garbage because RCO violate > >basic Container axioms (and you know this as well > >as I do). > > I already gave the example of a directory structure. > Recursive data structures are widely used, and a > friend verified for me that it is common to use a > caching algorithm like the one I coded. (Hopefully > without that bug.) You can always write a specialised directory tree class for this (you can base this class on array and change the equal operator with any equality scheme you want and id-caching is not the only possibility) there is not need to burden the general array class with the heavy cost and problems of more complicated equality notions ... [...] > But Ruby already does: > > x = [1] > a = [x, x] > b = [[1], [1]] > p (a == b) # => true > a[0][1] = 2 > b[0][1] = 2 > p (a == b) # => false > which is the same error. In other words == does not this the same error but RCO make things even worse they would introduce side effects for #delete_at,#delete #uniq! , reverse!, #& - there is no pressing need to introduce extra side effects into Ruby ... RCO also do something I find particularly nasty - by assigning b[0] = 2 you actually changed the state of the object b[1] - in your example you changed the state of the array itself but you did not change the state ``x'' which is not as bad IMO. > currently take into account issues with deep copies vs > shallow copies except when it causes a crash. With id > caching == does not take into account issues with deep > copies vs shallow copies and it doesn't crash. > > Which behaviour is better? Simple crashing (the current behavior) - it tells you that there is probably something fundamentally wrong with your program and/or input - a type exception simply tells what went wrong and where ... > [...] > >> In what you cut out I did construct them I thought. > >I know - I was thinking of [[[..],2],1] > > > Ah, that is a lot harder. You can do it with streams, > but then you don't use the default array comparisons, > so we need not worry about it. :-) You can create this using reverse! ... > but no longer seems to. One of my (few and in this case it > is far too late to change) irritations is that Ruby lacks a > simple end of expression rule. I would far prefer always > typing a ;, or having to always use \ for end of line, than > having it be so ambiguous in some cases. I sort of agree with you but I am not particularly opinionated about this ... > > >----------------- > >$ ruby bad_equal.rb > >true > >true > >----------------- > >require 'Ben' > >def cl( a, n) > > base=loop= [a.clone] > > (n-1).times { tmp = [a.clone]; loop << tmp; loop = tmp } > > loop << base > > base > >end > > > >p (cl("a",1) == cl("a",101)) # all id-cachings have this problem > > Is this a problem? Yes because you identify a loop of size 100 with loop of size one - you might think this is natural I don't (certainly not as a default behavior) and do say it again the algorithm takes forever to figure out that (cl("a",100) == cl("a",101)) are equal because you have run through the loop 100*101 times before realizing that they are equal . [...] Christoph