5 ms·
Enums are a natural fit for event handling. If you write an api that can manage 50 different kinds of events, a single enum consisting of 50 variants would be
by Dowwie 5y ago
Enums are a natural fit for event handling. If you write an api that can manage 50 different kinds of events, a single enum consisting of 50 variants would be able to facilitate that. A closure isn't identifiable to the request handler. It's just a thing that does stuff, when you're ready to call it. How do you know what stuff to do with it?
- amelius 5y agoWhat I mean is: binding an enum to an action, which then sends a message containing the enum, deciphering it and executing code based on its value, and not forgetting to define the enum somewhere, when ... you could simply bind the closure to the action. So instead of: Button::new(&mut self.increment_button, Text::new("+")) .on_press(Message::IncrementPressed) you would write: Button::new(&mut self.increment_button, Text::new("+")) .on_press(|| MY_CODE_HERE) For comparison, in JavaScript you can write: button.onclick = function(){ ++counter; } That's quite a direct way of formulating what you want to happen. All in a single line and no Enums involved.
- WJW 5y agoThe enum of all possible events is still there, it's just spread over dozens of different callback properties belonging to several different objects. Splitting out via an enum to a big `handle` type function makes it possible to detect whether you have handled all possible events at compile time instead of having to raise an exception at runtime.
- jbverschoor 5y agoJust require a callback to be non-null.
- varajelle 5y agoI see little value in seeing that enum of all possible event on one place. On the other hand, I want to see what is the action performed by that button and there is value in having small event handler close to the thing they handle.
- verdagon 5y agoIf we had a closure, we wouldn't ever need to "handle all possible events", we would just do a virtual call. It's guaranteed to be handled.
- nybble41 5y agoThe iced package requires the messages to implement the Debug, Clone, and Send traits, none of which are available for closures. I was able to implement something similar to your example[0] but it only supports plain function pointers for the callbacks. The compiler wasn't able to derive a sufficiently general Debug trait for the function pointer due to an issue with the lifetime of the argument, so I had to implement that myself as well. [Edit: Ignore this next paragraph; as steveklabnik pointed out, this change has already been implemented and "Message(|c| c.value += 1)" is accepted by the latest stable version.] Incidentally, as long as there are situations where only function pointers can be used and not closures it would be really nice to have some support for anonymous function pointers in Rust (with the fn type and not just the Fn trait) so that one could write e.g. "Message(fn |c| c.value += 1)" instead of "Message({ fn f(c: &mut Counter) { c.value += 1 } f })". Or just infer the fn type for "closures" which don't actually close over any variables without the need for an extra keyword. [0] https://github.com/nybble41/iced-counter2/blob/master/src/main.rs https://github.com/nybble41/iced-counter2/blob/master/src/ma...
- steveklabnik 5y agoI’m not at my computer but I thought non-capturing closures already will coerce into a fn.
- nybble41 5y agoIt seems you're right. That didn't work the last time I tried it—which I admit was some time ago—but it does work in the latest stable version of rustc.
- steveklabnik 5y agoLooks like support was added about four years ago, but it is true this wasn’t the case a whole back. Glad it’s working now though!
- jayd16 5y agoPretty funny to read the arguments about how enums are the one true way and here we see function pointers are already supported.
- int_19h 5y agoIronic. Desktop UI APIs used to be designed around enums of messages as the primary surface (e.g. Win32), but then UI frameworks wrapped all that to allow us to write code that looks exactly like you suggested. Now it's back to messages again... I wonder when we get back to wrapping them. ~