Fork me on GitHub
Denis G09:05:14

Just implemented Brainfuck interpreter in Clojure 😄 Is there a smart way of doing ADTs other than dictionaries and creating multimethods which are dispatched by key? This is the way I did it :face_with_rolling_eyes: Challenge link: Code link:

👍 4

@denisgrebennicov that's the usual way to do it


After a long time in the CLJS world, I need to jump back to Clojure to create a simple server (mostly a wrapper around large existing Java libs, to deliver a REST API). What's the current best-practice set of libraries for this?

Denis G13:05:06

I guess it’s compojure, but don’t quote me on that


I've got a load of functions that take an optional first parameter, and then calls itself inside a binding. e.g.

(defn foo 
  ([opts a b c] (binding [*options* opts] (foo a b c)))
  ([a b c] (+ a b c)))
but it's a bit... repetitive, so I decided to write a macro, to do the binding for me
(defmacro defn-opts [name args & body]
  `(defn ~name
     ([options# [email protected]] (with-options options# (~name [email protected])))
     ([[email protected]] [email protected])))
Works fine... Until my function has var-args. e.g.
(defn-opts vargs [& args] (count args))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: & in this context, compiling:(/tmp/form-init835293560141170332.clj:1:1)
but I'm finding it impossible to google a solution, because & isn't googleable. Is there a solution to this? I imagine it is as defn is a macro.


also, is there a way to support (optional?) docstrings in my macro like defn would? or do I need to rewrite most of defn?


you would need to rewalk some of what defn does - both looking for and handling the special symbol & and determining whether the first arg is a string


one way to do this would be to write a spec for the args and conform the arg list against the spec - this gives you a data structure describing how the args conform


lucky for you, defn already has a spec!


oh what. defn is a function.


defn is a macro and you can see it’s spec with (doc defn)

xlevus15:05:50 looks pretty functioney here? or is the (. (var defn) (setMacro)) the special sauce?


macros are functions with a meta flag


that flag tells the compiler to expand rather than invoke


in this particular case, defn is being defined not with defmacro because defmacro has not yet been defined (as this is during bootstrap)


defmacro is itself … a macro


anyhow, I digress


you can conform the args to a defn-like macro using the spec :clojure.core.specs.alpha/defn-args


user=> (s/conform :clojure.core.specs.alpha/defn-args '[vargs [& args] (count args)])
{:name vargs, :bs [:arity-1 {:args {:varargs {:amp &, :form [:sym args]}}, :body [:body [(count args)]]}]}


the defn spec knows how to parse the varargs out and break down the inputs. some code would be needed to decide how to transform this data structure into your macro output. That may or may not be harder than manipulating the incoming args directly (but keep in mind that the spec understand the full set of destructuring and nested destructuring that’s possible)


user=> (pprint (s/conform :clojure.core.specs.alpha/defn-args '[vargs [{:keys [foo bar]} [[a b & c]] & args] (count args)]))
{:name vargs,
    [[:map {:keys [foo bar]}]
         {:elems [[:sym a] [:sym b]],
          :rest {:amp &, :form [:sym c]}}]]}]],
    :varargs {:amp &, :form [:sym args]}},
   :body [:body [(count args)]]}]}


you should be able to actually manipulate that data structure too and then s/unform to get back to a “signature” but there is a known issue in this particular spec that the arg vectors will roundtrip back to lists instead


[a & b], & b is just a way of denoting rest parameters, correct?


i’m trying to write a clojurescript macro that expands to include a function call that is defined in my own code base. e.g.: i’m writing a macro in my-project/macros ns in a clojure file and i want the expanded macro to call a function in my-project/util, which is a cljs file. do i just hard code the namespace?


Hello, I am a beginner in Clojure with async.core. I was wondering if knew of any good resources regarded async especially with 'channels'.