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

Allow defining callable types in different cells as the struct definition #2038

Open
kalmarek opened this issue Apr 19, 2022 · 6 comments
Open
Labels
reactivity The Pluto programming paradigm

Comments

@kalmarek
Copy link

Sorry, but there will be no video for this one, It's literally too simple ;)

Happens with

[c3e4b0f8] Pluto v0.19.0

Consider the following code:

julia> struct AAA
               x::Int
       end

julia> a = AAA(3)
AAA(3)

julia> function (a::AAA)(b::Int)
               return b*a.x
       end

julia> a(5)
15

I created a type, instantiated it, added a call method to it, called the instance on an argument.

When trying the same in Pluto I get

Multiple definitions for [AAA](http://localhost:1234/edit?id=90461ae2-bff1-11ec-20af-87661f3a3747#).

Combine all definitions into a single reactive cell using a `begin ... end` block.

when defining call method. Here's a Pluto notebook showing the issue.

@Pangoraw
Copy link
Collaborator

Hello. This behavior is intended to encourage adding the call method and the struct definition inside the same cell (see #288).
The error message should be improved.

@kalmarek
Copy link
Author

@Pangoraw Thanks for the answer! Though throwing an error on a perfectly valid julia code it's a rather heavy-handed encouragement ;)

So my use-case is as follows:
I'm writing interactive materials for my classes where I go slowly explaining every function/step one by one. For this "one computation per block" suits it very well. But then 4 screens after the introduction of a struct I'd like to add callable method to my struct with math explanation + syntax explanation. And now it seems that I should have to either

  1. break the notebook into parts
  2. break the flow of the document by introducing a callable method in begin... end block out-of-context and describing it only 4 screens later (where it fits naturally to the narrative).

I tried to read the issue, but I didn't see the rationale for treating call method any differently from other functions, except for
some technical reasons (which I admittedly didn't understand too deeply).

Is there a documented list of what is a valid in julia code but is not valid in Pluto?

@Pangoraw
Copy link
Collaborator

Pluto schedules cells to run based on their dependencies so without this workaround the callable method will behave like any cell using the struct. That means that for cells using the struct only the cell order (whether the cell is higher in the notebook order) will determine the run order which Pluto tries very hard to avoid.

For example if you disable this behavior and let the callable method be defined in any cell:

image

What Pluto needs is a way to schedule these cells with a higher priority than other cells using the A struct the same problem happens with Base.show() methods (see #326). In the linked issue (#288) there was mention that this is currently a workaround and a new issue should track the problem so let's track it here!

Is there a documented list of what is a valid in julia code but is not valid in Pluto?

There is this wiki page but its not very exhaustive.

@Pangoraw Pangoraw added the reactivity The Pluto programming paradigm label Apr 23, 2022
@Pangoraw Pangoraw changed the title Multiple definitions for … when defininig callable type Allow defining callable types in different cells as the struct definition Apr 23, 2022
@Pangoraw
Copy link
Collaborator

Struct with generics are exempt of this "rule" so you can try out the problem in base Pluto:

image

@kalmarek
Copy link
Author

Thanks for the extensive explanation!

@chelate
Copy link

chelate commented Feb 2, 2024

I have a problem that even when I wrap in a

begin
  struct thingy
  end
  function (t::thingy)
   something(t::thingy) # call another dispatching on thing
  end
end

it won't work consistently unless the definition of something is ALSO in the begin end. It seems to me that there I a statically resolvable sense that structs go first if possible, then function definitions, since these just add methods if the function type already been defined. Ps. I love Pluto!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reactivity The Pluto programming paradigm
Projects
None yet
Development

No branches or pull requests

3 participants