Learn X in Y minutes

Where X=clojure

Get the code: learnclojure.clj

Clojure is a Lisp family language developed for the Java Virtual Machine. It hasa much stronger emphasis on purefunctional programming thanCommon Lisp, but
includes severalSTM utilities to handlestate as it comes up.

This combination allows it to handle concurrent processing very simply,and often automatically.

(You need a version of Clojure 1.2 or newer)

; Comments start with semicolons.

; Clojure is written in "forms", which are just
; lists of things inside parentheses, separated by whitespace.
;
; The clojure reader assumes that the first thing is a
; function or macro to call, and the rest are arguments. ; The first call in a file should be ns, to set the namespace
(ns learnclojure) ; More basic examples: ; str will create a string out of all its arguments
(str "Hello" " " "World") ; => "Hello World" ; Math is straightforward
(+ 1 1) ; => 2
(- 2 1) ; => 1
(* 1 2) ; => 2
(/ 2 1) ; => 2 ; Equality is =
(= 1 1) ; => true
(= 2 1) ; => false ; You need not for logic, too
(not true) ; => false ; Nesting forms works as you expect
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2 ; Types
;;;;;;;;;;;;; ; Clojure uses Java's object types for booleans, strings and numbers.
; Use `class` to inspect them.
(class 1) ; Integer literals are java.lang.Long by default
(class 1.); Float literals are java.lang.Double
(class ""); Strings always double-quoted, and are java.lang.String
(class false) ; Booleans are java.lang.Boolean
(class nil); The "null" value is called nil ; If you want to create a literal list of data, use ' to stop it from
; being evaluated
'(+ 1 2) ; => (+ 1 2)
; (shorthand for (quote (+ 1 2))) ; You can eval a quoted list
(eval '(+ 1 2)) ; => 3 ; Collections & Sequences
;;;;;;;;;;;;;;;;;;; ; Lists are linked-list data structures, while Vectors are array-backed.
; Vectors and Lists are java classes too!
(class [1 2 3]); => clojure.lang.PersistentVector
(class '(1 2 3)); => clojure.lang.PersistentList ; A list would be written as just (1 2 3), but we have to quote
; it to stop the reader thinking it's a function.
; Also, (list 1 2 3) is the same as '(1 2 3) ; "Collections" are just groups of data
; Both lists and vectors are collections:
(coll? '(1 2 3)) ; => true
(coll? [1 2 3]) ; => true ; "Sequences" (seqs) are abstract descriptions of lists of data.
; Only lists are seqs.
(seq? '(1 2 3)) ; => true
(seq? [1 2 3]) ; => false ; A seq need only provide an entry when it is accessed.
; So, seqs which can be lazy -- they can define infinite series:
(range 4) ; => (0 1 2 3)
(range) ; => (0 1 2 3 4 ...) (an infinite series)
(take 4 (range)) ; (0 1 2 3) ; Use cons to add an item to the beginning of a list or vector
(cons 4 [1 2 3]) ; => (4 1 2 3)
(cons 4 '(1 2 3)) ; => (4 1 2 3) ; Conj will add an item to a collection in the most efficient way.
; For lists, they insert at the beginning. For vectors, they insert at the end.
(conj [1 2 3] 4) ; => [1 2 3 4]
(conj '(1 2 3) 4) ; => (4 1 2 3) ; Use concat to add lists or vectors together
(concat [1 2] '(3 4)) ; => (1 2 3 4) ; Use filter, map to interact with collections
(map inc [1 2 3]) ; => (2 3 4)
(filter even? [1 2 3]) ; => (2) ; Use reduce to reduce them
(reduce + [1 2 3 4])
; = (+ (+ (+ 1 2) 3) 4)
; => 10 ; Reduce can take an initial-value argument too
(reduce conj [] '(3 2 1))
; = (conj (conj (conj [] 3) 2) 1)
; => [3 2 1] ; Functions
;;;;;;;;;;;;;;;;;;;;; ; Use fn to create new functions. A function always returns
; its last statement.
(fn [] "Hello World") ; => fn ; (You need extra parens to call it)
((fn [] "Hello World")) ; => "Hello World" ; You can create a var using def
(def x 1)
x ; => 1 ; Assign a function to a var
(def hello-world (fn [] "Hello World"))
(hello-world) ; => "Hello World" ; You can shorten this process by using defn
(defn hello-world [] "Hello World") ; The [] is the list of arguments for the function.
(defn hello [name]
(str "Hello " name))
(hello "Steve") ; => "Hello Steve" ; You can also use this shorthand to create functions:
(def hello2 #(str "Hello " %1))
(hello2 "Fanny") ; => "Hello Fanny" ; You can have multi-variadic functions, too
(defn hello3
([] "Hello World")
([name] (str "Hello " name)))
(hello3 "Jake") ; => "Hello Jake"
(hello3) ; => "Hello World" ; Functions can pack extra arguments up in a seq for you
(defn count-args [& args]
(str "You passed " (count args) " args: " args))
(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)" ; You can mix regular and packed arguments
(defn hello-count [name & args]
(str "Hello " name ", you passed " (count args) " extra args"))
(hello-count "Finn" 1 2 3)
; => "Hello Finn, you passed 3 extra args" ; Maps
;;;;;;;;;; ; Hash maps and array maps share an interface. Hash maps have faster lookups
; but don't retain key order.
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap ; Arraymaps will automatically become hashmaps through most operations
; if they get big enough, so you don't need to worry. ; Maps can use any hashable type as a key, but usually keywords are best
; Keywords are like strings with some efficiency bonuses
(class :a) ; => clojure.lang.Keyword (def stringmap {"a" 1, "b" 2, "c" 3})
stringmap ; => {"a" 1, "b" 2, "c" 3} (def keymap {:a 1, :b 2, :c 3})
keymap ; => {:a 1, :c 3, :b 2} ; By the way, commas are always treated as whitespace and do nothing. ; Retrieve a value from a map by calling it as a function
(stringmap "a") ; => 1
(keymap :a) ; => 1 ; Keywords can be used to retrieve their value from a map, too!
(:b keymap) ; => 2 ; Don't try this with strings.
;("a" stringmap)
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn ; Retrieving a non-present key returns nil
(stringmap "d") ; => nil ; Use assoc to add new keys to hash-maps
(def newkeymap (assoc keymap :d 4))
newkeymap ; => {:a 1, :b 2, :c 3, :d 4} ; But remember, clojure types are immutable!
keymap ; => {:a 1, :b 2, :c 3} ; Use dissoc to remove keys
(dissoc keymap :a :b) ; => {:c 3} ; Sets
;;;;;; (class #{1 2 3}) ; => clojure.lang.PersistentHashSet
(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3} ; Add a member with conj
(conj #{1 2 3} 4) ; => #{1 2 3 4} ; Remove one with disj
(disj #{1 2 3} 1) ; => #{2 3} ; Test for existence by using the set as a function:
(#{1 2 3} 1) ; => 1
(#{1 2 3} 4) ; => nil ; There are more functions in the clojure.sets namespace. ; Useful forms
;;;;;;;;;;;;;;;;; ; Logic constructs in clojure are just macros, and look like
; everything else
(if false "a" "b") ; => "b"
(if false "a") ; => nil ; Use let to create temporary bindings
(let [a 1 b 2]
(> a b)) ; => false ; Group statements together with do
(do
(print "Hello")
"World") ; => "World" (prints "Hello") ; Functions have an implicit do
(defn print-and-say-hello [name]
(print "Saying hello to " name)
(str "Hello " name))
(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff") ; So does let
(let [name "Urkel"]
(print "Saying hello to " name)
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel") ; Modules
;;;;;;;;;;;;;;; ; Use "use" to get all functions from the module
(use 'clojure.set) ; Now we can use set operations
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
(difference #{1 2 3} #{2 3 4}) ; => #{1} ; You can choose a subset of functions to import, too
(use '[clojure.set :only [intersection]]) ; Use require to import a module
(require 'clojure.string) ; Use / to call functions from a module
; Here, the module is clojure.string and the function is blank?
(clojure.string/blank? "") ; => true ; You can give a module a shorter name on import
(require '[clojure.string :as str])
(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
; (#"" denotes a regular expression literal) ; You can use require (and use, but don't) from a namespace using :require.
; You don't need to quote your modules if you do it this way.
(ns test
(:require
[clojure.string :as str]
[clojure.set :as set])) ; Java
;;;;;;;;;;;;;;;;; ; Java has a huge and useful standard library, so
; you'll want to learn how to get at it. ; Use import to load a java module
(import java.util.Date) ; You can import from an ns too.
(ns test
(:import java.util.Date
java.util.Calendar)) ; Use the class name with a "." at the end to make a new instance
(Date.) ; <a date object> ; Use . to call methods. Or, use the ".method" shortcut
(. (Date.) getTime) ; <a timestamp>
(.getTime (Date.)) ; exactly the same thing. ; Use / to call static methods
(System/currentTimeMillis) ; <a timestamp> (system is always present) ; Use doto to make dealing with (mutable) classes more tolerable
(import java.util.Calendar)
(doto (Calendar/getInstance)
(.set 2000 1 1 0 0 0)
.getTime) ; => A Date. set to 2000-01-01 00:00:00 ; STM
;;;;;;;;;;;;;;;;; ; Software Transactional Memory is the mechanism clojure uses to handle
; persistent state. There are a few constructs in clojure that use this. ; An atom is the simplest. Pass it an initial value
(def my-atom (atom {})) ; Update an atom with swap!.
; swap! takes a function and calls it with the current value of the atom
; as the first argument, and any trailing arguments as the second
(swap! my-atom assoc :a 1) ; Sets my-atom to the result of (assoc {} :a 1)
(swap! my-atom assoc :b 2) ; Sets my-atom to the result of (assoc {:a 1} :b 2) ; Use '@' to dereference the atom and get the value
my-atom ;=> Atom<#...> (Returns the Atom object)
@my-atom ; => {:a 1 :b 2} ; Here's a simple counter using an atom
(def counter (atom 0))
(defn inc-counter []
(swap! counter inc)) (inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter) @counter ; => 5 ; Other STM constructs are refs and agents.
; Refs: http://clojure.org/refs
; Agents: http://clojure.org/agents

Further Reading

This is far from exhaustive, but hopefully it’s enough to get you on your feet.

Clojure.org has lots of articles:http://clojure.org/

Clojuredocs.org has documentation with examples for most core functions:http://clojuredocs.org/quickref/Clojure%20Core

4Clojure is a great way to build your clojure/FP skills:http://www.4clojure.com/

Clojure-doc.org (yes, really) has a number of getting started articles:http://clojure-doc.org/


Got a suggestion? A correction, perhaps? Open an Issue on the Github Repo, or make a pull request yourself!

Originally contributed by Adam Bard, and updated by 4 contributors

这里是原文

Learn clojure in Y minutes的更多相关文章

  1. Learn X in Y minutes(python一页纸代码)

    一篇非常好的文章,解释了python基本语法的方方面面: # Single line comments start with a hash. """ Multiline ...

  2. Learn X in Y minutes Where X=c++

    http://learnxinyminutes.com/docs/c++/ C++ is a systems programming language that, according to its i ...

  3. Learn Lua in 15 Minutes

    原文地址:http://tylerneylon.com/a/learn-lua/ Learn Lua in 15 Minutes more or less For a more in-depth Lu ...

  4. 十分钟入门less(翻译自:Learn lESS in 10 Minutes(or less))

    十分钟入门less(翻译自:Learn lESS in 10 Minutes(or less)) 注:本文为翻译文章,因翻译水平有限,难免有缺漏不足之处,可查看原文. 我们知道写css代码是非常枯燥的 ...

  5. (76) Clojure: Why would someone learn Clojure? - Quora

    (76) Clojure: Why would someone learn Clojure? - Quora ★ Why would someone learn Clojure?   Edit

  6. Learn HTML5 in 5 Minutes!

    There's no question, HTML5 is a hot topic for developers. If you need a crash course to quickly unde ...

  7. 快速入门:十分钟学会PythonTutorial - Learn Python in 10 minutes

    This tutorial is available as a short ebook. The e-book features extra content from follow-up posts ...

  8. Learn jQuery in y seconds

    [兼容IE8以下没办法][虽不是Modern Web(不建议直接操作DOM)但也是一大利器] 个人推荐书[CSS 网站实录][JavaScript Dom 编程艺术][刚开始学不能太纠结机制机理原理因 ...

  9. Clojure新手入门

    官方网站 clojure.org 环境安装 Java(JDK) Leiningen 编辑工具 Eclipse插件 -- Counterclockwise IntelliJ插件 -- Cursive E ...

随机推荐

  1. iOS - MVP 架构模式

    1.MVP 从字面意思来理解,MVP 即 Modal View Presenter(模型 视图 协调器),MVP 实现了 Cocoa 的 MVC 的愿景.MVP 的协调器 Presenter 并没有对 ...

  2. Python学习(7)数字

    目录 Python 数字 Python 数字类型转换 Python 数学函数 Python 随机数函数 Python 三角函数 Python 数学常量 Python 数字 Python 数字数据类型用 ...

  3. Linux小知识

    1,ubuntu下,开机如何进行命令行? 图形模式下,首先进入终端: 1. 找到 /etc/default/grub文件: 2. 修改 GRUB_CMDLINE_LINUX_DEFAULT=" ...

  4. (一)解决Sublime Text 2中文显示乱码问题

    欲解决问题,关键在于让Sublime Text 2支持GB2312和GBK.步骤如下: 1.安装Sublime Package Control.   在Sublime Text 2上用Ctrl+-打开 ...

  5. SVM(支持向量机)与统计机器学习 & 也说一下KNN算法

    因为SVM和统计机器学习内容很多,所以从 http://www.cnblogs.com/charlesblc/p/6188562.html 这篇文章里面分出来,单独写. 为什么说SVM和统计学关系很大 ...

  6. 关于Java函数传参以及参数在函数内部改变的问题——JAVA值传递与引用最浅显的说明!

    看了很多关于阐述JAVA传参到底是值传递还是引用的问题,有些说得很肤浅让人感觉似懂非懂的感觉,但是好像又能解决一些问题,然后就止步了.还有一些则是,讲得很深奥,看着好像很有道理的样子,但是其实还是没怎 ...

  7. iOS开发之 XCode6.0的iOS免证书真机测试方法(MAC及黑苹果均有效)

    参考:http://mobile.51cto.com/iphone-455500.htm XCode6.0的iOS免证书真机测试方法(MAC及黑苹果均有效) 前提:设备已经越狱 目前在XCode上开发 ...

  8. VI经典插件ctags

    Vi经典插件ctags(转) (为了提高工作效率,必须学会使用一些工具) . 查看 key 相关信息说明的命令 :help keycodes ============================= ...

  9. Machine Learning for hackers读书笔记(三)分类:垃圾邮件过滤

    #定义函数,打开每一个文件,找到空行,将空行后的文本返回为一个字符串向量,该向量只有一个元素,就是空行之后的所有文本拼接之后的字符串 #很多邮件都包含了非ASCII字符,因此设为latin1就可以读取 ...

  10. NOI LINUX装机记

    装了差不多一天啊!! 首先自己用虚拟光驱来运行,然后莫名其妙就炸了. 搞到最后刻了一个盘. 然后装完linux之后发现回不到windows7了. 网上找各种资料. 最后搞了个root,再启动的文件中加 ...