On Mon, 14 Feb 2005 17:07:00 +0900, E S <eero.saynatkari / kolumbus.fi> wrote:
> > Lett Luke Graham <spoooq / gmail.com>
> > Aihe: can anyone verify this code as correct?
> >
> >  class Object
> >     def choices(choicelist)
> >       if (!Class.class_variables.include? "@@cont")
> >               @@cont = []
> >       end
> 
> You can use '@@cont ||= []'.

Thanks, I like that one.

> >       choicelist.each { |choice|
> >               callcc { |cc|
> >                       @@cont << cc
> >                       return choice
> >               }
> >       }
> >       nil
> >   end
> 
> Continuation returns after the block, either with the value of the
> block or the parameter to #call, and it stores its execution context.
> Here you're returning in the middle of a loop, so I'm thinking each
> #call will cause the remaining 'choicelist' to be iterated over again,
> so the actual return value is going to be 'choicelist'.

I dont understand... the return value is definitely not choicelist, but
a different choice each time. The callcc is -inside- the internal iteration.
After all values have been exhausted, nil is the last thing to be
returned, and effectively marks the limit of choices, as '\0' does for
c-strings. The array could probably stand to be flattened first, just
in case.

> >   def condition(cond)
> >     return if (self.class == NilClass?)
> >     @@cont.pop.call if !cond.call
> >   end
> >  end
> 
> You're attempting to loop until the condition is true? If I'm
> understanding correctly you're trying to find the first values that
> fill all the conditions set forth?

Yes, or nil if there are no such values.

> >   class NilClass?
> >    def method_missing(methId, *args)
> >       return false
> >    end
> >  end
> >
> >
> >  foo = choices(1..100)
> >  bar = choices(1..100)
> 
> choices() returns nil, no?

If all choices are exhausted, it does eventually return nil. However,
in the case of bar, it will once again start returning from the
beginning of the array if foo is unacceptable. Of course, we dont
really know if that value of foo is unacceptable or if its just that
all possible values of bar are unacceptable - that can only be
determined by more computation.

> >  condition(lambda{foo == (bar * 3)})
> >  condition(lambda{bar > 10})
> >  condition(lambda{(bar % 2) == 0})
> >  puts foo
> >  puts bar
> >
> > Thanks for your help.
> 
> What are you trying to do, exactly? I'm sure there's an easier way if
> you just want to compose conditionals like this; or are you trying to
> get a handle on how callcc works? In the former case, you'd probably
> want to try something with blocks instead... callcc is really just a
> glorified goto.
> 
> E

Im just hacking around to see what sort of valid flow control
constructs exist apart from the regular loops and such. The major
problem Ive seen so far with what I have is adding a further set of
choices after the originals, and before the conditions, adds
exponentially to the time required. To be honest, that doesnt worry me
because Im just having fun.