Search code examples
juliabindpluto.jlplutoui

Two-way binding in PlutoUI.jl?


I am trying to do a simple (I think) thing. I want to have a TextField and some variable bound to it and be able to modify this variable and by that the text displayed by the TextField.

I tried:

@bind x TextField()

print(x)

It works fine and whatever I type in the tex field is printed.

Now, what if I want programmatically change x and display it in the TextField?

if I write x="trelemorele", I am getting:

  • error of "Multiple definitions for x", if it is in a separate cell
  • no error but my TextField disappear, if it is in the same cell within begin .. end

Any ideas?


Solution

  • What you're trying to do is fundamentally at odds with Pluto's reactivity.

    At the heart of the idea of Pluto is that cells are connected by a dependency graph which Pluto automatically figures out for you from the code you've written, and which it uses to determine which cells need to be updated when another cell changes, because they depend on the changed cell.

    So in simple terms if you have:

    # Cell 1
    x = 1
    
    # Cell 2
    y = x^2
    

    Pluto will determine that cell 2 depends on cell 1, as x is defined there and used as an input in cell 2. But what if you now add

    # Cell 3
    x = 2
    

    ? Well you've now broken reactivity - Pluto can't work out the result of cell 2 anymore because there's now two competing definitions of x. Now you might say "well but I've put in the definition on cell 3 after the one in cell 1, so clearly it should be using x = 2", but that's exactly what Pluto wants to avoid. This is possible in Jupyter notebooks - the value of x would depend on whether cell 1 or cell 3 was executed last, but this means there's "hidden state" in the notebook; it is not possible from just looking at cell 1 or cell 3 whether their definitions haven't been overwritten elsewhere.

    When you do @bind x TextField() that's roughly the same as doing x = TextField() (the actual generate code is a bit more complicated, but in the end it assigns something to the variable x), so doing that in one cell and x = "trelemorele" is the same thing.

    Now as to your second point, Pluto does not complain because you now have an unambiguous ouptut for what should be bound to x after executing your cell - it's the last assignment to x, which is the same in a normal Julia session:

    julia> begin
               x = 1
               x = 2
           end;
    
    julia> x
    2