Code Monkey home page Code Monkey logo

reactive.jl's People

Contributors

alainlich avatar catawbasam avatar dldx avatar dpsanders avatar femtocleaner[bot] avatar ffreyer avatar hgeorgako avatar iainnz avatar jaakkor2 avatar jiahao avatar jobjob avatar juliatagbot avatar jw3126 avatar keno avatar mlubin avatar mschauer avatar paethon avatar pallharaldsson avatar rdeits avatar shashi avatar simondanisch avatar sjkelly avatar staticfloat avatar stefankarpinski avatar stevengj avatar timholy avatar tkelman avatar tsurherman avatar yakir12 avatar yuyichao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reactive.jl's Issues

Latest Julia0.4: tests/basics.jl fails on push!

This looks different enough from #42, failure occurs in .julia/v0.4/Reactive/tests/basics.jl
in statement push!(a, 1.0) (line 15)

      8 a = Input(number())
      9 b = lift(x -> x*x, a)
     10 
     11 # Lift type
     12 @test isa(b, Reactive.Lift{Int})
     13 
     14 # type conversion
     15 push!(a, 1.0)
julia> using Reactive

julia> include("test.jl")
WARNING: int(x::FloatingPoint) is deprecated, use round(Int,x) instead.
 in depwarn at ./deprecated.jl:40
 in int at deprecated.jl:29
 in number at /home/alain/.julia/v0.4/Reactive/tests/basics.jl:4
 in include at ./boot.jl:250
 in include_from_node1 at ./loading.jl:129
 in include at ./boot.jl:250
 in include_from_node1 at ./loading.jl:129

 in push! at /home/alain/.julia/v0.4/Reactive/src/Reactive.jl:224
 in include at ./boot.jl:250
 in include_from_node1 at ./loading.jl:129
 in include at ./boot.jl:250
 in include_from_node1 at ./loading.jl:129

ERROR: LoadError: LoadError: MethodError: `getindex` has no method matching getindex(::Tuple{DataType,DataType})
Closest candidates are:
  getindex(::Tuple, ::Int64)
  getindex(::Tuple, ::Real)
  getindex(::Tuple, ::AbstractArray{Bool,N})
  ...
 in push! at /home/alain/.julia/v0.4/Reactive/src/Reactive.jl:273
 in include at ./boot.jl:250
 in include_from_node1 at ./loading.jl:129
 in include at ./boot.jl:250
 in include_from_node1 at ./loading.jl:129
while loading /home/alain/.julia/v0.4/Reactive/tests/basics.jl, in expression starting on line 15
while loading /home/alain/.julia/v0.4/Reactive/tests/test.jl, in expression starting on line 1
versioninfo()
Julia Version 0.4.0-dev+4500
Commit 30b94a1* (2015-04-25 15:54 UTC)
Platform Info:
  System: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge)
  LAPACK: libopenblas
  LIBM: libopenlibm
  LLVM: libLLVM-3.3

master fails on 0.5

Things seem to fail on 0.5, so I tried this:

steve:~/.julia/v0.5/Reactive(sjk/node-call)$ git diff
diff --git a/src/core.jl b/src/core.jl
index 14e2b76..d45a748 100644
--- a/src/core.jl
+++ b/src/core.jl
@@ -189,7 +189,8 @@ let timestep = 0
             timestep += 1
             iter += 1

-            let message = take!(_messages)
+            let 
+                @show @which take!(_messages)
                 node, value, onerror = message
                 try
                     send_value!(node, value, timestep)

and got this error:

steve:~/.julia/v0.5/Reactive(sjk/node-call)$ julia5 ./test/runtests.jl 
INFO: Recompiling stale cache file /home/steve/.julia/lib/v0.5/Reactive.ji for module Reactive.
Killing Task (runnable) @0x00007efb5a0528b0
fatal: error thrown and no exception handler available.
Base.AssertionError(msg="shift!(Workqueue).state == :queued")
rec_backtrace at /home/steve/Software/julia5/usr/bin/../lib/libjulia.so (unknown line)
jl_throw at /home/steve/Software/julia5/usr/bin/../lib/libjulia.so (unknown line)
wait at ./task.jl:359
task_done_hook at task.jl:173
jl_apply_generic at /home/steve/Software/julia5/usr/bin/../lib/libjulia.so (unknown line)
unknown function (ip: 0x7efd5c0deda6)
unknown function (ip: (nil))

JuliaLang/julia@312e65c made some changes to channels so I jumped back to before it was merged but got the same error.

Problems with GLFW

System: Windows 8.1 (x64)
Julia: 0.4.0

when i use GLFW.PollEvents() and sleep(0.01) in a while loop it seems signals are not updated. sometimes it works and sometimes not. (this often happens when i move the glfw window. it just breaks and i get no more updates)

May its a common problem when using GLFW. Is there a workround for it?

I use signals to check a file update, it prints me a msg when i change the file.
Code:

function isUpdated(file::File, updatewhile=Reactive.Signal(true), update_interval=1.0)
    fn = filename(file)
    file_edited = foldp((false, mtime(fn)), fpswhen(updatewhile, 1.0/update_interval)) do v0, v1
        time_edited = mtime(fn)
        (!isapprox(0.0, v0[2] - time_edited), time_edited)
    end
    filter(identity, false, map(first, file_edited))
end

function watchFileUpdate(path::AbstractString, OnUpdate::Function)
    map(isUpdated(query(path))) do _unused
        println("OnUpdate: ", path)
    end
end

Change the name?

As mentioned in #12 it's easy to think that React.jl has anything to do with Facebook's React. Now that this has been moved to JuliaLang organization, this may be a good time to reconsider changing the name. Possible names:

  • Reactive.jl - this is not consistent with Interact.jl
  • Reactor.jl - I like this one better

Any suggestions? cc @stevengj @StefanKarpinski @IainNZ @JuliaLang/admin

Real-time signal processing

I would like to do real time signal processing in Julia. By this I mean a replacement for simulink (MATLAB) or LabView (NI). I would like to be able to take measurements, set up a processing chain and output the result.

Reactive looks like a nice framework for this processing. With the previous() command most filtering configurations can be implemented. Ideally this could be integrated with DSP.jl (@simonster, @JayKickliter). Combined with AudioIO.jl (@ssfrr, @wherrera10) for input and output, I have proposed a basic acquisition example in AudioIO issues.

For my uses I need to process data at a minimum of a 1kHz rate. I know the processing time will depending on the complexity. But will Reactive.jl be a limiting factor?

My questions are

  1. Has anyone used Reactive.jl in this way successfully? If so, have they documented it?
  2. Will Reactive be fast enough for real time processing? I am starting to test this myself, but have no intuitive feeling for the code base yet.

(edit: added processing rate requirements)

more generic push

Might be nice to define (in addition to what you have now):

push!{T}(inp::Input{T}, value) = convert(T, value)

instead of requiring the value argument to have exactly the same type.

fpswhen related error when using VideoIO/Reactive

When I tried the following code on my MacOSX, Julia v0.4, I get an "ERROR: Timing is not defined." or "fpswhen is not defined". I understand that fpswhen is used in the lift step to control the acquisition timing of VideoIO.read, but I am not sure what I could do to make it work with the latest VideoIO package from Tim Holy. It would be nice to be able to do filtering and tracking on live video feed from the webcam. Is this problem due to the changes from React to Reactive? The same script worked for me last week with the previous version of VideoIO and when I had React (not Reactive).

VideoIO and ImageView are working fine since I can obtain video from the built-in camera using the f = VideoIO.opencamera() and img = read(f, image).

  using ImageView
  import ImageView
  using VideoIO
  import VideoIO

  #Reactive should have replaced React by now
  using GLPlot, Reactive, GLAbstraction

   #VideoIO.DEFAULT_CAMERA_DEVICE
  device    =  "Innebygd iSight"
  format    = VideoIO.DEFAULT_CAMERA_FORMAT
  camera    = VideoIO.opencamera(device, format)
  img   = VideoIO.read(camera)

  # Just for fun, lets apply a laplace filter:
  kernel    = [-1 -1 -1;
                   -1  8 -1;
                   -1 -1 -1]

  #async=true, for REPL use. Then you don't have to call renderloop(window) 
  window    = createdisplay(#=async=true =#)
  img   = glplot(Texture(img, 3), kernel=kernel, filternorm=0.1f0)

  #Get Gpu memory object
  glimg     = img.uniforms[:image]

  #Asynchronous updating with React:
  lift(Timing.fpswhen(window.inputs[:open], 30.0)) do x
        newframe = VideoIO.read(camera)
        update!(glimg,  mapslices(reverse, newframe, 3)) # needs to be mirrored :(
  end

  renderloop(window)

Feature Request: Stopping a signal

image

Is it simple to implement an optional stop signal for every lift?
Background: if I animate a large array, e.g. particles, it would be great if I can stop it at some point and clean up the resources.
Similar thing for cameras. It is sometimes simpler to just stop one camera and create a new one, instead of trying to recycle a pool of cameras.

Best,
Simon

Signal difference error in tutorial example

Difference code from the introduction results in bounds error. When this line

diff = lift(x->x[1], foldl(difference, 0.0, signal))

is modified by providing a tuple as the initial fold value instead

diff = lift(x->x[1], foldl(difference, (0.0, 0.0), s))

then everything seems to work.

Circular references

Hi,
just wanted to check, that this the is intended behavior:

julia> a = Input(0)
julia> b = Input(false)
julia> keepwhen(b, 0, a)
julia> c = keepwhen(b, 9, a)
julia> println(c)
DropWhen{Int64}(0x0000000000000017,Signal[],Lift{Bool}(0x0000000000000016,Signal
[],(anonymous function),(Input{Bool}(0x0000000000000013,Signal[Lift{Bool}(0x0000
000000000014,Signal[],(anonymous function),(Input{Bool}(#= circular reference =#
),),true),Lift{Bool}(#= circular reference =#)],false),),true),Input{Int64}(0x00
00000000000012,Signal[DropWhen{Int64}(0x0000000000000015,Signal[],Lift{Bool}(0x0
000000000000014,Signal[],(anonymous function),(Input{Bool}(0x0000000000000013,Si
gnal[Lift{Bool}(#= circular reference =#),Lift{Bool}(0x0000000000000016,Signal[]
,(anonymous function),(Input{Bool}(#= circular reference =#),),true)],false),),t
rue),Input{Int64}(#= circular reference =#),9),DropWhen{Int64}(#= circular refer
ence =#)],9),9)

The circular references seem weird, and I think on some platform it crashes, when you try to print this.
Best,
Simon

RFC: Signal type hell

Passing in the right types to lift, foldl and flatten (and finally resorting to Any) in these lines caused me a lot of distress. This was mainly because a signal of type Board{true} will not update to Board{false}, and you are forced to annotate the type in each node in the subgraph.

This has got me wondering if there is any use to having the default type be the tightest possible type depending on the initial value in lift, foldl and flatten. It would be useful if one could statically warn of potential errors due to wrong types, Julia does not do this anyway. I am inclining towards using Any as default, and making tighter types as opt-in.

Also need consistency in the API for specifying types. I am thinking a typ keyword argument for lift, foldl and flatten can be consistent.

@stevengj @SimonDanisch what do you think of this?

typo in documentation

In the Maintaining State section a copy-paste of the leading definition generates an error

julia> leading = lift((a, b) -> if a > b ? :Alice : a < b ? :Bob : :Tie, alice, bob)
ERROR: syntax: unexpected ,

UID type

Wouldn't it be better to use Base.UUID to match IPython?

fpswhen broken

    From worker 3:  MethodError: `filter` has no method matching filter(::Function, ::Bool, ::Bool)
    From worker 3:  Closest candidates are:
    From worker 3:    filter{T}(::Function, ::Any, !Matched::Reactive.Signal{T})
    From worker 3:    filter(::Any, ::Any)
    From worker 3:    filter(::Any, !Matched::Array{T,1})

using:

eventloop = fpswhen(true,7)

React Benchmark

Hi,
I made a little benchmark, to see how big the performance gap is between React and "unrolled" code.
Here's the code
https://gist.github.com/SimonDanisch/fe5eaa964a5a1c197f01
Results:
unrolled: 6.8611264019997655e-6
React: 6.653197434700169e-5
Which isn't too bad, considering what React does.
I'm wondering, if my benchmark code is a good comparison though.
Also, I want to start a discussion on how to make React faster ;)
Maybe we can start to emit customized code, instead of putting the lifts in data structures?

[PkgEval] Reactive may have a testing issue on Julia 0.4 (2015-06-23)

PackageEvaluator.jl is a script that runs nightly. It attempts to load all Julia packages and run their tests (if available) on both the stable version of Julia (0.3) and the nightly build of the unstable version (0.4). The results of this script are used to generate a package listing enhanced with testing results.

On Julia 0.4

  • On 2015-06-22 the testing status was Tests pass.
  • On 2015-06-23 the testing status changed to Tests fail.

This issue was filed because your testing status became worse. No additional issues will be filed if your package remains in this state, and no issue will be filed if it improves. If you'd like to opt-out of these status-change messages, reply to this message saying you'd like to and @IainNZ will add an exception. If you'd like to discuss PackageEvaluator.jl please file an issue at the repository. For example, your package may be untestable on the test machine due to a dependency - an exception can be added.

Test log:

>>> 'Pkg.add("Reactive")' log
INFO: Cloning cache of Reactive from git://github.com/JuliaLang/Reactive.jl.git
INFO: Installing FactCheck v0.2.7
INFO: Installing Reactive v0.2.0
INFO: Package database updated

>>> 'Pkg.test("Reactive")' log
INFO: Testing Reactive
ERROR: LoadError: LoadError: LoadError: syntax: local declaration in global scope
 in include at ./boot.jl:254
 in include_from_node1 at ./loading.jl:133
 in reload_path at ./loading.jl:157
 in _require at ./loading.jl:69
 in require at ./loading.jl:52
 in include at ./boot.jl:254
 in include_from_node1 at ./loading.jl:133
 in include at ./boot.jl:254
 in include_from_node1 at loading.jl:133
 in process_options at ./client.jl:304
 in _start at ./client.jl:404
while loading /home/vagrant/.julia/v0.4/Reactive/src/Reactive.jl, in expression starting on line 33
while loading /home/vagrant/.julia/v0.4/Reactive/test/basics.jl, in expression starting on line 2
while loading /home/vagrant/.julia/v0.4/Reactive/test/runtests.jl, in expression starting on line 1

==============================[ ERROR: Reactive ]===============================

failed process: Process(`/home/vagrant/julia/bin/julia --check-bounds=yes --code-coverage=none --color=no /home/vagrant/.julia/v0.4/Reactive/test/runtests.jl`, ProcessExited(1)) [1]

================================================================================
INFO: No packages to install, update or remove
ERROR: Reactive had test errors
 in error at ./error.jl:21
 in test at pkg/entry.jl:746
 in anonymous at pkg/dir.jl:31
 in cd at file.jl:22
 in cd at pkg/dir.jl:31
 in test at pkg.jl:71
 in process_options at ./client.jl:280
 in _start at ./client.jl:404


>>> End of log

fps and fpswhen don't return Δt

It seems to create a signal of negatively accumulated timestamps instead of a Δt values

julia> using Reactive

julia> lift((delta) -> println(delta), fps(0.5))
1.437081000427725e9
nothing

julia> -1.4370810026088e9
-2.8741620071283436e9
-4.311243013650205e9
-5.74832402217328e9
-7.185405032698582e9

tested in Julia 0.3.10

foldl uses more state than necessary?

For example, to delay a signal -

function delay_func(state, value)
    older_value, prev_value = state
    return (prev_value, value)
end

delay(init_value, signal) = map(x -> x[1], foldl(delay_func, (0, init_value), signal))

It seems that older_value is unnecessary. To compare with Elm,

delay init_value signal = foldp (\value state -> value) init_value signal

One way around is to define a foldp using foldl, but then I wonder why foldl and its extra state is needed in the first place.

Package fails to load on latest Julia v0.4

julia> versioninfo()
Julia Version 0.4.0-dev+4319
Commit ef06211* (2015-04-17 03:26 UTC)
Platform Info:
  System: Darwin (x86_64-apple-darwin13.4.0)
  CPU: Intel(R) Core(TM)2 Duo CPU     P7350  @ 2.00GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Penryn)
  LAPACK: libopenblas
  LIBM: libopenlibm
  LLVM: libLLVM-3.6.0

julia> using Reactive
WARNING: uint(x) is deprecated, use UInt(x) instead.
 in depwarn at ./deprecated.jl:40
 in uint at no file
 in anonymous at no file
 in include at ./boot.jl:250
 in include_from_node1 at ./loading.jl:129
 in reload_path at ./loading.jl:153
 in _require at ./loading.jl:68
 in require at ./loading.jl:52
ERROR: LoadError: MethodError: `start` has no method matching start(::Type{Reactive.Signal{T}})
 in append_any at no file
 in include at ./boot.jl:250
 in include_from_node1 at ./loading.jl:129
 in reload_path at ./loading.jl:153
 in _require at ./loading.jl:68
 in require at ./loading.jl:52
while loading /Users/Administrator/.julia/v0.4/Reactive/src/Reactive.jl, in expression starting on line 63

make children an Array rather than a Set

Since the only operations on children that you seem to need are push! and iterating over elements, a Set seems like overkill (it introduces the overhead of a hash table, which is only useful if you want fast inclusion testing).

Allow multiple signals updating at once

When using signals heavily, it quickly becomes very annoying that only one signal can update at a time. What is the reason for this? I understand that you have to detect the same signal updating recursively, but why can't multiple independent signals update simultaneously? @shashi

global roots?

It looks worrisome that push! updates everything in a global roots array. This seems like it will scale badly.

Surely, pushing a value to an input should only affect the signals that depend on that input. Aren't you already storing the dependency DAG via the children field etcetera?

Error: "Patchable not defined" under Julia 0.4.0

The following code runs fine under Julia 0.3.10 but it produces an error under Julia 0.4.0

using Interact, Reactive, Gadfly

sl_β = slider(0:1:50, label="Npoints")    
display(sl_β) #displays the slider at the output of the current cell

#tie the slider with the plotting routine
plt_pa = lift(β->begin
                    plt_pagw = plot(x=rand(β),y=rand(β),Geom.point, Geom.line)
                 end,sl_β)

The output in Julia 0.4.0 is

UndefVarError: Patchable not defined

 in anonymous at D:\JuiliaPackages\v0.4\Gadfly\src\Gadfly.jl:891
 in lift at D:\JuiliaPackages\v0.4\Reactive\src\Reactive.jl:364
 in writemime at D:\JuiliaPackages\v0.4\Gadfly\src\Gadfly.jl:891
 in sprint at iostream.jl:206
 in display_dict at D:\JuiliaPackages\v0.4\IJulia\src\execute_request.jl:39

I'm running this on the release of Julia 0.4.0 and I have checked out the Interact.jl master - here's the specific package versions I'm using

 - Gadfly                        0.3.17
 - IJulia                        1.1.7
 - Interact                      0.2.1+             master
 - Patchwork                     0.1.8
 - Reactive                      0.2.4

Thanks for having a look into this!

Pkg.test("Reactive")

Hey guys,

i've tried to install GLPlot but always got the error:

Pkg.test("GLPlot")

ERROR: `lift` has no method matching lift(::Function, ::Type{Vector2{Float64}}, ::Input{Vector2{Float64}}, ::Input{Vector4{Int64}})
 in createwindow at /Users/Max/.julia/v0.3/GLWindow/src/reactglfw.jl:359
 in createdisplay at /Users/Max/.julia/v0.3/GLPlot/src/GLPlot.jl:51
 in include at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include_from_node1 at loading.jl:128
 in process_options at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in _start at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
while loading /Users/Max/.julia/v0.3/GLPlot/test/runtests.jl, in expression starting on line 3

So i did a Pkg.test("Reactive") and got this message:

INFO: Testing Reactive
Basic checks
     - lift
InexactError()

 in push! at /Users/Max/.julia/v0.3/Reactive/src/Reactive.jl:261
 in anonymous at /Users/Max/.julia/v0.3/FactCheck/src/FactCheck.jl:178
 in do_fact at /Users/Max/.julia/v0.3/FactCheck/src/FactCheck.jl:201
 in anonymous at /Users/Max/.julia/v0.3/Reactive/test/basics.jl:177
 in context at /Users/Max/.julia/v0.3/FactCheck/src/FactCheck.jl:341
 in anonymous at /Users/Max/.julia/v0.3/Reactive/test/basics.jl:15
 in facts at /Users/Max/.julia/v0.3/FactCheck/src/FactCheck.jl:315
 in include at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include_from_node1 at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include_from_node1 at loading.jl:128
 in process_options at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in _start at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
     - merge
     - foldl
     - filter
     - sampleon
     - droprepeats
     - dropwhen
28 facts verified.
trylift
     - trylift
5 facts verified.
Call counting
600 facts verified.
push! inside push!
push! called when another signal is still updating.

 in push! at /Users/Max/.julia/v0.3/Reactive/src/Reactive.jl:257
 in crash at /Users/Max/.julia/v0.3/Reactive/test/concurrency.jl:7
 in update at /Users/Max/.julia/v0.3/Reactive/src/Reactive.jl:95
 in push! at /Users/Max/.julia/v0.3/Reactive/src/Reactive.jl:286
 in anonymous at /Users/Max/.julia/v0.3/FactCheck/src/FactCheck.jl:178
 in do_fact at /Users/Max/.julia/v0.3/FactCheck/src/FactCheck.jl:201
 in anonymous at /Users/Max/.julia/v0.3/Reactive/test/concurrency.jl:177
 in facts at /Users/Max/.julia/v0.3/FactCheck/src/FactCheck.jl:315
 in include at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include_from_node1 at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include_from_node1 at loading.jl:128
 in process_options at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
 in _start at /Applications/Julia-0.3.8.app/Contents/Resources/julia/lib/julia/sys.dylib
1 fact verified.
@lift
     - @lift input expressions
     - @lift basics
     - @lift inside a function
7 facts verified.
Flatten
     - Signal{Signal} -> flat Signal
     - Initial update count
     - Current signal updates
     - Signal swap
11 facts verified.
INFO: Reactive tests passed
INFO: No packages to install, update or remove

I'm using Julia 0.3.8 on my Macbook with OS X Yosemite installed.

Maybe you could help to find a solution.

Thanks Max

RFC: Handling invalid values (errors?) gracefully

Consider a hypothetical text box which has a character counter and an upper limit on the number of characters (and possibly also a pattern matcher to validate input). Now we want to be able to create a signal which can represent both valid and invalid input. This can be done nicely with an Either type

I am thinking of introducing a variation of the Either type called Try:

abstract Try{T}

immutable Success{T} <: Try{T}
    value::T
end

success(T, value) = Success{T}(value)

immutable Failure{T} <: Try{T}
    value::Exception
end

failure(T, value) = Failure{T}(value)

get(t::Try) = t.value

A text box described above could give out a signal of Try{String} values. Further, it can define the type

immutable TooLong <: Exception
    value::String
end

Now, a valid update would result in a Success{String}("text here") value on which you can call get to get the string. an invalid string can result in a Failure{String}(TooLong("longer text here")).

Can these types be any better? Are there any better ways to handle invalid values?

cc @stevengj

[BUG] Random error occurs after a period of frequent updating (burst of 4 Signal.push! in one go)

My code runs through perfectly on first pass (inside an Escher page request). The next time I refresh the page all hell breaks loose.

It looks like

Using Type:
immutable recordingUpdate
    sess::Base.Random.UUID
    prop::Symbol
    value::Any
    dt::DateTime
end

And signal:

Signal(recordingUpdate, recordingUpdate(Base.Random.uuid4(),:status,"BOOTED",now()))

After a while, (indeterminate time) this happens:

Failed to push!
    recordingUpdate(29c04b23-aa04-4b17-81a4-5fb1479246f1,:label,"END",2016-03-09T18:39:51)
to node
    WeakRef(Signal{recordingUpdate}(recordingUpdate(29c04b23-aa04-4b17-81a4-5fb1479246f1,:label,"END",2016-03-09T18:39:51), nactions=1))
MethodError: `convert` has no method matching convert(::Type{Void}, ::recordingUpdate)
This may have arisen from a call to the constructor Void(...),
since type constructors fall back to convert methods.
Closest candidates are:
  call{T}(::Type{T}, ::Any)
  convert{T}(::Type{T}, !Matched::T)
  Void()
 in send_value! at /home/a/.julia/v0.4/Reactive/src/core.jl:128
 in anonymous at /home/a/.julia/v0.4/Reactive/src/operators.jl:37
 in do_action at /home/a/.julia/v0.4/Reactive/src/core.jl:135
 in send_value! at /home/a/.julia/v0.4/Reactive/src/core.jl:130
 in send_value! at /home/a/.julia/v0.4/Reactive/src/core.jl:133
 in run at /home/a/.julia/v0.4/Reactive/src/core.jl:190
 in run at /home/a/.julia/v0.4/Reactive/src/core.jl:181
 [inlined code] from /home/a/.julia/v0.4/Reactive/src/core.jl:228
 in anonymous at task.jl:447

I added this to core:

function send_value!(node::Signal, x, timestep)
    # Dead node?
    !node.alive && return

    # Set the value and do actions
    if string(typeof(x)) == "recordingUpdate"
      remotecall(print,1,typeof(node.value),typeof(x))
    end
    node.value = x
    for action in node.actions
        do_action(action, timestep)
    end
end

And it turns out the Signals are doubling up (notice the Void):

**recordingUpdaterecordingUpdateVoidrecordingUpdate**Failed to push!
    recordingUpdate(88c3f609-4ca8-40dc-99ec-ba9f9227d3e6,:label,"BLACK",2016-03-09T19:42:15)
to node
    WeakRef(Signal{recordingUpdate}(recordingUpdate(88c3f609-4ca8-40dc-99ec-ba9f9227d3e6,:label,"BLACK",2016-03-09T19:42:15), nactions=1))
MethodError: `convert` has no method matching convert(::Type{Void}, ::recordingUpdate)
This may have arisen from a call to the constructor Void(...),
since type constructors fall back to convert methods.
Closest candidates are:
  call{T}(::Type{T}, ::Any)
  convert{T}(::Type{T}, !Matched::T)
  Void()
 in send_value! at /home/a/.julia/v0.4/Reactive/src/core.jl:131
 in anonymous at /home/a/.julia/v0.4/Reactive/src/operators.jl:37
 in do_action at /home/a/.julia/v0.4/Reactive/src/core.jl:138
 in send_value! at /home/a/.julia/v0.4/Reactive/src/core.jl:133
 in send_value! at /home/a/.julia/v0.4/Reactive/src/core.jl:136
 in run at /home/a/.julia/v0.4/Reactive/src/core.jl:193
 in run at /home/a/.julia/v0.4/Reactive/src/core.jl:184
 [inlined code] from /home/a/.julia/v0.4/Reactive/src/core.jl:231
 in anonymous at task.jl:447

After further tests, I can confirm I'm only calling the method push! once so I think this is definitely a bug.

Trying to lift...

Hi,

Maybe I'm just missing something obvious, but I'm not able to get the "lift" part of the tutorial working. I'd really like to use it! I've tried on Julia 0.3.8/10 and 0.4-dev
#40~14.04.1-Ubuntu SMP Thu Jan 15 17:43:14 UTC 2015

$ ./julia-dev
...
Version 0.4.0-dev+5696 (2015-06-29 15:30 UTC)
Commit 1544e4e* (0 days old master)
x86_64-unknown-linux-gnu

julia> Pkg.add("Reactive")
INFO: Initializing package repository /home/dehann/.julia/v0.4
INFO: Cloning METADATA from git://github.com/JuliaLang/METADATA.jl
INFO: Installing Compat v0.4.6
INFO: Installing FactCheck v0.2.8
INFO: Installing Reactive v0.2.2
INFO: Package database updated

julia> using Reactive

julia> x = Input(0)
0

julia> xsqr = lift(a -> a*a, Int, x)
ERROR: MethodError: consume has no method matching consume(::Function, ::Type{Int64}, ::Reactive.Input{Int64})
Closest candidates are:
consume(::Task, ::Any...)
consume(::Union{DataType,Function}, ::Reactive.Signal{T}...)
consume(::Union{DataType,Function}, ::Reactive.SignalSource...)
in lift at /home/dehann/.julia/v0.4/Reactive/src/Reactive.jl:362

Thanks,
Dehann

rename reduce to foldl, add foldr

Since you are doing a foldl operation, you should call the function this. Also, it would be nice to mimic the Base.foldl function in making v0 optional (if it is not given, you initialize with the current value of the signal.)

You should probably also have a foldr function for completeness.

push! must be called asynchronously

Not sure if this should go on the mailing list instead, but what is the correct pattern to propagate changes from one input to another? I tried this:

using Reactive
a = Input(0)
b = Input(0)

lift(x -> push!(a,x), b)

But with push!(b, 1) I get the error "push! must be called asynchronously".

Feature Request: De/Attachable Subgraphs

Hi,
I've been speaking about this with Shashi, but I think so far I haven't had good examples, so the conclusion was mostly, that I'm using react wrong.
I did some more thinking, and I came to the conclusion, that we really need some mechanisms, to connect different react graphs, as you can't always construct the whole graph.
Example:
In an API I want to offer, to make a shader out of some string signal. But at shader creation, I don't want to force the user to decide, from which string signal he wants to create the shader.

function makeshader(defaultsource::String)
   sourcecode = ascii(defaultsource)
   dummyInput = Input(sourcecode)
   lift(dummyInput) do sourcecode
      ... Make new shader
      ... Delete old shader
      return shader
   end
   return dummyInput # return "socket" to which one can connect
end
# At initializsation, by some API, somewhere, where the user has no access
shader = makeshader(SomeShaderSource)

# At a different time point, user wants to interact with the shader, namely updating it
newsource = lift(x -> readall(open("filename")), every(1.0)) # this is just exemplary and a really wasteful way of doing this

# Now, this doesn't work in the current API:
lift(x-> push!(shader, x), newsource)
# So something like this is needed!?
connect(shader.dummyInput, newsource)

Another example:
I'm working on widgets for my plots.
The data for a plot in GLPlot looks a little like this:

[
:attributename => Input(someValue)
:attributname => SomeLift
....
]

Now, at the part where I initialize this datastructure, I don't even remotely know, if the person wants to change the value via a my glwidgets, via the commandline with push!(), or if someone builds, for example, some tk wrapper.

Best,
Simon

lift API tweaks

I would suggest defining it as:

lift(f::Function, output_type::Type, inputs::Signal...)

so that:

  • Putting the Function argument first allows one to use do-block syntax with lift.
  • Using Type rather than DataType allows functions that return tuples of types.

It would eventually be nice to have:

valtype{T}(::Signal{T}) = T
lift(f::Function, inputs::Signal...) = lift(f, return_type(f, tuple(map(valtype, inputs))), inputs...)

so that you don't need to specify the return type if Julia can infer it. The return_type functionality is not in Julia yet, though; see JuliaLang/julia#6692

Compiler complains about map redefinition

Julia Version 0.4.3

WARNING: New definition 
    map(Any, Reactive.Signal...) at /home/ul/.julia/v0.4/Reactive/src/operators.jl:26
is ambiguous with: 
    map(Function, Lazy.List...) at /home/ul/.julia/v0.4/Lazy/src/liblazy.jl:98.
To fix, define 
    map(Function)
before the new definition.
WARNING: New definition 
    map(Any, Reactive.Signal...) at /home/ul/.julia/v0.4/Reactive/src/operators.jl:26
is ambiguous with: 
    map(DataType, Lazy.List...) at /home/ul/.julia/v0.4/Lazy/src/liblazy.jl:99.
To fix, define 
    map(DataType)
before the new definition.

More expansive documentation?

I'm pretty interested in learning more about this, but since I don't speak javascript, http://facebook.github.io/react/ isn't very useful to me as documentation, and neither is http://library.elm-lang.org/catalog/evancz-Elm/0.12/Signal. Is there another source for this? Or can the README be expanded?

One small point: in your current README, the Usage section seems to contain a mix of material that mimics "declarations" and code one might actually type. So for example, it's not entirely obvious that Signal{T} is something that's defined in React.jl code. Perhaps a clearer separation between API-documentation and demo would be helpful?

Change repo description

says :

Reactive programming primitives for Julia http://julialang.github.io/React.jl/

Should update the URL, but I don't have the right to.

No getindex method defined for Input

julia> sensor_input = Input([0.0, 1.0, 0.0]) 
3-element Array{Float64,1}:
 0.0
 1.0
 0.0

julia> left_motor  = @lift sensor_input[1] - sensor_input[3]
ERROR: MethodError: `getindex` has no method matching getindex(::Reactive.Input{Array{Float64,1}}, ::Int64)
 in anonymous at no file
 in lift at no file

[PkgEval] React may have a testing issue on Julia 0.2 (2014-06-27)

PackageEvaluator.jl is a script that runs nightly. It attempts to load all Julia packages and run their tests (if available) on both the stable version of Julia (0.2) and the nightly build of the unstable version (0.3). The results of this script are used to generate a package listing enhanced with testing results.

On Julia 0.2

  • On 2014-06-26 the testing status was Tests pass.
  • On 2014-06-27 the testing status changed to Tests fail, but package loads.

Tests pass. means that PackageEvaluator found the tests for your package, executed them, and they all passed.

Tests fail, but package loads. means that PackageEvaluator found the tests for your package, executed them, and they didn't pass. However, trying to load your package with using worked.

This issue was filed because your testing status became worse. No additional issues will be filed if your package remains in this state, and no issue will be filed if it improves. If you'd like to opt-out of these status-change messages, reply to this message saying you'd like to and @IainNZ will add an exception. If you'd like to discuss PackageEvaluator.jl please file an issue at the repository. For example, your package may be untestable on the test machine due to a dependency - an exception can be added.

Test log:

INFO: Cloning cache of React from git://github.com/shashi/React.jl.git
INFO: Installing React v0.1.2
INFO: REQUIRE updated.
Warning: could not import Base.foldl into React
Warning: could not import Base.foldr into React
Warning: could not import Base.foldl into React
Warning: could not import Base.foldr into React
ERROR: wrong number of arguments
 in include at boot.jl:238
at /home/idunning/pkgtest/.julia/v0.2/React/tests/basics.jl:13
at /home/idunning/pkgtest/.julia/v0.2/React/tests/test.jl:1
INFO: REQUIRE updated.

Mention `yield` in tutorial?

I was having issues with Reactive, where a map/lift command was not running consistently, and eventually error messages about a queue being filled appeared. Adding yield to the code generating the data appears to have resolved the data. (I suppose map/lift runs as an @async process and so yield is needed for it to run.)

I'd suggest this is added to the tutorial as it took me a bit of guessing to determine the issue.

@lift macro?

I find the lift(x -> foo(x), y) syntax a little awkward. What you really want to do is to be able to just write foo(y) and have it automatically create a Lift.

Doing that directly seems too hard, because it would involve overriding every conceivable function to have Signal variants. But something like this could be accomplished by a macro:

x = Input(3)
y = Input(7)
@lift x + y - 5*sin(x)

What the @lift macro would do would be to walk the expression tree, and any symbol that it finds corresponding to a defined value of type <: Signal would get converted into a function parameter in a call to lift.

It's a little tricky to get the metaprogramming right here, but I think it should be do-able and will make this a lot easier to use.

Merge error and fix

Hi, this lib (and Interact etc.) rock - thank you so much!
Small bug it seems, try this:

using Reactive
input1 = Input("yah")
input2 = Input("nah")
merge(input1, input2)

`convert` has no method matching convert(::Type{Char}, ::ASCIIString)
while loading In[1], in expression starting on line 4

 in Merge at .../.julia/v0.3/Reactive/src/Reactive.jl:171
 in merge at .../.julia/v0.3/Reactive/src/Reactive.jl:372

Reactive:372 is
merge(signals::Signal...) = Merge{join_eltype(map(eltype, signals)...)}(signals)

As it turns out Base.join_eltype calls eltype itself, so eltype is being called twice (per signal), first on the signal in the map, returning String, then again on String, returning Char (eltype(String) returns Char), resulting in Merge{Char} being called with ASCIIString signals. This wouldn't have come up for Numbers etc. because eltype seems to just return the argument provided to it for Int, Real, Float64, etc., e.g. eltype(Int64) returns Int64

Accordingly, changing Reactive:372 to
merge(signals::Signal...) = Merge{join_eltype(signals...)}(signals)
fixes it.

Keep up the good work!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.