Reactive GUI Implemented in Clojure
-
Upload
denyslebediev -
Category
Software
-
view
220 -
download
0
Transcript of Reactive GUI Implemented in Clojure
![Page 1: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/1.jpg)
Reactive GUI Implemented in Clojure
Denys Lebediev
![Page 2: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/2.jpg)
Quick background
![Page 3: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/3.jpg)
Traditional approach
• Event Listener pattern
• Widget model is mutable
– Example: isPressed/setPressed
• Widget state is mutable
– Example: isEnabled/setEnabled
![Page 4: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/4.jpg)
Traditional approach: problems
• Complicated GUI containers (dialogs, wizards, etc) are often difficult to implement, support and extend. Why?
![Page 5: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/5.jpg)
Traditional approach: problems
• Obscuring the logic
![Page 6: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/6.jpg)
Traditional approach: problems
• Obscuring the logic
– It may be unclear why the button is enabled and when it becomes enabled
![Page 7: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/7.jpg)
Traditional approach: problems
• Obscuring the logic
– It may be unclear why the button is enabled and when it becomes enabled
• Spreading the logic
![Page 8: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/8.jpg)
Traditional approach: problems
• Obscuring the logic
– It may be unclear why the button is enabled and when it becomes enabled
• Spreading the logic
– The reasons for the button to be enabled tend to be spread across the application code
![Page 9: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/9.jpg)
Traditional approach: problems
• Obscuring the logic
– It may be unclear why the button is enabled and when it becomes enabled
• Spreading the logic
– The reasons for the button to be enabled tend to be spread across the application code
– Moreover with time
![Page 10: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/10.jpg)
Traditional approach: problems
• Incidental complexity
– In fact, non-essential code has to be written
– Developer has to bother deciding when
– And spend time investigating another developer’s decisions
• Automated testing is tricky
– Robot-based testing
![Page 11: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/11.jpg)
There is another way
• The framework takes care of routine
– It is already implemented and tested
– Developer concentrates on essential application logic
![Page 12: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/12.jpg)
There is another way
• The framework takes care of routine
– It is already implemented and tested
– Developer concentrates on essential application logic
• All logic about a single property in a single place
![Page 13: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/13.jpg)
There is another way
• The framework takes care of routine
– It is already implemented and tested
– Developer concentrates on essential application logic
• All logic about a single property in a single place
• Unit tests for code that manages widget model and state
![Page 14: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/14.jpg)
Hello world with FlatGUI
(defcomponent checkbox :say-hello {:text "Greeting"})
(def nogreeting-text "Greeting not provided")
(def greeting-text "Hello, world!")
(defevolverfn greeting-evolver :text
(if (get-property [:say-hello] :pressed)
greeting-text
nogreeting-text))
(defcomponent label :greeting-label
{:text nogreeting-text
:evolvers {:text greeting-evolver}})
![Page 15: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/15.jpg)
Hello world with FlatGUI
(defcomponent checkbox :say-hello {:text "Greeting"})
(def nogreeting-text "Greeting not provided")
(def greeting-text "Hello, world!")
(defevolverfn greeting-evolver :text
(if (get-property [:say-hello] :pressed)
greeting-text
nogreeting-text))
(defcomponent label :greeting-label
{:text nogreeting-text
:evolvers {:text greeting-evolver}})
![Page 16: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/16.jpg)
Hello world with FlatGUI
(defcomponent checkbox :say-hello {:text "Greeting"})
(def nogreeting-text "Greeting not provided")
(def greeting-text "Hello, world!")
(defevolverfn greeting-evolver :text
(if (get-property [:say-hello] :pressed)
greeting-text
nogreeting-text))
(defcomponent label :greeting-label
{:text nogreeting-text
:evolvers {:text greeting-evolver}})
![Page 17: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/17.jpg)
What’s the difference?
• greeting-evolver is a single place for the logic of
label’s :text property
![Page 18: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/18.jpg)
What’s the difference?
• greeting-evolver is a single place for the logic of
label’s :text property
• It contains the logic, not routine
![Page 19: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/19.jpg)
What’s the difference?
• greeting-evolver is a single place for the logic of
label’s :text property
• It contains the logic, not routine
• It’s easy to troubleshoot
![Page 20: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/20.jpg)
What’s the difference?
• greeting-evolver is a single place for the logic of
label’s :text property
• It contains the logic, not routine
• It’s easy to troubleshoot
• It’s easy to cover with unit tests
![Page 21: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/21.jpg)
What’s the difference?
• greeting-evolver is a single place for the logic of
label’s :text property
• It contains the logic, not routine
• It’s easy to troubleshoot
• It’s easy to cover with unit tests
• Developer does not have to decide when to call it
![Page 22: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/22.jpg)
What’s the difference?
• greeting-evolver is a single place for the logic of
label’s :text property
• It contains the logic, not routine
• It’s easy to troubleshoot
• It’s easy to cover with unit tests
• Developer does not have to decide when to call it
• Developer does not have to call it
![Page 23: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/23.jpg)
What’s the difference?
• Reactive framework takes care of these routine things
– Implemented once, no need to solve similar problems again
– Tested
![Page 24: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/24.jpg)
FlatGUI architecture
![Page 25: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/25.jpg)
Engine performs state transition
![Page 26: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/26.jpg)
Option to run as RIA
![Page 27: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/27.jpg)
Setup collaboration sessions
![Page 28: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/28.jpg)
Clojure usage
• Macros are nice
– defining widget types and instances, property evolvers
– Layout management, like “below” “to the right of”
– Though IDE capabilities are still not enough
• Had fun with profiler to tune engine performance
– Introduced some non-idiomatic code
![Page 29: Reactive GUI Implemented in Clojure](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a6c8fe1a28ab5d1d8b468b/html5/thumbnails/29.jpg)
Current state of the project
• This is a poof-of-concept implementation
• What’s next
– Publish sources
– Prepare documentation and examples
– Launch the website
– Finalize the engine and basic widgets
– Optimize network solution