Can anyone verify this code as correct?

class Object
    def choices(choicelist)
  if (!Class.class_variables.include? "@@cont")
    @@cont = []
  end
  choicelist.each { |choice|
    callcc { |cc|
      @@cont << cc
      return choice
    }
  }
  nil
  end

  def condition(cond)
    return if (self.class == NilClass?)
    @@cont.pop.call if !cond.call
  end
end

  class NilClass?
   def method_missing(methId, *args)
      return false
   end
end

foo = choices(1..100)
bar = choices(1..100)
condition(lambda{foo == (bar * 3)})
condition(lambda{bar > 10})
condition(lambda{(bar % 2) == 0})
puts foo
puts bar

Thanks for your help.

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 }

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).

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?

Interesting idea, at any rate. The code is correct, though you have to
drop the ? in NilClass?.

···

--
William <wmorgan-ruby-talk@masanjin.net>

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 :slight_smile:

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.

···

On Tue, 15 Feb 2005 00:01:44 +0900, William Morgan <wmorgan-ruby-talk@masanjin.net> wrote:

--
spooq

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 :slight_smile:

> 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

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 :slight_smile:
>
> > 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

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 :smiley:

···

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 :slight_smile:
> >
> > > 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

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! :wink:

···

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 :smiley:

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 :slight_smile:
> > >
> > > > 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

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! :wink:

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 :smiley:
>
>
> 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 :slight_smile:
> > > >
> > > > > 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