├── assets └── images │ └── content │ └── reference │ └── transducers │ └── xf.png ├── content ├── news │ ├── 2014 │ │ └── 08 │ │ │ └── 06 │ │ │ └── transducers-are-coming.adoc │ ├── 2015 │ │ └── 06 │ │ │ └── 30 │ │ │ └── clojure-17.adoc │ └── news.adoc ├── search.adoc ├── community │ ├── events.adoc │ ├── contributors.adoc │ ├── license.adoc │ ├── resources.adoc │ ├── libraries.adoc │ ├── downloads.adoc │ ├── swag.adoc │ ├── books.adoc │ ├── downloads_older.adoc │ ├── start_group.adoc │ ├── editing.adoc │ ├── contributing.adoc │ ├── contributing_site.adoc │ └── companies.adoc ├── guides │ ├── guides.adoc │ └── getting_started.adoc ├── 404.adoc ├── events │ ├── 2015 │ │ └── clojurex.adoc │ └── 2016 │ │ ├── dutch_clojure_days.adoc │ │ ├── clojurewest.adoc │ │ ├── clojureremote.adoc │ │ └── clojured.adoc ├── about │ ├── clojurescript.adoc │ ├── clojureclr.adoc │ ├── features.adoc │ ├── jvm_hosted.adoc │ ├── lisp.adoc │ ├── dynamic.adoc │ ├── runtime_polymorphism.adoc │ ├── rationale.adoc │ ├── concurrent_programming.adoc │ └── functional_programming.adoc ├── reference │ ├── documentation.adoc │ ├── metadata.adoc │ ├── atoms.adoc │ ├── namespaces.adoc │ ├── libs.adoc │ ├── lisps.adoc │ ├── evaluation.adoc │ ├── reducers.adoc │ ├── other_functions.adoc │ ├── other_libraries.adoc │ ├── transients.adoc │ ├── protocols.adoc │ ├── repl_and_main.adoc │ ├── refs.adoc │ ├── macros.adoc │ ├── vars.adoc │ ├── agents.adoc │ ├── compilation.adoc │ └── multimethods.adoc ├── api │ └── api.adoc └── privacy.adoc ├── .gitignore └── README.adoc /assets/images/content/reference/transducers/xf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/magnars/clojure-site/master/assets/images/content/reference/transducers/xf.png -------------------------------------------------------------------------------- /content/news/news.adoc: -------------------------------------------------------------------------------- 1 | = News 2 | Alex Miller 3 | 2015-11-25 4 | :jbake-type: news 5 | :toc: macro 6 | 7 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 8 | 9 | 10 | -------------------------------------------------------------------------------- /content/search.adoc: -------------------------------------------------------------------------------- 1 | = Search Results 2 | Rich Hickey 3 | 2015-01-01 4 | :type: search 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | -------------------------------------------------------------------------------- /content/community/events.adoc: -------------------------------------------------------------------------------- 1 | = Upcoming Clojure Events 2 | Rich Hickey 3 | 2015-01-01 4 | :jbake-type: events 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/guides/guides.adoc: -------------------------------------------------------------------------------- 1 | = Guides 2 | Alex Miller 3 | 2015-11-25 4 | :type: guides 5 | :toc: macro 6 | 7 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 8 | 9 | * <> 10 | 11 | -------------------------------------------------------------------------------- /content/404.adoc: -------------------------------------------------------------------------------- 1 | = Page Not Found 2 | Rich Hickey 3 | 2015-01-01 4 | :type: notfound 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | We're sorry, that page could not be found on this site. 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | *.iml 9 | *.zip 10 | /.lein-* 11 | /.nrepl-port 12 | /.idea 13 | .hgignore 14 | .hg/ 15 | jbake.properties 16 | /output 17 | /assets/css 18 | /assets/fonts 19 | /assets/js 20 | /assets/favicon.ico 21 | /assets/images 22 | /assets/images/theme 23 | /templates 24 | -------------------------------------------------------------------------------- /content/events/2016/dutch_clojure_days.adoc: -------------------------------------------------------------------------------- 1 | = Dutch Clojure Days 2 | Dutch Clojure Days 3 | 2016-03-19 4 | :jbake-type: event 5 | :jbake-edition: 2016 6 | :jbake-link: http://www.ticketbase.com/events/dutch-clojure-days-2016 7 | :jbake-location: Amsterdam, Netherlands 8 | :jbake-start: 2016-03-19 9 | :jbake-end: 2016-03-19 10 | 11 | The Annual Gathering of Clojure Enthusiasts and Practitioners in the Netherlands! 12 | -------------------------------------------------------------------------------- /content/community/contributors.adoc: -------------------------------------------------------------------------------- 1 | = Contributors 2 | Rich Hickey 3 | 2015-11-12 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | Below is a list of all signers of the Clojure Contributor Agreement. For more info, see <>. 11 | 12 | == _Signed Contributor Agreement:_ 13 | 14 | [format="csv", options="header"] 15 | |=== 16 | include::contributors.csv[] 17 | |=== 18 | -------------------------------------------------------------------------------- /content/community/license.adoc: -------------------------------------------------------------------------------- 1 | = License 2 | Rich Hickey 3 | 2015-01-01 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | The use and distribution terms for this software are covered by the http://opensource.org/licenses/eclipse-1.0.php[Eclipse Public License 1.0], which can be found in the file epl-v10.html at the root of this distribution. By using this software in any fashion, you are agreeing to be bound by the terms of this license. You must not remove this notice, or any other, from this software. 11 | -------------------------------------------------------------------------------- /content/events/2016/clojurewest.adoc: -------------------------------------------------------------------------------- 1 | = Clojure/west 2 | Cognitect 3 | 2016-04-15 4 | :jbake-type: event 5 | :jbake-edition: 2016 6 | :jbake-link: http://clojurewest.org 7 | :jbake-location: Seattle, Washington 8 | :jbake-start: 2016-04-15 9 | :jbake-end: 2016-04-16 10 | 11 | Clojure/west is the biggest Clojure conference in the western United States. 12 | Founded in 2012, the conference is a great place to meet Clojure developers and 13 | learn about what is happening in the language, in the community, and in companies 14 | using Clojure. Clojure/west features two tracks of sessions. 15 | -------------------------------------------------------------------------------- /content/events/2016/clojureremote.adoc: -------------------------------------------------------------------------------- 1 | = Clojure Remote 2 | Homegrown Labs 3 | 2016-02-11 4 | :jbake-type: event 5 | :jbake-edition: 2016 6 | :jbake-link: http://clojureremote.com/ 7 | :jbake-location: Online 8 | :jbake-start: 2016-02-11 9 | :jbake-end: 2016-02-12 10 | 11 | This February, Homegrown Labs presents Clojure Remote—Clojure’s first exclusively Remote conference. Join us anywhere; from your home, your office, or the coffee shop. 12 | 13 | Over two days, you’ll join hundreds of other Clojurists online via crowdcast.io to enjoy up to two tracks of beginner to intermediate Clojure talks. 14 | -------------------------------------------------------------------------------- /content/about/clojurescript.adoc: -------------------------------------------------------------------------------- 1 | = ClojureScript 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: jvm_hosted 8 | :prevpagetitle: JVM Hosted 9 | :nextpagehref: clojureclr 10 | :nextpagetitle: ClojureCLR 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | ClojureScript is a compiler for Clojure that targets JavaScript. It is designed to emit JavaScript code which is compatible with the advanced compilation mode of the http://code.google.com/closure/[Google Closure] optimizing compiler. 15 | 16 | * https://github.com/clojure/clojurescript[ClojureScript Home] 17 | -------------------------------------------------------------------------------- /content/about/clojureclr.adoc: -------------------------------------------------------------------------------- 1 | = Clojure CLR 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: clojurescript 8 | :prevpagetitle: ClojureScript 9 | 10 | 11 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 12 | 13 | This project is a native implementation of Clojure on the Common Language Runtime (CLR), the execution engine of Microsoft's .Net Framework. 14 | 15 | ClojureCLR is programmed in C# (and Clojure itself) and makes use of Microsoft's Dynamic Language Runtime (DLR). 16 | 17 | * https://github.com/clojure/clojure-clr[ClojureCLR Home] 18 | * https://github.com/clojure/clojure-clr/wiki/Getting-binaries[Downloading Binaries] 19 | -------------------------------------------------------------------------------- /content/events/2015/clojurex.adoc: -------------------------------------------------------------------------------- 1 | = Clojure eXchange 2 | Skills Matter 3 | 2015-12-03 4 | :jbake-type: event 5 | :jbake-edition: 2015 6 | :jbake-link: https://skillsmatter.com/conferences/6861-clojure-exchange-2015 7 | :jbake-location: London, UK 8 | :jbake-start: 2015-12-03 9 | :jbake-end: 2015-12-04 10 | 11 | Do you want to explore the latest innovations in Clojure and meet with your peers attempting to solve complex software problems using this Functional language? 12 | 13 | Clojure's rise to prominence and it's increasing popularity as 'weapon of choice' for tackling complex software problems got us thinking; wouldn't it be great to get the world's greatest Clojure experts in London with hundreds of fellow Clojurians? Well, we thought so too. 14 | -------------------------------------------------------------------------------- /content/events/2016/clojured.adoc: -------------------------------------------------------------------------------- 1 | = :clojureD 2 | clojureD 3 | 2016-02-20 4 | :jbake-type: event 5 | :jbake-edition: 2016 6 | :jbake-link: http://www.clojured.de/ 7 | :jbake-location: Berlin, Germany 8 | :jbake-start: 2016-02-20 9 | :jbake-end: 2016-02-20 10 | 11 | :clojureD is an independent non-profit conference from the Clojure community for the Clojure community. Focus points will be interesting developments and ideas in the global Clojure community as well as introductory-level talks highlighting the fun aspects of learning and messing with Clojure. Besides a day of interesting talks :clojureD will be an opportunity to meet the German & European Clojure community and share a good time together. 12 | 13 | The conference will be held in English. 14 | -------------------------------------------------------------------------------- /content/about/features.adoc: -------------------------------------------------------------------------------- 1 | = Features 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | Clojure has a set of useful features that together form a simple, coherent, and powerful tool. In Clojure you'll find ideas from Lisp, ML, Haskell, and others, but the end result is unique. This section is a brief, non-comprehensive tour of some of the features of Clojure. Consult the http://clojure.org/documentation[reference] for more details. 11 | 12 | * <> 13 | * <> 14 | * <> 15 | * <> 16 | * <> 17 | * <> -------------------------------------------------------------------------------- /content/community/resources.adoc: -------------------------------------------------------------------------------- 1 | = Community Resources 2 | Rich Hickey 3 | 2015-01-01 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | 11 | * http://groups.google.com/group/clojure[Clojure Google Group] 12 | 13 | * #clojure on IRC 14 | * http://clojurians.net[Clojurians Slack Chat] 15 | * http://dev.clojure.org/display/community/Home[Community Wiki] 16 | * http://dev.clojure.org/display/doc/Home[Documentation Wiki] 17 | * http://dev.clojure.org/display/design/Home[Design Wiki] 18 | * http://clojure-conj.org/[Clojure/conj] conference 19 | * http://dev.clojure.org/display/community/Clojure+User+Groups[Clojure User Groups] 20 | * http://planet.clojure.in/[Planet Clojure] meta blog 21 | * <> 22 | * <> 23 | -------------------------------------------------------------------------------- /content/reference/documentation.adoc: -------------------------------------------------------------------------------- 1 | = Documentation 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | == Reference Documentation 11 | 12 | * <> 13 | * <> 14 | * <> 15 | * <> 16 | * <> 17 | * <> 18 | * <> 19 | * <> 20 | * <> 21 | * <> 22 | * <> 23 | * <> 24 | * <> 25 | * <> 26 | * <> 27 | * <> 28 | * <> 29 | * <> 30 | * <> 31 | * <> 32 | * <> 33 | * <> 34 | * <> 35 | * <> 36 | * <> 37 | 38 | == API Documentation 39 | 40 | * <> 41 | -------------------------------------------------------------------------------- /content/community/libraries.adoc: -------------------------------------------------------------------------------- 1 | = Clojure Libraries 2 | Rich Hickey 3 | 2015-01-01 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | == Clojure Contrib 11 | 12 | Clojure Contrib is a collection of libraries managed with the same Contributor Agreement, license, and development workflow as Clojure itself. Code in Clojure Contrib can be considered for inclusion in newer versions of Clojure. 13 | 14 | Clojure Contrib library code is hosted on https://github.com/clojure[Github]. Design and issue tracking are via http://dev.clojure.org/display/doc/Clojure+Contrib[Confluence] and JIRA. 15 | 16 | Prior to Clojure 1.3, Contrib was packaged as a single monolithic JAR. If you are migrating from a pre-1.3 version of Clojure, please see http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go[this page] for migration help regarding old contrib libraries. 17 | 18 | == Leiningen 19 | 20 | The vast majority of Clojure developers use https://github.com/technomancy/leiningen[Leiningen] to create and manage Clojure projects. 21 | 22 | == IDEs and Developer Tools 23 | 24 | Community volunteers maintain http://dev.clojure.org/display/doc/getting+started[Getting Started] documentation for a number of different developer tools. 25 | 26 | == Finding Libraries 27 | 28 | http://search.maven.org/[Maven Central] is a searchable repository of open source JVM libraries. 29 | 30 | https://clojars.org/[Clojars] is a community repository for open source Clojure libraries. 31 | 32 | You can narrow Github search https://github.com/search?language=Clojure[by language] to find Clojure libraries. 33 | -------------------------------------------------------------------------------- /content/community/downloads.adoc: -------------------------------------------------------------------------------- 1 | = Clojure Downloads 2 | Rich Hickey 3 | 2015-01-01 4 | :jbake-type: page 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | == Stable Release: 1.7.0 (June 30, 2015) 11 | 12 | 13 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.7.0/clojure-1.7.0.zip[Clojure 1.7.0] 14 | * https://github.com/clojure/clojure/blob/master/changes.md[Changelog] 15 | 16 | == Development Release: 1.8.0-RC5 17 | 18 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.8.0-RC5/clojure-1.8.0-RC5.zip[Clojure 1.8.0-RC5] 19 | * http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.clojure%22%20AND%20a%3A%22clojure%22%20AND%20v%3A1.8.0*[Clojure 1.8 pre-release builds] 20 | 21 | == Clojure Source 22 | 23 | Clojure source code is hosted at http://github.com/clojure/clojure[github.com/clojure/clojure]. Builds of the very latest version of Clojure's master branch are available at https://oss.sonatype.org/content/repositories/snapshots/org/clojure/clojure/1.8.0-master-SNAPSHOT/[build.clojure.org]. 24 | 25 | == Get Clojure via Leiningen 26 | 27 | Modify the dependencies and repositories sections of your http://leiningen.org/[Leiningen] project.clj file, specifying the version of Clojure that you want: 28 | [source,clojure] 29 | ---- 30 | ; under dependencies, select the release of clojure that you want 31 | :dependencies [[org.clojure/clojure "1.7.0"]] 32 | 33 | ---- 34 | == Where did Clojure Contrib go? 35 | 36 | If you are migrating from a pre-1.3 version of Clojure, please see http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go[this page] for migration help regarding old contrib libraries. 37 | 38 | == <> 39 | -------------------------------------------------------------------------------- /content/community/swag.adoc: -------------------------------------------------------------------------------- 1 | = Swag 2 | Rich Hickey 3 | 2015-01-01 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | == Official Clojure Gear 11 | 12 | The http://www.zazzle.com/clojureappreciation[Clojure Appreciation store] is the only place to get authorized gear. Proceeds go to Rich Hickey, the creator of Clojure. 13 | 14 | [[stickers]] 15 | === Stickers 16 | 17 | image:http://rlv.zcache.com/clojure_stickers_3_sheet_of_6-p217097870517528844en8u1_125.jpg[Clojure Stickers 3" - Sheet of 6,link="http://www.zazzle.com/clojure_stickers_3_sheet_of_6-217097870517528844?rf=238716329365496646"] Clojure Stickers 3" - Sheet of 6 18 | 19 | image:http://rlv.zcache.com/clojure_stickers_1_5_sheet_of_20-p217379761338416613en8u1_125.jpg[Clojure Stickers 1.5" - Sheet of 20,link="http://www.zazzle.com/clojure_stickers_1_5_sheet_of_20-217379761338416613?rf=238716329365496646"] Clojure Stickers 1.5" - Sheet of 20 20 | 21 | Browse other http://www.zazzle.com/clojure+stickers?rf=238716329365496646[Clojure Stickers] by http://www.zazzle.com/clojureappreciation*[ClojureAppreciation]. 22 | 23 | === T Shirts 24 | 25 | +Note: You can customize the color and shirt style, get hoodies, jerseys etc. If ordering a light shirt you'll need to set the font color to something dark.+ 26 | 27 | image:http://rlv.zcache.com/clojure_t_large_logo-raf7c54b4b4ec4537afd1e5cb1824168d_vj82h_250.jpg?bg=0xffffff[Clojure T, Large Logo,link="http://www.zazzle.com/clojure_t_large_logo-235776431459512494?rf=238716329365496646"] Clojure T, Large Logo 28 | 29 | image:http://rlv.zcache.com/clojure_t_small_logo-rda2f449605144baf8631399aa19d8c63_vj82h_250.jpg?bg=0xffffff[Clojure T, Small Logo,link="http://www.zazzle.com/clojure_t_small_logo-235264388339470561?rf=238716329365496646"] Clojure T, Small Logo 30 | 31 | -------------------------------------------------------------------------------- /content/about/jvm_hosted.adoc: -------------------------------------------------------------------------------- 1 | = Hosted on the JVM 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: JVM Hosted 8 | :prevpagehref: concurrent_programming 9 | :prevpagetitle: Concurrent Programming 10 | :nextpagehref: clojurescript 11 | :nextpagetitle: ClojureScript 12 | 13 | 14 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 15 | 16 | Clojure is designed to be a hosted language, sharing the JVM type system, GC, threads etc. It compiles all functions to JVM bytecode. Clojure is a great Java library consumer, offering the dot-target-member notation for calls to Java. Class names can be referenced in full, or as non-qualified names after being imported. Clojure supports the dynamic implementation of Java interfaces and classes using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/reify[reify] and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/proxy[proxy]: 17 | 18 | Here's a small Swing app: 19 | [source,clojure] 20 | ---- 21 | (import '(javax.swing JFrame JLabel JTextField JButton) 22 | '(java.awt.event ActionListener) 23 | '(java.awt GridLayout)) 24 | (defn celsius [] 25 | (let [frame (JFrame. "Celsius Converter") 26 | temp-text (JTextField.) 27 | celsius-label (JLabel. "Celsius") 28 | convert-button (JButton. "Convert") 29 | fahrenheit-label (JLabel. "Fahrenheit")] 30 | (.addActionListener 31 | convert-button 32 | (reify ActionListener 33 | (actionPerformed 34 | [_ evt] 35 | (let [c (Double/parseDouble (.getText temp-text))] 36 | (.setText fahrenheit-label 37 | (str (+ 32 (* 1.8 c)) " Fahrenheit")))))) 38 | (doto frame 39 | (.setLayout (GridLayout. 2 2 3 3)) 40 | (.add temp-text) 41 | (.add celsius-label) 42 | (.add convert-button) 43 | (.add fahrenheit-label) 44 | (.setSize 300 80) 45 | (.setVisible true)))) 46 | (celsius) 47 | ---- 48 | <> 49 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = README 2 | Alex Miller 3 | 2015-10-19 4 | :jbake-type: page 5 | :toc: macro 6 | 7 | This web site is an open-source repository of content about the Clojure programming language and its greater ecosystem, hosted at http://clojure.org. 8 | 9 | == Contributing 10 | 11 | If you wish to point out an issue in the site or propose a new page, you can do so by filing a GitHub issue at https://github.com/clojure/clojure-site/issues. 12 | 13 | If you wish to make a contribution (typo, modification, or new content), you must become a contributor and follow the https://github.com/clojure/clojure-site/blob/master/content/community/contributing_site.adoc[contribution process]. 14 | 15 | == Building the Site 16 | 17 | The site is built using http://jbake.org/[JBake]. 18 | 19 | To http://jbake.org/docs/2.4.0/#installation[install] JBake 2.5.0-SNAPSHOT: 20 | 21 | . `curl -O http://cdn.cognitect.com/clojure.org/jbake-2.5.0-SNAPSHOT-bin.zip` (or download this file with your browser) 22 | . `unzip -o jbake-2.5.0-SNAPSHOT-bin.zip` 23 | . Add jbake-2.5.0-SNAPSHOT/bin to your system PATH 24 | 25 | To build the site: 26 | 27 | Retrieve the content: 28 | 29 | . `git clone https://github.com/clojure/clojure-site.git` (or your own fork) 30 | . `cd clojure-site` 31 | 32 | Retrieve and install the current theme assets (these don't change very often so you don't need to do this every time): 33 | 34 | . `curl -O http://cdn.cognitect.com/clojure.org/clojuretheme.zip` (or download this file with your browser to the clojure-site directory) 35 | . `unzip -o clojuretheme.zip` 36 | 37 | Generate the pages: 38 | 39 | . `jbake` - this will create the static site in the output directory 40 | . Run `jbake -s` to serve these pages at http://localhost:8820/index 41 | 42 | ## Terms of Use 43 | 44 | Copyright © 2015 Rich Hickey and contributors 45 | 46 | All documentation contained in this repository is licensed by Rich Hickey under the http://www.eclipse.org/legal/epl-v10.html[Eclipse Public License v1.0] unless otherwise noted. To submit a pull request or other contribution, you must sign the http://clojure.org/community/contributing[Clojure Contributor Agreement]. 47 | -------------------------------------------------------------------------------- /content/about/lisp.adoc: -------------------------------------------------------------------------------- 1 | = Clojure as a Dialect of Lisp 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: Lisp 8 | :prevpagehref: functional_programming 9 | :prevpagetitle: Functional Programming 10 | :nextpagehref: runtime_polymorphism 11 | :nextpagetitle: Runtime Polymorphism 12 | 13 | 14 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 15 | 16 | Clojure is a member of the Lisp family of languages. Many of the features of Lisp have made it into other languages, but Lisp's approach to code-as-data and its <> still set it apart. Clojure extends the code-as-data system beyond parenthesized lists (s-expressions) to vectors and maps. Thus vectors and maps can be used in macro syntax, have literal reader representations etc. 17 | 18 | Lisp data, and thus Lisp code, is read by the <>. The result of reading is the data structure represented by the forms. Clojure can compile data structures that represent code, and as part of that process it looks for calls to macros. When it sees one, it calls the macro, passing the forms themselves as arguments, then uses the return value of the macro in place of the macro itself. Thus macros are functions that are called at compile time to perform transformations of code. Since code is data, all of the Clojure library is available to assist in the transformation. Thus macros allow Lisps, and Clojure, to support syntactic abstraction. You use macros for the same reasons you use functions - to eliminate repetition in your code. Macros should be reserved for situations for which functions are insufficient, e.g. when you need to control evaluation, generate identifiers etc. Many of the core constructs of Clojure are not built-in primitives but macros just like users can define. Here's _**and**_: 19 | 20 | [source,clojure] 21 | ---- 22 | (defmacro and 23 | ([] true) 24 | ([x] x) 25 | ([x & rest] 26 | `(let [and# ~x] 27 | (if and# (and ~@rest) and#)))) 28 | 29 | ---- 30 | Note the use of syntax-quote (`), which makes it easy to define macros whose forms mimic the forms they generate. 31 | -------------------------------------------------------------------------------- /content/about/dynamic.adoc: -------------------------------------------------------------------------------- 1 | = Dynamic Development 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: state 8 | :prevpagetitle: State 9 | :nextpagehref: functional_programming 10 | :nextpagetitle: Functional Programming 11 | 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | toc::[] 16 | 17 | First and foremost, Clojure is dynamic. That means that a Clojure program is not just something you compile and run, but something with which you can interact. Clojure is not a language abstraction, but an environment, where almost all of the language constructs are reified, and thus can be examined and changed. This leads to a substantially different experience from running a program, examining its results (or failures) and trying again. In particular, you can grow your program, with data loaded, adding features, fixing bugs, testing, in an unbroken stream. 18 | 19 | == The REPL 20 | 21 | While Clojure can be embedded in a Java application, or used as a scripting language, the primary programming interface is the Read-Eval-Print-Loop (REPL). This is a simple console interface that allows you to enter and execute commands, and examine their results. You can start the Clojure REPL like this, and then follow along trying the samples in this feature tour: 22 | [source,clojure] 23 | ---- 24 | java -cp clojure.jar clojure.main 25 | ---- 26 | This will give you a prompt like this: 27 | [source,clojure] 28 | ---- 29 | user=> 30 | ---- 31 | Most Clojure commands take the form (command arguments*). Try it: 32 | [source,clojure] 33 | ---- 34 | (def x 6) 35 | -> #'user/x 36 | (def y 36) 37 | -> #'user/y 38 | (+ x y) 39 | -> 42 40 | ---- 41 | 42 | == Basics 43 | 44 | Clojure has arbitrary precision integers, strings, ratios, doubles, characters, symbols, keywords. 45 | [source,clojure] 46 | ---- 47 | (* 12345678 12345678) 48 | -> 152415765279684 49 | "string" 50 | -> "string" 51 | 22/7 52 | -> 22/7 53 | 3.14159 54 | -> 3.14159 55 | \a 56 | -> \a 57 | 'symbol 58 | -> symbol 59 | :keyword 60 | -> :keyword 61 | ;a comment 62 | ---- 63 | 64 | == Dynamic Compilation 65 | 66 | Clojure is a compiled language, so one might wonder when you have to run the compiler. You don't. Anything you enter into the REPL or load using load-file is automatically compiled to JVM bytecode on the fly. Compiling ahead-of-time is also possible, but not required. -------------------------------------------------------------------------------- /content/reference/metadata.adoc: -------------------------------------------------------------------------------- 1 | = Metadata 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: protocols 8 | :prevpagetitle: Protocols 9 | :nextpagehref: namespaces 10 | :nextpagetitle: Namespaces 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | toc::[] 15 | 16 | Symbols and collections support metadata, a map of data _about_ the symbol or collection. The metadata system allows for arbitrary annotation of data. It is used to convey information to the compiler about types, but can also be used by application developers for many purposes, annotating data sources, policy etc. 17 | 18 | An important thing to understand about metadata is that it is not considered to be part of the value of an object. As such, _metadata does not impact equality (or hash codes)_. Two objects that differ only in metadata are equal. 19 | 20 | That said, metadata and its relationship to an object is immutable - an object with different metadata is a different object. One consequence of this is that applying metadata to a lazy sequence will realize the head of the sequence so that both objects can share the same sequence. 21 | 22 | '''' 23 | 24 | == (_meta_ obj) 25 | 26 | Returns the metadata of obj, returns nil if there is no metadata. 27 | 28 | '''' 29 | 30 | == (_with-meta_ obj map) 31 | Returns an object of the same type and value as obj, with map as its metadata. 32 | 33 | == Metadata Reader Macros 34 | 35 | In addition to with-meta, there are a number of reader macros (<>) for applying metadata to the expression following it: 36 | 37 | * `^{:doc "How obj works!"} obj` - Sets the metadata of obj to the provided map. 38 | ** Equivalent to `(with-meta obj {:doc "How obj works!"})` 39 | * `^:dynamic obj` - Sets the given keyword to true in the object's metadata. 40 | ** Equivalent to `^{:dynamic true} obj` 41 | * `^String obj` - Sets the value of :tag key in the object's metadata. 42 | ** Equivalent to `^{:tag java.lang.String} obj` 43 | ** Used to hint an objects type to the Clojure compiler. See <> for more information and a complete list of special type hints. 44 | 45 | It is possible to add multiple pieces of metadata by chaining the metadata reader macros together. 46 | For example: `^:dynamic ^ints obj` would apply both the :dynamic flag and ints type-hint to obj. 47 | -------------------------------------------------------------------------------- /content/reference/atoms.adoc: -------------------------------------------------------------------------------- 1 | = Atoms 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: agents 8 | :prevpagetitle: Agents 9 | :nextpagehref: reducers 10 | :nextpagetitle: Reducers 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | Atoms provide a way to manage shared, synchronous, independent state. They are a reference type like refs and vars. You create an atom with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/atom[atom], and can access its state with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/deref[deref/@]. Like refs and agents, atoms support validators. To change the value of an atom, you can use http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/swap![swap!]. A lower-level http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/compare-and-set![compare-and-set!] is also provided. Changes to atoms are always free of race conditions. 15 | 16 | As with all reference types, the intended use of atom is to hold one of Clojure's immutable data structures. And, similar to ref's alter and agent's send, you change the value by applying a function to the old value. This is done in an atomic manner by http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/swap![swap!] Internally, http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/swap![swap!] reads the current value, applies the function to it, and attempts to compare-and-set it in. Since another thread may have changed the value in the intervening time, it may have to retry, and does so in a spin loop. The net effect is that the value will always be the result of the application of the supplied function to a current value, atomically. However, because the function might be called multiple times, it must be free of side effects. 17 | 18 | Atoms are an efficient way to represent some state that will never need to be coordinated with any other, and for which you wish to make synchronous changes (unlike agents, which are similarly independent but asynchronous). A typical usage might be for memoization: 19 | 20 | [source,clojure] 21 | ---- 22 | (defn memoize [f] 23 | (let [mem (atom {})] 24 | (fn [& args] 25 | (if-let [e (find @mem args)] 26 | (val e) 27 | (let [ret (apply f args)] 28 | (swap! mem assoc args ret) 29 | ret))))) 30 | 31 | (defn fib [n] 32 | (if (<= n 1) 33 | n 34 | (+ (fib (dec n)) (fib (- n 2))))) 35 | 36 | (time (fib 35)) 37 | user=> "Elapsed time: 941.445 msecs" 38 | 39 | (def fib (memoize fib)) 40 | 41 | (time (fib 35)) 42 | 43 | user=> "Elapsed time: 0.044 msecs" 44 | ---- -------------------------------------------------------------------------------- /content/api/api.adoc: -------------------------------------------------------------------------------- 1 | = API Documentation 2 | Rich Hickey 3 | 2015-01-01 4 | :jbake-type: page 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | == Clojure API 11 | 12 | * http://clojure.github.io/clojure/[Clojure API] 13 | * http://clojure.github.io/clojure/javadoc/[Clojure Java API] - for calling from Java into Clojure 14 | * <> 15 | 16 | == ClojureScript API 17 | 18 | * http://cljs.info/[ClojureScript API] 19 | 20 | == Clojure Contrib Libraries 21 | 22 | * http://clojure.github.io/algo.generic/[algo.generic] 23 | * http://clojure.github.io/algo.graph/[algo.graph] 24 | * http://clojure.github.io/algo.monads/[algo.monads] 25 | * http://clojure.github.io/core.async/[core.async] 26 | * http://clojure.github.io/core.cache/[core.cache] 27 | * http://clojure.github.io/core.contracts/[core.contracts] 28 | * http://clojure.github.io/core.incubator/[core.incubator] 29 | * http://clojure.github.io/core.logic/[core.logic] 30 | * http://clojure.github.io/core.match/[core.match] 31 | * http://clojure.github.io/core.memoize/[core.memoize] 32 | * http://clojure.github.io/core.rrb-vector/[core.rrb-vector] 33 | * http://clojure.github.io/core.typed/[core.typed] 34 | * http://clojure.github.io/core.unify/[core.unify] 35 | * http://clojure.github.io/data.avl/[data.avl] 36 | * http://clojure.github.io/data.codec/[data.codec] 37 | * http://clojure.github.io/data.csv/[data.csv] 38 | * http://clojure.github.io/data.finger-tree/[data.finger-tree] 39 | * http://clojure.github.io/data.fressian/[data.fressian] 40 | * http://clojure.github.io/data.generators/[data.generators] 41 | * http://clojure.github.io/data.json/[data.json] 42 | * http://clojure.github.io/data.priority-map/[data.priority-map] 43 | * http://clojure.github.io/data.xml/[data.xml] 44 | * http://clojure.github.io/data.zip/[data.zip] 45 | * http://clojure.github.io/java.classpath/[java.classpath] 46 | * http://clojure.github.io/java.data/[java.data] 47 | * http://clojure.github.io/java.jdbc/[java.jdbc] 48 | * http://clojure.github.io/java.jmx/[java.jmx] 49 | * http://clojure.github.io/math.combinatorics/[math.combinatorics] 50 | * http://clojure.github.io/math.numeric-tower/[math.numeric-tower] 51 | * http://clojure.github.io/test.generative/[test.generative] 52 | * http://clojure.github.io/tools.analyzer/[tools.analyzer] 53 | * http://clojure.github.io/tools.analyzer.js/[tools.analyzer.js] 54 | * http://clojure.github.io/tools.analyzer.jvm/[tools.analyzer.jvm] 55 | * http://clojure.github.io/tools.cli/[tools.cli] 56 | * http://clojure.github.io/tools.emitter.jvm/[tools.emitter.jvm] 57 | * http://clojure.github.io/tools.logging/[tools.logging] 58 | * http://clojure.github.io/tools.macro/[tools.macro] 59 | * http://clojure.github.io/tools.namespace/[tools.namespace] 60 | * http://clojure.github.io/tools.nrepl/[tools.nrepl] 61 | * http://clojure.github.io/tools.reader/[tools.reader] 62 | * http://clojure.github.io/tools.trace/[tools.trace] 63 | 64 | == Other resources 65 | 66 | * http://grimoire.arrdem.com/[Grimoire] - community combined cheatsheet + examples 67 | * http://clojuredocs.org[ClojureDocs] - community provided example repository 68 | * http://crossclj.info/[CrossClj] - library cross-reference 69 | 70 | == Deprecated (pre Clojure 1.3) 71 | 72 | * http://clojure.github.io/clojure-contrib/[Clojure Contrib API] 73 | -------------------------------------------------------------------------------- /content/about/runtime_polymorphism.adoc: -------------------------------------------------------------------------------- 1 | = Runtime Polymorphism 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: lisp 8 | :prevpagetitle: Lisp 9 | :nextpagehref: concurrent_programming 10 | :nextpagetitle: Concurrent Programming 11 | 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | Systems that utilize runtime polymorphism are easier to change and extend. Clojure supports polymorphism in several ways: 16 | 17 | * Most core infrastructure data structures in the Clojure runtime are defined by Java interfaces. 18 | * Clojure supports the generation of implementations of Java interfaces in Clojure using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/proxy[proxy] (<>). 19 | * The Clojure language supports polymorphism along both class and custom hierarchies with <>s. 20 | * The Clojure language also supports a faster form of polymorphism with <> (but limited only to class polymorphism to take advantage of the JVMs existing capabilities for invocation). 21 | 22 | Clojure multimethods are a simple yet powerful mechanism for runtime polymorphism that is free of the trappings of OO, types and inheritance. The basic idea behind runtime polymorphism is that a single function designator dispatches to multiple independently-defined function definitions based upon some value of the call. For traditional single-dispatch OO languages that value is the type of the 'receiver' or 'this'. CLOS generic functions extend dispatch value to a composite of the type or value of multiple arguments, and are thus multimethods. Clojure multimethods go further still to allow the dispatch value to be the result of an arbitrary function of the arguments. Clojure does not support implementation inheritance. 23 | 24 | Multimethods are defined using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmulti[defmulti], which takes the name of the multimethod and the dispatch function. Methods are independently defined using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmethod[defmethod], passing the multimethod name, the dispatch _value_ and the function body. 25 | 26 | [source,clojure] 27 | ---- 28 | (defmulti encounter (fn [x y] [(:Species x) (:Species y)])) 29 | (defmethod encounter [:Bunny :Lion] [b l] :run-away) 30 | (defmethod encounter [:Lion :Bunny] [l b] :eat) 31 | (defmethod encounter [:Lion :Lion] [l1 l2] :fight) 32 | (defmethod encounter [:Bunny :Bunny] [b1 b2] :mate) 33 | (def b1 {:Species :Bunny :other :stuff}) 34 | (def b2 {:Species :Bunny :other :stuff}) 35 | (def l1 {:Species :Lion :other :stuff}) 36 | (def l2 {:Species :Lion :other :stuff}) 37 | (encounter b1 b2) 38 | -> :mate 39 | (encounter b1 l1) 40 | -> :run-away 41 | (encounter l1 b1) 42 | -> :eat 43 | (encounter l1 l2) 44 | -> :fight 45 | ---- 46 | 47 | Multimethods are in every respect fns, e.g. can be passed to http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/map[map] etc. 48 | 49 | Similar to interfaces, Clojure protocols define only function specifications (no implementation) and allow types to implement multiple protocols. Additionally, protocols are open to later dynamic extension for new types. Protocols are limited just to dispatch on class type to take advantage of the native Java performance of polymorphic method calls. For more details, see the <> page. 50 | -------------------------------------------------------------------------------- /content/news/2015/06/30/clojure-17.adoc: -------------------------------------------------------------------------------- 1 | = Clojure 1.7 is now available 2 | Alex Miller 3 | 2015-06-30 4 | :jbake-type: post 5 | 6 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 7 | 8 | We are pleased to announce the release of Clojure 1.7. The two headline features for 1.7 are transducers and reader conditionals. Also see the https://github.com/clojure/clojure/blob/master/changes.md[complete list] of all changes since Clojure 1.6 for more details. 9 | 10 | == Transducers 11 | 12 | http://clojure.org/transducers[Transducers] are composable algorithmic transformations. They are independent from the context of their input and output sources and specify only the essence of the transformation in terms of an individual element. Because transducers are decoupled from input or output sources, they can be used in many different processes - collections, streams, channels, observables, etc. Transducers compose directly, without awareness of input or creation of intermediate aggregates. 13 | 14 | Many existing sequence functions now have a new arity (one fewer argument than before). This arity will return a transducer that represents the same logic but is independent of lazy sequence processing. Functions included are: map, mapcat, filter, remove, take, take-while, drop, drop-while, take-nth, replace, partition-by, partition-all, keep, keep-indexed, map-indexed, distinct, and interpose. Additionally some new transducer functions have been added: cat, dedupe, and random-sample. 15 | 16 | Transducers can be used in several new or existing contexts: 17 | 18 | * into - to collect the results of applying a transducer 19 | * sequence - to incrementally compute the result of a transducer 20 | * transduce - to immediately compute the result of a transducer 21 | * eduction - to delay computation and recompute each time 22 | * core.async - to apply a transducer while values traverse a channel 23 | 24 | == Portable Clojure and Reader Conditionals 25 | 26 | It is now common to see a library or application targeting multiple Clojure platforms with a single codebase. Clojure 1.7 introduces a new extension (.cljc) for files that can be loaded by Clojure and ClojureScript (and other Clojure platforms). 27 | 28 | There will often be some parts of the code that vary between platforms. The primary mechanism for dealing with platform-specific code is to isolate that code into a minimal set of namespaces and then provide platform-specific versions (.clj/.class or .cljs) of those namespaces. 29 | 30 | To support cases where is not feasible to isolate the varying parts of the code, or where the code is mostly portable with only small platform-specific parts, 1.7 provides http://clojure.org/reader#The%20Reader--Reader%20Conditionals[Reader Conditionals]. 31 | 32 | Reader conditionals are a new reader form that is only allowed in portable cljc files. A reader conditional expression is similar to a cond in that it specifies alternating platform identifiers and expressions. Each platform is checked in turn until a match is found and the expression is read. All expressions not selected are read but skipped. A final :default fallthrough can be provided. If no expressions are matched, the reader conditional will read nothing. The reader conditional splicing form takes a sequential expression and splices the result into the surrounding code. 33 | 34 | == Contributors 35 | 36 | Thanks to all of those who contributed patches to Clojure 1.7: 37 | 38 | * Timothy Baldridge 39 | * Bozhidar Batsov 40 | * Brandon Bloom 41 | * Michael Blume 42 | * Ambrose Bonnaire-Sergeant 43 | * Aaron Cohen 44 | * Pepijn de Vos 45 | * Andy Fingerhut 46 | * Gary Fredricks 47 | * Daniel Solano Gómez 48 | * Stuart Halloway 49 | * Rich Hickey 50 | * Immo Heikkinen 51 | * Andrei Kleschinsky 52 | * Howard Lewis Ship 53 | * Alex Miller 54 | * Steve Miner 55 | * Nicola Mometto 56 | * Tomasz Nurkiewicz 57 | * Ghadi Shayban 58 | * Paul Stadig 59 | * Zach Tellman 60 | * Luke VanderHart 61 | * Jozef Wagner 62 | * Devin Walters 63 | * Jason Wolfe 64 | * Steven Yi 65 | 66 | Also, continued thanks to the total list of contributors from all releases. -------------------------------------------------------------------------------- /content/reference/namespaces.adoc: -------------------------------------------------------------------------------- 1 | = Namespaces 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: metadata 8 | :prevpagetitle: Metadata 9 | :nextpagehref: libs 10 | :nextpagetitle: Libs 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | toc::[] 15 | 16 | Namespaces are mappings from simple (unqualified) symbols to Vars and/or Classes. Vars can be interned in a namespace, using _**def**_ or any of its variants, in which case they have a simple symbol for a name and a reference to their containing namespace, and the namespace maps that symbol to the same var. A namespace can also contain mappings from symbols to vars interned in other namespaces by using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/refer[refer] or http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/use[use], or from symbols to Class objects by using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/import[import]. Note that namespaces are first-class, they can be enumerated etc. Namespaces are also dynamic, they can be created, removed and modified at runtime, at the Repl etc. 17 | 18 | The best way to set up a new namespace at the top of a Clojure source file is to use the http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns[ns macro]. By default this will create a new namespace contains mappings for the classnames in +java.lang+ plus `clojure.lang.Compiler`, and the functions in `clojure.core`. 19 | 20 | At the Repl it's best to use http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/in-ns[in-ns], in which case the new namespace will contain mappings only for the classnames in +java.lang+. In order to access the names from the `clojure.core` namespace you must execute +(clojure.core/refer 'clojure.core)+. The `user` namespace at the Repl has already done this. 21 | 22 | The current namespace, _pass:[*ns*]_ can and should be set only with a call to http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/in-ns[in-ns] or the http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns[ns macro], both of which create the namespace if it doesn't exist. 23 | 24 | == Related functions 25 | 26 | [%hardbreaks] 27 | Creating and switching to a namespace: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/in-ns[in-ns] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns[ns] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/create-ns[create-ns] 28 | Adding to a namespace: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/alias[alias] <> http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/import[import] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/intern[intern] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/refer[refer] 29 | Finding what namespaces exist: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/all-ns[all-ns] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/find-ns[find-ns] 30 | Examining a namespace: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-name[ns-name] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-aliases[ns-aliases] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-imports[ns-imports] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-interns[ns-interns] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-map[ns-map] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-publics[ns-publics] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-refers[ns-refers] 31 | Getting a namespace from a symbol: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/resolve[resolve] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-resolve[ns-resolve] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/namespace[namespace] 32 | Removing things: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-unalias[ns-unalias] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-unmap[ns-unmap] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/remove-ns[remove-ns] 33 | -------------------------------------------------------------------------------- /content/reference/libs.adoc: -------------------------------------------------------------------------------- 1 | = Using Libs 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: Libs 8 | :prevpagehref: namespaces 9 | :prevpagetitle: Namespaces 10 | :nextpagehref: vars 11 | :nextpagetitle: Vars and Environments 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | toc::[] 16 | 17 | Clojure provides for code loading and dependency tracking via its "lib" facility. A lib is a named unit of Clojure source code contained in a Java resource within classpath. A lib will typically provide the complete set of definitions that make up one Clojure namespace. 18 | 19 | == Lib Conventions 20 | 21 | Clojure defines conventions for naming and structuring libs: 22 | 23 | * A lib name is a symbol that will typically contain two or more parts separated by periods. 24 | * A lib's container is a Java resource whose classpath-relative path is derived from the lib name: 25 | ** The path is a string 26 | ** Periods in the lib name are replaced by slashes in the path 27 | ** Hyphens in the lib name are replaced by underscores in the path 28 | ** The path may end with ".class", ".clj", or ".cljc" (see <> below) 29 | * A lib begins with an "ns" form that 30 | ** creates the Clojure namespace that shares its name, and 31 | ** declares its dependencies on Java classes, Clojure's core facilities, and/or other libs, 32 | 33 | Clojure ensures that if the call to "ns" completes without throwing an exception, the declared dependencies have been satisfied and the capabilities they provide are available. 34 | 35 | == Example Lib 36 | 37 | A simple lib: 38 | 39 | [source,clojure] 40 | ---- 41 | (ns com.my-company.clojure.examples.my-utils 42 | (:import java.util.Date) 43 | (:use [clojure.string :only (join)]) 44 | (:require [clojure.java.io :as jio])) 45 | ---- 46 | 47 | * The `ns` form names the lib's namespace and declares its dependencies. Based on its name, this lib is typically defined in a source file at the classpath-relative path: com/my_company/clojure/examples/my_utils.clj (note the translations from period to slash and hyphen to underscore). 48 | * The `:import` clause declares this lib's use of `java.util.Date` and makes it available to code in this lib using its unqualified name. 49 | * The `:use` clause declares a dependency on the `clojure.string` lib for its `join` function only. +join+ may be used in this lib's code using its unqualified name. 50 | * The `:require` clause declares a dependency on the `clojure.java.io` lib and enables using its members using the shorter namespace alias `jio`. 51 | 52 | == Prefix Lists 53 | 54 | It's common for a lib to depend on several other libs whose full names share a common prefix. In calls to `require` and `use` (and in `:require` and `:use` clauses within an +ns+ form), the common prefix can be extracted and provided once using a prefix list. For example, these two forms are equivalent: 55 | 56 | [source,clojure] 57 | ---- 58 | (require 'clojure.contrib.def 'clojure.contrib.except 'clojure.contrib.sql) 59 | (require '(clojure.contrib def except sql)) 60 | ---- 61 | 62 | '''' 63 | 64 | == Related functions 65 | 66 | Creating a namespace: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns[ns] 67 | 68 | Ensuring a lib is loaded: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/require[require] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/use[use] 69 | 70 | Listing loaded libs: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/loaded-libs[loaded-libs] 71 | 72 | [[order]] 73 | == Lib load order 74 | 75 | Libs may exist in either compiled (`.class`) or source (`.clj` or `.cljc`) form. In some cases, one or even all of these might exist on the classpath. The lib is loaded from one of them based on the following rules: 76 | 77 | * A `.class` file is always preferred over a source file, unless the source file's timestamp is newer than the `.class` file, in which case the source file is preferred. 78 | * A `.clj` (platform-specific file) is always preferred over a `.cljc` (common across platforms). 79 | 80 | The second rule allows a library author to ship both a portable common definition of a lib while also shipping platform-specific libs that override the portable version to do something that leverages the host platform. 81 | -------------------------------------------------------------------------------- /content/reference/lisps.adoc: -------------------------------------------------------------------------------- 1 | = Differences with other Lisps 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: Differences with Lisps 8 | :prevpagehref: other_libraries 9 | :prevpagetitle: Other Libraries 10 | 11 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 12 | 13 | This information is provided for programmers familiar with Common Lisp or Scheme. 14 | 15 | * Clojure is case sensitive 16 | * Clojure is a Lisp-1 17 | * () is not the same as nil 18 | * The reader is side-effect free 19 | * Keywords are not Symbols 20 | * Symbols are not storage locations (see Var) 21 | * _**nil**_ is not a Symbol 22 | * t is not syntax, use _**true**_ 23 | * The read table is currently not accessible to user programs 24 | * _**let**_ binds sequentially 25 | * _**do**_ is not a looping construct 26 | * There is no tail-call optimization, use _**recur**_. 27 | * syntax-quote does symbol resolution, so `x is not the same as 'x. 28 | * ` has auto-gensyms. 29 | * ~ is unquote ',' is whitespace 30 | * There is reader syntax for maps, vectors, and sets 31 | * _**cons**_, _**first**_ and _**rest**_ manipulate sequence abstractions, not concrete cons cells 32 | * Most data structures are immutable 33 | * lambda is _**fn**_, and supports overloading by arity 34 | * _**pass:[=]**_ is the equality predicate 35 | * Global Vars can be dynamically rebound (if declared dynamic) without interfering with lexical local bindings. No special declarations are necessary to distinguish between dynamic and lexical bindings. Since Clojure is a Lisp-1, (global) functions can be dynamically rebound (if they are marked as dynamic). 36 | * No letrec, labels or flet - use (fn name [args]...) for self-reference, http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/letfn[letfn] for mutual reference. 37 | * In Clojure _**nil**_ means 'nothing'. It signifies the absence of a value, of any type, and is not specific to lists or sequences. 38 | * Empty collections are distinct from _**nil**_. Clojure does not equate _**nil**_ and '(). 39 | * _**false**_ means one of the two possible boolean values, the other being _**true**_ 40 | * There is more to collections than lists. You can have instances of empty collections, some of which have literal support ([], {}, and ()). Thus there can be no sentinel empty collection value. 41 | * Coming from Scheme, _**nil**_ may map most closely to your notion of #f. 42 | * A big difference in Clojure, is sequences. Sequences are not specific collections, esp. they are not necessarily concrete lists. When you ask an empty collection for a sequence of its elements (by calling *seq*) it returns _**nil**_, saying "I can't produce one". When you ask a sequence on its last element for the _**rest**_ it returns _**another logical sequence.**_ You can only tell if that sequence is empty by calling *seq* on it in turn. This enables sequences and the sequence protocol to be _lazy_. 43 | * Some of the sequence functions correspond to functions from Scheme and CL that there manipulated only pairs/conses ('lists') and returned sentinel values ('() and nil) that represented 'empty' lists. The Clojure return values differ in not returning specific empty collections, but rather another logical sequence. Some of the sequence functions have no counterpart in Scheme/CL, and map to Haskell/ML-like functions. Some of those functions return infinite or calculated sequences, where the analogy to concrete data-structures like Scheme/CL lists is tenuous at best. 44 | * It helps to distinguish collections/data-structures and seqs/iteration. In both CL and Scheme they are conflated, in Clojure they are separate. 45 | 46 | [cols="<*,", options="header", role="table"] 47 | |=== 48 | | | Clojure | Common Lisp | Scheme | Java | 49 | | Has nil? | nil - means 'nothing' | nil - means false or empty list | - | null | 50 | | Has true? | true | - | #t | true (primitive) | 51 | | Has false? | false | - | #f | false (primitive) | 52 | | Conditionals distinguish: | nil or false/ everything else | nil/non-nil | #f/non-#f | false/true | 53 | | List/sequence library manipulates distinguished concrete type(s)? | No - seq abstraction with many collection implementations | Yes - cons and vector | Yes - pair | No - Iterator abstraction with many collection implementations | 54 | | Singleton empty-list value? | No - can have distinct empty values of concrete collection types | nil | '() | No | 55 | | End-of-sequence returns: | a logical sequence for which *seq* returns nil | nil | '() | false | 56 | | Host null: | nil | NA | NA | NA | 57 | | Host true: | true (boxed) | NA | NA | NA | 58 | | Host false: | false (boxed) | NA | NA | NA | 59 | |=== 60 | -------------------------------------------------------------------------------- /content/community/books.adoc: -------------------------------------------------------------------------------- 1 | = Books 2 | Rich Hickey 3 | 2015-01-01 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | Please support these fine books about Clojure. 9 | 10 | _Listed in order of descending release date of newest edition._ 11 | 12 | [width="80", cols="<.^30a,.^70"] 13 | |=== 14 | 15 | | image::http://ecx.images-amazon.com/images/I/6112vbQYDLL._SL160.jpg[Clojure for the Brave and True,link="http://amzn.com/1593275919"] 16 | | http://amzn.com/1593275919[Clojure for the Brave and True] + 17 | by Daniel Higginbotham 18 | 19 | | image::http://ecx.images-amazon.com/images/I/51aMgNS%2BK7L._SL160.jpg[Clojure Recipes,link="http://amzn.com/0321927737"] 20 | | http://amzn.com/0321927737[Clojure Recipes] + 21 | by Julian Gamble 22 | 23 | | image::http://ecx.images-amazon.com/images/I/51Nym1wJXVL._SL160.jpg[Clojure High Performance Programming,link="http://amzn.com/1785283642"] 24 | | http://amzn.com/1785283642[Clojure High Performance Programming] + 25 | by Shantanu Kumar 26 | 27 | | image::http://ecx.images-amazon.com/images/I/41iH5aTHB3L._SL160.jpg[Clojure Applied,link="http://amzn.com/1680500740"] 28 | | http://amzn.com/1680500740[Clojure Applied: From Practice to Practitioner] + 29 | by Ben Vandgrift, Alex Miller 30 | 31 | | image::http://ecx.images-amazon.com/images/I/51ki-47i6bL._SL160.jpg[Clojure for Data Science,link="http://amzn.com/1784397180"] 32 | | http://amzn.com/1784397180[Clojure for Data Science] + 33 | by Henry Garner 34 | 35 | | image::http://ecx.images-amazon.com/images/I/515vh5czqnL._SL160.jpg[Clojure Data Structures and Algorithms,link="http://amzn.com/1785281453"] 36 | | http://amzn.com/1785281453[Clojure Data Structures and Algorithms] + 37 | by Rafik Naccache 38 | 39 | | image::http://ecx.images-amazon.com/images/I/5122uV93jfL._SL160.jpg[Living Clojure,link="http://amzn.com/1491909048"] 40 | | http://amzn.com/1491909048[Living Clojure] + 41 | by Carin Meier 42 | 43 | | image::http://ecx.images-amazon.com/images/I/51l1oGz9N7L._SL160.jpg[Clojure Reactive Programming,link="http://amzn.com/1783986662"] 44 | | http://amzn.com/1783986662[Clojure Reactive Programming] + 45 | by Leonardo Borges 46 | 47 | | image::http://ecx.images-amazon.com/images/I/51XnilmUaIL._SL160.jpg[Clojure Web Development Essentials,link="http://amzn.com/1784392227"] 48 | | http://amzn.com/1784392227[Clojure Web Development Essentials] + 49 | by Ryan Baldwin 50 | 51 | | image::http://ecx.images-amazon.com/images/I/51-B3kElSiL._SL160.jpg[Clojure Data Analysis Cookbook, link="http://amzn.com/1784390291"] 52 | | http://amzn.com/1784390291[Clojure Data Analysis Cookbook] + 53 | by Eric Rochester 54 | 55 | | image::http://ecx.images-amazon.com/images/I/51nhUEYSLhL._SL160.jpg[Mastering Clojure Macros,link="http://amzn.com/1941222226"] 56 | | http://amzn.com/1941222226[Mastering Clojure Macros] + 57 | by Colin Jones 58 | 59 | | image::http://ecx.images-amazon.com/images/I/518RxlXpXsL._SL160.jpg[The Joy of Clojure,link="http://amzn.com/1617291412"] 60 | | http://amzn.com/1617291412[The Joy of Clojure] + 61 | by Michael Fogus, Chris Houser 62 | 63 | | image::http://ecx.images-amazon.com/images/I/51Af%2B5qKOeL._SL160.jpg[Clojure for Machine Learning,link="http://amzn.com/1783284358"] 64 | | http://amzn.com/1783284358[Clojure for Machine Learning] + 65 | by Akhil Wali 66 | 67 | | image::http://ecx.images-amazon.com/images/I/51NPZu-5PiL._SL160.jpg[Clojure Cookbook, link="http://amzn.com/1449366171"] 68 | | http://amzn.com/1449366171[Clojure Cookbook] + 69 | by Luke VanderHart and Ryan Neufeld 70 | 71 | | image::http://ecx.images-amazon.com/images/I/51t6UhYc%2BCL._SL160.jpg[Web Development with Clojure,link="http://amzn.com/1680500821"] 72 | | http://amzn.com/1680500821[Web Development with Clojure] + 73 | by Dmitri Sotnikov 74 | 75 | | image::http://ecx.images-amazon.com/images/I/41sY2b6MKiL._SL160.jpg[Clojure Programming,link="http://amzn.com/1449394701"] 76 | | http://amzn.com/1449394701[Clojure Programming] + 77 | by Chas Emerick, Brian Carper, Christophe Grand 78 | 79 | | image::http://ecx.images-amazon.com/images/I/41aJY7x54bL._SL160.jpg[Programming Clojure,link="http://amzn.com/1934356867"] 80 | | http://amzn.com/1934356867[Programming Clojure] + 81 | by Stuart Halloway, Aaron Bedra 82 | 83 | | image::http://ecx.images-amazon.com/images/I/51QWOEjmtIL._SL160.jpg[Clojure In Action, link="http://amzn.com/1617291528"] 84 | | http://amzn.com/1617291528[Clojure In Action] + 85 | by Amit Rathore 86 | 87 | | image::http://ecx.images-amazon.com/images/I/51dWGdAPwUL._SL160.jpg[Practical Clojure, link="http://amzn.com/1430272317"] 88 | | http://amzn.com/1430272317[Practical Clojure] + 89 | by Luke VanderHart, Stuart Sierra 90 | 91 | |=== 92 | 93 | 94 | -------------------------------------------------------------------------------- /content/community/downloads_older.adoc: -------------------------------------------------------------------------------- 1 | = Downloads Older 2 | Rich Hickey 3 | 2015-01-01 4 | :jbake-type: page 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | == Older Clojure Releases 11 | 12 | == Older Production Releases 13 | 14 | 15 | * http://central.maven.org/maven2/org/clojure/clojure/1.6.0/[Clojure 1.6.0] (March, 2014) 16 | * http://central.maven.org/maven2/org/clojure/clojure/1.5.1/[Clojure 1.5.1] (March, 2013) 17 | * http://central.maven.org/maven2/org/clojure/clojure/1.4.0/[Clojure 1.4.0] (April, 2012) 18 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.3.0/clojure-1.3.0.zip[Clojure 1.3] (September, 2011) 19 | * https://github.com/downloads/clojure/clojure/clojure-1.2.1.zip[Clojure 1.2.1] (September, 2010) 20 | * http://github.com/downloads/clojure/clojure-contrib/clojure-contrib-1.2.0.zip[Clojure Contrib 1.2] 21 | * http://github.com/downloads/clojure/clojure/clojure-1.2.0.zip[Clojure 1.2] (August, 2010) 22 | * Clojure 1.1.0 (January, 2010) 23 | * http://github.com/downloads/clojure/clojure/clojure-1.0.0.zip[Clojure 1.0.0] (July, 2009) 24 | 25 | == Older Developer Releases 26 | 27 | 28 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-beta7/clojure-1.4.0-beta7.zip[Clojure 1.4 Beta 7] 29 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-beta6/clojure-1.4.0-beta6.zip[Clojure 1.4 Beta 6] 30 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-beta5/clojure-1.4.0-beta5.zip[Clojure 1.4 Beta 5] 31 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-beta4/clojure-1.4.0-beta4.zip[Clojure 1.4 Beta 4] 32 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-beta3/clojure-1.4.0-beta3.zip[Clojure 1.4 Beta 3] 33 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-beta2/clojure-1.4.0-beta2.zip[Clojure 1.4 Beta 2] 34 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-beta1/clojure-1.4.0-beta1.zip[Clojure 1.4 Beta 1] 35 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-alpha5/clojure-1.4.0-alpha5.zip[Clojure 1.4 Alpha 5] 36 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-alpha4/clojure-1.4.0-alpha4.zip[Clojure 1.4 Alpha 4] 37 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-alpha3/clojure-1.4.0-alpha3.zip[Clojure 1.4 Alpha 3] 38 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-alpha2/clojure-1.4.0-alpha2.zip[Clojure 1.4 Alpha 2] 39 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.4.0-alpha1/clojure-1.4.0-alpha1.zip[Clojure 1.4 Alpha 1] 40 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.3.0-RC0/clojure-1.3.0-RC0.zip[Clojure 1.3 RC0] 41 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.3.0-beta3/clojure-1.3.0-beta3.zip[Clojure 1.3 Beta 3] 42 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.3.0-beta2/clojure-1.3.0-beta2.zip[Clojure 1.3 Beta 2] 43 | * http://repo1.maven.org/maven2/org/clojure/clojure/1.3.0-beta1/clojure-1.3.0-beta1.zip[Clojure 1.3 Beta 1] 44 | * https://oss.sonatype.org/content/repositories/releases/org/clojure/clojure/1.3.0-alpha8/clojure-1.3.0-alpha8.zip[Clojure 1.3 Alpha 8] 45 | * https://oss.sonatype.org/content/repositories/releases/org/clojure/clojure/1.3.0-alpha7/clojure-1.3.0-alpha7.zip[Clojure 1.3 Alpha 7] 46 | * https://github.com/downloads/clojure/clojure/clojure-1.3.0-alpha6.zip[Clojure 1.3 Alpha 6] 47 | * https://github.com/downloads/clojure/clojure/clojure-1.3.0-alpha4.zip[Clojure 1.3 Alpha 4] 48 | * https://github.com/downloads/clojure/clojure/clojure-1.3.0-alpha3.zip[Clojure 1.3 Alpha 3] 49 | * http://github.com/downloads/clojure/clojure/clojure-1.3.0-alpha2.zip[Clojure 1.3 Alpha 2] 50 | * http://github.com/downloads/clojure/clojure/clojure-1.3.0-alpha1.zip[Clojure 1.3 Alpha 1] 51 | * http://github.com/downloads/clojure/clojure/clojure-1.2.0-RC3.zip[Clojure 1.2 RC3] 52 | * http://github.com/downloads/clojure/clojure-contrib/clojure-contrib-1.2.0-RC3.zip[Clojure Contrib 1.2 RC3] 53 | * http://github.com/downloads/clojure/clojure/clojure-1.2.0-RC2.zip[Clojure 1.2 RC2] 54 | * http://github.com/downloads/clojure/clojure-contrib/clojure-contrib-1.2.0-RC2.zip[Clojure Contrib 1.2 RC2] 55 | * http://github.com/downloads/clojure/clojure/clojure-1.2.0-RC1.zip[Clojure 1.2 RC1] 56 | * http://github.com/downloads/clojure/clojure-contrib/clojure-contrib-1.2.0-RC1.zip[Clojure Contrib 1.2 RC1] 57 | * http://github.com/downloads/clojure/clojure/clojure-1.2.0-beta1.zip[Clojure 1.2 Beta 1] 58 | * http://github.com/downloads/clojure/clojure-contrib/clojure-contrib-1.2.0-beta1.zip[Clojure Contrib 1.2 Beta 1] 59 | * http://github.com/downloads/clojure/clojure/clojure-20090320.zip[Clojure 20090320] (pre 1.0) 60 | * http://github.com/downloads/clojure/clojure/clojure-20081217.zip[Clojure 20081217] (pre 1.0) -------------------------------------------------------------------------------- /content/community/start_group.adoc: -------------------------------------------------------------------------------- 1 | = Start Group 2 | Alex Miller 3 | 2015-01-01 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | == Tips on Starting a Clojure User Group 11 | 12 | 13 | Starting a user group is a great way to improve your Clojure skills and find others interested in Clojure in your area. If you've never run a user group before, that's ok! Anyone can do it. 14 | 15 | A user group needs the following elements: 16 | 17 | 18 | . *A meeting place.* Finding a regular meeting place is sometimes the biggest hurdle a group faces when getting off the ground. Often the ideal option is finding a company that can host a group after-hours. If that's not an option, some other choices include libraries, churches, or coffee shops. 19 | . *A meeting time.* It's important to establish a rhythm to keep a group going. Pick a night (like the 2nd Tuesday of the month) and try as much as possible to have your meeting on that same night every month. 20 | . *A home on the web.* It's important to have an address on the web that can be found by a search engine. There are lots of ways to put together a web page for free or cheap - see below for some tools you can use. 21 | . *People!* You can't have a meeting without people. Ask around at other mailing lists or user groups in your area for people that might be interested. 22 | 23 | == Tools 24 | 25 | * Google Calendar - http://www.google.com/calendar[http://www.google.com/calendar] 26 | * Wordpress - http://wordpress.com[http://wordpress.com] - free blog and web site 27 | * Meetup - http://meetup.com/[http://meetup.com] - meeting discovery, calendar, user network (75% discount available) 28 | * Google Groups - http://groups.google.com[http://groups.google.com] - free mailing list 29 | * Yahoo Groups - http://groups.yahoo.com[http://groups.yahoo.com] - free mailing list 30 | * Wikispaces - http://wikispaces.com/[http://wikispaces.com] - free wiki 31 | * YouTube - http://youtube.com[http://youtube.com] - video hosting 32 | 33 | == Common problems 34 | 35 | _"We have a group but it's hard to find enough speakers."_ or _"The same people always give talks."_ 36 | 37 | Not every meeting has to have a speaker that gives a prepared talk. Think creatively about other ways to have a meeting that gives value. Some ideas: 38 | 39 | * *Lightning talks* - do 5 or 10 minute talks on small subjects. Paradoxically, doing more shorter talks at a meeting is sometimes easier than scheduling one big talk. Each presenter has to prepare less material and meetings have a smaller risk of a bad meeting due to one inexperienced speaker. Try doing two or three talks per meeting. 40 | * *Live coding session* - start with a small problem (it's hard to start too small for this) and let the group drive the evolution of the solution. 41 | * *Code review* - bring some code and walk through it. Explain the code, take comments on style, performance, etc. Rewrite parts of it to make it better. 42 | * *Contribute* - pick a bug from the Clojure bug tracker and work on it together. Or review the documentation and figure out some improvements. Even providing a list of things confusing to newcomers is useful. 43 | * *Review a paper* - there are tons of great books and papers on Lisp, Clojure, functional programming, persistent data structures, etc. Pick one and lead a discussion about the merits or flaws of the paper. 44 | * *Book study group* - review a classic book like __Structure and Interpretation of Computer Programs__ (http://mitpress.mit.edu/sicp/[SICP]) or some other http://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH[classic] 45 | * *Competition* - have everyone bring a solution to the same problem in Clojure or other languages and compare the result. 46 | 47 | _"We have a mailing list but no one ever uses it."_ 48 | 49 | The best way to get people talking on a mailing list is to talk on it yourself. Post your meeting announcements, meeting recaps, articles of interest, code snippets, etc. Ask people to introduce themselves on the list - people love to talk about themselves. Mailing lists require some bootstrapping. Eventually, the mailing list will become self-maintaining but it takes some work at the beginning or if there is a lull. 50 | 51 | _"Recruiters have joined our mailing list and keep posting job ads."_ 52 | 53 | It's important to have a policy for recruiters and job postings. Decide on your policy, document it, and refer people to it. Some common policies are: "job postings are allowed", "only job postings pertinent to the group are allowed", "only approved job postings are allowed", etc. Some groups have a separate mailing list only for jobs and recruiting. 54 | 55 | _"I can't find enough people to have a meeting."_ 56 | 57 | If you can't find enough people to start a Clojure group, perhaps you can broaden the scope to find others that might like to talk about Clojure some of the time. Are there people interested in a functional programming group? A programming languages group? A JVM-based languages group? A programmer's club? 58 | -------------------------------------------------------------------------------- /content/news/2014/08/06/transducers-are-coming.adoc: -------------------------------------------------------------------------------- 1 | = Transducers are Coming 2 | Rich Hickey 3 | 2014-08-06 4 | :jbake-type: post 5 | 6 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 7 | 8 | Transducers are a powerful and composable way to build algorithmic transformations that you can reuse in many contexts, and they're coming to Clojure core and core.async. 9 | 10 | Two years ago, in a http://clojure.com/blog/2012/05/15/anatomy-of-reducer.html[blog post describing how reducers work], I described the reducing function transformers on which they were based, and provided explicit examples like `mapping`, `filtering` and `mapcatting`. Because the reducers library intends to deliver an API with the same 'shape' as existing sequence function APIs, these transformers were never exposed a la carte, instead being encapsulated by the macrology of reducers. 11 | 12 | In working recently on providing algorithmic combinators for core.async, I became more and more convinced of the superiority of reducing function transformers over channel->channel functions for algorithmic transformation. In fact, I think they are a better way to do many things for which we normally create bespoke replicas of map, filter etc. 13 | 14 | So, reducing function transformers are getting a name - *transducers*, and first-class support in Clojure core and core.async. 15 | 16 | == What's a Transducer? 17 | 18 | To recap that earlier post: 19 | 20 | A reducing function is just the kind of function you'd pass to `reduce` - it takes a result so far and a new input and returns the next result-so-far. In the context of transducers it's best to think about this most generally: 21 | 22 | [source] 23 | ---- 24 | ;;reducing function signature 25 | whatever, input -> whatever 26 | ---- 27 | 28 | and a transducer is a function that takes one reducing function and returns another: 29 | 30 | [source,clojure] 31 | ---- 32 | ;;transducer signature 33 | (whatever, input -> whatever) -> (whatever, input -> whatever) 34 | ---- 35 | 36 | The primary power of transducers comes from their fundamental decoupling - they don't care (or know about): 37 | 38 | * the 'job' being done (what the reducing function does) 39 | * the context of use (what 'whatever' is) 40 | * the source of inputs (where input comes from). 41 | 42 | The other source of power comes from the fact that transducers compose using ordinary function composition. 43 | 44 | The reducers library leverages transducers' decoupling from the job, the representation, and the source of inputs to accomplish parallel reduction. But transducers can also be used for: 45 | 46 | * a la carte laziness 47 | * transformations during collection building 48 | * collection/iteration/laziness-free transforming reductions 49 | * channel transformations, event notifications and more. 50 | 51 | All of this is coming to Clojure core and core.async. 52 | 53 | == New stuff 54 | 55 | Concretely, most of the core sequence functions are gaining a new arity, one shorter than their current shortest, which elides the final collection source argument. This arity will return a transducer that represents the same logic, independent of lazy sequence processing. 56 | 57 | Thus: 58 | 59 | [source,clojure] 60 | ---- 61 | ;;look Ma, no collection! 62 | (map f) 63 | ---- 64 | 65 | returns a 'mapping' transducer. filter et al get similar support. 66 | 67 | You can build a 'stack' of transducers using ordinary function composition (comp): 68 | 69 | [source,clojure] 70 | ---- 71 | (def xform (comp (map inc) (filter even?))) 72 | ---- 73 | 74 | You might notice the similarity between the above comp and a call to ->>: 75 | 76 | [source,clojure] 77 | ---- 78 | (->> aseq (map inc) (filter even?)) 79 | ---- 80 | 81 | One way to think of transducers is like ->> but independent of the job (lazy sequence creation) and the source of inputs (aseq). 82 | 83 | == Transducers in action 84 | 85 | Once you've got a transducer, what can you do with it? _**An open set of things.**_ 86 | 87 | For instance, given the above transducer and some data in a vector, you can: 88 | 89 | * lazily transform the data (one lazy sequence, not three as with composed sequence functions) + 90 | [source,clojure] 91 | ---- 92 | (sequence xform data) 93 | ---- 94 | * reduce with a transformation (no laziness, just a loop) + 95 | [source,clojure] 96 | ---- 97 | (transduce xform + 0 data) 98 | ---- 99 | * build one collection from a transformation of another, again no laziness + 100 | [source,clojure] 101 | ---- 102 | (into [] xform data) 103 | ---- 104 | * create a recipe for a transformation, which can be subsequently sequenced, iterated or reduced + 105 | [source,clojure] 106 | ---- 107 | (iteration xform data) 108 | ---- 109 | * or use the same transducer to transform everything that goes through a channel + 110 | [source,clojure] 111 | ---- 112 | (chan 1 xform) 113 | ---- 114 | 115 | The latter demonstrates the corresponding new capability of core.async channels - they can take transducers. 116 | 117 | This post is just to serve as a heads up on what the ongoing work is about. There will be more explanations, tutorials and derivations to follow, here and elsewhere. 118 | 119 | I'm excited about transducers and the power they bring, and I hope you are too! 120 | 121 | Rich -------------------------------------------------------------------------------- /content/privacy.adoc: -------------------------------------------------------------------------------- 1 | = Privacy 2 | Rich Hickey 3 | 2015-01-01 4 | :jbake-type: page 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | == Privacy Policy 11 | 12 | This website is administered by Cognitect, Inc. and our Privacy Policy explains how we collect and use the personal information you provide to us and to assist you in making informed decisions when using our site and services. By visiting the site, you expressly consent to the use and disclosure of your information as described below. We will neither sell personal or anonymous data to any third party, nor distribute personal data to a third party for any reason other than as may be required by law. 13 | 14 | == Types of information we collect 15 | 16 | We may collect, store and use personal data about your visits to and use of this website. Additionally, we may collect, store, and use personal data such as your name, email address, and phone number that you submit to us. By submitting such information, you authorize Cognitect to contact you with more information about our business services. 17 | 18 | We may collect, store and use non-personal data about your visits to and use of this website. We may collect information about your computer and your visits to this website such as your IP address, geographical location, browser type, referral source, length of visit and number of page views. We may use this information in the administration of this website, to improve the website’s usability, and for marketing purposes regarding our business services. 19 | 20 | We use cookies on this website. A cookie is a text file sent by a web server to a web browser, and stored by the browser. The text file is then sent back to the server each time the browser requests a page from the server. This enables the web server to identify and track the web browser. 21 | 22 | We may send a cookie which may be stored on by your browser on your computer’s hard drive. We may use the information we obtain from the cookie in the administration of this website, to improve the website’s usability and for marketing purposes. We may also use that information to recognize your computer when you visit our website, and to personalize our website for you. 23 | 24 | We may use anonymous cookies to record non-personal information such as website activity, date and time of visit, and domain type. We may use this information for retargeting purposes. Most browsers allow you to refuse to accept cookies. (For example, in Internet Explorer you can refuse all cookies by clicking “Tools”, “Internet Options”, “Privacy”, and selecting “Block all cookies” using the sliding selector.) This may have a negative impact upon the usability of many websites, including this one. 25 | 26 | == Using your personal data 27 | 28 | Personal data submitted on this website will be used for the purposes specified in this privacy policy. In addition to the uses identified elsewhere in this privacy policy, we may use your personal information to improve your browsing experience by personalizing the website or send you information (other than marketing communications) which we think may be of interest as well as marketing communications relating to our business. If you wish to opt-out of receiving such communications you may do so by contacting us at <>. 29 | 30 | == Using your non-personal data 31 | 32 | Non-personal data may be collected and shared with 3rd party services to provide relevant and targeted advertisements through retargeting. All data is anonymous and cannot be used to identify the visitor. Retargeting recognizes that the internet browser has visited the website in the last 90 days. If you would like to not participate in retargeting, you may opt-out by contacting us at <>. 33 | 34 | == Other disclosures 35 | 36 | In addition to the disclosures reasonably necessary for the purposes identified elsewhere in this privacy policy, we may disclose information about you to the extent that we are required to do so by law in connection with any legal proceedings or prospective legal proceedings or in order to establish, exercise or defend our legal rights (including providing information to others for the purposes of fraud prevention and reducing credit risk). 37 | 38 | == Security of your personal data 39 | 40 | We will take reasonable precautions and follow industry standard security protocols to prevent the loss, misuse or alteration of your personal information. Of course, data transmission over the Internet is inherently insecure, and we cannot guarantee the security of data sent over the Internet. 41 | 42 | == Policy updates 43 | 44 | We may update this privacy policy when appropriate by posting a new version on our website, and will update the "Last Updated" date to reflect the date the changes take effect. By continuing to use this site after we post any such changes, you are indicating acceptance of the current privacy policy. 45 | 46 | == Contact 47 | If you have any questions about this privacy policy or our treatment of your personal data, or wish to opt-out of data collection by this site, please email us at <>, or send mail to Cognitect, Inc., 303 S. Roxboro St. Suite #20, Durham, NC 27701. 48 | 49 | _Last Updated: 7/07/2014_ 50 | -------------------------------------------------------------------------------- /content/reference/evaluation.adoc: -------------------------------------------------------------------------------- 1 | = Evaluation 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: repl_and_main 8 | :prevpagetitle: REPL and main 9 | :nextpagehref: special_forms 10 | :nextpagetitle: Special Forms 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | Evaluation can occur in many contexts: 15 | 16 | * Interactively, in the REPL 17 | * On a sequence of forms read from a stream, via `load` / `load-file` / `load-reader` / `load-string` 18 | * Programmatically, via `eval` 19 | 20 | Clojure programs are composed of expressions. Every form not handled specially by a special form or macro is considered by the compiler to be an expression, which is evaluated to yield a value. There are no declarations or statements, although sometimes expressions may be evaluated for their side-effects and their values ignored. 21 | In all cases, evaluation is the same - a single object is considered by the compiler, evaluated, and its result returned. If an expression needs to be compiled, it will be. There is no separate compilation step, nor any need to worry that a function you have defined is being interpreted. _Clojure has no interpreter_. 22 | 23 | Strings, numbers, characters, `true`, `false`, `nil` and keywords evaluate to themselves. 24 | 25 | A Symbol is _resolved_: 26 | 27 | * If it is namespace-qualified, the value is the value of the binding of the global var named by the symbol. It is an error if there is no global var named by the symbol, or if the reference is to a non-public var in a different namespace. 28 | * If it is package-qualified, the value is the Java class named by the symbol. It is an error if there is no Class named by the symbol. 29 | * Else, it is not qualified and the first of the following applies: 30 | . If it names a special form it is considered a special form, and must be utilized accordingly. 31 | . A lookup is done in the current namespace to see if there is a mapping from the symbol to a class. If so, the symbol is considered to name a Java class object. Note that class names normally denote class objects, but are treated specially in certain special forms, e.g. `.` and `new`. 32 | . If in a local scope (i.e. in a function definition), a lookup is done to see if it names a local binding (e.g. a function argument or let-bound name). If so, the value is the value of the local binding. 33 | . A lookup is done in the current namespace to see if there is a mapping from the symbol to a var. If so, the value is the value of the binding of the var referred-to by the symbol. 34 | . It is an error. 35 | 36 | If a Symbol has metadata, it may be used by the compiler, but will not be part of the resulting value. 37 | 38 | Vectors, Sets and Maps yield vectors and (hash) sets and maps whose contents are the _evaluated values_ of the objects they contain. Vector elements are evaluated left to right, Sets and Maps are evaluated in an undefined order. The same is true of metadata maps. If the vector or map has metadata, the _evaluated_ metadata map will become the metadata of the resulting value. 39 | 40 | [source,clojure-repl] 41 | ---- 42 | user=> (def x 1) 43 | user=> (def y 2) 44 | user=> ^{:x x} [x y 3] 45 | ^{:x 1} [1 2 3] 46 | ---- 47 | 48 | An empty list `()` evaluates to an empty list. 49 | 50 | Non-empty Lists are considered _calls_ to either special forms, macros, or functions. A call has the form +(operator operands*)+. 51 | 52 | Special forms are primitives built-in to Clojure that perform core operations. If the operator of a call is a symbol that resolves to the name of a special form, the call is to that special form. Each form discussed individually under <>. 53 | 54 | <> are functions that manipulate forms, allowing for syntactic abstraction. If the operator of a call is a symbol that names a global var that is a macro function, that macro function is called and is passed the _unevaluated_ operand forms. The return value of the macro is then evaluated in its place. 55 | 56 | If the operator is not a special form or macro, the call is considered a function call. Both the operator and the operands (if any) are evaluated, from left to right. The result of the evaluation of the operator is then cast to IFn (the interface representing Clojure functions), and invoke() is called on it, passing the evaluated arguments. The return value of invoke() is the value of the call expression. If the function call form has metadata, it may be used by the compiler, but will not be part of the resulting value. 57 | Note that special forms and macros might have other-than-normal evaluation of their arguments, as described in their entries under <>. 58 | 59 | Any object other than those discussed above will evaluate to itself. 60 | 61 | '''' 62 | 63 | *(_load_ classpath-resource ...)* + 64 | *(_load-file_ filename)* + 65 | *(_load-reader_ reader)* + 66 | *(_load-string_ string)* 67 | 68 | The above describes the evaluation of a single form. The various load forms will sequentially read and evaluate the set of forms contained in the source. Such sets of forms usually have side effects, often on the global environment, defining functions etc. 69 | 70 | The loading functions occur in a temporary context, in which +*ns*+ has a fresh binding. That means that, should any form have an effect on that var (e.g. +in-namespace+), the effect will unwind at the completion of the load. load et al return the value produced by the last expression. 71 | 72 | '''' 73 | 74 | *(_eval_ form)* 75 | 76 | Evaluates the form _data structure_ (not text!) and returns the result. 77 | 78 | [source,clojure] 79 | ---- 80 | (eval (list + 1 2 3)) 81 | -> 6 82 | ---- 83 | 84 | -------------------------------------------------------------------------------- /content/community/editing.adoc: -------------------------------------------------------------------------------- 1 | = Editing 2 | Alex Miller 3 | 2015-09-29 4 | :jbake-type: page 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | This page covers helpful Asciidoc editing tips for writing content on this site. It does not cover every feature of Asciidoc, just the ones that have come up most commonly while writing content on this site. 11 | 12 | == File metadata 13 | 14 | Every file should start with a metadata block that looks like this: 15 | 16 | ---- 17 | = Mechanical Computing 18 | Ada Lovelace 19 | 2015-12-31 20 | :jbake-type: page 21 | :toc: macro 22 | ---- 23 | 24 | The first lines indicate the title, author, and creation date. The last two lines are necessary boilerplate metadata attributes. 25 | 26 | == Headers 27 | 28 | == h2 29 | 30 | ---- 31 | == h2 32 | ---- 33 | 34 | === h3 35 | 36 | ---- 37 | === h3 38 | ---- 39 | 40 | ==== h4 41 | 42 | ---- 43 | ==== h4 44 | ---- 45 | 46 | == Text markup 47 | 48 | [cols="<*,", options="header"] 49 | |=== 50 | | markup | effect 51 | | pass:[_italic_] | _italic_ 52 | | pass:[*bold*] | *bold* 53 | | pass:[_**italic and bold**_] | _**italic and bold**_ 54 | | pass:[`inline code`] | `inline code` 55 | | pass:[(C) (R) (TM)] | (C) (R) (TM) 56 | | pass:[-- ...] | -- ... 57 | | pass:[-> <- => <=] | -> <- => <= 58 | |=== 59 | 60 | To get a line break without a paragraph change, append + to the end of the line: 61 | 62 | ---- 63 | force + 64 | line break 65 | ---- 66 | 67 | force + 68 | line break 69 | 70 | '''' 71 | 72 | If you have many lines in a row that will need breaks you can prefix them with pass:[[%hardbreaks]]: 73 | 74 | ---- 75 | [%hardbreaks] 76 | first line 77 | second line 78 | ---- 79 | 80 | [%hardbreaks] 81 | first line 82 | second line 83 | 84 | '''' 85 | 86 | There are a number of ways to handle escaping in Asciidoc but one of the most helpful is to omit all formatting by using: 87 | 88 | ---- 89 | pass:[*ns*] 90 | ---- 91 | 92 | pass:[*ns*] 93 | 94 | == Links 95 | 96 | Create an anchor in a page: 97 | 98 | ---- 99 | [[dot]] 100 | ---- 101 | 102 | '''' 103 | 104 | Link to another internal page (note the trailing # after the page - this is required in our generator!): 105 | 106 | ---- 107 | <> 108 | ---- 109 | 110 | <> 111 | 112 | There is a bug in the parser used in the current version of JBake for links to a page in a parent directory. For example, to link to a page at ../reference/java_interop.adoc, you can use a link like this: 113 | 114 | ---- 115 | <> 116 | ---- 117 | 118 | This goes to a (fictitious) subdirectory xref, then back a directory, and then finally the path you wish to follow. While the choice of "xref" here is arbitrary, please use only this string so that we can more easily find and update these upward cross references later when there is a version that fixes this issue. 119 | 120 | '''' 121 | 122 | Link to an anchor in an internal page: 123 | 124 | ---- 125 | <> 126 | ---- 127 | 128 | <> 129 | 130 | '''' 131 | 132 | Link to an external page: 133 | 134 | ---- 135 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn[defn] 136 | ---- 137 | 138 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn[defn] 139 | 140 | == Images 141 | 142 | Images should be placed in the assets/images/content directory in a subdirectory corresponding to the page location. 143 | 144 | Reference the image in a page as follows: 145 | 146 | ---- 147 | image::/images/content/reference/transducers/xf.png[Nested transformations] 148 | ---- 149 | 150 | image::/images/content/reference/transducers/xf.png[Nested transformations] 151 | 152 | == Code blocks 153 | 154 | You can insert a Clojure formatted code block as follows: 155 | 156 | .... 157 | [source,clojure] 158 | ---- 159 | (defn hey 160 | [] 161 | (println "hey")) 162 | ---- 163 | .... 164 | 165 | [source,clojure] 166 | ---- 167 | (defn hey 168 | [] 169 | (println "hey")) 170 | ---- 171 | 172 | == Lists 173 | 174 | There are a lot of options for creating lists. Only the most common ones are shown here: 175 | 176 | Bulleted lists: 177 | 178 | ---- 179 | * first 180 | * second 181 | ** nested 182 | *** more nested 183 | ---- 184 | 185 | * first 186 | * second 187 | ** nested 188 | *** more nested 189 | 190 | Ordered lists: 191 | 192 | ---- 193 | . a 194 | . b 195 | .. b.1 196 | ... b.1.a 197 | ---- 198 | 199 | . a 200 | . b 201 | .. b.1 202 | ... b.1.a 203 | 204 | Mixed lists: 205 | 206 | ---- 207 | * a 208 | . a.1 209 | . a.2 210 | * b 211 | . b.1 212 | . b.2 213 | ---- 214 | 215 | * a 216 | . a.1 217 | . a.2 218 | * b 219 | . b.1 220 | . b.2 221 | 222 | Use the line break advice from the text formatting section to create lists with multi-line items. 223 | 224 | == Tables 225 | 226 | Tables are another large Asciidoc topic with extensive formatting options. This is a basic table example however: 227 | 228 | ---- 229 | [options="header"] 230 | |=== 231 | | col1 | col2 232 | | a | b 233 | | b | c 234 | |=== 235 | ---- 236 | 237 | [options="header"] 238 | |=== 239 | | col1 | col2 240 | | a | b 241 | | b | c 242 | |=== 243 | 244 | == Other 245 | 246 | Horizontal rule: 247 | 248 | ---- 249 | '''' 250 | ---- 251 | 252 | Insert table of contents, which should generally be done at the top of your file (the page template will position this appropriately): 253 | 254 | ---- 255 | toc::[] 256 | ---- 257 | 258 | 259 | == More resources 260 | 261 | Asciidoc is an extensive language and there is likely some way to do anything you want to do. Below are some more Asciidoc resources to answer more advanced questions. 262 | 263 | * http://powerman.name/doc/asciidoc[Asciidoc cheat sheet] 264 | * http://asciidoctor.org/docs/user-manual[Asciidoctor user manual] 265 | -------------------------------------------------------------------------------- /content/reference/reducers.adoc: -------------------------------------------------------------------------------- 1 | = Reducers 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: atoms 8 | :prevpagetitle: Atoms 9 | :nextpagehref: java_interop 10 | :nextpagetitle: Java Interop 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | toc::[] 15 | 16 | Reducers provide an alternative approach to using <> to manipulate standard Clojure collections. Sequence functions are typically applied lazily, in order, create intermediate results, and in a single thread. However, many sequence functions (like map and filter) could conceptually be applied in parallel, yielding code that will get faster automatically as machines get more cores. For more details on the rationale for reducers, see the original http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html[blog] http://clojure.com/blog/2012/05/15/anatomy-of-reducer.html[posts]. 17 | 18 | A _reducer_ is the combination of a _reducible collection_ (a collection that knows how to reduce itself) with a _reducing function_ (the "recipe" for what needs to be done during the reduction). The standard sequence operations are replaced with new versions that do not perform the operation but merely transform the reducing function. Execution of the operations is deferred until the final reduction is performed. This removes the intermediate results and lazy evaluation seen with sequences. 19 | 20 | Additionally, some collections (persistent vectors and maps) are _foldable_. The _fold_ operation on a reducer executes the reduction in parallel by: 21 | 22 | . Partitioning the reducible collection at a specified granularity (default = 512 elements) 23 | . Applying reduce to each partition 24 | . Recursively combining each partition using Java's http://gee.cs.oswego.edu/dl/papers/fj.pdf[fork/join] framework. 25 | 26 | If a collection does not support folding, it will fall back to non-parallel reduce instead. 27 | 28 | == reduce and fold 29 | 30 | The *clojure.core.reducers* namespace (aliased here as *r*) provides an alternate http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/reduce[r/reduce] function. 31 | 32 | [%hardbreaks] 33 | *(r/reduce f coll)* 34 | *(r/reduce f init coll)* 35 | 36 | The reducers version differs in that: 37 | 38 | * Map colls are reduced with reduce-kv 39 | * When init is not provided, f is invoked with no arguments to produce an identity value 40 | ** _Note: f may be invoked multiple times to provide the identity value_ 41 | 42 | In general most users will not call r/reduce directly and instead should prefer http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/fold[r/fold], which implements parallel reduce and combine. However, it may be useful to execute an eager reduce with fewer intermediate results. 43 | 44 | [%hardbreaks] 45 | *(r/fold reducef coll)* 46 | *(r/fold combinef reducef coll)* 47 | *(r/fold n combinef reducef coll)** 48 | 49 | r/fold takes a reducible collection and partitions it into groups of approximately n (default 512) elements. Each group is reduced using the reducef function. The reducef function will be called with no arguments to produce an identity value _in each partition_. The results of those reductions are then reduced with the combinef (defaults to reducef) function. When called with no arguments, (combinef) must produce its identity element - this will be called multiple times. Operations may be performed in parallel. Results will preserve order. 50 | 51 | The following functions (analagous to the sequence versions) create reducers from a reducible or foldable collection: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/map[r/map] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/mapcat[r/mapcat] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/filter[r/filter] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/remove[r/remove] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/flatten[r/flatten] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/take-while[r/take-while] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/take[r/take] and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/drop[r/drop]. None of these functions actually transforms the source collection. To produce an accumulated result, you must use r/reduce or r/fold. To produce an output collection, use http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/into[clojure.core/into] to choose the collection type or the provided http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/foldcat[r/foldcat] to produce a collection that is reducible, foldable, seqable, and counted. 52 | 53 | == Using Reducers 54 | 55 | Use fold to sum with +: 56 | [source,clojure] 57 | ---- 58 | (require '[clojure.core.reducers :as r]) 59 | (r/fold + (r/filter even? (r/map inc [1 1 1 2]))) 60 | ;=> 6 61 | ---- 62 | Use http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/into[into] to produce a final collection: 63 | [source,clojure] 64 | ---- 65 | (into [] (r/filter even? (r/map inc (range 100000)))) 66 | ---- 67 | Or http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/foldcat[r/foldcat]: 68 | [source,clojure] 69 | ---- 70 | (r/foldcat (r/filter even? (r/map inc (range 100000)))) 71 | ---- 72 | Specify a reduce function and a combine function with fold: 73 | [source,clojure] 74 | ---- 75 | (defn count-words 76 | ([] {}) 77 | ([freqs word] 78 | (assoc freqs word (inc (get freqs word 0))))) 79 | 80 | (defn merge-counts 81 | ([] {}) 82 | ([& m] (apply merge-with + m))) 83 | 84 | (defn word-frequency [text] 85 | (r/fold merge-counts count-words (clojure.string/split text #"\s+"))) 86 | ---- 87 | == When to use 88 | Use the reducer form of these operations when: 89 | 90 | * Source data can be generated and held in memory 91 | * Work to be performed is computation (not I/O or blocking) 92 | * Number of data items or work to be done is "large" 93 | -------------------------------------------------------------------------------- /content/community/contributing.adoc: -------------------------------------------------------------------------------- 1 | = Contributing to Clojure 2 | Rich Hickey 3 | 2015-01-01 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | Following the lead of other open source projects, the Clojure project requires contributors to jointly assign their copyright on contributed code. The https://secure.echosign.com/public/hostedForm?formid=95YMDL576B336E[Contributor Agreement] (CA) gives Rich Hickey and the contributor joint copyright interests in the code: the contributor retains copyrights while also granting those rights to Rich Hickey as the open source project sponsor. 11 | 12 | The CA is derived from the Oracle Contributor Agreement (OCA), used for OpenJDK, Netbeans and OpenSolaris projects and others. There is a good http://www.oracle.com/technetwork/oca-faq-405384.pdf[OCA FAQ] answering many questions. 13 | 14 | The CA does not change the rights or responsibilities of the Clojure community under the http://opensource.org/licenses/eclipse-1.0.php[Eclipse Public License (EPL)]. By executing the CA, contributors protect the Clojure code base, enable alternative licensing models, and protect the flexibility to adapt the project to the changing demands of the community. In order for the CA to be effective, the Clojure project must obtain an assignment for all contributions. Please review the CA for a complete understanding of its terms and conditions. By contributing source code or other material to Clojure, you represent that you have a CA with Rich Hickey for such contributions. In order to track contributors, you understand that your full name and username may be posted on a web page listing authorized contributors that is accessible via a public URL. 15 | 16 | == Instructions for submitting the agreement 17 | 18 | * Fill out and submit the https://secure.echosign.com/public/hostedForm?formid=95YMDL576B336E[Contributor Agreement] (an online e-form) 19 | 20 | == Making a contribution 21 | 22 | Before you invest time working on a change, discuss what you're trying to do with others on the http://groups.google.com/group/clojure-dev[Clojure Dev Google group]. They're likely to be able to offer comments and suggestions that will result in a higher-quality change and a smoother submission process. Announcing that you're working on a particular item can also help to avoid wasted effort in case someone else is already working on it. Once you've submitted the CA, you can http://dev.clojure.org/jira/browse/CLJ[submit patches via JIRA]. Frequent and trusted contributors of more substantial libraries may be granted committer membership in the Clojure contrib projects. 23 | 24 | Please see the http://dev.clojure.org/display/community/Contributing[Contributing] wiki for a collection of resources on tickets, builds, patches, source, and more. If you'd like to submit a patch, please follow these guidelines on the http://dev.clojure.org/display/community/JIRA+workflow[preferred process for submitting]. 25 | 26 | [[contributors]] 27 | == Contributors 28 | 29 | See the full <> that have signed the Clojure Contributor Agreement. 30 | 31 | [[patches]] 32 | == Contributed patches to Clojure: 33 | 34 | * Aaron Bedra 35 | * Aaron Cohen 36 | * Achim Passen 37 | * Alan Dipert 38 | * Alan Malloy 39 | * Alex Miller 40 | * Alex Osborne 41 | * Alex Ott 42 | * Alex Redington 43 | * Alexander Taggart 44 | * Alexander Yakushev 45 | * Alf Kristian Stoyle 46 | * Allen Rohner 47 | * Ambrose Bonnaire-Sergeant 48 | * Andrei Kleschinski 49 | * Andrew Rosa 50 | * Andy Fingerhut 51 | * Andy Sheldon 52 | * Anthony Grimes 53 | * Aspasia Beneti 54 | * Baishampayan Ghose 55 | * Ben Smith-Mannschott 56 | * Benjamin Teuber 57 | * Blake West 58 | * Bozhidar Batsov 59 | * Brandon Bloom 60 | * Brenton Ashworth 61 | * Brian Hurt 62 | * Brian Taylor 63 | * Bruce Adams 64 | * Chas Emerick 65 | * Chris Gray 66 | * Chris Houser 67 | * Chris Perkins 68 | * Christoffer Sawicki 69 | * Christophe Grand 70 | * Christopher Redinger 71 | * Clinton R. Nixon 72 | * Colin Jones 73 | * Cosmin Stejerean 74 | * Daniel Compton 75 | * Daniel Solano Gómez 76 | * David Liebke 77 | * David McNeil 78 | * David Miller 79 | * David Powell 80 | * David Rupp 81 | * David Santiago 82 | * Devender Gollapally 83 | * Devin Walters 84 | * Dimitry Gashinsky 85 | * Drew Raines 86 | * Ed Bowler 87 | * Eric Schoonover 88 | * Erik Assum 89 | * Federico Brubacher 90 | * Frantisek Sodomka 91 | * Gabriel Horner 92 | * Gary Fredericks 93 | * George Jahad 94 | * Ghadi Shayban 95 | * Gordon Syme 96 | * Herwig Hochleitner 97 | * Howard Lewis Ship 98 | * Hubert Iwaniuk 99 | * Hugo Duncan 100 | * Immo Heikkinen 101 | * James Reeves 102 | * Jarkko Oranen 103 | * Jason Wolfe 104 | * Jean Niklas L'orange 105 | * Jeremy Heiler 106 | * Joe Gallo 107 | * John Szakmeister 108 | * Jonas Enlund 109 | * Jozef Wagner 110 | * Juha Arpiainen 111 | * Justin Balthrop 112 | * Justin Kramer 113 | * Karsten Schmidt 114 | * Kevin Downey 115 | * Konrad Hinsen 116 | * Kurt Harriger 117 | * Laurent Petit 118 | * Lauri Pesonen 119 | * Luke VanderHart 120 | * Mark Simpson 121 | * Matt Revelle 122 | * Max Penet 123 | * Meikel Brandmeyer 124 | * Micah Martin 125 | * Michael Blume 126 | * Michael Fogus 127 | * Michał Marczyk 128 | * Michel Alexandre Salim 129 | * Mike Anderson 130 | * Mike Hinchey 131 | * Nahuel Greco 132 | * Nicola Mometto 133 | * Nicolas Buduroi 134 | * Nikita Prokopov 135 | * Nola Stowe 136 | * Paul M Bauer 137 | * Paul Stadig 138 | * Pepijn de Vos 139 | * Phil Hagelberg 140 | * Philip Aston 141 | * Philip Potter 142 | * Ragnar Dahlén 143 | * Ralf Schmitt 144 | * Rasmus Svensson 145 | * Rich Hickey 146 | * Richard Newman 147 | * Robert Lachlan 148 | * Russ Olsen 149 | * Scott Lowe 150 | * Sean Devlin 151 | * Shogo Ohta 152 | * Stefan Kamphausen 153 | * Stephen C. Gilardi 154 | * Steve Miner 155 | * Steven Yi 156 | * Stuart Halloway 157 | * Stuart Sierra 158 | * Tassilo Horn 159 | * Tim Dysinger 160 | * Tim McCormack 161 | * Timothy Baldridge 162 | * Timothy Pratley 163 | * Toby Crawley 164 | * Tom Faulhaber 165 | * Tomasz Nurkiewicz 166 | * Tsutomu Yano 167 | * Vipul Amler 168 | * Yanxiang Lou 169 | * Zach Tellman 170 | 171 | _**Many thanks for your contributions to Clojure!**_ 172 | -------------------------------------------------------------------------------- /content/reference/other_functions.adoc: -------------------------------------------------------------------------------- 1 | = Other Useful Functions and Macros 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :toclevels: 1 7 | :icons: font 8 | :navlinktext: Other Functions 9 | :prevpagehref: macros 10 | :prevpagetitle: Macros 11 | :nextpagehref: data_structures 12 | :nextpagetitle: Data Structures 13 | 14 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 15 | 16 | toc::[] 17 | 18 | [%hardbreaks] 19 | Boolean and comparison functions: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/=[=] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/==[==] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/identical?[identical?] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not=[not=] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not[not] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/true?[true?] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/false?[false?] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/nil?[nil?] 20 | Miscellaneous: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/identity[identity] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dotimes[dotimes] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/time[time] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/assert[assert] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-open[with-open] 21 | 22 | [[creating-functions]] 23 | == Creating functions 24 | 25 | [cols="<*,", options="header", role="table"] 26 | |=== 27 | | Function | Example expression | Return value | 28 | | <> | `(map (fn [x] (+ 2 x)) [1 2 3])` | `(3 4 5)` | 29 | | pass:[#()] <> macro | `(map #(+ 2 %) [1 2 3])` | `(3 4 5)` | 30 | | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/partial[partial] | `(map (partial + 2) [1 2 3])` | `(3 4 5)` | 31 | | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/comp[comp] | `(map (comp - *) [2 4 6] [1 2 3])` | `(-2 -8 -18)` | 32 | | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/complement[complement] | `(map (complement zero?) [3 2 1 0])` | `(true true true false)` | 33 | | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/constantly[constantly] | `(map (constantly 9) [1 2 3])` | `(9 9 9)` | 34 | |=== 35 | 36 | [[printing]] 37 | == Printing 38 | 39 | Several functions are provided to print objects to the output stream that is the current value of *out*. The -str versions bind *out* to a StringWriter, print to that, and return the resulting string. http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/pr[pr] prints the object(s), separated by spaces if there is more than one. http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/prn[prn] does the same and follows it with a http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/newline[newline]. http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/print[print] and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/println[println] call http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/pr[pr] and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/prn[prn] respectively, with `pass:[*print-readably*]` (which defaults to true) bound to nil, which causes strings to print without surrounding quotes or any escape character encoding, and characters to print without the leading '\', or any escape character encoding. By default, http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/pr[pr] and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/prn[prn] print in a way that objects can be read by the reader, while http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/print[print] and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/println[println] produce output for human consumption. When `pass:[*print-readably*]` is non-nil, the printing of metadata is toggled by `pass:[*print-meta*]`, which defaults to nil. 40 | 41 | === Related functions 42 | 43 | [%hardbreaks] 44 | Print to pass:[*out*]: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/pr[pr] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/prn[prn] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/print[print] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/println[println] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/newline[newline] 45 | Print to string: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/pr-str[pr-str] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/prn-str[prn-str] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/print-str[print-str] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/println-str[println-str] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-out-str[with-out-str] 46 | 47 | [[regex]] 48 | == Regex Support 49 | 50 | Regex patterns can be compiled at read-time via the `#"pattern"` reader macro, or at run time with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/re-pattern[re-pattern]. Both forms produce http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html[java.util.regex.Pattern] objects. 51 | 52 | [source,clojure-repl] 53 | ---- 54 | user=> (re-seq #"[0-9]+" "abs123def345ghi567") 55 | ("123" "345" "567") 56 | user=> (re-find #"([-+]?[0-9]+)/([0-9]+)" "22/7") 57 | ["22/7" "22" "7"] 58 | user=> (let [[a b c] (re-matches #"([-+]?[0-9]+)/([0-9]+)" "22/7")] 59 | [a b c]) 60 | ["22/7" "22" "7"] 61 | user=> (re-seq #"(?i)[fq].." "foo bar BAZ QUX quux") 62 | ("foo" "QUX" "quu") 63 | ---- 64 | 65 | === Related functions 66 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/re-matcher[re-matcher] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/re-find[re-find] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/re-matches[re-matches] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/re-groups[re-groups] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/re-seq[re-seq] 67 | -------------------------------------------------------------------------------- /content/reference/other_libraries.adoc: -------------------------------------------------------------------------------- 1 | = Other Included Libraries 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: Other Libraries 8 | :prevpagehref: compilation 9 | :prevpagetitle: Compilation and Class Generation 10 | :nextpagehref: lisps 11 | :nextpagetitle: Differences with Lisps 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | toc::[] 16 | 17 | == Other included Libraries 18 | 19 | == Java Utilities (clojure.java.*) 20 | 21 | **http://clojure.github.io/clojure/clojure.java.io-api.html[clojure.java.io]** 22 | Contains polymorphic I/O utility functions for Clojure backed by Java classes. 23 | 24 | **http://clojure.github.io/clojure/clojure.java.javadoc-api.html[clojure.java.javadocs]** 25 | 26 | Provides the function http://clojure.github.io/clojure/clojure.java.javadoc-api.html#clojure.java.javadoc/javadoc[javadoc] that attempts to display the appropriate Javadocs for a class or instance class. 27 | 28 | **http://clojure.github.io/clojure/clojure.java.shell-api.html[clojure.java.shell]** 29 | 30 | Provides a http://clojure.github.io/clojure/clojure.java.shell-api.html#clojure.java.shell/sh[sh] function that facilitates launching and managing subprocesses. See the function documentation for details on its expected arguments. 31 | 32 | == Parallel Processing (DEPRECATED) 33 | 34 | The parallel library (namespace _**parallel**_, in parallel.clj) wraps the http://gee.cs.oswego.edu/dl/concurrency-interest/index.html[ForkJoin library]. This lib is now deprecated. 35 | 36 | You'll need `jsr166y.jar` in your classpath in order to use this library. The basic idea is that Clojure collections, and most efficiently vectors, can be turned into parallel arrays for use by this library with the function par, although most of the functions take collections and will call _**par**_ if needed, so normally you will only need to call par explicitly in order to attach bound/filter/map ops. 37 | 38 | Parallel arrays support the attachment of bounds, filters and mapping functions prior to realization/calculation, which happens as the result of any of several operations on the array (pvec/psort/pfilter-nils/pfilter-dupes). Rather than perform composite operations in steps, as would normally be done with sequences, maps and filters are instead attached and thus composed by providing ops to _**par**_. Note that there is an order sensitivity to the attachments - bounds precede filters precede mappings. All operations then happen in parallel, using multiple threads and a sophisticated work-stealing system supported by fork-join, either when the array is realized, or to perform aggregate operations like preduce/pmin/pmax etc. 39 | 40 | A parallel array can be realized into a Clojure vector using pvec 41 | 42 | [source,clojure] 43 | ---- 44 | (load-file "src/parallel.clj") 45 | (refer 'parallel) 46 | 47 | (def f (vec (take 20 (repeatedly #(rand-int 20))))) 48 | 49 | f 50 | -> [11 7 10 9 4 1 4 18 15 13 10 7 0 9 16 6 19 11 14 7] 51 | 52 | ;return value/index pairs of all entries < their index, in parallel 53 | 54 | (pvec (par f :filter-index < :map-index vector)) 55 | -> [[1 5] [4 6] [7 11] [0 12] [9 13] [6 15] [11 17] [14 18] [7 19]] 56 | ---- 57 | 58 | == Reflection Utilities (http://clojure.github.io/clojure/clojure.reflect-api.html[clojure.reflect]) 59 | 60 | Provides functions and protocols useful for gathering and building host type reflection information as Clojure data. 61 | 62 | == REPL Utilities (http://clojure.github.io/clojure/clojure.repl-api.html[clojure.repl]) 63 | 64 | Utilities meant to be used interactively at the REPL. 65 | 66 | == Sets and Relational Algebra (http://clojure.github.io/clojure/clojure.set-api.html[clojure.set]) 67 | 68 | Functions useful for manipulating, building, and querying mathematical sets using relational algebra. 69 | 70 | == String Handling (http://clojure.github.io/clojure/clojure.string-api.html[clojure.string]) 71 | 72 | Functions for manipulating strings. 73 | 74 | == Unit Testing (http://clojure.github.io/clojure/clojure.test-api.html[clojure.test]) 75 | 76 | A Clojure unit testing framework. 77 | 78 | == Walking Data Structures (http://clojure.github.io/clojure/clojure.walk-api.html[clojure.walk]) 79 | 80 | Utilities for traversing and manipulating nested data structures. 81 | 82 | == XML (http://clojure.github.io/clojure/clojure.xml-api.html[clojure.xml]) 83 | 84 | Utilities for reading and writing XML data. 85 | 86 | == Zippers - Functional Tree Editing (http://clojure.github.io/clojure/clojure.zip-api.html[clojure.zip]) 87 | 88 | Clojure includes purely functional, generic tree walking and editing, using a technique called a zipper (in namespace _**zip**_) . For background, see the http://www.google.com/search?q=huet%20functional%20zipper[paper by Huet]. A zipper is a data structure representing a location in a hierarchical data structure, and the path it took to get there. It provides down/up/left/right navigation, and localized functional 'editing', insertion and removal of nodes. With zippers you can write code that looks like an imperative, destructive walk through a tree, call http://clojure.github.io/clojure/clojure.zip-api.html#clojure.zip/root[root] when you are done and get a new tree reflecting all the changes, when in fact nothing at all is mutated - it's all thread safe and shareable. The http://clojure.github.io/clojure/clojure.zip-api.html#clojure.zip/next[next] function does a depth-first walk, making for easy to understand loops: 89 | 90 | [source,clojure] 91 | ---- 92 | (def data '[[a * b] + [c * d]]) 93 | (def dz (zip/vector-zip data)) 94 | 95 | ;find the second * 96 | (-> dz zip/down zip/right zip/right zip/down zip/right zip/node) 97 | -> * 98 | 99 | ;'remove' the first 2 terms 100 | (-> dz zip/next zip/remove zip/next zip/remove zip/root) 101 | -> <> 102 | 103 | 104 | ;'replace' * with / 105 | (loop [loc dz] 106 | (if (zip/end? loc) 107 | (zip/root loc) 108 | (recur 109 | (zip/next 110 | (if (= (zip/node loc) '*) 111 | (zip/replace loc '/) 112 | loc))))) 113 | 114 | -> [[a / b] + [c / d]] 115 | 116 | 117 | ;'remove' * 118 | (loop [loc dz] 119 | (if (zip/end? loc) 120 | (zip/root loc) 121 | (recur 122 | (zip/next 123 | (if (= (zip/node loc) '*) 124 | (zip/remove loc) 125 | loc))))) 126 | 127 | -> [[a b] + [c d]] 128 | 129 | 130 | ;original is intact 131 | (zip/root dz) 132 | -> [[a * b] + [c * d]] 133 | ---- 134 | 135 | Zipper constructors are provided for nested seqs, nested vectors, and the xml elements generated by _**xml/parse**_. All it takes is a 4-5 line function to support other data structures. 136 | -------------------------------------------------------------------------------- /content/about/rationale.adoc: -------------------------------------------------------------------------------- 1 | = Rationale 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | :nextpagehref: state 8 | :nextpagetitle: State 9 | 10 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 11 | 12 | toc::[] 13 | 14 | Customers and stakeholders have substantial investments in, and are comfortable with the performance, security and stability of, industry-standard platforms like the JVM. While Java developers may envy the succinctness, flexibility and productivity of dynamic languages, they have concerns about running on customer-approved infrastructure, access to their existing code base and libraries, and performance. In addition, they face ongoing problems dealing with concurrency using native threads and locking. Clojure is an effort in pragmatic dynamic language design in this context. It endeavors to be a general-purpose language suitable in those areas where Java is suitable. It reflects the reality that, for the concurrent programming future, pervasive, unmoderated mutation simply has to go. 15 | 16 | Clojure meets its goals by: embracing an industry-standard, open platform - the JVM; modernizing a venerable language - Lisp; fostering functional programming with immutable persistent data structures; and providing built-in concurrency support via software transactional memory and asynchronous agents. The result is robust, practical, and fast. 17 | 18 | Clojure has a distinctive approach to <>. 19 | 20 | == Why Clojure? 21 | 22 | Why did I write yet another programming language? Basically because I wanted: 23 | 24 | * A Lisp 25 | * for Functional Programming 26 | * symbiotic with an established Platform 27 | * designed for Concurrency 28 | 29 | and couldn't find one. Here's an outline of some of the motivating ideas behind Clojure. 30 | 31 | == Lisp is a good thing 32 | 33 | * Often emulated/pillaged, still not duplicated 34 | * Lambda calculus yields an extremely small core 35 | * Almost no syntax 36 | * Core advantage still code-as-data and syntactic abstraction 37 | * What about the standard Lisps (Common Lisp and Scheme)? 38 | ** Slow/no innovation post standardization 39 | ** Core data structures mutable, not extensible 40 | ** No concurrency in specs 41 | ** Good implementations already exist for JVM (ABCL, Kawa, SISC et al) 42 | ** Standard Lisps are their own platforms 43 | * Clojure is a Lisp not constrained by backwards compatibility 44 | ** Extends the code-as-data paradigm to maps and vectors 45 | ** Defaults to immutability 46 | ** Core data structures are extensible abstractions 47 | ** Embraces a platform (JVM) 48 | 49 | == Functional programming is a good thing 50 | 51 | * Immutable data + first-class functions 52 | * Could always be done in Lisp, by discipline/convention 53 | ** But if a data structure _can_ be mutated, dangerous to presume it won't be 54 | ** In traditional Lisp, only the list data structure is structurally recursive 55 | * Pure functional languages tend to strongly static types 56 | ** Not for everyone, or every task 57 | * Clojure is a functional language with a dynamic emphasis 58 | ** All data structures immutable & persistent, supporting recursion 59 | ** Heterogeneous collections, return types 60 | ** Dynamic polymorphism 61 | 62 | == Languages and Platforms 63 | 64 | * VMs, not OSes, are the platforms of the future, providing: 65 | ** Type system 66 | *** Dynamic enforcement and safety 67 | ** Libraries 68 | *** Abstract away OSes 69 | *** _Huge_ set of facilities 70 | *** Built-in and 3rd-party 71 | ** Memory and other resource management 72 | *** GC is platform, not language, facility 73 | ** Bytecode + JIT compilation 74 | *** Abstracts away hardware 75 | * Language as platform vs. language + platform 76 | ** Old way - each language defines its own runtime 77 | *** GC, bytecode, type system, libraries etc 78 | ** New way (JVM, .Net) 79 | *** Common runtime independent of language 80 | * Language built for platform vs language ported-to platform 81 | ** Many new languages still take 'Language as platform' approach 82 | ** When ported, have platform-on-platform issues 83 | *** Memory management, type-system, threading issues 84 | *** Library duplication 85 | *** If original language based on C, some extension libraries written in C don't come over 86 | * Platforms are dictated by clients 87 | ** 'Must run on JVM' or .Net vs 'must run on Unix' or Windows 88 | ** JVM has established track record and trust level 89 | *** Now also open source 90 | ** Interop with other code required 91 | *** C linkage insufficient these days 92 | * Java/JVM _is_language + platform 93 | ** Not the original story, but other languages for JVM always existed, now embraced by Sun 94 | ** Java can be tedious, insufficiently expressive 95 | *** Lack of first-class functions, no type inference, etc 96 | ** Ability to call/consume Java is critical 97 | * Clojure is the language, JVM the platform 98 | 99 | == Object Orientation is overrated 100 | 101 | * Born of simulation, now used for everything, even when inappropriate 102 | ** Encouraged by Java/C# in all situations, due to their lack of (idiomatic) support for anything else 103 | * Mutable stateful objects are the new spaghetti code 104 | ** Hard to understand, test, reason about 105 | ** Concurrency disaster 106 | * Inheritance is _not_ the only way to do polymorphism 107 | * "It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures." - Alan J. Perlis 108 | * Clojure models its data structures as immutable objects represented by interfaces, and otherwise does not offer its own class system. 109 | * Many functions defined on few primary data structures (seq, map, vector, set). 110 | * Write Java in Java, consume and extend Java from Clojure. 111 | 112 | == Polymorphism is a good thing 113 | 114 | * Switch statements, structural matching etc yield brittle systems 115 | * Polymorphism yields extensible, flexible systems 116 | * Clojure multimethods decouple polymorphism from OO and types 117 | ** Supports multiple taxonomies 118 | ** Dispatches via static, dynamic or external properties, metadata, etc 119 | 120 | == Concurrency and the multi-core future 121 | 122 | * Immutability makes much of the problem go away 123 | ** Share freely between threads 124 | * But changing state a reality for simulations and for in-program proxies to the outside world 125 | * Locking is too hard to get right over and over again 126 | * Clojure's software transactional memory and agent systems do the hard part 127 | 128 | In short, I think Clojure occupies a unique niche as a functional Lisp for the JVM with strong concurrency support. Check out some of the <>. 129 | -------------------------------------------------------------------------------- /content/reference/transients.adoc: -------------------------------------------------------------------------------- 1 | = Transient Data Structures 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: Transients 8 | :prevpagehref: sequences 9 | :prevpagetitle: Sequences 10 | :nextpagehref: transducers 11 | :nextpagetitle: Transducers 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | toc::[] 16 | 17 | == Rationale 18 | 19 | _If a tree falls in the woods, does it make a sound?_ + 20 | _If a pure function mutates some local data in order to produce an immutable return value, is that ok?_ 21 | 22 | It's an interesting question. Clojure data structures use mutation every time you call, e.g. *assoc*, creating one or more arrays and mutating them, before returning them for immutable use thereafter. The reason is performance - you simply can't get as fast using only pure functions and immutable data. Once constructed and shared however, being immutable and persistent is essential to robust programs. The things Clojure mutates internally are small, newly allocated arrays that constitute the internal nodes of its data structures. No one ever sees the arrays. 23 | 24 | You run into a similar scenario, at a higher level, when you want to initialize or transform a large persistent data structure using multiple steps, none of which will be seen by any code other than the constructing/transforming code. The challenge here is that the source of a transformation will be an existing persistent data structure, and the result of the function _will_ be shared. Copying into a traditional mutable data structure and back involves O(n) copying, and the internal code is an imperative mess quite unlike the rest of your Clojure code. Furthermore, there are no guards against accidentally sharing or aliasing the mutable data structure, especially if you need to call helper functions to do the work. In short, it would be a shame if you had to leave Clojure's model in order to speed up a piece of code like this. Transient data structures are a solution to this optimization problem that integrates with the Clojure model and provides the same thread safety guarantees you expect of Clojure. 25 | 26 | == How they work 27 | 28 | Transient data structures are always created from an existing persistent Clojure data structure. As of Clojure 1.1.0, vectors, hash-maps, and hash-sets are supported. Note that not all Clojure data structures can support this feature, but most will. Lists will not, as there is no benefit to be had. 29 | 30 | You obtain a transient 'copy' of a data structure by calling *transient*. This creates a new transient data structure that is a copy of the source, and has the same performance characteristics. In fact, it mostly _is_ the source data structure, and highlights the first feature of transients - creating one is O(1). It shares structure with its source, just as persistent copies share structure. 31 | 32 | The second feature of transients is that creating one does not modify the source, and the source cannot be modified via use of the transient. Your source data is immutable and persistent as always. 33 | 34 | Transients support the read-only interface of the source, i.e. you can call *nth*, *get*, *count* and fn-call a transient vector, just like a persistent vector. 35 | 36 | Transients _**do not**_ support the persistent interface of the source data structure. *assoc*, *conj* etc will all throw exceptions, because transients are not persistent. Thus you cannot accidentally leak a transient into a context requiring a persistent. 37 | 38 | Transients support a parallel set of 'changing' operations, with similar names followed by *!* - *assoc!*, *conj!* etc. These do the same things as their persistent counterparts except the return values are themselves transient. Note in particular that transients are not designed to be bashed in-place. You must capture and use the return value in the next call. In this way, they support the same code structure as the functional persistent code they replace. As the example will show, this will allow you to easily enhance the performance of a piece of code without structural change. 39 | 40 | When you are finished building up your results, you can create a persistent data structure by calling *persistent!* on the transient. This operation is also O(1). Subsequent to calling *persistent!*, the transient should not be used, and all operations will throw exceptions. This will be true also for any aliases you might have created. 41 | 42 | == Example 43 | 44 | Here's a very typical example, some code that builds up a vector for return, all 'changes' being local to the function. Note how the transient-using version has exactly the same structure, just: 45 | 46 | * Calling *transient* on the source vector 47 | * Using *conj!* instead of *conj* 48 | * Calling *persistent!* on return 49 | [source,clojure] 50 | ---- 51 | (defn vrange [n] 52 | (loop [i 0 v []] 53 | (if (< i n) 54 | (recur (inc i) (conj v i)) 55 | v))) 56 | 57 | (defn vrange2 [n] 58 | (loop [i 0 v (transient [])] 59 | (if (< i n) 60 | (recur (inc i) (conj! v i)) 61 | (persistent! v)))) 62 | 63 | ;; benchmarked (Java 1.8, Clojure 1.7) 64 | (def v (vrange 1000000)) ;; 73.7 ms 65 | (def v2 (vrange2 1000000))) ;; 19.7 ms 66 | ---- 67 | Oh, yeah, _**transients are fast!**_ 68 | 69 | == Concurrent use 70 | 71 | That's all there is to using transients, but they have another important constraint: *Transients require thread isolation.* Because each result of a transient operation shares (mutable) structure with the previous, it is an error if more than one thread manipulates a transient at once. Use of a particular transient instance should be controlled either by using it in an single-threaded scope, or in a framework that enforces this. 72 | 73 | In Clojure 1.6 and earlier, transients would detect any (read or write) use from a thread other than the one that created them and throw an exception. That check was removed in 1.7 to allow for more flexible use in frameworks like core.async go blocks that enforce the single-threaded constraint via other means. 74 | 75 | == Summary 76 | 77 | Transients provide a high-performance optimization of functional data-structure-building code that works with Clojure's data structures and provides critical safety guarantees. 78 | 79 | 80 | * Single-path use 81 | * Thread isolation - enforced 82 | * O(1) creation from persistent data structures 83 | * Shares structure with persistent source 84 | * O(1) creation of persistent data structure when editing session finished 85 | * Same code structure as functional version 86 | ** Capture return value, use for next call 87 | ** Don't bash in place 88 | ** Not persistent, so you can't hang onto interim values or alias 89 | * Can't use after returning a persistent version 90 | * Fast 91 | 92 | Transient persistent vectors, hash-maps, and hash-sets were added in Clojure 1.1. -------------------------------------------------------------------------------- /content/about/concurrent_programming.adoc: -------------------------------------------------------------------------------- 1 | = Concurrent Programming 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: runtime_polymorphism 8 | :prevpagetitle: Runtime Polymorphism 9 | :nextpagehref: jvm_hosted 10 | :nextpagetitle: JVM Hosted 11 | 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | Today's systems have to deal with many simultaneous tasks and leverage the power of multi-core CPUs. Doing so with threads can be very difficult due to the complexities of synchronization. Clojure simplifies multi-threaded programming in several ways. Because the core data structures are immutable, they can be shared readily between threads. However, it is often necessary to have state change in a program. Clojure, being a practical language, allows state to change but provides mechanism to ensure that, when it does so, it remains consistent, while alleviating developers from having to avoid conflicts manually using locks etc. The <> (STM), exposed through http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dosync[dosync], http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ref[ref], http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set[set], http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/alter[alter], et al, supports _sharing_ changing state between threads in a _synchronous_ and _coordinated_ manner. The <> system supports sharing changing state between threads in an _asynchronous_ and _independent_ manner. The <> system supports sharing changing state between threads in a _synchronous_ and _independent_ manner. The <>, exposed through <>, http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/binding[binding], et al, supports isolating changing state within threads. 16 | 17 | In all cases, Clojure does not replace the Java thread system, rather it works with it. Clojure functions are java.util.concurrent.Callable, therefore they work with the Executor framework etc. 18 | 19 | Most of this is covered in more detail in the http://www.youtube.com/watch?v=dGVqrGmwOAw[concurrency screencast]. 20 | 21 | <> are mutable references to objects. They can be http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ref-set[ref-set] or http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/alter[alter]ed to refer to different objects during transactions, which are delimited by http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dosync[dosync] blocks. All ref modifications within a transaction happen or none do. Also, reads of refs within a transaction reflect a snapshot of the reference world at a particular point in time, i.e. each transaction is isolated from other transactions. If a conflict occurs between 2 transactions trying to modify the same reference, one of them will be retried. All of this occurs without explicit locking. 22 | 23 | In this example a vector of Refs containing integers is created _(+refs+)_, then a set of threads are set up _(+pool+)_ to run a number of iterations of incrementing every Ref _(+tasks+)_. This creates extreme contention, but yields the correct result. No locks! 24 | [source,clojure] 25 | ---- 26 | (import '(java.util.concurrent Executors)) 27 | 28 | (defn test-stm [nitems nthreads niters] 29 | (let [refs (map ref (repeat nitems 0)) 30 | pool (Executors/newFixedThreadPool nthreads) 31 | tasks (map (fn [t] 32 | (fn [] 33 | (dotimes [n niters] 34 | (dosync 35 | (doseq [r refs] 36 | (alter r + 1 t)))))) 37 | (range nthreads))] 38 | (doseq [future (.invokeAll pool tasks)] 39 | (.get future)) 40 | (.shutdown pool) 41 | (map deref refs))) 42 | 43 | (test-stm 10 10 10000) 44 | -> (550000 550000 550000 550000 550000 550000 550000 550000 550000 550000) 45 | ---- 46 | In typical use refs can refer to Clojure collections, which, being persistent and immutable, efficiently support simultaneous speculative 'modifications' by multiple transactions. Mutable objects should not be put in refs. 47 | 48 | By default Vars are static, but per-thread bindings for Vars defined with <> mark them as dynamic. <> are also mutable references to objects. They have a (thread-shared) root binding which can be established by <>, and can be set using _*set!*_, but only if they have been bound to a new storage location thread-locally using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/binding[binding]. Those bindings and any subsequent modifications to those bindings will only be seen _within_ the thread by code in the dynamic scope of the binding block. Nested bindings obey a stack protocol and unwind as control exits the binding block. 49 | [source,clojure] 50 | ---- 51 | (def ^:dynamic *v*) 52 | 53 | (defn incv [n] (set! *v* (+ *v* n))) 54 | 55 | (defn test-vars [nthreads niters] 56 | (let [pool (Executors/newFixedThreadPool nthreads) 57 | tasks (map (fn [t] 58 | #(binding [*v* 0] 59 | (dotimes [n niters] 60 | (incv t)) 61 | *v*)) 62 | (range nthreads))] 63 | (let [ret (.invokeAll pool tasks)] 64 | (.shutdown pool) 65 | (map #(.get %) ret)))) 66 | 67 | (test-vars 10 1000000) 68 | -> (0 1000000 2000000 3000000 4000000 5000000 6000000 7000000 8000000 9000000) 69 | (set! *v* 4) 70 | -> java.lang.IllegalStateException: Can't change/establish root binding of: *v* with set 71 | ---- 72 | Dynamic vars provide a way to communicate between different points on the call stack without polluting the argument lists and return values of the intervening calls. In addition, dynamic vars support a flavor of context-oriented programming. Because fns defined with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn[defn] are stored in vars, they too can be dynamically rebound: 73 | [source,clojure] 74 | ---- 75 | (defn ^:dynamic say [& args] 76 | (apply str args)) 77 | 78 | (defn loves [x y] 79 | (say x " loves " y)) 80 | 81 | (defn test-rebind [] 82 | (println (loves "ricky" "lucy")) 83 | (let [say-orig say] 84 | (binding [say (fn [& args] 85 | (println "Logging say") 86 | (apply say-orig args))] 87 | (println (loves "fred" "ethel"))))) 88 | 89 | (test-rebind) 90 | 91 | ricky loves lucy 92 | Logging say 93 | fred loves ethel 94 | ---- -------------------------------------------------------------------------------- /content/reference/protocols.adoc: -------------------------------------------------------------------------------- 1 | = Protocols 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: multimethods 8 | :prevpagetitle: Multimethods and Hierarchies 9 | :nextpagehref: metadata 10 | :nextpagetitle: Metadata 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | toc::[] 15 | 16 | == Motivation 17 | 18 | Clojure is written in terms of abstractions. There are abstractions for sequences, collections, callability, etc. In addition, Clojure supplies many implementations of these abstractions. The abstractions are specified by host interfaces, and the implementations by host classes. While this was sufficient for bootstrapping the language, it left Clojure without similar abstraction and low-level implementation facilities. The <> and <> features add powerful and flexible mechanisms for abstraction and data structure definition with no compromises vs the facilities of the host platform. 19 | 20 | There are several motivations for protocols: 21 | 22 | * Provide a high-performance, dynamic polymorphism construct as an alternative to interfaces 23 | * Support the best parts of interfaces 24 | ** specification only, no implementation 25 | ** a single type can implement multiple protocols 26 | * While avoiding some of the drawbacks 27 | ** Which interfaces are implemented is a design-time choice of the type author, cannot be extended later (although interface injection might eventually address this) 28 | ** implementing an interface creates an isa/instanceof type relationship and hierarchy 29 | * Avoid the 'expression problem' by allowing independent extension of the set of types, protocols, and implementations of protocols on types, by different parties 30 | ** do so without wrappers/adapters 31 | * Support the 90% case of multimethods (single dispatch on type) while providing higher-level abstraction/organization 32 | 33 | [NOTE] 34 | Protocols were introduced in Clojure 1.2. 35 | 36 | == Basics 37 | 38 | A protocol is a named set of named methods and their signatures, defined using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defprotocol[defprotocol]: 39 | 40 | [source,clojure] 41 | ---- 42 | (defprotocol AProtocol 43 | "A doc string for AProtocol abstraction" 44 | (bar [a b] "bar docs") 45 | (baz [a] [a b] [a b c] "baz docs")) 46 | ---- 47 | 48 | * No implementations are provided 49 | * Docs can be specified for the protocol and the functions 50 | * The above yields a set of polymorphic functions and a protocol object 51 | ** all are namespace-qualified by the namespace enclosing the definition 52 | * The resulting functions dispatch on the type of their first argument, and thus must have at least one argument 53 | * defprotocol is dynamic, and does not require AOT compilation 54 | 55 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defprotocol[defprotocol] will automatically generate a corresponding interface, with the same name as the protocol, i.e. given a protocol my.ns/Protocol, an interface my.ns.Protocol. The interface will have methods corresponding to the protocol functions, and the protocol will automatically work with instances of the interface. 56 | 57 | Note that you do not need to use this interface with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/deftype[deftype] , http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defrecord[defrecord] , or http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/reify[reify], as they support protocols directly: 58 | 59 | [source,clojure] 60 | ---- 61 | (defprotocol P 62 | (foo [x]) 63 | (bar-me [x] [x y])) 64 | 65 | (deftype Foo [a b c] 66 | P 67 | (foo [x] a) 68 | (bar-me [x] b) 69 | (bar-me [x y] (+ c y))) 70 | 71 | (bar-me (Foo. 1 2 3) 42) 72 | = > 45 73 | 74 | (foo 75 | (let [x 42] 76 | (reify P 77 | (foo [this] 17) 78 | (bar-me [this] x) 79 | (bar-me [this y] x)))) 80 | 81 | > 17 82 | ---- 83 | 84 | A Java client looking to participate in the protocol can do so most efficiently by implementing the protocol-generated interface. 85 | 86 | External implementations of the protocol (which are needed when you want a class or type not in your control to participate in the protocol) can be provided using the http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/extend[extend] construct: 87 | 88 | [source,clojure] 89 | ---- 90 | (extend AType 91 | AProtocol 92 | {:foo an-existing-fn 93 | :bar (fn [a b] ...) 94 | :baz (fn ([a]...) ([a b] ...)...)} 95 | BProtocol 96 | {...} 97 | ...) 98 | ---- 99 | 100 | extend takes a type/class (or interface, see below), a one or more protocol + function map (evaluated) pairs. 101 | 102 | * Will extend the polymorphism of the protocol's methods to call the supplied functions when an AType is provided as the first argument 103 | * Function maps are maps of the keywordized method names to ordinary fns 104 | ** this facilitates easy reuse of existing fns and maps, for code reuse/mixins without derivation or composition 105 | * You can implement a protocol on an interface 106 | ** this is primarily to facilitate interop with the host (e.g. Java) 107 | ** but opens the door to incidental multiple inheritance of implementation 108 | *** since a class can inherit from more than one interface, both of which implement the protocol 109 | *** if one interface is derived from the other, the more derived is used, else which one is used is unspecified. 110 | * The implementing fn can presume first argument is instanceof AType 111 | * You can implement a protocol on _**nil**_ 112 | * To define a default implementation of protocol (for other than nil) just use Object 113 | 114 | Protocols are fully reified and support reflective capabilities via http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/extends%3F[extends?] , http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/extenders[extenders] , and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/satisfies%3F[satisfies?] . 115 | 116 | * Note the convenience macros http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/extend-type[extend-type] , and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/extend-protocol[extend-protocol] 117 | * If you are providing external definitions inline, these will be more convenient than using *extend* directly 118 | 119 | [source,clojure] 120 | ---- 121 | (extend-type MyType 122 | Countable 123 | (cnt [c] ...) 124 | Foo 125 | (bar [x y] ...) 126 | (baz ([x] ...) ([x y zs] ...))) 127 | 128 | ;expands into: 129 | 130 | (extend MyType 131 | Countable 132 | {:cnt (fn [c] ...)} 133 | Foo 134 | {:baz (fn ([x] ...) ([x y zs] ...)) 135 | :bar (fn [x y] ...)}) 136 | ---- 137 | -------------------------------------------------------------------------------- /content/reference/repl_and_main.adoc: -------------------------------------------------------------------------------- 1 | = The REPL and main entry points 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: REPL and main 8 | :prevpagehref: reader 9 | :prevpagetitle: Reader 10 | :nextpagehref: evaluation 11 | :nextpagetitle: Evaluation 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | toc::[] 16 | 17 | == The clojure.main namespace 18 | 19 | The `clojure.main` namespace provides functions that allow Clojure programs and interactive sessions to be launched via Java's application launcher tool `java`. 20 | 21 | == clojure.main --help 22 | 23 | The `clojure.main/main` entry point accepts a variety of arguments and flags as described in its usage message: 24 | 25 | [source,clojure] 26 | ---- 27 | Usage: java -cp clojure.jar clojure.main [init-opt*] [main-opt] [arg*] 28 | 29 | With no options or args, runs an interactive Read-Eval-Print Loop 30 | 31 | init options: 32 | -i, --init path Load a file or resource 33 | -e, --eval string Evaluate expressions in string; print non-nil values 34 | 35 | main options: 36 | -r, --repl Run a repl 37 | path Run a script from from a file or resource 38 | - Run a script from standard input 39 | -m, --main A namespace to find a -main function for execution 40 | -h, -?, --help Print this help message and exit 41 | 42 | operation: 43 | 44 | - Establishes thread-local bindings for commonly set!-able vars 45 | - Enters the user namespace 46 | - Binds *command-line-args* to a seq of strings containing command line 47 | args that appear after any main option 48 | - Runs all init options in order 49 | - Runs a repl or script if requested 50 | 51 | The init options may be repeated and mixed freely, but must appear before 52 | any main option. The appearance of any eval option before running a repl 53 | suppresses the usual repl greeting message: "Clojure ~(clojure-version)". 54 | 55 | Paths may be absolute or relative in the filesystem or relative to 56 | classpath. Classpath-relative paths have prefix of @ or @/ 57 | ---- 58 | 59 | == Launching a REPL 60 | 61 | The simplest way to launch a Clojure _repl_ is to use the following command line from within Clojure's home directory: 62 | 63 | [source,clojure] 64 | ---- 65 | java -cp clojure.jar clojure.main 66 | ---- 67 | 68 | The REPL prompt shows the name of the current namespace (pass:[*ns*]), which defaults to _user_. 69 | 70 | Several special vars are available when using the REPL: 71 | 72 | * *1, *2, *3 - hold the result of the last three expressions that were evaluated 73 | * *e - holds the result of the last exception. 74 | 75 | The http://clojure.github.io/clojure/clojure.repl-api.html[clojure.repl] namespace has a number of useful functions for inspecting the source and documentation of available functions: 76 | 77 | * http://clojure.github.io/clojure/clojure.repl-api.html#clojure.repl/doc[doc] - prints the docstring for a var given its name 78 | * http://clojure.github.io/clojure/clojure.repl-api.html#clojure.repl/find-doc[find-doc] - prints the docstring for any var whose doc or name matches the pattern 79 | * http://clojure.github.io/clojure/clojure.repl-api.html#clojure.repl/apropos[apropos] - returns a seq of definitions matching a regex 80 | * http://clojure.github.io/clojure/clojure.repl-api.html#clojure.repl/source[source] - prints the source for a symbol 81 | * http://clojure.github.io/clojure/clojure.repl-api.html#clojure.repl/pst[pst] - **p**rint **s**tack **t**race for a given exception or *e by default 82 | 83 | == Launching a Script 84 | 85 | To run a file full of Clojure code as a script, pass the path to the script to `clojure.main` as an argument: 86 | 87 | [source,clojure] 88 | ---- 89 | java -cp clojure.jar clojure.main /path/to/myscript.clj 90 | ---- 91 | 92 | == Passing arguments to a Script 93 | 94 | To pass in arguments to a script, pass them in as further arguments when launching `clojure.main`: 95 | 96 | [source,clojure] 97 | ---- 98 | java -cp clojure.jar clojure.main /path/to/myscript.clj arg1 arg2 arg3 99 | ---- 100 | 101 | The arguments will be provided to your program as a seq of strings bound to the var `pass:[*command-line-args*]`: 102 | 103 | [source,clojure] 104 | ---- 105 | *command-line-args* => ("arg1" "arg2" "arg3") 106 | ---- 107 | 108 | == Launching a Socket Server 109 | 110 | [NOTE] 111 | This feature was added in 1.8.0. 112 | 113 | The Clojure runtime now has the ability to start a socket server at initialization based on system properties. One expected use for this is serving a socket-based REPL, but it also has many other potential uses for dynamically adding server capability to existing programs without code changes. 114 | 115 | A socket server will be started for each JVM system property like "clojure.server.". The value for this property is an edn map representing the configuration of the socket server with the following properties: 116 | 117 | * `server-daemon` - defaults to true, socket server thread doesn't block exit 118 | * `address` - host or address, defaults to loopback 119 | * `port` - positive integer, required 120 | * `accept` - namespaced symbol of function to invoke on socket accept, required 121 | * `args` - sequential collection of args to pass to accept 122 | * `bind-err` - defaults to true, binds `pass:[*err*]` to socket out stream 123 | * `client-daemon` - defaults to true, socket client thread doesn't block exit 124 | 125 | Additionally, there is a repl function provided that is slightly customized for use with the socket server in http://clojure.github.io/clojure/clojure.repl-api.html#clojure.core.server/repl[clojure.core.server/repl]. 126 | 127 | Following is an example of starting a socket server with a repl listener. This can be added to any existing Clojure program to allow it to accept external REPL clients via a local connection to port 5555. 128 | 129 | [source,clojure] 130 | ---- 131 | -Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}" 132 | ---- 133 | 134 | An example client you can use to connect to this socket repl is telnet: 135 | 136 | [source,clojure] 137 | ---- 138 | $ telnet 127.0.0.1 5555 139 | Trying 127.0.0.1... 140 | Connected to localhost. 141 | Escape character is '^]'. 142 | user=> (println "hello") 143 | hello 144 | ---- 145 | 146 | Also see: 147 | 148 | * http://dev.clojure.org/jira/browse/CLJ-1671[CLJ-1671] 149 | * http://dev.clojure.org/display/design/Socket+Server+REPL[Socket REPL design page] 150 | 151 | == Related functions 152 | 153 | Main Entry Point: `http://clojure.github.io/clojure/clojure.main-api.html#clojure.main/main[clojure.main/main]` 154 | 155 | Reusable REPL: `http://clojure.github.io/clojure/clojure.main-api.html#clojure.main/repl[clojure.main/repl]` 156 | 157 | Allowing set! for the customary REPL vars: `http://clojure.github.io/clojure/clojure.main-api.html#clojure.main/with-bindings[clojure.main/with-bindings]` 158 | -------------------------------------------------------------------------------- /content/reference/refs.adoc: -------------------------------------------------------------------------------- 1 | = Refs and Transactions 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: vars 8 | :prevpagetitle: Vars and Environments 9 | :nextpagehref: agents 10 | :nextpagetitle: Agents 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | toc::[] 15 | 16 | While <> ensure safe use of mutable storage locations via thread _isolation_, transactional references (Refs) ensure safe _shared_ use of mutable storage locations via a http://en.wikipedia.org/wiki/Software_transactional_memory[software transactional memory] (STM) system. Refs are bound to a single storage location for their lifetime, and only allow mutation of that location to occur within a transaction. 17 | 18 | Clojure transactions should be easy to understand if you've ever used database transactions - they ensure that all actions on Refs are atomic, consistent, and isolated. Atomic means that every change to Refs made within a transaction occurs or none do. Consistent means that each new value can be checked with a validator function before allowing the transaction to commit. Isolated means that no transaction sees the effects of any other transaction while it is running. Another feature common to STMs is that, should a transaction have a conflict while running, it is automatically retried. 19 | 20 | There are many ways to do STMs (locking/pessimistic, lock-free/optimistic and hybrids) and it is still a research problem. The Clojure STM uses http://en.wikipedia.org/wiki/Multiversion_concurrency_control[multiversion concurrency control] with adaptive history queues for http://en.wikipedia.org/wiki/Snapshot_isolation[snapshot isolation], and provides a distinct http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/commute[commute] operation. 21 | 22 | In practice, this means: 23 | 24 | . All reads of Refs will see a consistent snapshot of the 'Ref world' as of the starting point of the transaction (its 'read point'). The transaction _will_ see any changes it has made. This is called the _in-transaction-value_. 25 | . All changes made to Refs during a transaction (via http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ref-set[ref-set], http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/alter[alter] or http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/commute[commute]) will appear to occur at a single point in the 'Ref world' timeline (its 'write point'). 26 | . No changes will have been made by any other transactions to any Refs that have been *ref-set**_ / _**altered**_ / _**ensured**_ by this transaction. 27 | . Changes _may have_ been made by other transactions to any Refs that have been commuted by this transaction. That should be okay since the function applied by _**commute**_ should be commutative. 28 | . Readers and commuters will never block writers, commuters, or other readers. 29 | . Writers will never block commuters, or readers. 30 | . I/O and other activities with side-effects should be avoided in transactions, since transactions _will_ be retried. The http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/io![io!] macro can be used to prevent the use of an impure function in a transaction. 31 | . If a constraint on the validity of a value of a Ref that is being changed depends upon the simultaneous value of a Ref that is _not being changed_, that second Ref can be protected from modification by calling http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ensure[ensure]. Refs 'ensured' this way will be protected (item #3), but don't change the world (item #2). 32 | . The Clojure MVCC STM is designed to work with the persistent collections, and it is strongly recommended that you use the Clojure collections as the values of your Refs. Since all work done in an STM transaction is speculative, it is imperative that there be a low cost to making copies and modifications. Persistent collections have free copies (just use the original, it can't be changed), and 'modifications' share structure efficiently. In any case: 33 | . The values placed in Refs _must be, or be considered, immutable_!! Otherwise, Clojure can't help you. 34 | 35 | == Example 36 | In this example a vector of references to vectors is created, each containing (initially sequential) unique numbers. Then a set of threads are started that repeatedly select two random positions in two random vectors and swap them, in a transaction. No special effort is made to prevent the inevitable conflicts other than the use of transactions. 37 | [source,clojure] 38 | ---- 39 | (defn run [nvecs nitems nthreads niters] 40 | (let [vec-refs (vec (map (comp ref vec) 41 | (partition nitems (range (* nvecs nitems))))) 42 | swap #(let [v1 (rand-int nvecs) 43 | v2 (rand-int nvecs) 44 | i1 (rand-int nitems) 45 | i2 (rand-int nitems)] 46 | (dosync 47 | (let [temp (nth @(vec-refs v1) i1)] 48 | (alter (vec-refs v1) assoc i1 (nth @(vec-refs v2) i2)) 49 | (alter (vec-refs v2) assoc i2 temp)))) 50 | report #(do 51 | (prn (map deref vec-refs)) 52 | (println "Distinct:" 53 | (count (distinct (apply concat (map deref vec-refs))))))] 54 | (report) 55 | (dorun (apply pcalls (repeat nthreads #(dotimes [_ niters] (swap))))) 56 | (report))) 57 | 58 | ---- 59 | When run, we see no values get lost or duplicated in the shuffle: 60 | [source,clojure] 61 | ---- 62 | (run 100 10 10 100000) 63 | 64 | ([0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] ... 65 | [990 991 992 993 994 995 996 997 998 999]) 66 | Distinct: 1000 67 | 68 | ([382 318 466 963 619 22 21 273 45 596] [808 639 804 471 394 904 952 75 289 778] ... 69 | [484 216 622 139 651 592 379 228 242 355]) 70 | Distinct: 1000 71 | ---- 72 | 73 | == Related functions 74 | 75 | Create a Ref: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ref[ref] 76 | 77 | Examine a Ref: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/deref[deref] _(see also the +@+ <> macro)_ 78 | 79 | Transaction macros: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dosync[dosync] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/io![io!] 80 | 81 | Allowed only in a transaction: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ensure[ensure] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ref-set[ref-set] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/alter[alter] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/commute[commute] 82 | 83 | Ref validators: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set-validator![set-validator!] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/get-validator[get-validator] 84 | -------------------------------------------------------------------------------- /content/guides/getting_started.adoc: -------------------------------------------------------------------------------- 1 | = Getting Started 2 | Rich Hickey 3 | 2015-01-01 4 | :type: guides 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | == Quick Start 11 | 12 | === Minimal Install 13 | 14 | Clojure requires only http://java.sun.com/javase/downloads/index.jsp[Java] 1.6 or greater, plus the Clojure JAR file itself. 15 | 16 | <> and unzip Clojure. In the directory in which you expanded clojure.zip, run: 17 | [source,clojure] 18 | ---- 19 | java -cp clojure-1.7.0.jar clojure.main 20 | ---- 21 | This will bring up a simple read-eval-print loop (REPL). From the REPL, try: 22 | [source,clojure] 23 | ---- 24 | user=> (+ 1 2 3) 25 | 6 26 | user=> (javax.swing.JOptionPane/showMessageDialog nil "Hello World") 27 | ---- 28 | Try Clojure online: 29 | 30 | * http://tryclj.com/[TryClojure] provides a brower-based Clojure REPL 31 | * http://himera.herokuapp.com/index.html[Himera] provides a browser-based ClojureScript REPL 32 | 33 | === Clojure Tools 34 | 35 | Community volunteers maintain http://dev.clojure.org/display/doc/getting+started[Getting Started] documentation for a number of different tools and approaches. Some of the most commonly used tools include: 36 | 37 | * http://leiningen.org/[Leiningen] - an extensible build tool that provides dependency management, REPL support, testing, packaging, deployment, and many other capabilities. 38 | * http://www.gnu.org/software/emacs/[Emacs] with https://github.com/clojure-emacs/cider[CIDER] 39 | * http://www.vim.org/[Vim] with https://github.com/tpope/vim-fireplace[Fireplace] 40 | * https://code.google.com/p/counterclockwise/[Eclipse Counterclockwise] 41 | * IntelliJ https://cursiveclojure.com/[Cursive] 42 | * https://sekao.net/nightcode/[Nightcode] 43 | * http://www.lighttable.com/[Light Table] 44 | * http://www.sublimetext.com/[Sublime Text] with https://github.com/wuub/SublimeREPL[SublimeREPL] 45 | 46 | === Books 47 | 48 | There are now many excellent books about Clojure and ClojureScript. This is an *incomplete* list of titles (as more keep arriving!): 49 | 50 | * http://amzn.com/1934356867[Programming Clojure] - Stuart Halloway, Aaron Bedra (Pragmatic Bookshelf) 51 | * http://amzn.com/B007Q4T040[Clojure Programming] - Chas Emerick, Brian Carper, Christophe Grand (O'Reilly) 52 | * http://amzn.com/1935182641[The Joy of Clojure: Thinking the Clojure Way] - Michael Fogus, Chris Houser (Manning) 53 | * http://amzn.com/1935182641[Clojure in Action] - Amit Rathore (Manning) 54 | * http://amzn.com/1430272317[Practical Clojure] - Luke VanderHart, Stuart Sierra (Apress) 55 | * http://amzn.com/B009WXWXPG[ClojureScript Up and Running] - Stuart Sierra, Luke VanderHart (O'Reilly) 56 | * http://amzn.com/B00IT6XZ0O[Clojure Cookbook: Recipes for Functional Programming] - Luke VanderHart, Ryan Neufeld (O'Reilly) 57 | * http://amzn.com/B00I800FCM[Web Development with Clojure] - Dmitri Sotnikov (Pragmatic Bookshelf) 58 | * http://shop.oreilly.com/product/0636920034292.do[Living Clojure] - Carin Meier (O'Reilly) 59 | * https://pragprog.com/book/vmclojeco/clojure-applied[Clojure Applied] - Ben Vandgrift, Alex Miller (Pragmatic Bookshelf) 60 | 61 | === Online Books, Tutorials, and Resources 62 | 63 | Official: 64 | 65 | * http://clojure.github.io/clojure/[Clojure API Docs] 66 | * http://clojure.github.io/[Clojure Contrib Library API Docs] 67 | * <> - official reference information 68 | * <> - helpful categorization of most core functions 69 | * Source - https://github.com/clojure/clojure[Clojure], https://github.com/clojure/clojurescript[ClojureScript], https://github.com/clojure/clojure-clr[ClojureCLR] 70 | * Issues - http://dev.clojure.org/jira/browse/CLJ[Clojure], http://dev.clojure.org/jira/browse/CLJS[ClojureScript], http://dev.clojure.org/jira/browse/CLJCLR[ClojureCLR] 71 | 72 | Community: 73 | 74 | * http://www.braveclojure.com/[Clojure for the Brave and True] - a beginner book by Daniel Higginbotham 75 | * http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome[Clojure from the ground up] - a series of intro articles by Kyle Kingsbury 76 | * https://github.com/ClojureBridge/curriculum[ClojureBridge Curriculum] 77 | * http://grimoire.arrdem.com/[Grimoire] - community combined cheatsheet + examples 78 | * http://clojuredocs.org[ClojureDocs] - community provided example repository 79 | * http://crossclj.info/[CrossClj] - library cross-reference 80 | * http://clojure-doc.org/[Clojure Documentation] - community-driven documentation site 81 | * http://clojurekoans.com/[Clojure Koans] (http://clojurescriptkoans.com/[online]) 82 | * http://www.4clojure.com/[4clojure] - Clojure practice problems 83 | * http://exercism.io/[exercism.io] - crowd-source code reviews (supports Clojure) 84 | * https://github.com/bbatsov/clojure-style-guide[Clojure Style Guide] 85 | * http://planet.clojure.in/[Planet Clojure] - Clojure blog aggregator 86 | * Newsletters - http://defnewsletter.com/[(def newsletter)] http://www.clojuregazette.com/[Clojure Gazette] http://reborg.tumblr.com/[Clojure Weekly] 87 | * http://www.clojureatlas.com/[Clojure Atlas] - visualization of Clojure and the core library 88 | * http://www.clojurebridge.org/[ClojureBridge] - beginner workshops for women 89 | 90 | Videos and presentations: 91 | 92 | * https://www.youtube.com/user/ClojureTV/videos[ClojureTV] - talks by Rich Hickey and presentations from Clojure/conj and Clojure/west 93 | * http://www.infoq.com/Clojure/presentations/[InfoQ Clojure Presentations] - from a variety of conferences 94 | 95 | Video training (commercial): 96 | 97 | * http://www.purelyfunctional.tv/intro-to-clojure[Introduction to Clojure] - Eric Normand (LispCast) 98 | * http://www.purelyfunctional.tv/web-dev-in-clojure[Web Development in Clojure] - Eric Normand (LispCast) 99 | * http://shop.oreilly.com/product/0636920030409.do[Clojure Inside Out] - Stuart Halloway, Neal Ford (O'Reilly) 100 | * http://pluralsight.com/training/courses/TableOfContents?courseName=clojure-fundamentals-part-one[Clojure Fundamentals] - Alan Dipert (PluralSight) 101 | * http://pluralsight.com/training/courses/TableOfContents?courseName=clojure-concurrency-tutorial&highlight=craig-andera_clojure-concurrency-tutorial-intro*3,8!craig-andera_clojure-concurrency-tutorial-vars!craig-andera_clojure-concurrency-tutorial-atoms!craig-andera_clojure-concurrency-tutorial-agents!craig-andera_clojure-concurrency-tutorial-refs!craig-andera_clojure-concurrency-tutorial-misc#clojure-concurrency-tutorial-intro[Clojure Concurrency] - Craig Andera (PluralSight) 102 | 103 | === Conferences 104 | 105 | * http://clojure-conj.org/[Clojure/conj] (usually in November) 106 | * http://www.clojurewest.org/[Clojure/west] (usually in March) 107 | * http://euroclojure.com[EuroClojure] (usually mid-year) 108 | * http://lanyrd.com/search/?context=future&q=clojure&type=conference[Clojure events] 109 | -------------------------------------------------------------------------------- /content/reference/macros.adoc: -------------------------------------------------------------------------------- 1 | = Macros 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: special_forms 8 | :prevpagetitle: Special Forms 9 | :nextpagehref: other_functions 10 | :nextpagetitle: Other Functions 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | toc::[] 15 | 16 | Clojure has a programmatic macro system which allows the compiler to be extended by user code. Macros can be used to define syntactic constructs which would require primitives or built-in support in other languages. Many core constructs of Clojure are not, in fact, primitives, but are normal macros. 17 | 18 | Some macros produce simple combinations of primitive forms. For example, http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when[`when`] combines <> and <>: 19 | 20 | [source,clojure-repl] 21 | ---- 22 | user=> (macroexpand '(when (pos? a) (println "positive") (/ b a))) 23 | (if (pos? a) (do (println "positive") (/ b a))) 24 | ---- 25 | 26 | Other macros re-arrange forms in useful ways, like the `pass:[->]` macro, which recursively inserts each expression as the first argument of the next expression: 27 | 28 | [source,clojure-repl] 29 | ---- 30 | user=> (-> {} (assoc :a 1) (assoc :b 2)) 31 | {:b 2, :a 1} 32 | user=> (macroexpand '(-> {} (assoc :a 1) (assoc :b 2))) 33 | (assoc (clojure.core/-> {} (assoc :a 1)) :b 2) 34 | ---- 35 | 36 | == Special variables 37 | 38 | Two special variables are available inside defmacro for more advanced usages: 39 | 40 | * `&form` - the actual form (as data) that is being invoked 41 | * `&env` - a map of local bindings at the point of macro expansion. The env map is from symbols to objects holding compiler information about that binding. 42 | 43 | All of the following macros are documented on the http://clojure.github.io/clojure/[API] page. Many are also discussed on topic pages as noted: 44 | 45 | [%hardbreaks] 46 | Creating macros: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmacro[defmacro] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/definline[definline] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/macroexpand-1[macroexpand-1] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/macroexpand[macroexpand] 47 | Branching: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/and[and] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/or[or] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when[when] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when-not[when-not] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when-let[when-let] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when-first[when-first] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/if-not[if-not] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/if-let[if-let] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/cond[cond] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/condp[condp] 48 | Looping (see also <>): http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/for[for] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/doseq[doseq] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dotimes[dotimes] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/while[while] 49 | Working with vars (see also <>): http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns[ns] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/declare[declare] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn[defn] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmacro[defmacro] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/definline[definline] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmethod[defmethod] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmulti[defmulti] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn-[defn-] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defonce[defonce] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defstruct[defstruct] 50 | Arranging code differently: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/%2E%2E[..] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/doto[doto] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/-%3e[pass:[->]] 51 | Dynamic scopes (see also <>): http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/binding[binding] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/locking[locking] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/time[time] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-in-str[with-in-str] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-local-vars[with-local-vars] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-open[with-open] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-out-str[with-out-str] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-precision[with-precision] 52 | Creating lazy things (see also <>): http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/lazy-cat[lazy-cat] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/lazy-cons[lazy-cons] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/delay[delay] 53 | <> macros: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/%2E%2E[..] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/amap[amap] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/areduce[areduce] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-class[gen-class] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-interface[gen-interface] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/proxy[proxy] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/proxy-super[proxy-super] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/memfn[memfn] 54 | Documenting code: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/assert[assert] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/comment[comment] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/doc[doc] 55 | Transactions: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dosync[dosync] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/io![io!] 56 | 57 | A few <> are actually implemented as macros, primarily to provide destructuring: fn let loop 58 | -------------------------------------------------------------------------------- /content/reference/vars.adoc: -------------------------------------------------------------------------------- 1 | = Vars and the Global Environment 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: Vars and Environments 8 | :prevpagehref: libs 9 | :prevpagetitle: Libs 10 | :nextpagehref: refs 11 | :nextpagetitle: Refs and Transactions 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | toc::[] 16 | 17 | Clojure is a practical language that recognizes the occasional need to maintain a persistent reference to a changing value and provides 4 distinct mechanisms for doing so in a controlled manner - Vars, <>, <> and <>. Vars provide a mechanism to refer to a mutable storage location that can be dynamically rebound (to a new storage location) on a per-thread basis. Every Var can (but needn't) have a root binding, which is a binding that is shared by all threads that do not have a per-thread binding. Thus, the value of a Var is the value of its per-thread binding, or, if it is not bound in the thread requesting the value, the value of the root binding, if any. 18 | 19 | The special form _**def**_ creates (and <>) a Var. If the Var did not already exist and no initial value is supplied, the var is unbound: 20 | 21 | [source,clojure] 22 | ---- 23 | user=> (def x) 24 | .'user/x 25 | user=> x 26 | java.lang.IllegalStateException: Var user/x is unbound. 27 | ---- 28 | 29 | Supplying an initial value binds the root (even if it was already bound). 30 | 31 | [source,clojure] 32 | ---- 33 | user=> (def x 1) 34 | .'user/x 35 | 36 | user=> x 37 | 1 38 | ---- 39 | 40 | By default Vars are static, but Vars can be marked as dynamic to allow per-thread bindings via the macro http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/binding[binding]. Within each thread they obey a stack discipline: 41 | 42 | [source,clojure] 43 | ---- 44 | user=> (def ^:dynamic x 1) 45 | user=> (def ^:dynamic y 1) 46 | user=> (+ x y) 47 | 2 48 | 49 | user=> (binding [x 2 y 3] 50 | (+ x y)) 51 | 5 52 | 53 | user=> (+ x y) 54 | 2 55 | ---- 56 | 57 | Bindings created with _**binding**_ cannot be seen by any other thread. Likewise, bindings created with _**binding**_ can be assigned to, which provides a means for a nested context to communicate with code before it on the call stack. This capability is opt-in only by setting a metadata tag: _**dynamic**_ to true as in the code block above. There are scenarios that one might wish to redefine static Vars within a context and Clojure (since version 1.3) provides the functions http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-redefs[with-redefs] and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-redefs-fn[with-redefs-fn] for such purposes. 58 | 59 | Functions defined with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn[defn] are stored in Vars, allowing for the re-definition of functions in a running program. This also enables many of the possibilities of aspect- or context-oriented programming. For instance, you could wrap a function with logging behavior only in certain call contexts or threads. 60 | 61 | [[set]] 62 | == (*set!* var-symbol expr) 63 | 64 | Assignment special form. 65 | 66 | When the first operand is a symbol, it must resolve to a global var. The value of the var's current thread binding is set to the value of expr. Currently, it is an error to attempt to set the root binding of a var using set!, i.e. var assignments are thread-local. In all cases the value of expr is returned. 67 | 68 | Note - _you cannot assign to function params or local bindings. Only Java fields, Vars, Refs and Agents are mutable in Clojure_. 69 | 70 | Using <> for Java fields is documented in <>. 71 | 72 | [[Interning]] 73 | == Interning 74 | 75 | The Namespace system maintains global maps of symbols to Var objects _(see <>)_. If a _**def**_ expression does not find an interned entry in the current namespace for the symbol being def-ed, it creates one, otherwise it uses the existing Var. This find-or-create process is called interning. This means that, unless they have been unmap-ed, Var objects are stable references and need not be looked up every time. It also means that namespaces constitute a global environment in which, as described in <>, the compiler attempts to resolve all free symbols as Vars. 76 | 77 | The <> special form or the `pass:[#']` reader macro _(see <>)_ can be used to get an interned Var object instead of its current value. 78 | 79 | [[local-vars]] 80 | == Non-interned Vars 81 | 82 | It is possible to create vars that are not interned by using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-local-vars[with-local-vars]. These vars will not be found during free symbol resolution, and their values have to be accessed manually. But they can serve as useful thread-local mutable cells. 83 | 84 | [[related]] 85 | == Related functions 86 | 87 | [%hardbreaks] 88 | Variants of _**def**_: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn[defn] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn-[defn-] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/definline[definline] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmacro[defmacro] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmethod[defmethod] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmulti[defmulti] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defonce[defonce] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defstruct[defstruct] 89 | Working with interned Vars: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/declare[declare] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/intern[intern] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/binding[binding] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/find-var[find-var] <> 90 | Working with Var objects: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-local-vars[with-local-vars] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/var-get[var-get] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/var-set[var-set] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/alter-var-root[alter-var-root] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/var?[var?] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-redefs[with-redefs] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-redefs-fn[with-redefs-fn] 91 | Var validators: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set-validator[set-validator] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/get-validator[get-validator] 92 | Common Var metadata: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/doc[doc] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/find-doc[find-doc] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/test[test] -------------------------------------------------------------------------------- /content/reference/agents.adoc: -------------------------------------------------------------------------------- 1 | = Agents and Asynchronous Actions 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: Agents 8 | :prevpagehref: refs 9 | :prevpagetitle: Refs and Transactions 10 | :nextpagehref: atoms 11 | :nextpagetitle: Atoms 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | toc::[] 16 | 17 | Like Refs, Agents provide shared access to mutable state. Where <> support _coordinated_, _synchronous_ change of _multiple_ locations, Agents provide _independent_, _asynchronous_ change of _individual_ locations. Agents are bound to a single storage location for their lifetime, and only allow mutation of that location (to a new state) to occur as a result of an action. Actions are functions (with, optionally, additional arguments) that are asynchronously applied to an Agent's state and whose return value becomes the Agent's new state. Because actions are functions they can also be multimethods and therefore actions are potentially polymorphic. Also, because the set of functions is open, the set of actions supported by an Agent is also open, a sharp contrast to pattern matching message handling loops provided by some other languages. 18 | 19 | Clojure's Agents are _reactive_, not autonomous - there is no imperative message loop and no blocking receive. The state of an Agent should be itself immutable (preferably an instance of one of Clojure's persistent collections), and the state of an Agent is always immediately available for reading by any thread (using the http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/deref[deref] function or <> macro +@+) without any messages, i.e. observation does not require cooperation or coordination. 20 | 21 | Agent action dispatches take the form +(send agent fn args*)+. http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/send[send] (and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/send-off[send-off]) always returns immediately. At some point later, in another thread, the following will happen: 22 | 23 | . The given +fn+ will be applied to the _state_ of the Agent and the args, if any were supplied. 24 | . The return value of +fn+ will be passed to the validator function, if one has been set on the Agent. See http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set-validator![set-validator!] for details. 25 | . If the validator succeeds or if no validator was given, the return value of the given +fn+ will become the new state of the Agent. 26 | . If any watchers were added to the Agent, they will be called. See http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/add-watch[add-watch] for details. 27 | . If during the function execution any other dispatches are made (directly or indirectly), they will be held until _after_ the state of the Agent has been changed. 28 | 29 | If any exceptions are thrown by an action function, no nested dispatches will occur, and the exception will be cached in the Agent itself. When an Agent has errors cached, any subsequent interactions will immediately throw an exception, until the agent's errors are cleared. Agent errors can be examined with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/agent-error[agent-error] and the agent restarted with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/restart-agent[restart-agent]. 30 | 31 | The actions of all Agents get interleaved amongst threads in a thread pool. At any point in time, at most one action for each Agent is being executed. Actions dispatched to an agent from another single agent or thread will occur in the order they were sent, potentially interleaved with actions dispatched to the same agent from other sources. http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/send[send] should be used for actions that are CPU limited, while http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/send-off[send-off] is appropriate for actions that may block on IO. 32 | 33 | Agents are integrated with the STM - any dispatches made in a transaction are held until it commits, and are discarded if it is retried or aborted. 34 | 35 | As with all of Clojure's concurrency support, no user-code locking is involved. 36 | 37 | Note that use of Agents starts a pool of non-daemon background threads that will prevent shutdown of the JVM. Use http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/shutdown-agents[shutdown-agents] to terminate these threads and allow shutdown. 38 | 39 | == Example 40 | 41 | This example is an implementation of the send-a-message-around-a-ring test. A chain of n agents is created, then a sequence of m actions are dispatched to the head of the chain and relayed through it. 42 | [source,clojure] 43 | ---- 44 | (defn relay [x i] 45 | (when (:next x) 46 | (send (:next x) relay i)) 47 | (when (and (zero? i) (:report-queue x)) 48 | (.put (:report-queue x) i)) 49 | x) 50 | 51 | (defn run [m n] 52 | (let [q (new java.util.concurrent.SynchronousQueue) 53 | hd (reduce (fn [next _] (agent {:next next})) 54 | (agent {:report-queue q}) (range (dec m)))] 55 | (doseq [i (reverse (range n))] 56 | (send hd relay i)) 57 | (.take q))) 58 | 59 | ; 1 million message sends: 60 | (time (run 1000 1000)) 61 | ->"Elapsed time: 2959.254 msecs" 62 | ---- 63 | 64 | == Related functions 65 | 66 | Create an Agent: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/agent[agent] 67 | 68 | Examine an Agent: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/deref[deref] _(see also the +@+ <> macro)_ http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/agent-error[agent-error] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/error-handler[error-handler] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/error-mode[error-mode] 69 | 70 | Change Agent state: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/send[send] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/send-off[send-off] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/restart-agent[restart-agent] 71 | 72 | Block waiting for an Agent: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/await[await] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/await-for[await-for] 73 | 74 | Ref validators: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set-validator![set-validator!] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/get-validator[get-validator] 75 | 76 | Watchers: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/add-watch[add-watch] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/remove-watch[remove-watch] 77 | 78 | Agent thread management: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/shutdown-agents[shutdown-agents] 79 | 80 | Agent error management: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/agent-error[agent-error] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/restart-agent[restart-agent] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set-error-handler![set-error-handler!] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/error-handler[error-handler] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set-error-mode![set-error-mode!] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/error-mode[error-mode] 81 | -------------------------------------------------------------------------------- /content/about/functional_programming.adoc: -------------------------------------------------------------------------------- 1 | = Functional Programming 2 | Rich Hickey 3 | 2015-01-01 4 | :type: about 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: dynamic 8 | :prevpagetitle: Dynamic Development 9 | :nextpagehref: lisp 10 | :nextpagetitle: Lisp 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | toc::[] 15 | 16 | Clojure is a functional programming language. It provides the tools to avoid mutable state, provides functions as first-class objects, and emphasizes recursive iteration instead of side-effect based looping. Clojure is _impure_, in that it doesn't force your program to be referentially transparent, and doesn't strive for 'provable' programs. The philosophy behind Clojure is that most parts of most programs should be functional, and that programs that are more functional are more robust. 17 | 18 | == First-class functions 19 | 20 | <> creates a function object. It yields a value like any other - you can store it in a var, pass it to functions etc. 21 | [source,clojure] 22 | ---- 23 | (def hello (fn [] "Hello world")) 24 | -> #'user/hello 25 | (hello) 26 | -> "Hello world" 27 | ---- 28 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defn[defn] is a macro that makes defining functions a little simpler. 29 | Clojure supports arity overloading in a _single_ function object, self-reference, and variable-arity functions using *&*: 30 | [source,clojure] 31 | ---- 32 | ;trumped-up example 33 | (defn argcount 34 | ([] 0) 35 | ([x] 1) 36 | ([x y] 2) 37 | ([x y & more] (+ (argcount x y) (count more)))) 38 | -> #'user/argcount 39 | (argcount) 40 | -> 0 41 | (argcount 1) 42 | -> 1 43 | (argcount 1 2) 44 | -> 2 45 | (argcount 1 2 3 4 5) 46 | -> 5 47 | ---- 48 | You can create local names for values inside a function using http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/let[let]. The scope of any local names is lexical, so a function created in the scope of local names will close over their values: 49 | [source,clojure] 50 | ---- 51 | (defn make-adder [x] 52 | (let [y x] 53 | (fn [z] (+ y z)))) 54 | (def add2 (make-adder 2)) 55 | (add2 4) 56 | -> 6 57 | ---- 58 | *Locals created with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/let[let] are not variables. Once created their values never change!* 59 | 60 | 61 | == Immutable Data Structures 62 | The easiest way to avoid mutating state is to use immutable <>. Clojure provides a set of immutable lists, vectors, sets and maps. Since they can't be changed, 'adding' or 'removing' something from an immutable collection means creating a new collection just like the old one but with the needed change. _Persistence_ is a term used to describe the property wherein the old version of the collection is still available after the 'change', and that the collection maintains its performance guarantees for most operations. Specifically, this means that the new version can't be created using a full copy, since that would require linear time. Inevitably, persistent collections are implemented using linked data structures, so that the new versions can share structure with the prior version. Singly-linked lists and trees are the basic functional data structures, to which Clojure adds a hash map, set and vector both based upon array mapped hash tries. The collections have readable representations and common interfaces: 63 | [source,clojure] 64 | ---- 65 | (let [my-vector [1 2 3 4] 66 | my-map {:fred "ethel"} 67 | my-list (list 4 3 2 1)] 68 | (list 69 | (conj my-vector 5) 70 | (assoc my-map :ricky "lucy") 71 | (conj my-list 5) 72 | ;the originals are intact 73 | my-vector 74 | my-map 75 | my-list)) 76 | -> ([1 2 3 4 5] {:ricky "lucy", :fred "ethel"} (5 4 3 2 1) [1 2 3 4] {:fred "ethel"} (4 3 2 1)) 77 | ---- 78 | Applications often need to associate attributes and other data about data that is orthogonal to the logical value of the data. Clojure provides direct support for this <>. Symbols, and all of the collections, support a metadata map. It can be accessed with the http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/meta[meta] function. Metadata does _not_ impact equality semantics, nor will metadata be seen in operations on the value of a collection. Metadata can be read, and can be printed. 79 | [source,clojure] 80 | ---- 81 | (def v [1 2 3]) 82 | (def attributed-v (with-meta v {:source :trusted})) 83 | (:source (meta attributed-v)) 84 | -> :trusted 85 | (= v attributed-v) 86 | -> true 87 | ---- 88 | 89 | == Extensible Abstractions 90 | 91 | Clojure uses Java interfaces to define its core data structures. This allows for extensions of Clojure to new concrete implementations of these interfaces, and the library functions will work with these extensions. This is a big improvement vs. hardwiring a language to the concrete implementations of its data types. 92 | 93 | A good example of this is the <> interface. By making the core Lisp list construct into an abstraction, a wealth of library functions are extended to any data structure that can provide a sequential interface to its contents. All of the Clojure data structures can provide seqs. Seqs can be used like iterators or generators in other languages, with the significant advantage that seqs are immutable and persistent. Seqs are extremely simple, providing a *_first_* function, which return the first item in the sequence, and a *_rest_* function which returns the rest of the sequence, which is itself either a seq or nil. 94 | [source,clojure] 95 | ---- 96 | (let [my-vector [1 2 3 4] 97 | my-map {:fred "ethel" :ricky "lucy"} 98 | my-list (list 4 3 2 1)] 99 | [(first my-vector) 100 | (rest my-vector) 101 | (keys my-map) 102 | (vals my-map) 103 | (first my-list) 104 | (rest my-list)]) 105 | -> [1 (2 3 4) (:ricky :fred) ("lucy" "ethel") 4 (3 2 1)] 106 | ---- 107 | Many of the Clojure library functions produce and consume seqs _lazily_: 108 | [source,clojure] 109 | ---- 110 | ;cycle produces an 'infinite' seq! 111 | (take 15 (cycle [1 2 3 4])) 112 | -> (1 2 3 4 1 2 3 4 1 2 3 4 1 2 3) 113 | ---- 114 | You can define your own lazy seq-producing functions using the http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/lazy-seq[lazy-seq] macro, which takes a body of expressions that will be called on demand to produce a list of 0 or more items. Here's a simplified http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/take[take]: 115 | [source,clojure] 116 | ---- 117 | (defn take [n coll] 118 | (lazy-seq 119 | (when (pos? n) 120 | (when-let [s (seq coll)] 121 | (cons (first s) (take (dec n) (rest s))))))) 122 | ---- 123 | 124 | == Recursive Looping 125 | 126 | In the absence of mutable local variables, looping and iteration must take a different form than in languages with built-in _for_ or _while_ constructs that are controlled by changing state. In functional languages looping and iteration are replaced/implemented via recursive function calls. Many such languages guarantee that function calls made in tail position do not consume stack space, and thus recursive loops utilize constant space. Since Clojure uses the Java calling conventions, it cannot, and does not, make the same tail call optimization guarantees. Instead, it provides the <>, which does constant-space recursive looping by rebinding and jumping to the nearest enclosing loop or function frame. While not as general as tail-call-optimization, it allows most of the same elegant constructs, and offers the advantage of checking that calls to recur can only happen in a tail position. 127 | [source,clojure] 128 | ---- 129 | (defn my-zipmap [keys vals] 130 | (loop [my-map {} 131 | my-keys (seq keys) 132 | my-vals (seq vals)] 133 | (if (and my-keys my-vals) 134 | (recur (assoc my-map (first my-keys) (first my-vals)) 135 | (next my-keys) 136 | (next my-vals)) 137 | my-map))) 138 | (my-zipmap [:a :b :c] [1 2 3]) 139 | -> {:b 2, :c 3, :a 1} 140 | ---- 141 | For situations where mutual recursion is called for, recur can't be used. Instead, http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/trampoline[trampoline] may be a good option. -------------------------------------------------------------------------------- /content/community/contributing_site.adoc: -------------------------------------------------------------------------------- 1 | = Contributing to This Site 2 | Alex Miller 3 | 2015-10-15 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 9 | 10 | This web site is an open-source repository of content about the Clojure programming language and its greater ecosystem, hosted at http://clojure.org. 11 | 12 | If you wish to point out an issue in the site or propose a new page, you can do so by filing a GitHub issue at https://github.com/clojure/clojure-site/issues. 13 | 14 | If you wish to make a contribution (typo, modification, or new content), you must become a contributor and use the processes described below: 15 | 16 | * <> 17 | * <> 18 | * <> 19 | * <> 20 | * <> 21 | * <> 22 | 23 | 24 | [[contributor]] 25 | == How To Become a Contributor 26 | 27 | Contributors must sign the Clojure Contributor Agreement prior to submitting changes. The https://secure.echosign.com/public/hostedForm?formid=95YMDL576B336E[Contributor Agreement] (CA) gives Rich Hickey and the contributor joint copyright interests: the contributor retains copyrights while also granting those rights to Rich Hickey as the open source project sponsor. 28 | 29 | The CA is derived from the Oracle Contributor Agreement (OCA), used for OpenJDK, Netbeans and OpenSolaris projects and others. There is a good http://www.oracle.com/technetwork/oca-faq-405384.pdf[OCA FAQ] answering many questions. 30 | 31 | By executing the CA, contributors protect the Clojure site content and protect the flexibility to adapt the project to the changing demands of the community. In order for the CA to be effective, the Clojure project must obtain an assignment for all contributions. Please review the CA for a complete understanding of its terms and conditions. By contributing source code or other material to Clojure, you represent that you have a CA with Rich Hickey for such contributions. In order to track contributors, you understand that your full name and username may be posted on a web page listing authorized contributors that is accessible via a public URL. 32 | 33 | To complete the agreement, fill out and submit the https://secure.echosign.com/public/hostedForm?formid=95YMDL576B336E[Contributor Agreement] (an online e-form). 34 | 35 | Note that if you have already signed the Clojure Contributor Agreement to supply patches to the Clojure source code, you do not need to sign it again as it is the same agreement. 36 | 37 | [[minor]] 38 | == Submitting Small Changes 39 | 40 | Small changes can be proposed directly in the GitHub web interface: 41 | 42 | . Go to the content repository https://github.com/clojure/clojure-site 43 | . Navigate to the page you wish to update under content/ - the url should match the file base name. For example, this file's content is at https://github.com/clojure/clojure-site/blob/master/content/community/contributing_site.adoc. 44 | . Click the edit (pencil) icon. 45 | . Content is written using the asciidoc format, which is similar to Markdown. The <> page lists examples of the most common things you will encounter when editing content on this site. Make your changes in the text box. You can preview your changes using the "Preview changes" tab. GitHub understands asciidoc format and will provide a formatted preview of your changes. 46 | . Write a concise description of the change in the bottom section of the page then click "Propose file change". This will fork the original repository into your own version of the repository with the change applied. 47 | . You will then be shown a "Comparing changes" page - all of the information should be filled out automatically and a summary of your changes will be at the bottom - this is a good time to look them over one more time. Assuming it all looks correct, you can propose the change back to the original repository by clicking "Create pull request". You'll then be able to add a comment to the pull request itself then click "Create pull request". 48 | 49 | [[major]] 50 | == Submitting Large Changes 51 | 52 | IMPORTANT: For any major changes, *please* open an https://github.com/clojure/clojure-site/issues[issue] first and discuss the change before spending time on it. 53 | 54 | If you are going to create an entirely new page or make significant changes requiring multiple commits, you will likely find it easier to work using command line tools. 55 | 56 | To create a local environment for working on a bigger change: 57 | 58 | . Fork the content repository https://github.com/clojure/clojure-site - this will create a version of the site content under your own user id. 59 | . `git clone` the forked repository in your local terminal and `cd clojure-site`. 60 | . `git checkout -b ` - create a new branch to work on your change. You'll use this branch to submit a pull request. 61 | . Make one or more commits on this branch, modifying or adding one or more files. See the section below on how to build and preview changes locally. The <> page lists examples of the most common things you will encounter when editing content on this site. 62 | . Use `git push` to push your changes to the branch. 63 | . Go to pass:[https://github.com/username/clojure-site/tree/branchname]. 64 | . Click the green button to "Compare, review, and create a pull request" and proceed through the prompts to submit the pull request. 65 | 66 | To actively contribute to the site, it's important to keep your own fork up-to-date with this repository. To do that: 67 | 68 | . Add this repository to your remote urls: `git remote add upstream https://github.com/clojure/clojure-site.git`. 69 | . Before every contribution: 70 | - fetch the content of upstream: `git fetch upstream` ; 71 | - move to your master branch: `git checkout master` (in case you aren't already there); 72 | - clean your master branch of any unplanned modifications by reseting the HEAD to the fetched branch: `git reset --hard upstream/master`; and 73 | - create a new branch as explained above: `git checkout -b ` 74 | 75 | [[build]] 76 | == Building and Previewing Changes 77 | 78 | When working on bigger changes it's useful to build the site locally. The site is built using http://jbake.org/[JBake]. 79 | 80 | To http://jbake.org/docs/2.4.0/#installation[install] JBake 2.5.0-SNAPSHOT: 81 | 82 | . `curl -O http://cdn.cognitect.com/clojure.org/jbake-2.5.0-SNAPSHOT-bin.zip` (or download this file with your browser) 83 | . `unzip -o jbake-2.5.0-SNAPSHOT-bin.zip` 84 | . Add jbake-2.5.0-SNAPSHOT/bin to your system PATH 85 | 86 | To build the site: 87 | 88 | Retrieve the content: 89 | 90 | . `git clone https://github.com/clojure/clojure-site.git` (or your own fork) 91 | . `cd clojure-site` 92 | 93 | Retrieve and install the current theme assets (these don't change very often so you don't need to do this every time): 94 | 95 | . `curl -O http://cdn.cognitect.com/clojure.org/clojuretheme.zip` (or download this file with your browser to the clojure-site directory) 96 | . `unzip -o clojuretheme.zip` 97 | 98 | Generate the pages: 99 | 100 | . `jbake` - this will create the static site in the output directory 101 | . To view the static files, open `output/index` in your browser 102 | . To view a live preview, run `jbake -s` and go to http://localhost:8820/index 103 | 104 | [[style]] 105 | == Style and Navigation Changes 106 | 107 | We are not currently looking for changes in the overall site styling, navigation, or infrastructure. There is ongoing work in that area that will be visible in the near future. 108 | 109 | If you have an issue in these areas, please open an https://github.com/clojure/clojure-site/issues[issue] rather than a pull request. 110 | 111 | [[review]] 112 | == How Contributions are Reviewed and Deployed 113 | 114 | After submitting a pull request, a contribution will be waiting for review. 115 | 116 | For each pull request, one more of the reviewers will take action: 117 | 118 | * Mark the comment with the Reviewed label. This indicates the reviewer approves of the changes and requests that an Editor merges those changes. 119 | * Comment on the pull request suggesting additional changes. You may address these changes with further commits on your local branch. 120 | * Close the pull request with a comment indicating why the change is not appropriate. 121 | 122 | == Thanks! 123 | 124 | Thanks for your contributions! 125 | 126 | == Terms of Use 127 | 128 | Copyright © 2015 Rich Hickey and contributors 129 | 130 | All documentation contained in this repository is licensed by Rich Hickey under the http://www.eclipse.org/legal/epl-v10.html[Eclipse Public License v1.0] unless otherwise noted. 131 | -------------------------------------------------------------------------------- /content/reference/compilation.adoc: -------------------------------------------------------------------------------- 1 | = Ahead-of-time Compilation and Class Generation 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :navlinktext: Compilation and Class Generation 8 | :prevpagehref: java_interop 9 | :prevpagetitle: Java Interop 10 | :nextpagehref: other_libraries 11 | :nextpagetitle: Other Libraries 12 | 13 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 14 | 15 | toc::[] 16 | 17 | This documentation is preliminary - please send feedback on the Google Group - thanks! 18 | 19 | Clojure compiles all code you load on-the-fly into JVM bytecode, but sometimes it is advantageous to compile ahead-of-time (AOT). Some reasons to use AOT compilation are: 20 | 21 | * To deliver your application without source 22 | * To speed up application startup 23 | * To generate named classes for use by Java 24 | * To create an application that does not need runtime bytecode generation and custom classloaders 25 | 26 | The Clojure compilation model preserves as much as possible the dynamic nature of Clojure, in spite of the code-reloading limitations of Java. 27 | 28 | * Source and classfile pathing follows Java classpath conventions. 29 | * The target of compile is a namespace 30 | * Each file, fn and gen-class will produce a .class file 31 | * Each file generates a loader class of the same name with "__init" appended. 32 | * The static initializer for a loader class produces the same effects as does loading its source file 33 | ** You generally shouldn't need to use these classes directly, as use, require and load will choose between them and more recent source 34 | * The loader class is generated for each file referenced when a namespace is compiled, when its loader .class file is older than its source. 35 | * A stand-alone http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-class[gen-class] facility is provided to create named classes for direct use as Java classes, with facilities for: 36 | * Naming the generated class 37 | * Selecting the superclass 38 | * Specifying any implemented interfaces 39 | * Specifying constructor signatures 40 | * Specifying state 41 | * Declaring additional methods 42 | * Generating static factory methods 43 | * Generating main 44 | * Controlling the mapping to an implementing namespace 45 | * Exposing inherited protected members 46 | ** Generating more than one named class from a single file, with implementations in one or more namespaces 47 | * An optional http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-class[:gen-class] directive can be used in the http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns[ns] declaration to generate a named class corresponding to a namespace. (:gen-class ...), when supplied, defaults to :name corresponding to the ns name, :main true, :impl-ns same as ns, and :init-impl-ns true. All options of gen-class are supported. 48 | * gen-class and the :gen-class directive are ignored when not compiling. 49 | * A stand-alone http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-interface[gen-interface] facility is provided for generating named interface classes for direct use as Java interfaces, with facilities for: 50 | * Naming the generated interface 51 | * Specifying any superintefaces 52 | ** Declaring the signatures of interface methods 53 | 54 | == Compiling 55 | To compile a lib, use the http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/compile[compile] function, and supply the namespace name as a symbol. For some namespace my.domain.lib, defined in my/domain/lib.clj, in the classpath, the following should occur: 56 | 57 | * A loader classfile will produced in ``my/domain/lib__init.class``, under *compile-path*, which must be in the classpath 58 | * A set of classfiles will be produced, one per fn in the namespace, with names such as ``my/domain/lib$fnname__1234.class`` 59 | * For each gen-class: 60 | ** A stub classfile will be produced with the specified name 61 | 62 | == Runtime 63 | Classes generated by Clojure are highly dynamic. In particular, note that no method bodies or other implementation details are specified in gen-class - it specifies only a signature, and the class that it generates is only a stub. This stub class defers all implementation to functions defined in the implementing namespace. At runtime, a call to some method foo of the generated class will find the current value of the var implementing.namespace/prefixfoo and call it. If the var is not bound or nil, it will call the superclass method, or if an interface method, generate an UnsupportedOperationException. 64 | 65 | == gen-class Examples 66 | In the simplest case, an empty :gen-class is supplied, and the compiled class has only main, which is implemented by defining -main in the namespace: 67 | [source,clojure] 68 | ---- 69 | (ns clojure.examples.hello 70 | (:gen-class)) 71 | 72 | (defn -main 73 | [greetee] 74 | (println (str "Hello " greetee "!"))) 75 | 76 | ---- 77 | This gets compiled as follows: 78 | [source,clojure] 79 | ---- 80 | (compile 'clojure.examples.hello) 81 | ---- 82 | And can be run like an ordinary Java app like so: 83 | [source,clojure] 84 | ---- 85 | java -cp ./classes:clojure.jar clojure.examples.hello Fred 86 | Hello Fred! 87 | ---- 88 | 89 | Here's an example using both a more involved :gen-class, and stand-alone calls to gen-class and gen-interface. In this case we are creating classes we intend to create instances of. The clojure.examples.instance class will implement java.util.Iterator, a particularly nasty interface, in that it requires the implementation to be stateful. This class is going to take a String in its constructor and implement the Iterator interface in terms of delivering the characters from the string. The :init clause names the constructor function. The :constructors clause is a map of constructor signature to superclass constructor signature. In this case, the superclass defaults to Object, whose constructor takes no arguments. This object will have state, called state, and a main so we can test it. 90 | 91 | :init functions (-init in this case) are unusual, in that they always return a vector, the first element of which is a vector of arguments for the superclass constructor - since our superclass takes no args, this vector is empty. The second element of the vector is the state for the instance. Since we are going to have to mutate the state (and the state is always final) we'll use a ref to a map containing the string and the current index. 92 | 93 | hasNext and next are implementations of methods in the Iterator interface. While the methods take no args, the implementation functions for instance methods will always take an additional first arg corresponding to the object the method is called upon, called by convention 'this' here. Note how the state can be obtained using an ordinary Java field access. 94 | 95 | The gen-interface call will create an interface called clojure.examples.IBar, with a single method bar. 96 | 97 | The stand-alone gen-class call will generate another named class, clojure.examples.impl, whose implementing namespace will default to the current namespace. It implements clojure.examples.IBar. The :prefix option causes the implementation of methods to bind to functions beginning with "impl-" rather than the default "-". The :methods option defines a new method foo not present in any superclass/interfaces. 98 | 99 | Note in main how an instances of the classes can be created, and methods called, using ordinary Java interop. Using it would be similarly ordinary from Java. 100 | 101 | [source,clojure] 102 | ---- 103 | (ns clojure.examples.instance 104 | (:gen-class 105 | :implements [java.util.Iterator] 106 | :init init 107 | :constructors {[String] []} 108 | :state state)) 109 | 110 | (defn -init [s] 111 | [[] (ref {:s s :index 0})]) 112 | 113 | (defn -hasNext [this] 114 | (let [{:keys [s index]} @(.state this)] 115 | (< index (count s)))) 116 | 117 | (defn -next [this] 118 | (let [{:keys [s index]} @(.state this) 119 | ch (.charAt s index)] 120 | (dosync (alter (.state this) assoc :index (inc index))) 121 | ch)) 122 | 123 | (gen-interface 124 | :name clojure.examples.IBar 125 | :methods [[bar [] String]]) 126 | 127 | (gen-class 128 | :name clojure.examples.impl 129 | :implements [clojure.examples.IBar] 130 | :prefix "impl-" 131 | :methods [[foo [] String]]) 132 | 133 | (defn impl-foo [this] 134 | (str (class this))) 135 | 136 | (defn impl-bar [this] 137 | (str "I " (if (instance? clojure.examples.IBar this) 138 | "am" 139 | "am not") 140 | " an IBar")) 141 | 142 | (defn -main [s] 143 | (let [x (new clojure.examples.instance s) 144 | y (new clojure.examples.impl)] 145 | (while (.hasNext x) 146 | (println (.next x))) 147 | (println (.foo y)) 148 | (println (.bar y)))) 149 | 150 | ---- 151 | Compile as above, and run like an ordinary Java app: 152 | [source,clojure] 153 | ---- 154 | java -cp ./classes:clojure.jar clojure.examples.instance asdf 155 | a 156 | s 157 | d 158 | f 159 | class clojure.examples.impl 160 | I am an IBar 161 | 162 | ---- -------------------------------------------------------------------------------- /content/reference/multimethods.adoc: -------------------------------------------------------------------------------- 1 | = Multimethods and Hierarchies 2 | Rich Hickey 3 | 2015-01-01 4 | :type: reference 5 | :toc: macro 6 | :icons: font 7 | :prevpagehref: transducers 8 | :prevpagetitle: Transducers 9 | :nextpagehref: protocols 10 | :nextpagetitle: Protocols 11 | 12 | ifdef::env-github,env-browser[:outfilesuffix: .adoc] 13 | 14 | toc::[] 15 | 16 | Clojure eschews the traditional object-oriented approach of creating a new data type for each new situation, instead preferring to build a large library of functions on a small set of types. However, Clojure fully recognizes the value of runtime polymorphism in enabling flexible and extensible system architecture. Clojure supports sophisticated runtime polymorphism through a multimethod system that supports dispatching on types, values, attributes and metadata of, and relationships between, one or more arguments. 17 | 18 | A Clojure multimethod is a combination of a _dispatching_ _function_, and one or more _methods_. When a multimethod is defined, using _**defmulti**_, a dispatching function must be supplied. This function will be applied to the arguments to the multimethod in order to produce a _dispatching value_. The multimethod will then try to find the method associated with the dispatching value or a value from which the dispatching value is derived. If one has been defined (via http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmethod[defmethod]), it will then be called with the arguments and that will be the value of the multimethod call. If no method is associated with the dispatching value, the multimethod will look for a method associated with the default dispatching value (which defaults to _**:default**_), and will use that if present. Otherwise the call is an error. 19 | 20 | The multimethod system exposes this API: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmulti[defmulti] creates new multimethods, http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defmethod[defmethod] creates and installs a new method of multimethod associated with a dispatch-value, http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/remove-method[remove-method] removes the method associated with a dispatch-value and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/prefer-method[prefer-method] creates an ordering between methods when they would otherwise be ambiguous. 21 | 22 | Derivation is determined by a combination of either Java inheritance (for class values), or using Clojure's ad hoc hierarchy system. The hierarchy system supports derivation relationships between names (either symbols or keywords), and relationships between classes and names. The http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/derive[derive] function create these relationships, and the http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa?[isa?] function tests for their existence. Note that http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa?[isa?] is not http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/instance?[instance?]. 23 | 24 | You can define hierarchical relationships with +(derive child parent)+. Child and parent can be either symbols or keywords, and must be namespace-qualified: 25 | 26 | _Note the pass:[::] reader syntax, ::keywords resolve namespaces._ 27 | 28 | [source,clojure] 29 | ---- 30 | ::rect 31 | -> :user/rect 32 | ---- 33 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/derive[derive] is the fundamental relationship-maker 34 | [source,clojure] 35 | ---- 36 | (derive ::rect ::shape) 37 | (derive ::square ::rect) 38 | ---- 39 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/parents[parents] / http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ancestors[ancestors] / http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/descendants[descendants] and http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa%3F[isa?] let you query the hierarchy 40 | 41 | [source,clojure] 42 | ---- 43 | (parents ::rect) 44 | -> #{:user/shape} 45 | 46 | (ancestors ::square) 47 | -> #{:user/rect :user/shape} 48 | 49 | (descendants ::shape) 50 | -> #{:user/rect :user/square} 51 | ---- 52 | 53 | `(= x y)` implies `(isa? x y)` 54 | 55 | [source,clojure] 56 | ---- 57 | (isa? 42 42) 58 | -> true 59 | ---- 60 | 61 | `isa?` uses the hierarchy system 62 | 63 | [source,clojure] 64 | ---- 65 | (isa? ::square ::shape) 66 | -> true 67 | ---- 68 | 69 | You can also use a class as the child (but not the parent, the only way to make something the child of a class is via Java inheritance). 70 | 71 | This allows you to superimpose new taxonomies on the existing Java class hierarchy: 72 | 73 | [source,clojure] 74 | ---- 75 | (derive java.util.Map ::collection) 76 | (derive java.util.Collection ::collection) 77 | 78 | (isa? java.util.HashMap ::collection) 79 | -> true 80 | ---- 81 | 82 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa%3F[isa?] also tests for class relationships: 83 | 84 | [source,clojure] 85 | ---- 86 | (isa? String Object) 87 | -> true 88 | ---- 89 | 90 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa%3F[isa?] works with vectors by calling http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa%3F[isa?] on their corresponding elements: 91 | 92 | [source,clojure] 93 | ---- 94 | (isa? [::square ::rect] [::shape ::shape]) 95 | -> true 96 | ---- 97 | 98 | as do http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/parents[parents] / http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ancestors[ancestors] (but not http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/descendants[descendants], since class descendants are an open set) 99 | 100 | [source,clojure] 101 | ---- 102 | (ancestors java.util.ArrayList) 103 | -> #{java.lang.Cloneable java.lang.Object java.util.List 104 | java.util.Collection java.io.Serializable 105 | java.util.AbstractCollection 106 | java.util.RandomAccess java.util.AbstractList} 107 | ---- 108 | 109 | == isa? based dispatch 110 | 111 | Multimethods use http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa%3F[isa?] rather than = when testing for dispatch value matches. Note that the first test of http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/isa%3F[isa?] is =, so exact matches work. 112 | 113 | [source,clojure] 114 | ---- 115 | (defmulti foo class) 116 | (defmethod foo ::collection [c] :a-collection) 117 | (defmethod foo String [s] :a-string) 118 | 119 | (foo []) 120 | :a-collection 121 | 122 | (foo (java.util.HashMap.)) 123 | :a-collection 124 | 125 | (foo "bar") 126 | :a-string 127 | ---- 128 | 129 | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/prefer-method[prefer-method] is used for disambiguating in case of multiple matches where neither dominates the other. You can just declare, per multimethod, that one dispatch value is preferred over another: 130 | 131 | [source,clojure] 132 | ---- 133 | (derive ::rect ::shape) 134 | 135 | (defmulti bar (fn [x y] [x y])) 136 | (defmethod bar [::rect ::shape] [x y] :rect-shape) 137 | (defmethod bar [::shape ::rect] [x y] :shape-rect) 138 | 139 | (bar ::rect ::rect) 140 | -> java.lang.IllegalArgumentException: 141 | Multiple methods match dispatch value: 142 | [:user/rect :user/rect] -> [:user/rect :user/shape] 143 | and [:user/shape :user/rect], 144 | and neither is preferred 145 | 146 | (prefer-method bar [::rect ::shape] [::shape ::rect]) 147 | (bar ::rect ::rect) 148 | -> :rect-shape 149 | ---- 150 | 151 | All of the examples above use the global hierarchy used by the multimethod system, but entire independent hierarchies can also be created with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/make-hierarchy[make-hierarchy], and all of the above functions can take an optional hierarchy as a first argument. 152 | 153 | This simple system is extremely powerful. One way to understand the relationship between Clojure multimethods and traditional Java-style single dispatch is that single dispatch is like a Clojure multimethod whose dispatch function calls getClass on the first argument, and whose methods are associated with those classes. Clojure multimethods are not hard-wired to class/type, they can be based on any attribute of the arguments, on multiple arguments, can do validation of arguments and route to error-handling methods etc. 154 | 155 | 156 | _Note: In this example, the keyword :Shape is being used as the dispatch function, as keywords are functions of maps, as described in the <> section._ 157 | 158 | [source,clojure] 159 | ---- 160 | (defmulti area :Shape) 161 | (defn rect [wd ht] {:Shape :Rect :wd wd :ht ht}) 162 | (defn circle [radius] {:Shape :Circle :radius radius}) 163 | (defmethod area :Rect [r] 164 | (* (:wd r) (:ht r))) 165 | (defmethod area :Circle [c] 166 | (* (. Math PI) (* (:radius c) (:radius c)))) 167 | (defmethod area :default [x] :oops) 168 | (def r (rect 4 13)) 169 | (def c (circle 12)) 170 | (area r) 171 | -> 52 172 | (area c) 173 | -> 452.3893421169302 174 | (area {}) 175 | -> :oops 176 | ---- -------------------------------------------------------------------------------- /content/community/companies.adoc: -------------------------------------------------------------------------------- 1 | = Companies 2 | Rich Hickey 3 | 2015-01-01 4 | :type: community 5 | :toc: macro 6 | :icons: font 7 | 8 | Below is a partial list of some companies using Clojure or ClojureScript. Most of this information comes from direct contacts, presentations, or other online resources. If you would like to be added or removed from this list, please contact __alex.miller@cognitect.com__. 9 | 10 | * http://8thlight.com/[8th Light] 11 | * http://www.adaptly.com/[Adaptly] 12 | * http://www.adgoji.com/[AdGoji] 13 | * http://adzerk.com/[Adzerk] 14 | * http://www.onthemarket.com/[Agents' Mutual] 15 | * http://akvo.org/[akvo.org] 16 | * http://altometrics.com/[Altometrics] 17 | * http://www.amazon.com[Amazon] 18 | * http://annadaletech.com/[Annadale Technologies] 19 | * http://www.answers.com[Answers.com] 20 | * http://www.anywhere.com/[Anywhere.com] 21 | * http://www.appsflyer.com/[AppsFlyer] 22 | * http://www.appsnsites.com/[Appsnsites] 23 | * http://ardoq.com/[Ardoq] 24 | * http://auspost.com.au/[Australia Post] 25 | * http://www.aviso.io/[Aviso] 26 | * http://beanstalkapp.com/[Beanstalk] 27 | * http://BearyInnovative.com[BearyInnovative] 28 | * http://bevuta.com/[bevuta] 29 | * https://www.braintreepayments.com/[Braintree Payments] (acquired by PayPal) 30 | * http://brickalloy.com/[BrickAlloy] 31 | * http://www.brightnorth.co.uk/[Bright North] 32 | * http://broadpeakpartners.com[BroadPeak] 33 | * http://bugsbio.org/[BUGS Bioscience] 34 | * http://buyhappy.co/[Buy Happy] 35 | * https://cardforcoin.com/[cardforcoin] and https://foldapp.com/[Fold] 36 | * https://carouselapps.com/[Carousel Apps] 37 | * http://www.cerner.com/[Cerner] 38 | * http://chariotsolutions.com/[Chariot Solutions] 39 | * http://chartbeat.com[Chartbeat] 40 | * http://www.cicayda.com/[Cicayda] 41 | * https://circleci.com/[CircleCI] 42 | * http://www.citi.com[Citi] 43 | * http://www.climate.com/[Climate Corp] (acquired by http://www.monsanto.com[Monsanto]) 44 | * http://www.clubhousehq.com/[Clubhouse] 45 | * http://www.codurance.com/[Codurance] 46 | * http://code54.com[Code54] 47 | * https://www.cognician.com/[Cognician] 48 | * http://codecentric.de[codecentric] 49 | * http://devartcodefactory.com/[Co(de)factory] 50 | * http://cognitect.com[Cognitect] 51 | * http://collectivedigitalstudio.com[Collective Digital Studio] 52 | * https://www.concur.com/[Concur] 53 | * http://www.consumerreports.org/cro/index.htm[Consumer Reports] 54 | * http://www.consumerfinance.gov/[CFPB (Credit Financial Protection Bureau)] 55 | * http://www.cycloid.io[Cycloid] 56 | * http://www.dailymail.co.uk/[Daily Mail MailOnline] 57 | * https://www.databaselabs.io/[Database Labs] 58 | * http://www.datacraft.sg/[Datacraft] 59 | * http://www.datasnap.io/[DataSnap.io] 60 | * http://www.datomic.com/[Datomic] 61 | * http://democracy.works/[Democracy Works] 62 | * http://www.designed.ly/[Designedly] 63 | * https://www.db.com[Deutsche Bank] 64 | * http://dov-e.com[DOV-E] 65 | * http://dploy.io/[dploy.io] 66 | * http://drwtrading.com[DRW Trading Group] 67 | * http://www.ebay.com/[eBay] 68 | * http://element84.com[Element 84] 69 | * http://eventfabric.com/[Event Fabric] 70 | * https://www.exoscale.ch/[exoscale] 71 | * http://facebook.com[Facebook] 72 | * http://www.facjure.com/[Facjure] 73 | * http://www.factual.com/[Factual] 74 | * http://www.farbetter.com/[FarBetter] 75 | * https://farmlogs.com/[FarmLogs] 76 | * http://www.finalist.nl/[Finalist] 77 | * http://flocktory.com[Flocktory] 78 | * http://www.flowa.fi/[Flowa] 79 | * http://try.framed.io/[Framed Data] 80 | * https://www.fullcontact.com/[FullContact] 81 | * http://fundingcircle.com[Funding Circle] 82 | * http://www.getcontented.com.au/[GetContented] 83 | * http://about.getset.com/[GetSet] 84 | * https://goldfynch.com/[GoldFynch] 85 | * https://goodhertz.co/[Goodhertz] 86 | * http://www.gracenote.com/[Gracenote] 87 | * http://www.groupon.com[Groupon] 88 | * https://hashrocket.com/[Hashrocket] 89 | * https://www.helpshift.com/[Helpshift] 90 | * http://www.hendrickauto.com/[Hendrick Automotive Group] 91 | * http://www.heroku.com[Heroku] 92 | * https://hexawise.com/[Hexawise] 93 | * https://homescreen.is/[#Homescreen] 94 | * http://www.ib5k.com/[IB5k] 95 | * https://indabamusic.com[Indaba Music] 96 | * http://innoq.com[InnoQ] 97 | * http://www.intentmedia.com/[Intent Media] 98 | * http://www.intuit.com[Intuit] 99 | * http://www.iplantcollaborative.org/[iPlant Collaborative] 100 | * http://juxt.pro[JUXT] 101 | * https://kirasystems.com/[Kira Inc] 102 | * http://www.kontor.com[Kontor] 103 | * https://kwelia.com/[Kwelia] 104 | * http://leancloud.cn[Leancloud.cn] 105 | * http://en.leanheat.com[Leanheat] 106 | * http://levelmoney.com[Level Money] 107 | * http://www.lifebooker.com[Lifebooker] 108 | * http://liftoff.io/[Liftoff] 109 | * http://lightmesh.com[LightMesh] 110 | * http://likely.co/[Likely] 111 | * http://www.listora.com/[Listora] 112 | * http://www.liveops.com/[LiveOps] 113 | * https://www.livingsocial.com/[LivingSocial] 114 | * http://logicsoft.co.in/[Logic Soft Pvt. Ltd.] 115 | * http://lonocloud.com/[LonoCloud] (acquired by https://www.viasat.com/[ViaSat]) 116 | * http://www.madriska.com/[Madriska Inc.] 117 | * http://mainstreetgenome.com/[Main Street Genome] 118 | * http://www.mastodonc.com/[Mastodon C] 119 | * https://mazira.com/[Mazira] 120 | * http://meewee.com[MeeWee] 121 | * http://www.metail.com[Metail] 122 | * http://metosin.fi/[Metosin] 123 | * http://www.mixrad.io/[MixRadio] 124 | * http://www.modelogiq.com/[modelogiq] 125 | * http://www.mysema.com/[Mysema] 126 | * http://nilenso.com/[nilenso] 127 | * http://nemCV.com[nemCV.com] 128 | * https://www.netflix.com[Netflix] 129 | * https://www.nubank.com.br/[Nubank] 130 | * https://nukomeet.com/[Nukomeet] 131 | * http://numerical.co.nz/[Numerical Brass Computing] 132 | * https://opencompany.io/[OpenCompany] 133 | * http://OpenSensors.io[OpenSensors.io] 134 | * http://www.opentable.com/[OpenTable] 135 | * http://www.oracle.com[Oracle] 136 | * http://www.orgsync.com/[OrgSync] 137 | * http://otto.de[Otto] 138 | * http://www.outpace.com/[Outpace] 139 | * http://owsy.com[Owsy] 140 | * http://paddleguru.com[PaddleGuru] 141 | * http://www.bdpanacea.com/[Panacea Systems] 142 | * http://paper.li[paper.li] 143 | * https://www.parcelbright.com/[ParcelBright] 144 | * http://www.passivsystems.com/[PassivSystems] 145 | * http://path.com/[Path] 146 | * http://paygarden.com[PayGarden] 147 | * http://www.pennymacusa.com[PennyMac] 148 | * http://www.pivotal.io/[Pivotal Labs] 149 | * http://www.pointslope.com[Point Slope] 150 | * http://dmarc.postmarkapp.com/[Postmark] 151 | * https://precursorapp.com/[Precursor] 152 | * http://www.print.io/[Print.IO] 153 | * http://projexsys.com/[Projexsys] 154 | * https://publizr.com/[Publizr] 155 | * http://puppetlabs.com/[Puppet Labs] 156 | * https://www.rallydev.com/[Rally] 157 | * https://www.rareburg.com/[Rareburg] 158 | * https://www.redpineapplemedia.com/[Red Pineapple Media] 159 | * http://rentpath.com/[RentPath] 160 | * http://rjmetrics.com/[RJMetrics] 161 | * http://rocketfuel.com/[Rocket Fuel] 162 | * http://www.roomkey.com/[RoomKey] - see http://cognitect.com/consulting/case-studies/roomkey[case study] 163 | * http://roximity.com/[ROXIMITY] 164 | * http://www.salesforce.com/[Salesforce] 165 | * http://www.shareablee.com/[Shareablee] 166 | * http://shore.li/[shore.li] 167 | * http://www.signafire.com[Signafire] 168 | * http://silverline.mobi/[Silverline Mobile] 169 | * http://www.silverpond.com.au/[Silverpond] 170 | * https://www.simple.com/[Simple] 171 | * http://www.sinapsi.com/[Sinapsi] 172 | * http://us.sios.com/[SIOS Technology Corp.] 173 | * http://smilebooth.com/[Smilebooth] 174 | * http://smxemail.com/[SMX] 175 | * http://sonian.com/[Sonian] 176 | * https://soundcloud.com[Soundcloud] 177 | * https://www.sparkfund.co/[SparkFund] 178 | * https://www.spotify.com[Spotify] 179 | * http://www.staples-sparx.com/[Staples Sparx] 180 | * http://structureddynamics.com/[Structured Dynamics] 181 | * http://www.studyflow.nl[Studyflow] 182 | * http://www.suprematic.net/[Suprematic] 183 | * http://swirrl.com/[Swirrl] 184 | * http://www.tappcommerce.com/[Tapp Commerce] 185 | * http://www.technoidentity.com/[TechnoIdentity] 186 | * http://www.teradata.com[Teradata] - http://www.teradata.com/Teradata-Loom[Loom] 187 | * http://www.thinktopic.com/[ThinkTopic] 188 | * http://www.thoughtworks.com/[ThoughtWorks] - http://www.thoughtworks.com/clients/ioof[IOOF] (and others) 189 | * http://www.threatgrid.com/[ThreatGRID] (acquired by http://www.cisco.com/[Cisco]) 190 | * https://truckerpath.com[Trucker Path] 191 | * http://www.twosigma.com/[Two Sigma] 192 | * http://unbounce.com/[Unbounce] 193 | * https://unfold.com/[Unfold] 194 | * http://www.uhn.ca/[University Health Network] 195 | * http://www.upworthy.com/[Upworthy] 196 | * http://ustream.tv/[Ustream] 197 | * http://www.uswitch.com/[uSwitch] 198 | * http://vigiglobe.com/[Vigiglobe] 199 | * https://www.virool.com/[Virool] 200 | * http://vitallabs.co/[Vital Labs] 201 | * http://www.walmartlabs.com/[Walmart Labs] 202 | * https://www.whibse.com[Whibse] 203 | * http://wikidocs.com/[Wikidocs] (acquired by https://www.atlassian.com[Atlassian]) 204 | * http://wildbit.com/[Wildbit] 205 | * http://wit.ai[Wit.ai] (acquired by http://facebook.com[Facebook]) 206 | * http://worldsingles.com/[World Singles] 207 | * https://xcoo.jp/[Xcoo, Inc.] - https://chrov.is[Chrovis], http://newshack.io/[Hacker News Hack] 208 | * http://xnlogic.com[XN Logic] 209 | * http://yellerapp.com/[Yeller] 210 | * http://www.yieldbot.com[Yieldbot] 211 | * http://yetanalytics.com/[Yet Analytics] 212 | * http://yousee.dk/[Yousee IT Innovation Labs] 213 | * http://www.yummly.com/[Yummly] 214 | * http://www.yuppiechef.com/[Yuppiechef] 215 | * http://www.zendesk.com[Zendesk] 216 | --------------------------------------------------------------------------------