I added memoizing and then tried being lazy about my input..
and it is so much faster than Range! Why is Range so slow???
def choices(choicelist)
@@cont ||=
choicelist.each { |choice|
callcc { |cc|
@@cont << cc
@@conditionCount = 0
return choice
}
}
nil
end
def condition(dependsOn)
@@memo ||= {}
@@conditionCount ||= 0
@@conditionCount += 1
@@memo[@@conditionCount] ||= {}
return if @@memo[@@conditionCount][dependsOn] == true
if dependsOn.include? nil or @@memo[@@conditionCount][dependsOn] ==
false or !(@@memo[@@conditionCount][dependsOn] = yield)
@@cont.pop.call if @@cont.last
end
end
class Lazy
def each
x = 0
while (x < 100)
x += 1
yield x
end
end
end
lazy = Lazy.new
foo = choices(lazy)
bar = choices(lazy)
condition([foo, bar]) { bar == (foo * 2) }
condition([bar]) { bar > 10 }
condition([bar]) { (bar % 2) == 0 }
condition([foo]) { foo > 30 }
puts foo
puts bar
···
On Wed, 16 Feb 2005 10:30:25 +1000, Luke Graham <spoooq@gmail.com> wrote:
On Tue, 15 Feb 2005 16:26:13 -0800 (PST), E S > <eero.saynatkari@kolumbus.fi> wrote:
> > Lähettäjä: Luke Graham <spoooq@gmail.com>
> > Aihe: Re: can anyone verify this code as correct?
> >
> > On Mon, 14 Feb 2005 17:52:06 +0900, E S <eero.saynatkari@kolumbus.fi> wrote:
> > > > Lähettäjä: Luke Graham <spoooq@gmail.com>
> > > > Aihe: Re: can anyone verify this code as correct?
> > > >
> > > > On Mon, 14 Feb 2005 17:07:00 +0900, E S <eero.saynatkari@kolumbus.fi> wrote:
> > > > > > Lähettäjä: 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.
> > >
> > > Ah, indeed. That's what I get for omitting 'return' (all keystrokes
> > > count at 03:00
So yes, the code remains valid (just without the
> > > interesting side-effects).
> >
> > They certainly do count, even at 3am when our human brains can
> > no longer compete with silicon.
Would you consider this a
> > non-evil use of continuations? If so, I will be very pleased
> > with myself for re-inventing it. Havent seen it before personally,
> > but nothing is new in this world - Im sure LISP had it years ago 
>
> Non-evil and valid, yes. It may not be the most effective way to
> implement your idiom -which, I'd say, is some sort of emulation of
> lazy evaluation- though. The enhancements detailed later address the
> shortcomings quite well.
>
> E
Lazy evaluation is another way of thinking of it. I believe you know you
are using true primitives (like callcc) when ideas start to blur into each
other and still take only a few lines of code.
--
spooq
--
spooq
Heres another funny little function. Next is getting a list of all
acceptable values.
def again
@@counter ||= 0
@@agains ||= 0
@@agains += 1
return if @@counter >= @@agains
@@counter += 1
@@agains = 0
@@cont.last.call if @@cont.last
end
foo = choices(1..10)
bar = choices(1..10)
condition([foo]) { foo > 3 }
condition([bar]) { bar > 3 }
again
again
again
puts foo
puts bar
···
On Wed, 16 Feb 2005 20:34:16 +1000, Luke Graham <spoooq@gmail.com> wrote:
I added memoizing and then tried being lazy about my input..
and it is so much faster than Range! Why is Range so slow???
def choices(choicelist)
@@cont ||=
choicelist.each { |choice|
callcc { |cc|
@@cont << cc
@@conditionCount = 0
return choice
}
}
nil
end
def condition(dependsOn)
@@memo ||= {}
@@conditionCount ||= 0
@@conditionCount += 1
@@memo[@@conditionCount] ||= {}
return if @@memo[@@conditionCount][dependsOn] == true
if dependsOn.include? nil or @@memo[@@conditionCount][dependsOn] ==
false or !(@@memo[@@conditionCount][dependsOn] = yield)
@@cont.pop.call if @@cont.last
end
end
class Lazy
def each
x = 0
while (x < 100)
x += 1
yield x
end
end
end
lazy = Lazy.new
foo = choices(lazy)
bar = choices(lazy)
condition([foo, bar]) { bar == (foo * 2) }
condition([bar]) { bar > 10 }
condition([bar]) { (bar % 2) == 0 }
condition([foo]) { foo > 30 }
puts foo
puts bar
On Wed, 16 Feb 2005 10:30:25 +1000, Luke Graham <spoooq@gmail.com> wrote:
> On Tue, 15 Feb 2005 16:26:13 -0800 (PST), E S > > <eero.saynatkari@kolumbus.fi> wrote:
> > > Lähettäjä: Luke Graham <spoooq@gmail.com>
> > > Aihe: Re: can anyone verify this code as correct?
> > >
> > > On Mon, 14 Feb 2005 17:52:06 +0900, E S <eero.saynatkari@kolumbus.fi> wrote:
> > > > > Lähettäjä: Luke Graham <spoooq@gmail.com>
> > > > > Aihe: Re: can anyone verify this code as correct?
> > > > >
> > > > > On Mon, 14 Feb 2005 17:07:00 +0900, E S <eero.saynatkari@kolumbus.fi> wrote:
> > > > > > > Lähettäjä: 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.
> > > >
> > > > Ah, indeed. That's what I get for omitting 'return' (all keystrokes
> > > > count at 03:00
So yes, the code remains valid (just without the
> > > > interesting side-effects).
> > >
> > > They certainly do count, even at 3am when our human brains can
> > > no longer compete with silicon.
Would you consider this a
> > > non-evil use of continuations? If so, I will be very pleased
> > > with myself for re-inventing it. Havent seen it before personally,
> > > but nothing is new in this world - Im sure LISP had it years ago 
> >
> > Non-evil and valid, yes. It may not be the most effective way to
> > implement your idiom -which, I'd say, is some sort of emulation of
> > lazy evaluation- though. The enhancements detailed later address the
> > shortcomings quite well.
> >
> > E
>
> Lazy evaluation is another way of thinking of it. I believe you know you
> are using true primitives (like callcc) when ideas start to blur into each
> other and still take only a few lines of code.
>
> --
> spooq
>
--
spooq
--
spooq