Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Julia 1.5 breaks @bind #200

Closed
fonsp opened this issue Jul 2, 2020 · 9 comments
Closed

Julia 1.5 breaks @bind #200

fonsp opened this issue Jul 2, 2020 · 9 comments
Labels
almost closed bug Something isn't working

Comments

@fonsp
Copy link
Owner

fonsp commented Jul 2, 2020

Posted by @cormullion on zulip:

image

@fonsp
Copy link
Owner Author

fonsp commented Jul 2, 2020

Can you do Pkg.status() in the terminal where you launched Pluto and send a screenshot?

@fonsp
Copy link
Owner Author

fonsp commented Jul 2, 2020

And can you create a cell with this content:

methods(Base.peek)

and send me the result?

@cormullion
Copy link
Contributor

Closing Pluto... Restart Julia for a fresh session. 

Have a nice day! 🎈

(@v1.5) pkg> st
Status `~/.julia/environments/v1.5/Project.toml`
  [537997a7] AbstractPlotting v0.11.2
  [c52e3926] Atom v0.12.15
  [336ed68f] CSV v0.7.1
  [159f3aea] Cairo v1.0.3
  [d3e213a1] ColorSchemeTools v0.2.0
  [35d6a980] ColorSchemes v3.9.0
  [5ae59095] Colors v0.12.2
  [a93c6f00] DataFrames v0.21.3
  [e30172f5] Documenter v0.25.0
  [186bb1d3] Fontconfig v0.4.0
  [916415d5] Images v0.22.3
  [682c06a0] JSON v0.21.0
  [e5e0dc1b] Juno v0.8.2
  [ae8d54c2] Luxor v2.2.0 `~/.julia/dev/Luxor`
  [ee78f7c6] Makie v0.11.0
  [91a5bcdd] Plots v1.4.4
  [c3e4b0f8] Pluto v0.9.11
  [7f904dfe] PlutoUI v0.3.0
  [c46f51b8] ProfileView v0.6.5
  [d330b81b] PyPlot v2.9.0
  [8b424ff8] Thebes v0.0.0 `~/.julia/dev/Thebes`



julia> methods(Base.peek)
# 11 methods for generic function "peek":
[1] peek(s::Base.Iterators.Stateful) in Base.Iterators at iterators.jl:1274
[2] peek(s::Base.Iterators.Stateful, sentinel) in Base.Iterators at iterators.jl:1274
[3] peek(t::REPL.Terminals.TTYTerminal, ::Type{T}) where T in REPL.Terminals at /Applications/Julia-1.5.app/Contents/Resources/julia/share/julia/stdlib/v1.5/REPL/src/Terminals.jl:163
[4] peek(io::Base.AbstractPipe, ::Type{T}) where T in Base at io.jl:358
[5] peek(from::Base.GenericIOBuffer, T::Union{Type{Float16}, Type{Float32}, Type{Float64}, Type{Int128}, Type{Int16}, Type{Int32}, Type{Int64}, Type{UInt128}, Type{UInt16}, Type{UInt32}, Type{UInt64}}) in Base at iobuffer.jl:175
[6] peek(from::Base.GenericIOBuffer, ::Type{UInt8}) in Base at iobuffer.jl:224
[7] peek(s::IOStream, ::Type{UInt8}) in Base at iostream.jl:528
[8] peek(s::Base.LibuvStream, ::Type{T}) where T in Base at stream.jl:1196
[9] peek(io::Base.SecretBuffer, ::Type{UInt8}) in Base at secretbuffer.jl:157
[10] peek(s::IO, ::Type{T}) where T in Base at io.jl:254
[11] peek(s) in Base at io.jl:262


@cormullion
Copy link
Contributor

Same output in a Plutonian cell...

@fonsp fonsp changed the title @bind error Julia 1.5 breaks @bind Jul 3, 2020
@fonsp fonsp added the bug Something isn't working label Jul 3, 2020
@fonsp
Copy link
Owner Author

fonsp commented Jul 3, 2020

well this was a rollercoaster!

it looks like we have to pick a different function to abuse than Base.peek, since this one was changed and got added to the Julia spec. It made me realise that we should use a function that is already part of the Julia spec. My shortlist is:
Base.yield, Base.readlink, Base.get, Base.download, Base.zero. I'll sleep on it 😴


In the future, I'd like to add the possibility for bonds to transform the JavaScript-returned object before it is made available in the Julia scope. (See JuliaPluto/PlutoUI.jl#3 for motivation.) So you could overload:

Base.peek(x::MyBondType) = default_value

for the default value, and

Base.peek(x::MyBondType, received::Dict) = ...

is a 'preprocessor', the result of which is assigned to the bound variable.

If no overload exists for the first function, then Base.peek(x) = missing is used. For the second function, Base.peek(x, received) = received is the default. (These fallback methods are not added to the global scope)

@fonsp
Copy link
Owner Author

fonsp commented Jul 4, 2020

I think Base.get is best - it is closest to being semantically correct, and it is a commonly overloaded method.

I see use cases where package creators overload Base.get for their custom types for other reasons than the default-value-for-Pluto-bonds feature, (a Table type, for example, where the interaction is the clicked column), but:

  1. Normal use of Base.get always takes 3 arguments, ours takes 1 or 2.
  2. Overloading Base.get is not necessary for @bond support, they can ignore it if there's a conflict.
  3. In the hard-to-imagine case that there is a conflict, the package creator can make JS return an object, and dispatch on Dict for the second argument. Or a singleton array and dispatch on Array{Dict} if Dict is the conflict. Or nested combinations even!

Let this be the only time that this API needs to change!

@fonsp
Copy link
Owner Author

fonsp commented Jul 4, 2020

The other option is to register a public AbstractPlutoBonds.jl package, but it's something I hope to avoid: We would be forcing a dependency upon other packages. Just like with the display system, I think that Julia's built-in features are good enough! Library packages should not depend on IDEs, and in Julia's case: packages should support rich output without depending/specializing on an IDE. Overloading a Base methods extends this concept to rich interactivity.

@cormullion
Copy link
Contributor

I use get in my packages too - it seems nicely general... But I use 2 and 3 arguments... ¯\_(ツ)_/¯

@fonsp
Copy link
Owner Author

fonsp commented Jul 6, 2020

Alright lets do get!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
almost closed bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants