Clojureand Swing – a new productivity sweet spot?Simon White
Skills MatterThe UK Open Source Training CompanyTraining on: Agile Development, Test Driven Development, Java, Eclipse, Spring, Hibernate, Ajax, Ruby on Rails, Struts Ti, Wicket, JavaServer Faces, Tapestry, Beehive, AOP, RIFE and more!Training straight from the SourceExperts write and teach our courses: Adrian Colyer, Chad Fowler, Howard M. Lewis Ship Craig Larman, Dave Crane, Kevlin Henney, Rob Harrop, Kito Mann, Rod Johnson and many morePartners with leading edge companiesBEA, IBM, Interface21, Sun, Tangosol, wso2© Catalysoft Ltd, 2010
Speaker QualificationsSimon White, IndependentJava developerGames published 1985PhD Artificial IntelligenceWritten Scientific Software for:Remote SensingDrug DiscoveryMedical & Genetics ResearchSwing Developer since 2000Author of JIDE ChartsSkillsMatter Author & Trainer© Catalysoft Ltd, 2010
What is Clojure?A functional language that runs on the JVMA new dialect of LISPNot ClosureNot ClozureMYTH: LISP is slowMYTH: Therefore Clojure is slow
Functional LanguagesWhat is a function?a mathematical relation such that each element of a given set (the domain of the function) is associated with an element of another set (the range of the function)) [Wordnet]Focus on the input/output relatione.g. length of a string maps a string to an integerImmutability Good; Side-effects Bad
LISP Syntax(functor param1 param2 ... paramn)for example, (+ 1 2)Brackets denote evaluationA single quote protects from evaluationso '(x y z) does not use x as a functionWith nested expressions, evaluate inner expression first: (+ (+ 2 3) (* 2 3)) is 11Special forms like let, cond deviate from the syntax and must be learned
Hello Factorialn! = n × (n-1) × (n-2) × ... × 1Also 0! = 1(defnfac “Computes the factorial of n”   [n]   (if (= n 0)       1       (* n (fac (- n 1)))))
REPLRead-Evaluate-Print-Loopuser=> (defn add-one [n] (+ 1 n))#'user/add-oneuser=> (add-one 6)7user=>
Java vs. LISP
Why mix Java and LISP?To get the best of both:Speedy development of custom code in LISPSpeedy development through library reuse in JavaSpeedy development of applications with concurrent processing
LISP Promotes AgilityLISP was agile long before agility was respected Easy to mix and match function applicationAccommodate changing requirementsMany small functions => very reusable codeREPL Encourages ad-hoc testingFunctional style makes it easy to write unit tests
Clojureas a LISP dialectSimplified syntax compared to Common LISPcond, letNot object-orientedBut you can define structures and multi-methodsNo multiple value returnsArguably syntactic sugar anywayLazy evaluation of sequencesDestructuringStructural pattern matching on function parametersConcurrency
Data Structures 1: Lists(list 'a 'b 'c) -> (a b c)(first '(a b c)) -> a(rest '(a b c)) -> (b c)(nth '(a b c) 1) -> b(cons 'a '(b c)) -> (a b c)(concat '(a b) '(c d)) -> (a b c d)
Data Structures 2: Vectors(vector 'a 'b 'c) -> [a b c](first '[a b c]) -> a(rest '[a b c]) -> (b c)(nth '[a b c] 1) -> b(cons 'a '[b c]) -> (a b c)(conj '[a b] 'c) -> [a b c](concat '[a b] '[c d]) -> (a b c d)
Data Structures 3: MapsKey-Value Pairs(get '{a 1, b 2} 'b) -> 2(assoc '{a 1, b 2} 'c 3) -> {c 3, a 1, b 2}(dissoc '{a 1, b 2} 'b) -> {a 1}(defstruct book :title :author)(struct-map book :title "Jungle Book" :author "Rudyard Kipling") (bean obj)
Everything is a SequenceLists, Vectors and Maps are all sequencesfirst, rest & cons always return a sequence(range 5) -> (0 1 2 3 4)(take 2 (range 5)) -> (0 1)(take 3 (repeat 'x)) -> (x xx)
Predicates (Boolean-Valued Tests)(= a 10)(identical? a b)(even? a)(odd? a)(integer? a)
Decisions(if (= a 1) 5 0)(cond     (= a 1) 5      (= a 2) 10     true 0)(when (= a 1) 5)a == 1 ? 5 : 0Java
"Iteration"(for [a '(1 2 3)] (+ a 1)) -> (2 3 4)(doseq [a (range 5)] a) -> nil(doseq [a (range 3)] (println a)) ->012nil
Anonymous Functionsuser=> (fn [a b] (+ a b 1))#<user$eval__101$fn__103 ...@a613f8>user=> ((fn [a b] (+ a b 1)) 3 4)8user=> #(+ %1 %2)#<user$eval__121$fn__123 ...@56f631>
Higher Order Functions(inc 1)->2(map inc '(1 2 3))->(2 3 4)(map + '(1 2 3) '(10 11 12))->(11 13 15)(max 1 2 3)->3(apply max '(1 2 3))->3(filter even? (range 10))->(0 2 4 6 8)
Partial FunctionsPartial returns a functionuser=> (def add-two (partial + 2))#'user/add-twouser=> (add-two 5)7
Java Interoperability
A GUI in a functional language?Functional languages use functions as mathematical models of computation:f(x1, x2, ...) -> x’Great for factorials, but how does it work with user-interfaces?Forms?Keyboard & Mouse?Events?
Need to Think DifferentlyValues of functions ‘computed’ as the result of a user-interactionConsider y-or-n-pCL> (y-or-n-p "Do you really want to quit?")T
Modelling Change of Statef(x) -> x’Name: “George”DOB: “11-Jul-73”Address: “16 Goldman Square”Name: “George”DOB: “11-Jul-73”Address: “3 Elm Avenue”This is a new (immutable) value,not a modified one
Java Swing: Create a JFrameimport javax.swing.JFrame;public class MyClass {...  public static void main(String[] args) {JFrame frame = new JFrame("My Frame");frame.setBounds(300, 300, 600, 400);frame.setVisible(true);  }}
Clojure Swing: Create a JFrame(ns user  (:import (javax.swingJFrame)))(defn make-frame []  (let [f (JFrame. "My Frame")]    (.setBounds f 300 300 600 400)    (.setVisible f true)    f    )  )f is the return value
Alternative: Use doto(defn make-frame []  (let [f (JFrame. "My Frame")]   (doto f      (.setBounds 300 300 600 400)      (.setVisible true))))
Create a Panel & Button(ns user  (:import java.awt.FlowLayout    (javax.swingJButtonJPanel)))(defn make-panel []  (let [panel (JPanel. (FlowLayout.))        button (JButton. "Press Me")]    (doto panel      (.add button))))
Make a Button do Something(defn make-panel2 []  (let [panel (JPanel. (FlowLayout.))        button (JButton. "Press Me")]    (.addActionListener button      (proxy [ActionListener] []        (actionPerformed [e] (println e))))    (doto panel      (.add button))    )  )#<ActionEventjava.awt.event.ActionEvent[ACTION_PERFORMED,cmd=Press Me...
Clojure Custom Component(defn make-component [msg]  (proxy [javax.swing.JComponent] []    (paintComponent [g]      (let [height (.getHeight this)            width (.getWidth this)]        (doto g           ...           )))))Detail on next slide
Custom Component (cont/d)(doto g  (.setColorColor/gray)  (.fillOval 20 20 (- width 20) (- height 20))  (.setColorColor/yellow)  (.fillOval 0 0 (- width 20) (- height 20))  (.setFont (.deriveFont (.getFont g) (float 50)))  (.setColorColor/black)  (.drawStringmsg(int (/ (- width (.stringWidth (.getFontMetrics g) msg)) 2))     (int (/ height 2))))
Three ways in which Clojure can help SwingReducing boiler-plate codeEasy to write code that generates the required patternsDefinitions of actions and easier bindingEasier to separate configuration (name, icon, keyboard shortcut, ...) from code hookFlexibility and ReusabilityUsing functions as parameters for user customisation of behaviour
1. Reducing Boiler-Plate CodeGridBagConstraints c = new GridBagConstraints();c.weighty = 1.0;c.weightx = 1.0;c.insets = new Insets(5, 5, 5, 5);c.gridx = 0;c.gridy = 0;c.gridheight = 2;c.anchor = GridBagConstraints.CENTER;c.fill = GridBagConstraints.BOTH;        add(leftListPane, c);c.gridx = 1;c.gridy = 0;c.gridheight = 1;        ...GridBagConstraints are unwieldy
Use the same options a lot of the time
Difficult to understandUsing a grid-bag-layout macro(def panel     (doto (JPanel. (GridBagLayout.))       (grid-bag-layout        :fill :BOTH, :insets (Insets. 5 5 5 5)        :gridx 0, :gridy 0        (JButton. "One")        :gridy 1        (JButton. "Two")        :gridx 1, :gridy 0, :gridheight 2        (JButton. "Three"))))See http://stuartsierra.com/2010/01/05/taming-the-gridbaglayout
2. Defining Swing ActionsSwing Actions are a nice idea, but have problems. Typically, you might have:Lots of inner classes with repeated boiler plate code, or:Separate classes that extend AbstractAction but are too tightly coupled to a main class so that they have the necessary context for the actionPerformed() method.
Clojure Actions: Defer binding for actionPerformed methodWith an Action in Clojure it’s possible to preset the ‘constant’ variables like Name, Icon, Accelerator ; but defer the binding for the handler.This means we can easily separate the creation of an action according to some template from its binding to a response function.
Create an Action when the handler function is known(defmacro copy-action [handler] `(make-action   {:name "Copy"    :command-key "copy"    :icon (ImageIcon. (fetch-image "copy.png"))    :handler ~handler    :mnemonic (mnemonic \C)    :accelerator (accelerator "ctrl C")}))
3. Flexibility and Reusability(def *tracing-actions* true) (defntrace-action [handler]  (fn [#^ActionEvent e]    (try      (when *tracing-actions* (print "Doing" (.getActionCommand e)))      (handler e)      (finally        (when *tracing-actions* (println "Done"))))))
Swing Worker & Busy Cursor(defmacro with-busy-cursor  [component f]  `(proxy [SwingWorker] []    (doInBackground []        (.setCursor ~component (Cursor/getPredefinedCursor Cursor/WAIT_CURSOR))      ~f)    (done []        (.setCursor ~component (Cursor/getDefaultCursor)))))(with-busy-cursor chart (load-file data-file))
Clojure/Swing in the Real World
Creating a Chart Model(defn make-model  "Create and return a ChartModel using the supplied rows and picking out the x and y columns"  [model-name rows #^String x-col #^String y-col]  (let [model (DefaultChartModel. model-name)]    (doseq [row rows]      (let [x (get row x-col)            y (get row y-col)]        (when (and (number? x) (number? y))          (.addPoint model (double x) (double y))))      )    model))

More Related Content

PDF
Polyglot JVM
PPT
Polyglot Programming in the JVM
PDF
Functional Programming with Groovy
PDF
Scala 2013 review
PDF
Clojure for Java developers - Stockholm
PDF
Scala for Java programmers
PDF
Dynamic C++ ACCU 2013
PDF
What can be done with Java, but should better be done with Erlang (@pavlobaron)
Polyglot JVM
Polyglot Programming in the JVM
Functional Programming with Groovy
Scala 2013 review
Clojure for Java developers - Stockholm
Scala for Java programmers
Dynamic C++ ACCU 2013
What can be done with Java, but should better be done with Erlang (@pavlobaron)

What's hot (20)

PDF
The Macronomicon
ODP
Naïveté vs. Experience
PDF
core.logic introduction
KEY
Code as data as code.
ODP
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
PDF
Better Software: introduction to good code
PDF
JavaOne 2013 - Clojure for Java Developers
PDF
The Ring programming language version 1.2 book - Part 79 of 84
KEY
Clojure Intro
KEY
Polyglot Grails
PDF
Coding in Style
PDF
(Greach 2015) Dsl'ing your Groovy
PDF
From Java to Parellel Clojure - Clojure South 2019
ODP
Groovy intro for OUDL
PDF
How to Clone Flappy Bird in Swift
PDF
awesome groovy
PDF
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
PPTX
Clean Code Development
PDF
Advanced python
PDF
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
The Macronomicon
Naïveté vs. Experience
core.logic introduction
Code as data as code.
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Better Software: introduction to good code
JavaOne 2013 - Clojure for Java Developers
The Ring programming language version 1.2 book - Part 79 of 84
Clojure Intro
Polyglot Grails
Coding in Style
(Greach 2015) Dsl'ing your Groovy
From Java to Parellel Clojure - Clojure South 2019
Groovy intro for OUDL
How to Clone Flappy Bird in Swift
awesome groovy
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
Clean Code Development
Advanced python
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
Ad

Similar to Clojure And Swing (20)

PPT
Groovy Introduction - JAX Germany - 2008
KEY
JavaScript Growing Up
PPTX
Groovy
PDF
Exploring Clojurescript
PDF
Go 1.10 Release Party - PDX Go
PDF
Clojure - A new Lisp
PPT
Groovy Update - JavaPolis 2007
PDF
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
PDF
Groovy On Trading Desk (2010)
PDF
Clojure made-simple - John Stevenson
PPTX
Java 7 Whats New(), Whats Next() from Oredev
PDF
Eric Lafortune - The Jack and Jill build system
ODP
Getting started with Clojure
PDF
Pune Clojure Course Outline
PDF
Practical REPL-driven Development with Clojure
PPT
Jet presentation
PDF
Polyglot Programming @ Jax.de 2010
PDF
HTML5 for the Silverlight Guy
PDF
Scala @ TechMeetup Edinburgh
PDF
Clojure 1.1 And Beyond
Groovy Introduction - JAX Germany - 2008
JavaScript Growing Up
Groovy
Exploring Clojurescript
Go 1.10 Release Party - PDX Go
Clojure - A new Lisp
Groovy Update - JavaPolis 2007
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
Groovy On Trading Desk (2010)
Clojure made-simple - John Stevenson
Java 7 Whats New(), Whats Next() from Oredev
Eric Lafortune - The Jack and Jill build system
Getting started with Clojure
Pune Clojure Course Outline
Practical REPL-driven Development with Clojure
Jet presentation
Polyglot Programming @ Jax.de 2010
HTML5 for the Silverlight Guy
Scala @ TechMeetup Edinburgh
Clojure 1.1 And Beyond
Ad

More from Skills Matter (20)

PDF
5 things cucumber is bad at by Richard Lawrence
ODP
Patterns for slick database applications
PDF
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
ODP
Oscar reiken jr on our success at manheim
ODP
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
PDF
Cukeup nyc ian dees on elixir, erlang, and cucumberl
PDF
Cukeup nyc peter bell on getting started with cucumber.js
PDF
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
ODP
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
ODP
Progressive f# tutorials nyc don syme on keynote f# in the open source world
PDF
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
PPTX
Dmitry mozorov on code quotations code as-data for f#
PDF
A poet's guide_to_acceptance_testing
PDF
Russ miles-cloudfoundry-deep-dive
KEY
Serendipity-neo4j
PDF
Simon Peyton Jones: Managing parallelism
PDF
Plug 20110217
PDF
Lug presentation
PPT
I went to_a_communications_workshop_and_they_t
PDF
Plug saiku
5 things cucumber is bad at by Richard Lawrence
Patterns for slick database applications
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Oscar reiken jr on our success at manheim
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc peter bell on getting started with cucumber.js
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Dmitry mozorov on code quotations code as-data for f#
A poet's guide_to_acceptance_testing
Russ miles-cloudfoundry-deep-dive
Serendipity-neo4j
Simon Peyton Jones: Managing parallelism
Plug 20110217
Lug presentation
I went to_a_communications_workshop_and_they_t
Plug saiku

Recently uploaded (20)

PPTX
How to Convert Tickets Into Sales Opportunity in Odoo 18
PPTX
Strategic Picks — Prioritising the Right Agentic Use Cases [2/6]
PPT
Storage Area Network Best Practices from HP
PPTX
From XAI to XEE through Influence and Provenance.Controlling model fairness o...
PDF
NewMind AI Journal Monthly Chronicles - August 2025
PDF
AI.gov: A Trojan Horse in the Age of Artificial Intelligence
PDF
Altius execution marketplace concept.pdf
PDF
Human Computer Interaction Miterm Lesson
PDF
Data Virtualization in Action: Scaling APIs and Apps with FME
PDF
Streamline Vulnerability Management From Minimal Images to SBOMs
PPTX
Rise of the Digital Control Grid Zeee Media and Hope and Tivon FTWProject.com
PDF
Ericsson 5G Feature,KPIs Analysis_ Overview, Dependencies & Recommendations (...
PDF
EGCB_Solar_Project_Presentation_and Finalcial Analysis.pdf
PDF
Optimizing bioinformatics applications: a novel approach with human protein d...
PPTX
Information-Technology-in-Human-Society (2).pptx
PDF
Ebook - The Future of AI A Comprehensive Guide.pdf
PDF
Intravenous drug administration application for pediatric patients via augmen...
PPTX
Build automations faster and more reliably with UiPath ScreenPlay
PDF
Connector Corner: Transform Unstructured Documents with Agentic Automation
PPTX
maintenance powerrpoint for adaprive and preventive
How to Convert Tickets Into Sales Opportunity in Odoo 18
Strategic Picks — Prioritising the Right Agentic Use Cases [2/6]
Storage Area Network Best Practices from HP
From XAI to XEE through Influence and Provenance.Controlling model fairness o...
NewMind AI Journal Monthly Chronicles - August 2025
AI.gov: A Trojan Horse in the Age of Artificial Intelligence
Altius execution marketplace concept.pdf
Human Computer Interaction Miterm Lesson
Data Virtualization in Action: Scaling APIs and Apps with FME
Streamline Vulnerability Management From Minimal Images to SBOMs
Rise of the Digital Control Grid Zeee Media and Hope and Tivon FTWProject.com
Ericsson 5G Feature,KPIs Analysis_ Overview, Dependencies & Recommendations (...
EGCB_Solar_Project_Presentation_and Finalcial Analysis.pdf
Optimizing bioinformatics applications: a novel approach with human protein d...
Information-Technology-in-Human-Society (2).pptx
Ebook - The Future of AI A Comprehensive Guide.pdf
Intravenous drug administration application for pediatric patients via augmen...
Build automations faster and more reliably with UiPath ScreenPlay
Connector Corner: Transform Unstructured Documents with Agentic Automation
maintenance powerrpoint for adaprive and preventive

Clojure And Swing

  • 1. Clojureand Swing – a new productivity sweet spot?Simon White
  • 2. Skills MatterThe UK Open Source Training CompanyTraining on: Agile Development, Test Driven Development, Java, Eclipse, Spring, Hibernate, Ajax, Ruby on Rails, Struts Ti, Wicket, JavaServer Faces, Tapestry, Beehive, AOP, RIFE and more!Training straight from the SourceExperts write and teach our courses: Adrian Colyer, Chad Fowler, Howard M. Lewis Ship Craig Larman, Dave Crane, Kevlin Henney, Rob Harrop, Kito Mann, Rod Johnson and many morePartners with leading edge companiesBEA, IBM, Interface21, Sun, Tangosol, wso2© Catalysoft Ltd, 2010
  • 3. Speaker QualificationsSimon White, IndependentJava developerGames published 1985PhD Artificial IntelligenceWritten Scientific Software for:Remote SensingDrug DiscoveryMedical & Genetics ResearchSwing Developer since 2000Author of JIDE ChartsSkillsMatter Author & Trainer© Catalysoft Ltd, 2010
  • 4. What is Clojure?A functional language that runs on the JVMA new dialect of LISPNot ClosureNot ClozureMYTH: LISP is slowMYTH: Therefore Clojure is slow
  • 5. Functional LanguagesWhat is a function?a mathematical relation such that each element of a given set (the domain of the function) is associated with an element of another set (the range of the function)) [Wordnet]Focus on the input/output relatione.g. length of a string maps a string to an integerImmutability Good; Side-effects Bad
  • 6. LISP Syntax(functor param1 param2 ... paramn)for example, (+ 1 2)Brackets denote evaluationA single quote protects from evaluationso '(x y z) does not use x as a functionWith nested expressions, evaluate inner expression first: (+ (+ 2 3) (* 2 3)) is 11Special forms like let, cond deviate from the syntax and must be learned
  • 7. Hello Factorialn! = n × (n-1) × (n-2) × ... × 1Also 0! = 1(defnfac “Computes the factorial of n” [n] (if (= n 0) 1 (* n (fac (- n 1)))))
  • 8. REPLRead-Evaluate-Print-Loopuser=> (defn add-one [n] (+ 1 n))#'user/add-oneuser=> (add-one 6)7user=>
  • 10. Why mix Java and LISP?To get the best of both:Speedy development of custom code in LISPSpeedy development through library reuse in JavaSpeedy development of applications with concurrent processing
  • 11. LISP Promotes AgilityLISP was agile long before agility was respected Easy to mix and match function applicationAccommodate changing requirementsMany small functions => very reusable codeREPL Encourages ad-hoc testingFunctional style makes it easy to write unit tests
  • 12. Clojureas a LISP dialectSimplified syntax compared to Common LISPcond, letNot object-orientedBut you can define structures and multi-methodsNo multiple value returnsArguably syntactic sugar anywayLazy evaluation of sequencesDestructuringStructural pattern matching on function parametersConcurrency
  • 13. Data Structures 1: Lists(list 'a 'b 'c) -> (a b c)(first '(a b c)) -> a(rest '(a b c)) -> (b c)(nth '(a b c) 1) -> b(cons 'a '(b c)) -> (a b c)(concat '(a b) '(c d)) -> (a b c d)
  • 14. Data Structures 2: Vectors(vector 'a 'b 'c) -> [a b c](first '[a b c]) -> a(rest '[a b c]) -> (b c)(nth '[a b c] 1) -> b(cons 'a '[b c]) -> (a b c)(conj '[a b] 'c) -> [a b c](concat '[a b] '[c d]) -> (a b c d)
  • 15. Data Structures 3: MapsKey-Value Pairs(get '{a 1, b 2} 'b) -> 2(assoc '{a 1, b 2} 'c 3) -> {c 3, a 1, b 2}(dissoc '{a 1, b 2} 'b) -> {a 1}(defstruct book :title :author)(struct-map book :title "Jungle Book" :author "Rudyard Kipling") (bean obj)
  • 16. Everything is a SequenceLists, Vectors and Maps are all sequencesfirst, rest & cons always return a sequence(range 5) -> (0 1 2 3 4)(take 2 (range 5)) -> (0 1)(take 3 (repeat 'x)) -> (x xx)
  • 17. Predicates (Boolean-Valued Tests)(= a 10)(identical? a b)(even? a)(odd? a)(integer? a)
  • 18. Decisions(if (= a 1) 5 0)(cond (= a 1) 5 (= a 2) 10 true 0)(when (= a 1) 5)a == 1 ? 5 : 0Java
  • 19. "Iteration"(for [a '(1 2 3)] (+ a 1)) -> (2 3 4)(doseq [a (range 5)] a) -> nil(doseq [a (range 3)] (println a)) ->012nil
  • 20. Anonymous Functionsuser=> (fn [a b] (+ a b 1))#<user$eval__101$fn__103 ...@a613f8>user=> ((fn [a b] (+ a b 1)) 3 4)8user=> #(+ %1 %2)#<user$eval__121$fn__123 ...@56f631>
  • 21. Higher Order Functions(inc 1)->2(map inc '(1 2 3))->(2 3 4)(map + '(1 2 3) '(10 11 12))->(11 13 15)(max 1 2 3)->3(apply max '(1 2 3))->3(filter even? (range 10))->(0 2 4 6 8)
  • 22. Partial FunctionsPartial returns a functionuser=> (def add-two (partial + 2))#'user/add-twouser=> (add-two 5)7
  • 24. A GUI in a functional language?Functional languages use functions as mathematical models of computation:f(x1, x2, ...) -> x’Great for factorials, but how does it work with user-interfaces?Forms?Keyboard & Mouse?Events?
  • 25. Need to Think DifferentlyValues of functions ‘computed’ as the result of a user-interactionConsider y-or-n-pCL> (y-or-n-p "Do you really want to quit?")T
  • 26. Modelling Change of Statef(x) -> x’Name: “George”DOB: “11-Jul-73”Address: “16 Goldman Square”Name: “George”DOB: “11-Jul-73”Address: “3 Elm Avenue”This is a new (immutable) value,not a modified one
  • 27. Java Swing: Create a JFrameimport javax.swing.JFrame;public class MyClass {... public static void main(String[] args) {JFrame frame = new JFrame("My Frame");frame.setBounds(300, 300, 600, 400);frame.setVisible(true); }}
  • 28. Clojure Swing: Create a JFrame(ns user (:import (javax.swingJFrame)))(defn make-frame [] (let [f (JFrame. "My Frame")] (.setBounds f 300 300 600 400) (.setVisible f true) f ) )f is the return value
  • 29. Alternative: Use doto(defn make-frame [] (let [f (JFrame. "My Frame")] (doto f (.setBounds 300 300 600 400) (.setVisible true))))
  • 30. Create a Panel & Button(ns user (:import java.awt.FlowLayout (javax.swingJButtonJPanel)))(defn make-panel [] (let [panel (JPanel. (FlowLayout.)) button (JButton. "Press Me")] (doto panel (.add button))))
  • 31. Make a Button do Something(defn make-panel2 [] (let [panel (JPanel. (FlowLayout.)) button (JButton. "Press Me")] (.addActionListener button (proxy [ActionListener] [] (actionPerformed [e] (println e)))) (doto panel (.add button)) ) )#<ActionEventjava.awt.event.ActionEvent[ACTION_PERFORMED,cmd=Press Me...
  • 32. Clojure Custom Component(defn make-component [msg] (proxy [javax.swing.JComponent] [] (paintComponent [g] (let [height (.getHeight this) width (.getWidth this)] (doto g ... )))))Detail on next slide
  • 33. Custom Component (cont/d)(doto g (.setColorColor/gray) (.fillOval 20 20 (- width 20) (- height 20)) (.setColorColor/yellow) (.fillOval 0 0 (- width 20) (- height 20)) (.setFont (.deriveFont (.getFont g) (float 50))) (.setColorColor/black) (.drawStringmsg(int (/ (- width (.stringWidth (.getFontMetrics g) msg)) 2)) (int (/ height 2))))
  • 34. Three ways in which Clojure can help SwingReducing boiler-plate codeEasy to write code that generates the required patternsDefinitions of actions and easier bindingEasier to separate configuration (name, icon, keyboard shortcut, ...) from code hookFlexibility and ReusabilityUsing functions as parameters for user customisation of behaviour
  • 35. 1. Reducing Boiler-Plate CodeGridBagConstraints c = new GridBagConstraints();c.weighty = 1.0;c.weightx = 1.0;c.insets = new Insets(5, 5, 5, 5);c.gridx = 0;c.gridy = 0;c.gridheight = 2;c.anchor = GridBagConstraints.CENTER;c.fill = GridBagConstraints.BOTH; add(leftListPane, c);c.gridx = 1;c.gridy = 0;c.gridheight = 1; ...GridBagConstraints are unwieldy
  • 36. Use the same options a lot of the time
  • 37. Difficult to understandUsing a grid-bag-layout macro(def panel (doto (JPanel. (GridBagLayout.)) (grid-bag-layout :fill :BOTH, :insets (Insets. 5 5 5 5) :gridx 0, :gridy 0 (JButton. "One") :gridy 1 (JButton. "Two") :gridx 1, :gridy 0, :gridheight 2 (JButton. "Three"))))See http://stuartsierra.com/2010/01/05/taming-the-gridbaglayout
  • 38. 2. Defining Swing ActionsSwing Actions are a nice idea, but have problems. Typically, you might have:Lots of inner classes with repeated boiler plate code, or:Separate classes that extend AbstractAction but are too tightly coupled to a main class so that they have the necessary context for the actionPerformed() method.
  • 39. Clojure Actions: Defer binding for actionPerformed methodWith an Action in Clojure it’s possible to preset the ‘constant’ variables like Name, Icon, Accelerator ; but defer the binding for the handler.This means we can easily separate the creation of an action according to some template from its binding to a response function.
  • 40. Create an Action when the handler function is known(defmacro copy-action [handler] `(make-action {:name "Copy" :command-key "copy" :icon (ImageIcon. (fetch-image "copy.png")) :handler ~handler :mnemonic (mnemonic \C) :accelerator (accelerator "ctrl C")}))
  • 41. 3. Flexibility and Reusability(def *tracing-actions* true) (defntrace-action [handler]  (fn [#^ActionEvent e]    (try      (when *tracing-actions* (print "Doing" (.getActionCommand e)))      (handler e)      (finally        (when *tracing-actions* (println "Done"))))))
  • 42. Swing Worker & Busy Cursor(defmacro with-busy-cursor [component f] `(proxy [SwingWorker] [] (doInBackground [] (.setCursor ~component (Cursor/getPredefinedCursor Cursor/WAIT_CURSOR)) ~f) (done [] (.setCursor ~component (Cursor/getDefaultCursor)))))(with-busy-cursor chart (load-file data-file))
  • 43. Clojure/Swing in the Real World
  • 44. Creating a Chart Model(defn make-model "Create and return a ChartModel using the supplied rows and picking out the x and y columns" [model-name rows #^String x-col #^String y-col] (let [model (DefaultChartModel. model-name)] (doseq [row rows] (let [x (get row x-col) y (get row y-col)] (when (and (number? x) (number? y)) (.addPoint model (double x) (double y)))) ) model))
  • 45. SummaryClojureis Powerful and FlexibleExcellent Java InteroperabilityOpportunities to apply LISP power to Swing GUI developmentCan be used for Real World ApplicationsA Secret Weapon for Productivity?
  • 46. Closure Example(defnplusn [x] (fn [y] (+ x y)))(def plus5 (plusn 5))(plus5 3)>> 8

Editor's Notes

  • #5: A closure is a feature provided by some languages that capture the lexical context in which a code fragment was written. The free variables in that lexical context are ‘closed over’ so the code fragment can be passed around and used elsewhere.Clozure is a dialect of LISP for the Mac (formerly Macintosh Common LISP)
  • #8: defn defines a function
  • #9: You can also create GUI elements such as JFrames and JButtons on the fly.
  • #10: There are only few libraries in LISP compared to Java because it is a niche language.However, the fact that it is a niche language could make it your secret weapon.
  • #20: For is actually a list comprehension
  • #23: Reasons for using partial functions: Binding parameters at different times (when they become known) Clearer semantics
  • #29: ns specifies the name space for the functions that followlet allows you to define some local variables
  • #30: ns specifies the name space for the functions that followlet allows you to define some local variables
  • #36: Or if you create a new GridBagConstraints object often, you might not remember what all the constructor arguments are
  • #42: The example with-busy-cursor is intended as an illustration only