Reader Monad、代码重构、动态绑定变量?

Reader Monad, Code Refactor, dynamically bound vars?

现有代码:

参见:https://gist.github.com/anonymous/35ebb1485967b1e4a69adbb6272b186e

我正在为学习目的编写 WebGL 绑定。 (这个问题的目的不是关于 gamma/glsl 或 cljs-webgl -- 它是关于重构。WebGL 是一个次要的细节)。

问题

如果我们看一下上面的代码,许多函数要么将 gl 作为参数,要么将 glshaderProgram 作为参数。这里,gl 是 OpenGL 上下文,shaderProgram 是片段和顶点着色器。

一直传递gl有点乏味。在标准 Haskell 方法中,可以使用 Reader monad,将 gl 粘贴到 reader monad 中,然后完成它。

在Clojure中,我能想到的最接近的类似方法是:

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

问题:

我应该注意这种方法(性能?)有什么缺点吗?

这种方法还有其他解决方案吗?

这种用法正是创建动态变量的目的。

我假设你已经阅读了 https://clojuredocs.org/clojure.core/binding

请注意,动态变量也可用于 return 值。

您还应该查看:

您还应该看看:

2016 年 10 月 30 日更新

关于Plumatic Sc​​hema,我总是这样设置的:

(ns xyz
  (:require ...
    [schema.core :as sk]
  ))

; Prismatic Schema type definitions
(sk/set-fn-validation! true) 

这告诉 Schema 在函数入口时验证函数参数的类型。

我总是在我的测试命名空间中使用它, 并且通常也用于我的其他命名空间(始终在开发过程中,也经常在开发过程中)。它与类型检查编译器不同,但很接近。