From: Michael Neumann Date: 2004-05-01T18:51:23+09:00 Subject: Re: Lazy evaluation On Sat, May 01, 2004 at 05:36:06PM +0900, Jean-Hugues ROBERT wrote: > > [...] > > This for sure works for Lazy, Future (Promise in some languages, Defered > in some others) and any other read-only cases. This is the rvalue case. > > The lvalue case is another beast: > def meth( x ) x = [x, "world"] end > r = Refererence.new > r = "Hello" > meth( r, "World") > p r # => Should be ["Hello", World] > > Once solved I will be able to implement LogicVariable: > v = LogicVariable.new > v = free > p match [[["x"]]], [[[v]]] # True > p v # => "x", changed as a side effect of match > v = "y" > p match [[["x"]]], [[[v]]] # False, "x" != "y" > p v # => "y", unchanged You might also have a look at the algebra module. But they are in the lucky position of not needing to assign to variables. > As a reminder: I need LogicVariable to prototype a new "match" builtin > and its "assign" variation in an RCR. "assign" does what Ruby does > today in multiple assignments and when it assigns actual parameters > to formal ones (for method calls and proc calls), and more. "match" > does both assignment and comparison (when previous value already bound) > > So far I implemented: > v = LogicPointer.new > v.free! > p match [[["x"]]], [[[v]]] # True > p v[] # => "x" > v[] = "y" > p match [[["x"]]], [[[v]]] # False > p v[] # => "y" > Which is close, besides the additional [] Hmm, it doesn't look that bad. The [] reminds me of "cells". > v.free! > p match [[["x"]]], [[[v]]] # True > p v[] # => "x" > v[] = "y" > p match [[["x"]]], [[[v]]] # False > p v[] # => "y" > > Thanks to your code, I think I will be able to: > v = LogicDelegator.new > v.free! > p match [[["x"]]], [[[v]]] # True > p v[] # => "x" > v[] = "y" > p match [[["x"]]], [[[v]]] # False > p v # => "y", note the absence of [] > Which is one step in the good direction. Thanks. But the problem is that "v[]" and "v" are still very different! The difference is not seen when using "p", as "p" calls "inspect" on the object, which gets delegated. But you probably don't want to use inspect all the time. So better use the explicit [] and []= methods. Personally, I'd prefer l.v and l.v= instead of l.[] and l.[]= but that is probably only due to very high usage of [ and ] in your example above. BTW, what are you exactly implementing? > >And to replace all Lazy objects with their values, I can now use > >obj = Marshal.load(Marshal.dump(obj)). > > I am sorry but I am not familiar with Marshal much yet. I guess > you serializes and then rebuild the object, but I don't see the > magic to make that efficient (I assumed @value was serialized too) It's just a "deep_clone". All Lazy objects marshal @value instead of itself, thus after Marshal.load there are no more Lazy objects. You are in the same situation as if you had replaced all Lazy objects with their value object via "become". Of course this is only useful if you're doing heavy calculations on the data (not sure whether it makes sense for an AST). Regards, Michael