Atom: where should we try to go #237
Replies: 4 comments 5 replies
-
Could you provide examples and/or thoughts on how de-correlating would work?
From a performance I'd rather delete all modes and make dedicated member types for each.. since all the code I've seen never modifies them anyways after initially setting them but each mode requires jumptables.
It wouldn't be hard to have a custom exception that collects the errors. Since the change_types flag wastes space (due to padding) it could be extended to pass in a separate mode on how errors should be handled.
I think this can be done with events/signals?
The observer pool pointer could be moved into the "slots" and be handled by a custom member. Or notification could be delegated to members themselves (since the pool currently has to copy each member name). |
Beta Was this translation helpful? Give feedback.
-
After looking through the code more... I noticed some of the member modes do not use the slot that is allocated to them. It'd be nice to avoid allocating space for members that will never use it. For example Event and Signal, on getattr these both create new "proxy" objects that just forward calls to observe/unobserve. The setattr for event just calls notify after validating the args and the setattr for signal is disabled (it instead has an emit method on the signal connector it returns). |
Beta Was this translation helpful? Give feedback.
-
You are being saddled by the bad design of the web document object model.
Not unrelatedly, what you describe is the reason for the existence of the
JavaScript prototype object model, instead of the traditional class
inheritance model.
…On Mon, Feb 3, 2025 at 7:52 PM frmdstryr ***@***.***> wrote:
After looking through the code some of the member modes do not use the
slot that is allocated to them. It'd be nice to avoid allocating space for
members that will never use it.
For example Event and Signal, on getattr these both create new "proxy"
objects that just forward calls to observe/unobserve. The setattr for event
just calls notify after validating the args and the setattr for signal is
disabled.
—
Reply to this email directly, view it on GitHub
<#237 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABBQSKOJULIXWZVMCWTIJL2OAMOPAVCNFSM6AAAAABVTD2MNGVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTEMBUHE3TEMY>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
I've been playing around with splitting validation and coercion but I don't think it's possible. Consider the following: class Foo(Atom):
items = Dict(str, List[int]) This would pass validation: foo = Foo()
foo.items = {'a': [1,2]} However without coercion (of the embedded list to the AtomList) it would not be able ensure modifications are typed. Eg foo.items['a'].append('a string') It's really unfortunate because the current handlers require coping everything. |
Beta Was this translation helpful? Give feedback.
-
Here are some of my opinions on things we could try to change in Atom. They may not all be feasible and are definitively backward incompatible for some. I would like to have some opinions on those or other things I did not list:
Members
De-correlate validation and access rules
I have found annoying on multiple occasion that there is strong link, at least
in the Member subclasses, between how we validate a value and how it can be
accessed. Those should be orthogonal concerns.
De-correlate validation and coercion
To me coercion should be an action that is available any time the validation
fails and not be strongly linked to the type of validation we carry.
De-correlate type check and value checking
Another point I have been considering if it would be possible to split the type
checking part of the logic and the value checking part of the logic. This would
allow to simply the range validation mode for example.
Removing Member subclasses
All in all I am in favor of removing all Member subclasses since I consider
that basing any decision on the class of a member instead of inspecting the
modes is wrong. To make this feasible it may desirable to improve the interface
to set and get members, in particular by providing a more strongly typed
interface.
Removing dead members
Some members seem of little value to me and removing them may mean we get more
space for some modes.
it is not used that uses a different class of the same name.
Atom UX
Make Atom more similar to a dataclass
When Atom was created dataclasses were not a thing, but they are now quite popular
and provide some nice default behavior and integrate very well with IDE.
For example, we could get autocompletion for
__init__
without actually writingan implementation. Similarly having the possibility generate optimized implementation
for eq, hash, etc may be interesting.
This would also require to improving support for creating Atom subclasses
using type annotations. Currently we can infer members but not tune default
values when a callable is required, specify metadata or select access restrictions
(ReadOnly, Constant).
Support for Generic[T] runtime checking when T is known
Since the strong point of Atom is perform runtime validation it would be valuable
to specialize this validation for Generic subclasses. For example in the following
we should be able to enforce that we get an int.
Support for immutable mapping
One nice feature in Atom is the ability to have immutable object. However often
one needs to store a Mapping and currently we cannot enforce immutability since
we can only use dict.
Notifications
Reduce cross-talk between observers
Currently an exception occurring in any observer handler prevent the others
from running. I have often been bitten by this in enaml where the whole UI
is broken because of an unrelated exception.
Preventing observer to raise does not seem very practical to me, however
if we limit ourselves to Python 3.11+ we could use ExceptionGroup to pack
together teh exception raised in all observers.
Custom container with user defined notification logic
While building UI models, I often needed container able to notify that a
change occurred. ContainerList is bad way to do this from my point of view
because it is often too granular.
What I would like to be able to do is define custom container and have a
built-in way to connect member observers to notification originating from the
container. For such a mechanism to be meaningful we would need to provide
a default payload for container notifications.
? make it possible to have un-observable Atom ?
Because the observers take some space on each atom instance it may be interesting
to be able to disable the notification system. This could be achieve using
a new base class.
Beta Was this translation helpful? Give feedback.
All reactions