Search code examples
clojureclojurescript

Reader Monad, Code Refactor, dynamically bound vars?


Existing Code:

See: https://gist.github.com/anonymous/35ebb1485967b1e4a69adbb6272b186e

I'm writing a WebGL binding for learning purposes. (The purpose of this question is not about gamma/glsl or cljs-webgl -- it's about refactoring. WebGL is a minor detail).

Problem

If we look at the code above, many functions take either gl as an argument or gl and shaderProgram as an argument. Here, gl is the OpenGL context and shaderProgram is the fragment and vertex shaders.

It's somewhat tedious to pass gl around all the time. In standard Haskell approach, one would use a Reader monad, stick gl in the reader monad, and be done with it.

In Clojure, the closest similar approach I can think of is:

(binding [*gl* ... ]) ;; and use a dynamically bound var.

Question:

Are there any downsides to this approach (performance?) I should be aware of?

Are there other solutions to this approach?


Solution

  • This usage is exactly what dynamic vars were created for.

    I assume you've read https://clojuredocs.org/clojure.core/binding

    Note that dynamic vars can also be used for return values.

    You should also check out:

    You should also look at:

    UPDATE 2016-10-30

    Regarding Plumatic Schema, I always set it up like so:

    (ns xyz
      (:require ...
        [schema.core :as sk]
      ))
    
    ; Prismatic Schema type definitions
    (sk/set-fn-validation! true) 
    

    This tells Schema to verify the types of function arguments upon function entry.

    I always use this in my test namespaces, and usually for my other namespaces as well (always during development, often later too). It is not the same as a type-checking compiler, but it is close.