You're viewing version 1.2.0 of let. The latest stable version of Clojure Core is 1.3.0.
1.2.0 Arrow_down_16x16
  • (let bindings & body)
Evaluates the exprs in a lexical context in which the symbols in
the binding-forms are bound to their respective init-exprs or parts
therein.

5 Examples top

  • ;; let is a Clojure special form, a fundamental building block of the language.
    ;;
    ;; In addition to parameters passed to functions, let provides a way to create
    ;; lexical bindings of data structures to symbols. The binding, and therefore 
    ;; the ability to resolve the binding, is available only within the lexical 
    ;; context of the let. 
    ;; 
    ;; let uses pairs in a vector for each binding you'd like to make and the value 
    ;; of the let is the value of the last expression to be evaluated. let also 
    ;; allows for destructuring which is a way to bind symbols to only part of a 
    ;; collection.
    
    ;; A basic use for a let:
    user=> (let [x 1] 
             x)
    1
    
    ;; Note that the binding for the symbol y won't exist outside of the let:
    user=> (let [y 1] 
             y)
    1
    user=> (prn y)
    java.lang.Exception: Unable to resolve symbol: y in this context (NO_SOURCE_FILE:7)
    
    ;; Another valid use of let:
    user=> (let [a 1 b 2] 
             (+ a b))
    3
    
    ;; The forms in the vector can be more complex (this example also uses
    ;; the thread macro):
    user=> (let [c (+ 1 2)
                 [d e] [5 6]] 
             (-> (+ d e) (- c)))
    8
    
    ;; The bindings for let need not match up (note the result is a numeric
    ;; type called a ratio):
    user=> (let [[g h] [1 2 3]] 
             (/ g h))
    1/2
    
    ;; From http://clojure-examples.appspot.com/clojure.core/let with permission.
  • user=> (let [a (take 5 (range))
                 {:keys [b c d] :or {d 10 b 20 c 30}} {:c 50 :d 100}
                 [e f g & h] ["a" "b" "c" "d" "e"]
                 _ (println "I was here!")
                 foo 12
                 bar (+ foo 100)]
             [a b c d e f g h foo bar])
    I was here!
    [(0 1 2 3 4) 20 50 100 "a" "b" "c" ("d" "e") 12 112]
    
  • ; :as example 
    
    user=> (let [[x y :as my-point] [5 3]]
             (println x y)
             (println my-point))
    
    5 3
    [5 3]
    
    ; :as names the group you just destructured.
    
    ; equivalent to (and better than)
    
    user=> (let [[x y] [5 3]
                 my-point [x y]]
             ;...
  • ;;; map destructuring, all features
    user=>
    (let [
          ;;Binding Map
          {:keys [k1 k2]        ;; bind vals with keyword keys
           :strs [s1 s2]        ;; bind vals with string keys
           :syms [sym1 sym2]    ;; bind vals with symbol keys
           :or {k2 :default-kw, ;; default values
                s2 :default-s, 
                sym2 :default-sym} 
           :as m}  ;; bind the entire map to `m`
          ;;Data
          {:k1 :keyword1, :k2 :keyword2,  ;; keyword keys
           "s1" :string1, "s2" :string2,  ;; string keys
           'sym1 :symbol1,                ;; symbol keys
           ;; 'sym2 :symbol2              ;; `sym2` will get default value
           }] 
      [k1 k2 s1 s2 sym1 sym2 m])  ;; return value
    
    [:keyword1, :keyword2, 
     :string1, :string2,
     :symbol1, :default-sym, ;; key didn't exist, so got the default
     {'sym1 :symbol1, :k1 :keyword1, :k2 :keyword2, 
      "s1" :string1, "s2" :string2}]
    
    ;; remember that vector and map destructuring can also be used with 
    ;; other macros that bind variables, e.g. `for` and `doseq`
  • ;;; no value of a key
    user> (let [{:keys [a b] :as m} (:x {})]
            [a b m])
    [nil nil nil]
    
    ;;; same as above
    user> (let [{:keys [a b] :as m} nil]
            [a b m])
    [nil nil nil]
    
    ;;; similar case on Vector
    user> (let [[a b :as v] nil]
            [a b v])
    [nil nil nil]
    
Log in to add / edit an example.

See Also top

Log in to add a see also.

Plus_12x12 Minus_12x12 Source clojure/core.clj:3461 top

(defmacro let
  "Evaluates the exprs in a lexical context in which the symbols in
  the binding-forms are bound to their respective init-exprs or parts
  therein."
  {:added "1.0"}
  [bindings & body]
  (assert-args let
     (vector? bindings) "a vector for its binding"
     (even? (count bindings)) "an even number of forms in binding vector")
  `(let* ~(destructure bindings) ~@body))
Vars in clojure.core/let: count defmacro destructure even? vector? concat list seq
Used in 849 other vars (expand)
find-protocol-impl vector-of time doseq for fn ns-publics with-open gen-interface distinct get-in dotimes promise derive -reset-methods partition-by proxy-call-with-super ns-interns re-matches find-doc loop import select-keys assoc! defrecord with-out-str re-groups concat bases assoc seque future-call doto rsubseq ns-refers map when-first slurp restart-agent ref definline bound-fn* shuffle re-find destructure intern to-array-2d filter re-seq -cache-protocol-fn ns test resultset-seq with-precision proxy-name or defn parents condp with-local-vars get-proxy-class when-let comp dissoc! load reduce interleave amap macroexpand bean memoize range tree-seq defmacro case deftype supers load-string group-by await pmap if-let and refer underive ancestors locking partition definterface defmulti proxy reify mod drop gen-class defonce disj io! merge-with areduce make-array juxt trampoline drop-while sort dissoc binding doc agent subseq await-for keep disj! arr-impl old-table-model list-model as-relative-path javadoc sh skip-if-eol repl-read repl formatter-out formatter write write-out cl-format pprint-logical-block set-pprint-dispatch apropos source-fn union join intersection index print-stack-trace print-trace-element replace capitalize escape replace-first trim-newline do-template assert-predicate testing-vars-str run-tests test-ns file-position test-all-vars assert-any start-suite message-el suite-attrs package-class with-junit-output keywordize-keys stringify-keys content-handler down insert-left up leftmost replace insert-right root right left remove rightmost deftype capture-and-send encode encode-str make-map with-command-line print-help cond-let print-stack-trace handler-case name-with-attributes defnk dissoc-in reverse-graph remove-cells update-values add-cell-watcher add-cells get-cell get-values print-dataflow dependency-list cell build-dataflow get-value ?- merge-relations <- add-index ensure-relation non-base-rules predicate-map apply-rule make-database compute-sip evaluate-soft-work-set remove-tuple build-soft-strat-work-plan is-safe? add-tuple is-query-var? map-values preduce is-var? build-seed-bindings delta-literal project-literal literal-magic? magic-literal build-atom magic-transform adorn-rules-set seed-rule seed-relation seed-predicate-for-insertion slurp* file-str read-lines deferror with-handler rebind-fn raise* fcase read-ns-decl show get-source expression-info apropos add-break-thread! generate-documentation start-handling-break find-javadoc-url javadoc defadt defmethod* fixed-point component-graph recursive-component? scc transitive-closure lazy-walk stratification-list headers-seq http-agent stream buffer-bytes import-static slurp* file-str read-lines delete-file-recursively with-system-properties as-properties delete-file-recursively open-url-in-swing with-connection guess-attribute-typename jmx-url -getAttributes json-str formatter-out write primes fill-queue parse-seq attributes emit log-stream log spy log-capture! macrolet deftemplate defsymbolmacro symbol-macrolet with-direct-linking letfn- exact-integer-sqrt add-components format-constraints miglayout parse-item-constraints mmap buffer-stream has-matching-signature? make-arg-checker make-mock make-count-checker get-ns immigrate with-monad domonad defmonad censor call-cc monad monad-transformer m-reduce listen write defmonadfn with-state-field m-lift update-val formatter column-writer consume-while map-passing-context execute-format consume end-block pprint-defn indent pretty-writer prefix-count rtrim pprint-anon-func buffer-length emit-nl pprint-let write-out ltrim start-block cl-format init-navigator nl compile-format add-core-ns pprint-logical-block set-pprint-dispatch pprint-reader-macro normalize uniform binomial normalize-cond sample-mean-variance sample sample-sum exponential interval n-sphere sample-mean normal-box-muller normal sample-reduce reject summarize prof print-summary with-system-properties as-properties escape repl-info set-repl-name print-repl-info repl-prompt repl stream-repl rec-seq partition-by shuffle group-by rec-seq partition-by fill-queue shuffle group-by sh sh global-singleton per-thread-singleton update-values insert-values transaction* get-connection delete-rows update-or-insert-values re-sub re-partition re-gsub swap-case codepoints docodepoints dochars escape partition chop pick pick-all defst stream-seq stream-drop swap-case replace-by codepoints replace-first-by docodepoints dochars partition chop make-menubar make-action add-key-typed-listener add-action-listener do-template assert-predicate testing-vars-str apply-template run-tests test-ns file-position test-all-vars assert-any dotrace deftrace trace-fn-call match with-temp-ns run-httpcore run-jetty make-service-method wrap-cookies wrap-file wrap-file-info wrap-flash wrap-lint wrap-multipart-params wrap-params memory-store wrap-session cookie-store wrap-static sample-mvn-params symmetric-matrix sample-mvn sample-inv-wishart sample-gamma mean sample-dirichlet kronecker sample-model-params sample-normal mmult truncated-variance pdf-normal censored-mean-upper censored-variance-upper censored-mean-lower censored-variance-two-sided censored-variance-lower censored-mean-two-sided cdf-normal area-chart* time-series-plot box-plot add-box-plot add-categories quantile-normal stacked-area-chart* add-function* scatter-plot* grid-apply set-stroke-color $ stacked-bar-chart bar-chart quantile add-histogram* heat-map xy-plot add-image add-pointer histogram* add-points* pie-chart scatter-plot dynamic-scatter-plot conj-cols line-chart heat-map* slider function-plot function-plot* add-polygon $group-by add-points add-categories* box-plot* add-text histogram sliders stacked-bar-chart* group-on pie-chart* trace-plot set-stroke qq-plot add-box-plot* bar-chart* xy-plot* bland-altman-plot add-function add-lines stacked-area-chart area-chart set-theme dynamic-xy-plot add-histogram sliders* line-chart* sum to-dummies $join decomp-eigenvalue to-dataset $rollup cumulative-sum decomp-svd query-dataset decomp-qr $order deshape query-to-pred sum-of-squares to-labels categorical-var conj-rows dataset solve-quadratic decomp-lu infix-to-prefix data-table to-levels prod to-matrix $map read-dataset get-dataset test-statistic-distribution read-xls save-xls write-cell latex add-latex add-latex-subtitle fetch-dataset hessian integrate gradient non-linear-model derivative save-pdf export-font with-rotation sketch with-translation save-font principal-components covariance som-batch-train cdf-t normalized-kendall-tau-distance t-test pdf-f cdf-exp quantile-t tabulate chisq-test pdf-neg-binomial detabulate mahalanobis-distance cdf-gamma cdf-beta pairings lee-distance sample damerau-levenshtein-distance pdf-poisson pdf-exp sample-uniform sample-t levenshtein-distance discordant-pairs kendalls-tau sample-exp sample-multinomial spearmans-rho pdf-gamma cdf-poisson cdf-uniform permute pdf-binomial cdf-binomial cosine-similarity median dice-coefficient simple-regression sample-poisson cdf-chisq sample-permutations pdf-chisq pdf-uniform sample-beta cdf-f predict hamming-distance pdf-t pairs minkowski-distance pdf-beta sweep linear-model tanimoto-coefficient correlation-ratio bootstrap cdf-neg-binomial sample-neg-binomial correlation sample-wishart chebyshev-distance sample-binomial sample-chisq deriv-fn* deriv* define-ant-task set-property! runonce instantiate-task ant-project define-ant-type deftarget checkout-deps-paths make-path empty-directory find-native-lib-path compilable-namespaces stale-namespaces eval-in-project deps defproject resolve-task -main make-dependency help-summary-for help-for pom install jar make-model make-local-repo get-jar-filename new make-git-scm make-mailing-list read-git-head repl-server repl test form-for-testing-namespaces uberjar describe for-these run-tests colorize report-function describe defn! has-matching-signature? make-arg-checker make-mock make-count-checker fail for-these symbol-of string-of list-of collection-generator for-all dump-results name-line report-string story-lines result-string default-error-message default-fail-message make-test-name report-tally run-tests with-timing rewrite-=> run-tests-and-exit should-exception-matches debug-repl local-bindings given and when then find-recent-namespaces-in-dir run-watcher test-namespace dr-read local-bindings eval-with-locals lefts annotate add-class union select transform-content text-pred lockstep-transform snippet* defsnippets select-nodes* intersection select-fragments* rights let-select remove-class move right left parse calculate-restarts operator-arglist eval-from-control who-specializes eval-for-emacs xref symbol-name-parts dothread-keeping-clj swank-toggle-trace ns-path char-position source-location-for-frame listener-eval with-env-locals list-threads find-definitions-for-emacs one-of? set-package local-bindings returning keep-bindings compile-string-for-emacs apropos-list-for-emacs who-calls dispatch-event with-package-tracking simple-completions expand-wildcard resolve-class scan-paths arglist-for-echo-area split-compound-prefix-match? completions compound-prefix-match? fuzzy-completions make-connection assign-index inspect-frame-var ref-pop inspector-call-nth-action inspector-next content-range print-part-to-string read-swank-message call-on-flush-stream read-chars relative-path-name init delete-file-recursive all-files-in-directory clean-up decode-message dispatch-message encode-message start-repl start-server receive send expect* call-faker expect user-file-position expect* call-faker user-file-position ssh-sftp-cmd ssh-shell session add-identity-with-keychain with-connection ssh-exec ssh-sftp ssh sftp create-ssh-agent with-ssh-agent contract defconstrainedfn new-object-tester i-want partial-namespace-matcher new-sandbox new-sandbox-compiler tree-map expand-and-quote thunk-timeout new-tester s-seq extend-tester general-button <3 seq-ref-combobox-model add-str-ref-doc-listener string-ref-content label paint-donut shelf mapref-tree-model general-panel jlist stack seq-ref-list-model frame tree-example tree changed-path cartesian-product combinations expect has-matching-signature? lex-permutations make-arg-checker make-count-checker make-mock permutations provide-contracts

Comments top

1 comment(s) for let.

Nota Bene: let in Clojure is like let* in Scheme -- each init-expr has access to the preceding binding forms. (There is also a let*, but it is more or less let without destructuring, and in fact is the underlying implementation.)

Log in to add a comment.