Wishing of reactive programming in ruby

ruby integrates power of functional programming from lisp , purest OO
from smalltalk, prototype oriented power from self etc etc into one
single language

i just was wondering that whether the heavy developers/users of
reactive languages like kanaputs or reactive-C etc will ever get
reactive features in ruby.

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

bye :slight_smile:
Ashish
ashishwave@yahoo.com.

That's interesting --a form of rational programming (like Prolog).

But I think it is far outside the scope of Ruby's design.

T.

···

On Aug 17, 7:34 am, ashishwave <ashishw...@gmail.com> wrote:

ruby integrates power of functional programming from lisp , purest OO
from smalltalk, prototype oriented power from self etc etc into one
single language

i just was wondering that whether the heavy developers/users of
reactive languages like kanaputs or reactive-C etc will ever get
reactive features in ruby.

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

ashishwave wrote:

i just was wondering that whether the heavy developers/users of
reactive languages like kanaputs or reactive-C etc will ever get
reactive features in ruby.

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

bye :slight_smile:
Ashish
ashishwave@yahoo.com.

I haven't used reactive languages, but can't this be emulated by using methods and instance variables?
To emulate:
c = a+b; c.reactive = true
use:
def c; @a+@b; end

Then you could pretend c was a variable. To reset the value, just redefine c(). It would be simpler if all variables were methods, not instance variables. If you wanted, you could write a wrapper for that, so that set_reactive("c", "a + b") or set_reactive("c=a+b") would wrab a call to class_eval or instance_eval that defined the method as "def c; a() + b(); end". If you did this, however, you could never set a, b, or c by simple assignment.

A big problem might be parsing the input. I could elaborate on some suggestions. (I wrote code that converts standard arithmatic notation to reverse polish notation, which is very easy to evaluate. You could also do a simpler scheme like not allowing more than one operation.) Let me know if you are interested. And let me know if I'm not grasping reactive programming correctly--I've never used it.

Dan

* ashishwave <ashishwave@gmail.com> (2007-08-17) schrieb:

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

In a simple and slow implementation you can just put expression in a
string, and eval it everytime the value is needed.

mfg, simon .... l

ashishwave wrote:

ruby integrates power of functional programming from lisp , purest OO
from smalltalk, prototype oriented power from self etc etc into one
single language

i just was wondering that whether the heavy developers/users of
reactive languages like kanaputs or reactive-C etc will ever get
reactive features in ruby.

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

bye :slight_smile:
Ashish
ashishwave@yahoo.com.

Not the same, probably rather slow, but hey:

class Expression < BlankSlate
  def initialize(&expression)
    @expression = expression
  end

  def method_missing(*a, &b)
    @expression.call.send(*a, &b)
  end
end

a = 1
b = 2
c = Expression.new { a + b }
c + 3 # => 6
a = 5
c + 3 # => 10

Have fun :wink:

Regards
Stefan

···

--
Posted via http://www.ruby-forum.com/\.

Cells: a dataflow extension to CLOS is an interesting common lisp
project in that area

martin

···

On 8/17/07, ashishwave <ashishwave@gmail.com> wrote:

ruby integrates power of functional programming from lisp , purest OO
from smalltalk, prototype oriented power from self etc etc into one
single language

i just was wondering that whether the heavy developers/users of
reactive languages like kanaputs or reactive-C etc will ever get
reactive features in ruby.

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

ashishwave wrote:

ruby integrates power of functional programming from lisp , purest OO
from smalltalk, prototype oriented power from self etc etc into one
single language

i just was wondering that whether the heavy developers/users of
reactive languages like kanaputs or reactive-C etc will ever get
reactive features in ruby.

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

bye :slight_smile:
Ashish
ashishwave@yahoo.com.

I think this may give you some ideas. A Reactive object
has a number of reactive objects it depends on as well
as a block to calculate it's own value. The self value
is calculated lazily and cached. It is only recalculated
when an object it depends on set's it's dirty flag
by calling notify.

class Reactive

    # On change of value dependants are notified
    # of updates
    def value=(val)
       @value=val
       @depends.each do |d|
          d.notify
       end
    end

    # Add d as a listener
    def notify_me d
       @depends << d
    end

    # Get the cached value unless the
    # dirty flag has been set then
    # recalc the value from the block
    def value
       if @block && @dirty
          argv =
          @args.each do |a|
             if a.respond_to? :value
                argv << a.value
             else
                argv << a
             end
          end
          @value = @block.call *argv
       end
       @dirty=false
       @value
    end

    # Notify this object that at
    # least one dependant has changed.
    def notify
       @dirty=true
    end

    # Init the class with the dependant
    # reative variables and a block to
    # evaluate to compute the value
    # of this object.
    def initialize *args, &block
       @depends =
       if block_given?
          @args = args
          @block = block
          @args.each do |a|
             a.notify_me self
          end
       else
          # This is a literal
          @value = *args
       end
       @dirty=true
    end

end

a = Reactive.new(10)
b = Reactive.new(20)
c = Reactive.new a,b do |_a,_b|
    _a + _b
end
d = Reactive.new b,c do |_b,_c|
    _b + _c
end

vars = {:a=>a,:b=>b,:c=>c,:d=>d}

vars.each do |k,v|
    puts "#{k} #{v.value}"
end

puts "------------------"

a.value = 40
vars.each do |k,v|
    puts "#{k} #{v.value}"
end

···

------------------

Output is

:!ruby reactive.rb
c 30
d 50
a 10
b 20
------------------
c 60
d 50
a 40
b 20

--
Brad Phelan
http://xtargets.com

ashishwave <ashishwave@gmail.com> writes:

ruby integrates power of functional programming from lisp , purest OO
from smalltalk, prototype oriented power from self etc etc into one
single language

i just was wondering that whether the heavy developers/users of
reactive languages like kanaputs or reactive-C etc will ever get
reactive features in ruby.

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

bye :slight_smile:
Ashish
ashishwave@yahoo.com.

Half-way done ideas wrt that, inspired by flapjax. No warranty.

$ cat /Users/chris/mess//2006/49/frp.rb

require '/Users/chris/projects/blogcode/dynamic.rb'

Thread.abort_on_exception = true

Dynamic.variable :current_calc

class Var
  def initialize(value=nil)
    @affects =
    @value = value
  end

  def set!(v)
    @value = v
    propagate
    v
  end

  def ~
    @affects << Dynamic.current_calc if Dynamic.current_calc
    @value
  end
  
  def propagate
    @affects.each { |a| a.call }
  end

  def map(init=nil, &block)
    new = Var.new init
    Calc.new { new.set! block.call(~self) }
    new
  end

  def inject(initial, &block)
    a = initial
    map { |e| a = block.call a, e }
  end

  def constant(const)
    map { const }
  end

  def hold(initial, &block)
    map(initial) { block.call }
  end

  def filter(&block)
    new = Var.new
    Calc.new {
      this = ~self
      if block.call this
        new.set! this
      end
    }
    new
  end

  def merge(other)
    new = Var.new
    Calc.new { new.set! ~self }
    Calc.new { new.set! ~other }
    new
  end

  def calm(window, &block)
    last = Time.now
    merge(Timer.for(window)).filter {
      p [:calm, last, Time.now]
      r = (Time.now - last) > window
      last = Time.now
      r
    }
  end
end

class Calc < Proc
  attr_reader :timers
  
  def initialize(&block)
    @timers = {}
    super(&block)

    Dynamic.let :current_calc => self do
      call
    end
  end
end

class Timer
  attr_reader :var

  def self.for(period)
    if Dynamic.current_calc.nil?
      new(period).var
    else
      Dynamic.current_calc.timers.fetch(period) {
        Dynamic.current_calc.timers[period] = new(period)
      }.var
    end
  end
  
  def initialize(period)
    @period = period
    @var = Var.new Time.now.to_f

    Thread.new {
      loop {
        p "sleeping for #@period"
        sleep @period
        @var.set! Time.now.to_f
      }
    }
  end
end

x = Var.new 5

# Calc.new { p ["at time ", ~Timer.for(0.1), "x is ", ~x] }
Calc.new { p ["x is ", ~x] }

y = x.map { |z| z * 2 }

Calc.new { p ["y is now", ~y] }

sum = x.inject(0) { |a,e| a + e }

Calc.new { p ["sum is now", ~sum] }

Timer.for(5).map { p "tick!" }

x.calm(2).map(false) { |v| p "no input for 2 secs!" }

# Timer.for(10).merge(x).map { p "either 10s or x" }

x.set! 7

while line = gets.to_i
  x.set! line
  p ["set to ", ~x]
end

···

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

ruby integrates power of functional programming from lisp , purest OO
from smalltalk, prototype oriented power from self etc etc into one
single language

i just was wondering that whether the heavy developers/users of
reactive languages like kanaputs or reactive-C etc will ever get
reactive features in ruby.

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

That's interesting --a form of rational programming (like Prolog).

But I think it is far outside the scope of Ruby's design.

I'm about to go home. Damn.

I've been very interested in reactive programming for about 10 years,
although I've never heard of it reffered to as such. The Empirical
Modelling group at Warwick University did a lot of work on it in a
language called EDEN. They called it Definative Programming (think
reactive is a much better name, as it happens).

It's entirely possible to build a library in an imperative language that
will provide reactive programming capabilities. I've previsouly used a
similar idea for a GUI application in C++, and it made implementation of
pretty complex change propagation very easy.

My recent thinking is that reactive programming shares a great deal with
software transactional memory, and could share a lot of infrastructure.

Something the Empirical Modelling group at Warwick found was that
Reactive Programming is also very useful for making systems that are
composable. They could often take a few models they'd built, and easily
combine them, make a few other changes, and come up with a new useful
model. This is curious because composability is also a strong advantage
of STM.

My personal opinion is that reactive programming is _the_ pattern for
building any kind of interactive software (ie - something that doesn't
just process a batch of data, but reacts to user initiated changes to
its state, or changes from an external system). As an approach, it's got
a lot of overlap with:

  Model View Controller pattern and Observer, etc,
  Spreadsheet change propagation,
  Database Triggers and propagation.

Basically, you just don't need to think about the complexity that's
caused by propagating changes through a program. It really is pretty
dramatically cool :slight_smile:

Cheers,
  Benjohn

···

On Aug 17, 7:34 am, ashishwave <ashishw...@gmail.com> wrote:

ashishwave wrote:

i just was wondering that whether the heavy developers/users of
reactive languages like kanaputs or reactive-C etc will ever get
reactive features in ruby.

in kanaputs, If the variable 'c' is defined as c = a + b; and if the
reactivity of 'c' is set (c.reactive = true;), then each time the
value of 'a' or 'b' changes then the value of 'c' is updated as the
result of the addition

bye :slight_smile:
Ashish
ashishwave@yahoo.com.

I haven't used reactive languages, but can't this be emulated by using methods and instance variables?
To emulate:
c = a+b; c.reactive = true
use:
def c; @a+@b; end

Then you could pretend c was a variable. To reset the value, just redefine c().

I guess there is one major drawback of your approach: it will break as soon as systems grow to a reasonable size because whenever you access a variable you have to reevaluate the complete formula. I guess any implementation that offers reasonable performance will have to do some kind of dependency tracking and caching of current values.

The interesting question is how could this be done in Ruby so it's nicely integrated or a clean DSL? For seamless integration you would have to be able to redefine (or hook into) variable access (which would be a nice feature btw). You also would need enhanced code inspection in order to be able to determine what other variables a variable depends on.

It would be simpler if all variables were methods, not instance variables. If you wanted, you could write a wrapper for that, so that set_reactive("c", "a + b") or set_reactive("c=a+b") would wrab a call to class_eval or instance_eval that defined the method as "def c; a() + b(); end". If you did this, however, you could never set a, b, or c by simple assignment.

Yep. Interesting topic nevertheless.

Kind regards

  robert

···

On 17.08.2007 18:44, Dan Zwell wrote:

I'm well aware and very respectful of the respect that many informed people
have for STM, but in my experience it's challenging to implement and
maintain in the real world.

I've always been a partisan of loosely-coupled systems that use idempotent
messaging. I'm still hopeful that such a thing will come to Ruby. (This in
fact was precisely the reason that the EventMachine library was developed,
and it's still on the roadmap.)

I'm not a mathematician so I can't prove this, but I have a hunch that all
of these approaches are equivalent in some deep sense, and the practical
considerations should drive the choice. (The exception of course is
distributed object models.)

···

On 8/17/07, benjohn@fysh.org <benjohn@fysh.org> wrote:

>
>
> On Aug 17, 7:34 am, ashishwave <ashishw...@gmail.com> wrote:
>> ruby integrates power of functional programming from lisp , purest OO
>> from smalltalk, prototype oriented power from self etc etc into one
>> single language
>>
>> i just was wondering that whether the heavy developers/users of
>> reactive languages like kanaputs or reactive-C etc will ever get
>> reactive features in ruby.
>>
>> in kanaputs, If the variable 'c' is defined as c = a + b; and if the
>> reactivity of 'c' is set (c.reactive = true;), then each time the
>> value of 'a' or 'b' changes then the value of 'c' is updated as the
>> result of the addition
>
> That's interesting --a form of rational programming (like Prolog).
>
> But I think it is far outside the scope of Ruby's design.

I'm about to go home. Damn.

I've been very interested in reactive programming for about 10 years,
although I've never heard of it reffered to as such. The Empirical
Modelling group at Warwick University did a lot of work on it in a
language called EDEN. They called it Definative Programming (think
reactive is a much better name, as it happens).

It's entirely possible to build a library in an imperative language that
will provide reactive programming capabilities. I've previsouly used a
similar idea for a GUI application in C++, and it made implementation of
pretty complex change propagation very easy.

My recent thinking is that reactive programming shares a great deal with
software transactional memory, and could share a lot of infrastructure.

Something the Empirical Modelling group at Warwick found was that
Reactive Programming is also very useful for making systems that are
composable. They could often take a few models they'd built, and easily
combine them, make a few other changes, and come up with a new useful
model. This is curious because composability is also a strong advantage
of STM.

My personal opinion is that reactive programming is _the_ pattern for
building any kind of interactive software (ie - something that doesn't
just process a batch of data, but reacts to user initiated changes to
its state, or changes from an external system). As an approach, it's got
a lot of overlap with:

  Model View Controller pattern and Observer, etc,
  Spreadsheet change propagation,
  Database Triggers and propagation.

Basically, you just don't need to think about the complexity that's
caused by propagating changes through a program. It really is pretty
dramatically cool :slight_smile:

Cheers,
  Benjohn

benjohn@fysh.org wrote:

I'm about to go home. Damn.
They called it Definative Programming (think
reactive is a much better name, as it happens).

A strongly related, but possibly even more advanced technique is called
Constraint Logic Programming, CLP. It's been around since around 1981
or earlier. Doing it with real numbers (so-called CLP/R) has a lot of
hardcore difficulties, but it's being used in high-end architectural
design packages, for example. In such tools, the formula for the size
of a beam required to span two walls and support a particular load is
dynamically recalculated as you vary the wall spacing, just to give you
an idea of why you might want such a language.

Clifford Heath.

I've always been a partisan of loosely-coupled systems that use idempotent
messaging. I'm still hopeful that such a thing will come to Ruby.

Are you aware of the Omnibus Concurrency Library?

http://rubyforge.org/projects/concurrent/

(This in fact was precisely the reason that the EventMachine library was developed, and it's still on the roadmap.)

To someone like me who has been looking at Erlang recently, this is very interesting. Can you share and of your plans for how EventMachine might evolve into this? I'm just curious.

James Edward Gray II

···

On Aug 17, 2007, at 11:44 AM, Francis Cianfrocca wrote:

You will probably find this interesting: http://www.flapjax-lang.org/

Cheers-
-- Ezra Zygmuntowicz-- Founder & Ruby Hacker
-- ez@engineyard.com
-- Engine Yard, Serious Rails Hosting
-- (866) 518-YARD (9273)

···

On Aug 17, 2007, at 8:05 PM, Clifford Heath wrote:

benjohn@fysh.org wrote:

I'm about to go home. Damn.
They called it Definative Programming (think
reactive is a much better name, as it happens).

A strongly related, but possibly even more advanced technique is called
Constraint Logic Programming, CLP. It's been around since around 1981
or earlier. Doing it with real numbers (so-called CLP/R) has a lot of
hardcore difficulties, but it's being used in high-end architectural
design packages, for example. In such tools, the formula for the size
of a beam required to span two walls and support a particular load is
dynamically recalculated as you vary the wall spacing, just to give you
an idea of why you might want such a language.

Clifford Heath.

*snip*

I've always been a partisan of loosely-coupled systems that use
idempotent
messaging. I'm still hopeful that such a thing will come to Ruby. (This
in
fact was precisely the reason that the EventMachine library was
developed,
and it's still on the roadmap.)

*snip*

If you've got some links you could share about idempotent messaging, I'd
like to read them. The hits I'm getting seem to be about interprocess
protocol, rather than an approach that you'd also use intraprocess.

Yes, I took a close look at the Erlang concurrency verbs (spawn, and the
verbs for sending messages to Erlang "processes") and I sketched out an
implementation of them above the standard EventMachine. I'd like to use
Stomp for message-passing across "processes" that are in different OS-level
processes or on different machines. When this gets done, current plans are
to release it as EventMachine version 0.9.0.

Any ideas, counterarguments, or offers to help?

···

On 8/17/07, James Edward Gray II <james@grayproductions.net> wrote:

> (This in fact was precisely the reason that the EventMachine
> library was developed, and it's still on the roadmap.)

To someone like me who has been looking at Erlang recently, this is
very interesting. Can you share and of your plans for how
EventMachine might evolve into this? I'm just curious.

Francis Cianfrocca wrote:

···

On 8/17/07, James Edward Gray II <james@grayproductions.net> wrote:

(This in fact was precisely the reason that the EventMachine
library was developed, and it's still on the roadmap.)

To someone like me who has been looking at Erlang recently, this is
very interesting. Can you share and of your plans for how
EventMachine might evolve into this? I'm just curious.

Yes, I took a close look at the Erlang concurrency verbs (spawn, and the
verbs for sending messages to Erlang "processes") and I sketched out an
implementation of them above the standard EventMachine. I'd like to use
Stomp for message-passing across "processes" that are in different OS-level
processes or on different machines. When this gets done, current plans are
to release it as EventMachine version 0.9.0.

Any ideas, counterarguments, or offers to help?

Well, I'll certainly offer to *test* it. :slight_smile: