• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

shaunlebron/ClojureScript-Syntax-in-15-minutes: cljs syntax is simple

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

shaunlebron/ClojureScript-Syntax-in-15-minutes

开源软件地址:

https://github.com/shaunlebron/ClojureScript-Syntax-in-15-minutes

开源编程语言:


开源软件介绍:

cljs

Translations: 中文.

If you just wanna try something, check out the interactive tutorial.

Hello, this is my attempt at a very concise guide to ClojureScript's syntax! ClojureScript is a Lisp dialect for front-end web development. It compiles to JavaScript for use in the browser.

ClojureScript is fundamentally different from JavaScript and other compile-to-JS languages like Dart, CoffeeScript, and TypeScript. It uses a more powerful yet simpler syntax. There are other differences not related to syntax, such as default immutability to combat the "new spaghetti code" that is mutatable stateful objects, and sane state management allowing language-level data-binding.

I believe that ClojureScript's largest barrier to entry for beginners is probably the foreign nature of its syntax. I hope to explain it as plainly and succinctly as possible with this guide.

Also, check out Parinfer if you want a simpler way to manage parentheses in ClojureScript.

Syntax

There is literal data:

; number
1.23

; string
"foo"

; keyword (like strings, but used as map keys)
:foo

; vector (array)
[:bar 3.14 "hello"]

; map (associative array)
{:msg "hello" :pi 3.14 :primes [2 3 5 7 11 13]}

; set (distinct elements)
#{:bar 3.14 "hello"}

And there is symbolic data:

; symbol (represents a named value)
foo

; list (represents a "call")
(foo :bar 3.14)

Evaluation

ClojureScript can evaluate data to create a new "value" from it.

  1. Literal data evaluates to itself, of course:

    1.23                 ; => 1.23
    "foo"                ; => "foo"
    [:bar 3.14 "hello"]  ; => [:bar 3.14 "hello"]
  2. A symbol evaluates to the value bound to it:

    foo                  ; => 3
  3. A list evaluates to the return value of a "call".

    (+ 1 2 3)            ; => 6
    (= 1 2)              ; => false
    (if true "y" "n")    ; => "y"

Calls

If the first element of a list is a function, then the rest of the elements are evaluated and passed to it (prefix notation).

; String concatenate function
(str "Hello " "World")  ; => "Hello World"

; Arithmetic functions
(= a b)     ; equality (true or false)
(+ a b)     ; sum
(- a b)     ; difference
(* a b c)   ; product
(< a b c)   ; true if a < b < c

; Evaluation Steps
(+ k (* 2 4))   ; assume k evalutes to 3
(+ 3 (* 2 4))   ; (* 2 4) evaluates to 8
(+ 3 8)         ; (+ 3 8) evalutes to 11
11

If the first element of a list is one of the language's few special forms, then the rest of the elements are passed to it unevaluated. (There are only 22 special forms.)

(if (= a b c)   ; <-- determines if a=b=c
    (foo 1)     ; <-- only evaluated if true
    (bar 2)     ; <-- only evaluated if false
    )

; define k as 3
(def k 3)       ; <-- notice that k is not evaluated here
                ;     (def needs the symbol k, not its value)

; make a greeting function
(fn [username]              ; <-- expected parameters vector
  (str "Hello " username))

; oops, give the function a name
(def greet (fn [username]
  (str "Hello " username)))

(greet "Bob")   ; => "Hello Bob"

If the first element of a list is a macro, then the rest of the elements are passed to it unevaluated, but the resulting value of the call is evaluated. Let's illustrate that difference with the following diagram:

calls

This difference in evaluation allows macros to act as code-generating functions. For example, the defn macro expands to def and fn, as we used separately in a previous example:

; create a named function using the defn macro
(defn greet [username]
  (str "Hello " username))

; the definition for the defn macro (over-simplified)
(defmacro defn [name args body]
  `(def ~name (fn ~args ~body)))

App developers rarely need to create their own macros, but it is an indispensible tool for the library developer to give app developers the full flexibility of the language.

Simple substitutions

There are a few macro characters that help make the language succinct by performing simple substitutions (not full macros):

; short-hand for creating a simple function:
; #(...) => (fn [args] (...))

#(* 3 %)         ; => (fn [x] (* 3 x))

#(* 3 (+ %1 %2)) ; => (fn [x y] (* 3 (+ x y)))

That's it for Syntax

You need to know more than syntax to be proficient in a language, of course. But you should now know enough to be comfortable looking around at examples and reasoning about how data is being evaluated and passed around:

; printing to the javascript console
(js/console.log "Hello World!")

; creating local bindings (constants)
(let [a (+ 1 2)
      b (* 2 3)]
  (js/console.log "The value of a is" a)
  (js/console.log "The value of b is" b))

; generate a sequence of numbers
(range 4) ; => (0 1 2 3)

; generate first four multiples of 3
(map #(* % 3) (range 4))           ;=> (0 3 6 9)

; count elements in a sequence
(count "Bob")     ; => 3
(count [4 5 2 3]) ; => 4

; select three letter names from a list
(def names ["Bob" "David" "Sue"])
(filter #(= (count %) 3) names) ; => ("Bob" "Sue")

(Don't worry about getting lost in parentheses. All modern text editors will highlight the corresponding ones and will indent your code automatically for readability, as is standard in every other language.)

ClojureScript vs JSX in HTML templating

See Jumping from HTML to ClojureScript to see how ClojureScript's syntax solves the verbosity/flexibility problems faced in the JS community by JSX.

A complete reference

The syntax section of the ClojureScript API reference is a comprehensive look at the possible syntax forms and even shows the source code for how each are read/parsed.

Useful Resources

Here are the resources and steps that I took while learning ClojureScript. (Most resources covering Clojure also apply to ClojureScript, since they share a significant subset with each other.)

  1. Reading through the ClojureScript Wiki
  2. Reading the book ClojureScript Up and Running
  3. Reading the book Clojure Programming
  4. Doing ClojureScript Koans
  5. Reading Clojure Style Guide
  6. Reading Clojure Programming By Example
  7. Reading Clojure Functional Programming
  8. Thumbing through Clojure Core API
  9. Reading ClojureScript - Differences from Clojure - Host Interop for accessing javascript properties like (.-Infinity js/window) and functions like (.sqrt js/Math 25).
  10. Reading JavaScript to ClojureScript synonyms
  11. Experimenting in lein repl for Clojure REPL.
  12. Experimenting in http://clojurescript.net/ for ClojureScript REPL with a browser context.
  13. Reading docstrings of functions I encounter with (doc <funcname>) in REPL.
  14. Miscellaneous ClojureScript things to know



鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap