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

Too Easy to Share state variable as Pointer in Python #18

Open
zoey1124 opened this issue Aug 28, 2022 · 4 comments
Open

Too Easy to Share state variable as Pointer in Python #18

zoey1124 opened this issue Aug 28, 2022 · 4 comments

Comments

@zoey1124
Copy link

If the target language is Python, it is really easy to share the state variable as a pointer but not as value.
Here is an example of me incorrectly passing the pointer of a list to reactors.
Also, it will be better if the example here from the tutorial video can clarify the state value must not be pointer when share to downstream reactors.

@lhstrh
Copy link
Member

lhstrh commented Aug 29, 2022

🤔 I had never really thought about this problem because I don't use Python much and I haven't been involved in the development of the Python target. But in Python, everything is an object, and Python is "pass-by-object-reference." This suggests that anything passed down to another reactor must either be deep copied or considered immutable. The latter of seems unenforceable in Python but the former would be costly.

@edwardalee
Copy link
Contributor

I don't think "everything" needs to be deep copied, only things that remain in scope at the source reactor, namely state variables (or global variables, but in that case it is obvious what you are doing). Any local variable containing a reference to a state variable will also create problems.

Python does not have any notion of "Const" variables, so I think we are stuck and just have to carefully document this flaw.

@lhstrh
Copy link
Member

lhstrh commented Aug 29, 2022

Right. How can we check whether a value is accessible through the source reactor's state though? If there is no good answer to that question, then we need to either always copy to be safe, or rely on the programmer to do the right thing.

@petervdonovan
Copy link
Contributor

This suggests that anything passed down to another reactor must either be deep copied or considered immutable. The latter of seems unenforceable in Python but the former would be costly.

Python does not have any notion of "Const" variables, so I think we are stuck and just have to carefully document this flaw.

Integers, floats, and strings in Python are immutable. Tuples and frozensets of immutable objects are immutable. Immutability can be emulated using arbitrary user-defined classes; furthermore, abstract data types can be implemented using tuples and primitives and be made immutable thereby. It is true that Python does not have "const" variables, but I don't think we need that in order to solve this problem. To my knowledge, we just need Python messages to be immutable, which seems like a practical solution to me because Python programmers are already used to being forced to make certain objects hashable, which is typically more restrictive than immutability.

We could even force messages to be immutable by throwing a runtime error if they are not hashable -- I think this would give wrong answers (both false positive and false negative) sometimes, but it would be very easy and it would at least "kind of" work.

This has already been a known issue for some time though and also applies to some other targets, especially the C target. The solution in the C target would involve parsing the C code as if non-unsafe C code were an integral part of LF. I suspect we will have to do this eventually if the C target is not superseded by the C++ target or Rust target.

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

No branches or pull requests

4 participants