Back
if-let (clj)
(source)macro
(if-let bindings then)
(if-let bindings then else & oldform)
bindings => binding-form test
If test is true, evaluates then with binding-form bound to the value of
test, if not, yields else
Examples
nextjournal/clerk
(ns nextjournal.clerk.atom
"Demo of Clerk's two-way bindings."
{:nextjournal.clerk/visibility {:code :hide :result :hide}}
(:require [clojure.core :as core]
[nextjournal.clerk :as clerk]))
(def counter-viewer
{:transform-fn transform-var
:render-fn '(fn [var-name]
(if-let [var (resolve var-name)]
(let [atom @var]
[:div
[:h2 "Counter Example"]
[:button.px-2.py-1.bg-blue-200.mr-1 {:on-click #(swap! atom update :counter inc)} "+"]
[:button.px-2.py-1.bg-blue-200.mr-1 {:on-click #(swap! atom update :counter dec)} "-"]
[:button.px-2.py-1.bg-blue-200.mr-1 {:on-click #(swap! atom (fn [_] {:counter 0}))} "reset"]
[nextjournal.clerk.render/inspect @atom]])
[:div "could not resolve" var-name]))})
clojure/core.typed
;copied from tools.analyzer.js
(ns clojure.core.typed.analyzer.js.passes.analyze-host-expr
(:require [clojure.core.typed.analyzer.common :as common]
[clojure.core.typed.analyzer.common.env :as env]
[clojure.core.typed.analyzer.common.js :as anajs]))
(defmethod analyze-host-expr :maybe-class
[{:keys [class env] :as ast}]
(if-let [v (common/resolve-sym class env)]
(merge (dissoc ast :class)
{:op :js-var
::common/op ::ana-js/js-var
:var v
:assignable? true})
ast))
mikera/core.matrix
WARNING: because they lack efficient indexed access, sequences will perform badly for most
array operations. In general they should be converted to other implementations before use."
(:require [clojure.core.matrix.protocols :as mp]
[clojure.core.matrix.implementations :as imp]
#?(:clj [clojure.core.matrix.macros :refer [scalar-coerce error]]))
#?(:clj (:import [clojure.lang ISeq])
:cljs (:require-macros [clojure.core.matrix.macros :refer [scalar-coerce error]])))
(extend-protocol mp/PIndexedAccess
ISeq
(get-1d [m x]
(scalar-coerce (nth m x)))
(get-2d [m x y]
(let [row (nth m x)]
(mp/get-1d row y)))
(get-nd [m indexes]
(if-let [indexes (seq indexes)]
(if-let [next-indexes (next indexes)]
(let [mv (nth m (first indexes))]
(mp/get-nd mv next-indexes))
(nth m (first indexes)))
m ;; TODO: figure out if this is a good return value? should it be an error?
)))
PrecursorApp/precursor
(ns pc.http.routes.api
(:require [cemerick.url :as url]
[cheshire.core :as json]
[clojure.core.memoize :as memo]
[clojure.string :as str]
[clojure.tools.reader.edn :as edn]
[crypto.equality :as crypto]
[defpage.core :as defpage :refer (defpage)]
[pc.auth :as auth]
[pc.crm :as crm]
[pc.datomic :as pcd]
[pc.early-access]
[pc.http.doc :as doc-http]
[pc.http.team :as team-http]
[pc.http.handlers.custom-domain :as custom-domain]
[pc.models.chat-bot :as chat-bot-model]
[pc.models.doc :as doc-model]
[pc.models.flag :as flag-model]
[pc.models.team :as team-model]
[pc.profile :as profile]
[ring.middleware.anti-forgery :as csrf]
[slingshot.slingshot :refer (try+ throw+)]))
(defpage early-access [:post "/api/v1/early-access"] [req]
(if-let [cust (get-in req [:auth :cust])]
(do
(pc.early-access/create-request cust (edn/read-string (slurp (:body req))))
(pc.early-access/approve-request cust)
{:status 200 :body (pr-str {:msg "Thanks!" :access-request-granted? true})})
{:status 401 :body (pr-str {:error :not-logged-in
:msg "Please log in to request early access."})}))
(defpage create-solo-trial [:post "/api/v1/create-solo-trial"] [req]
(if-let [cust (get-in req [:auth :cust])]
(do
(flag-model/add-flag cust :flags/private-docs)
{:status 200 :body (pr-str {:msg "Thanks!" :solo-plan-created? true})})
{:status 401 :body (pr-str {:error :not-logged-in
:msg "Please log in to request early access."})}))
hraberg/deuce
(ns deuce.emacs.eval
(:use [deuce.emacs-lisp :only (defun defvar)])
(:require [clojure.core :as c]
[deuce.emacs.alloc :as alloc]
[deuce.emacs.data :as data]
[deuce.emacs-lisp.cons :as cons]
[deuce.emacs-lisp :as el])
(:import [clojure.lang Var])
(:refer-clojure :exclude [apply eval macroexpand]))
(defun defvaralias (new-alias base-variable &optional docstring)
"Make NEW-ALIAS a variable alias for symbol BASE-VARIABLE.
Aliased variables always have the same value; setting one sets the other.
Third arg DOCSTRING, if non-nil, is documentation for NEW-ALIAS. If it is
omitted or nil, NEW-ALIAS gets the documentation string of BASE-VARIABLE,
or of the variable at the end of the chain of aliases, if BASE-VARIABLE is
itself an alias. If NEW-ALIAS is bound, and BASE-VARIABLE is not,
then the value of BASE-VARIABLE is set to that of NEW-ALIAS.
The return value is BASE-VARIABLE."
(if-let [base (el/global base-variable)]
(el/defvar-helper* 'deuce.emacs-lisp.globals new-alias
@base (or docstring (-> base meta :doc)))
(when-let [new (el/global new-alias)]
(el/defvar-helper* 'deuce.emacs-lisp.globals base-variable
@new (or docstring (-> new meta :doc)))))
base-variable)
The second optional arg ENVIRONMENT specifies an environment of macro
definitions to shadow the loaded ones for use in file byte-compilation."
;; Not sure how this is supposed to work even after reading eval.c, attempts to mimic observed behavior.
;; It is used in conjunction with cl-macroexpand-all, and should not expand into "raw" Clojure.
(let [shadow (into {} (map #(vector (data/car %) (data/cdr %)) environment))
shadow #(shadow % (shadow (str %)))
unshadowed-form ((fn shadow-walker [form]
(if-let [expander (shadow form)]
(if (= '(true) (data/cdr-safe expander))
(cons (first (data/car expander))
(map #(list 'quote %) (rest (data/car expander))))
(expander form))
(if (and (seq? form)
(not= 'quote (first form)))
(cons/maybe-seq (map shadow-walker form))
form))) form)
expansion (if-let [m (and (seq? form) (-> (el/fun (first form)) meta))]
(if (and (:macro m) (= (the-ns 'deuce.emacs-lisp) (:ns m)))
unshadowed-form
(macroexpand-1 unshadowed-form))
unshadowed-form)]
;; Protect against eq check in cl-macroexpand-all
(if (= form expansion)
form
expansion)))