Skip to content

Instantly share code, notes, and snippets.

@thheller
Last active August 19, 2022 17:14
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thheller/fa044450a6470fdd1afdbcf3f37a65e3 to your computer and use it in GitHub Desktop.
Save thheller/fa044450a6470fdd1afdbcf3f37a65e3 to your computer and use it in GitHub Desktop.

Dealing with platform specific code

Sometimes you need to modifiy code depending on which target it is running in. Say you are writing a :browser app but parts of the code should also work in :react-native. The way I deal with this by abstracting out the relevant bits and either providing separate implementations of a protocol or just plain functions.

Interface code

;; shared ns that defines the "interface"
;; with actual implementation added later
(ns my.app.env)

(defonce runtime-ref (atom {})

(defprotocol HostSpecific
  (-something [impl foo bar]))

(defn something [foo bar]
  (-something (:impl @runtime-ref) foo bar))

(defn just-a-fn [foo bar]
  (let [actual (:just-a-fn @runtime-ref)]
    (actual foo bar))

Consumer of "interface" without knowing impl

(ns my.app.shared
  (:require [my.app.env :as env]))

...

(defn some-shared-fn [foo]
  (env/something foo (some-thing-shared)))

Main Host

only included in actual browser build (via :entries)

(ns my.app.browser
  (:require
    [my.app.env :as env]
    [my.app.shared :as shared]
    ["react-dom" :as x]))

(defn that-fn [foo bar]
  [::browser foo bar])) 

(defn init []
  (swap! env/runtime-ref assoc
    :just-a-fn that-fn
    :impl (reify env/HostSpecific
            (-something [_ foo bar]
              [::browser foo bar]))))

Other Host specific parts

(ns my.app.react-native
  (:require
    [my.app.env :as env]
    [my.app.shared :as shared]
    ["react-native" :as x]))

(defn that-fn [foo bar]
  [::react-native foo bar])) 

(defn init []
  (swap! env/runtime-ref assoc
    :just-a-fn that-fn
    :impl (reify env/HostSpecific
            (-something [_ foo bar]
              [::react-native foo bar]))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment