From: Luke Graham Date: 2005-02-15T10:25:00+09:00 Subject: Re: can anyone verify this code as correct? def condition(value) if value.include?(nil) || !yield @@cont.pop.call if @@cont.last end end I can hear my boss coming... On Tue, 15 Feb 2005 11:16:36 +1000, Luke Graham wrote: > def condition(value) > @@cont.pop.call if value.include?(nil) || !yield > end > > Of course we can write it like this too... ok I am really going now! ;) > > > On Tue, 15 Feb 2005 11:15:13 +1000, Luke Graham wrote: > > def condition(value) > > @@cont.pop.call if value.include? nil > > @@cont.pop.call if !yield > > end > > > > This appears to work. I do not claim to understand why. I am going to > > do some work now before I get fired :D > > > > > > On Tue, 15 Feb 2005 11:12:31 +1000, Luke Graham wrote: > > > Ok, I see the problem; > > > > > > foo = choices(1..100) > > > bar = choices(1..100) > > > > > > condition([bar]) { bar > 10 } > > > condition([bar]) { (bar % 2) == 0 } > > > condition([foo, bar]) { bar == (foo * 2) } > > > > > > foo never increments because we fall through when bar is exhausted. > > > > > > > > > On Tue, 15 Feb 2005 10:58:00 +1000, Luke Graham wrote: > > > > Forgot this snippet that may be on the way to fixing the NilClass problem... > > > > > > > > def choices(choicelist) > > > > @@cont ||= [] > > > > choicelist.each { |choice| > > > > callcc { |cc| > > > > @@cont << cc > > > > return choice > > > > } > > > > } > > > > nil > > > > end > > > > > > > > def condition(value) > > > > return if value.include? nil > > > > @@cont.pop.call if !yield > > > > end > > > > > > > > foo = choices(1..100) > > > > bar = choices(1..100) > > > > > > > > condition([foo]) { foo > 101 } > > > > condition([bar]) { bar == 1 } > > > > > > > > puts foo > > > > puts bar > > > > > > > > > > > > On Tue, 15 Feb 2005 10:51:21 +1000, Luke Graham wrote: > > > > > On Tue, 15 Feb 2005 00:01:44 +0900, William Morgan > > > > > wrote: > > > > > > Hi, > > > > > > > > > > > > > foo = choices(1..100) > > > > > > > bar = choices(1..100) > > > > > > > condition(lambda{foo == (bar * 3)}) > > > > > > > condition(lambda{bar > 10}) > > > > > > > condition(lambda{(bar % 2) == 0}) > > > > > > > > > > > > Cute! Some comments: > > > > > > > > > > > > > def condition(cond) > > > > > > > return if (self.class == NilClass?) > > > > > > > @@cont.pop.call if !cond.call > > > > > > > end > > > > > > > > > > > > More idiomatic usage would be to take a block here, rather than > > > > > > requiring an explicit lambda. Then calling it looks like: > > > > > > > > > > > > condition { foo == bar * 3 } > > > > > > > > > > Thusly... > > > > > > > > > > def condition > > > > > return if (self.class == NilClass) > > > > > @@cont.pop.call if !yield > > > > > end > > > > > > > > > > > Also, you can drop the "class Object" declaration if you like, as > > > > > > top-level methods are automatically defined in Object. Or, move > > > > > > everything to a new class (even better). > > > > > > > > > > Now that Ive seen the light with the ||= operator, I can indeed drop that class > > > > > declaration. Ruby didnt seem to like it the way I had it originally. Maybe > > > > > that was when I used attr_accessor, hmm cant remember. At any rate, > > > > > the class line can go now. I dont want to move to another class > > > > > because that would ruin the simplicity of use :) > > > > > > > > > > > The real problem, though, is here: > > > > > > > > > > > > > class NilClass? > > > > > > > def method_missing(methId, *args) > > > > > > > return false > > > > > > > end > > > > > > > end > > > > > > > > > > > > Which has high potential to break existing code, or at least make > > > > > > debugging very difficult. I haven't thought this through thoroughly, but > > > > > > rather than returning nil, maybe you can jump to another continuation? > > > > > > > > > > I have thought about that too, condition is a possible place to jump back to. > > > > > That could have implications though, so I want to be sure of it first. > > > > > A manual checkpoint/escape continuation may be necessary. > > > > > > > > > > At the moment Im concentrating more on something like : > > > > > condition([bar, foo]) {bar < foo} > > > > > > > > > > The argument tells us what variables affect the outcome of the condition, > > > > > so a hash table of results can be created. Then computation can be optimised > > > > > by quickly allowing through values that are true and popping continuations that > > > > > have no effect on the important input values. Note that the value of bar is good > > > > > enough, ie theres no point using :bar, and that the value returned by time() > > > > > is a valid and useful argument as well. This is straying into monadic territory > > > > > if my understanding of those strange beasts is correct. > > > > > > > > > > > Interesting idea, at any rate. The code is correct, though you have to > > > > > > drop the ? in NilClass?. > > > > > > > > > > Yeah, sorry about that, that came from a wiki I posted the code on, > > > > > didnt realise till after I sent the mail. > > > > > > > > > > -- > > > > > spooq > > > > > > > > > > > > > -- > > > > -- > > > > spooq > > > > > > > > > > -- > > > spooq > > > > > > > -- > > spooq > > > > -- > spooq > -- spooq