Luke Graham
2/15/2005 1:25:00 AM
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 <spoooq@gmail.com> 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 <spoooq@gmail.com> 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 <spoooq@gmail.com> 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 <spoooq@gmail.com> 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 <spoooq@gmail.com> wrote:
> > > > > On Tue, 15 Feb 2005 00:01:44 +0900, William Morgan
> > > > > <wmorgan-ruby-talk@masanjin.net> 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