Fork me on GitHub
Drew Verlee00:10:53

are their any problems with referring ... cross referring namespaces?

(ns foo (:require [bar]))
(ns bar (:require [foo]))
I would think so, but i just tried it at seems to work.


it will work if the other ns already exists in your process


circular deps break when starting from scratch though

Drew Verlee00:10:28

so its better to just think of a different way?


the answer is usually a third ns that uses both


or a third ns that both use


for things near the "edges" of my system (things other code outside my codebase interact with) it's often worth it to break things up into a protocol and something that implements the protocol - the code defining the protocol has no dependencies and everyone can access it, and other namespaces can implement its functions


that way everybody can call code from everybody else, as long as the functions called are protocol functions and the implementing things are passed in at runtime

Drew Verlee01:10:54

Thats interesting, ill have to bookmark that thought and think about it for a while. I have been shying away from protocols. I think i understand the usefulness, i just assumed it was mainly about the polymorphism.


it is mainly about polymorphism, but it can be a useful kind of indirection as well


but it's not always appropriate to formalize things like that, functions and hash-maps get you pretty far too, it depends on what you are implementing and how it's meant to be used

Drew Verlee01:10:56

i think i understand, for my immediate problem i just reconciled that even though the vars were the same values, they weren't really the same var. So i can duplicate var across the two namespaces, as its actual more clear that way (they dont need to be kept in sync).


this is why protocols help, since the functionality belongs to an object, not a namespace, and each object can interact with functionality provided by the other if you line up the argument passing right

Drew Verlee01:10:04

If the shared concept was a datastructure though, would this be relevant? (def person "jeff") in namespace foo and in bar? I think i might need to see a toy example to be sure i understand you correctly.


look at how clojure implements datastructures - it's protocol first, all the code on datastructures targets a protocol not a specific class


but wait, "jeff" isn't a datastructure, it's a string


the idea is that instead of referring to globals in other namespaces, you use keywords to access it on a record if it's data, and protocol methods to invoke it if it's code


when you aren't pointing at a global any more, the circularity problems disappear

Drew Verlee01:10:48

Your right "jeff" is just a string, i suppose i was trying to express that my global is data that wasn't a function. i must have a misunderstanding. How does it change circulatory problems if i refer to a map vs a record? I thought records were just maps that were more faster to do runtime dispatch on with procols (vs multimethods). Are records not namespaced in the same way?


a map doesn't belong to some global storage, so it's easy to make two namespaces share functionality via a map


@drewverlee code organization has always been a bit of a hurdle IMO. I think Zach Tellman’s book Elements of Clojure is worth a read, as is Practical Clojure.


Is there an idiomatic non-lazy version of a single level flatmap that can be used instead of (apply contact (map ...))?


into only has 2 arities.


@vinai (into [] cat [coll0 coll1 coll2])


Thanks @rauh... need to digest that one a moment 🙂


Oh, cat is cool. Never saw it until now!


Hello! Do you have suggestions for open-source projects that showcase the strengths of combining Clojure on the server with Clojurescript on the browser? Simple or complex, I'm just curious to see how such a project would look like.


is there actively developed clj oauth library ? from Web Dev with Clj i got but last commit was in 2016 is that still good for production ?


@lepistane A lot of Clojure libraries are small but become stable quickly and often need no further maintenance. Last commit isn't always a useful measure. See if there are outstanding PRs or issues with no follow-up from the maintainer.


makes sense i will pay more attention on that


Hi. I’ve done most of my variable assignments with (let ...) and (def ...). If I declare a variable with (declare x), how can I later assign a value to x?


declare does a def behind the scenes anyway


(macroexpand '(declare a b c))
(do (def a) (def b) (def c))


@wpcarro declare is mostly useful for defining functions, where fn A calls fn B and B calls A. Use (declare B) so the compiler won’t complain about undefined vars, then define fn A using B, then define B with defn just like you normally would.


@manutter51 ah the motivation behind that makes sense since there’s no hoisting etc


whole point of functional programming is to avoid variable assignment @wpcarro read get fully get what i am talking about having said that i haven't used declare so i am unable to help you there specifically. hope you are using assignment intelligently good lcuky


thanks @sundarj did not know that


@lepistane I’m familiar with the impetus behind FP… unfortunately I’m porting a JavaScript example to ClojureScript ………. it’s full of evil


usually, when porting something from JS to Cljs, it should not be a literal port (if you have the time) and rather it should be re-thought in a functional context. A literal port would not be very idiomatic Cljs most of the time.


i agree with @U5YHNV0EA on this i maybe you should use atoms instead of declarations good luck


I need to share a variable b/w functions A and B when function A assigns a value to the variable


I assume that (declare x) as a peer to (defn a [] (def x 10)) will allow (defn b [] x) to return 10


I supposed I should just cider-scratch buffer to verify


def creates a top-level var no matter where it is


@sundarj is there anyway to make a function-local variable without (let ...)?


let is the way to do that


can you explain what issue you are working around. when fighting assignment and such like this normally if you change your approach to the problem, this manufactured problem goes away


@dpsutton basically I need a function A to assign to a variable that function B can access later in execution


so you want B to pass a value to A and A can decide to return that value or a different one upon consideration of other things


@dpsutton not quite… a library will be calling A first then B second, so unfortunately I don’t have control over which arguments are passed in


(defn a [] (def x 10)) will create the top-level x var regardless of whether it has been declared beforehand


@sundarj that seems closer to what I’m after


and you are not in control of the library?


@dpsutton unfortunately not


i'm not sure i see how creation of a new var would help you, as presumably B is not looking for this new var?


(defn a [] (def x 10))                                   

(defn b [] x)                                            

#object[clojure.lang.Var$Unbound 0x246769c2 "Unbound: #'boot.user/x"]



ah this is it exactly… thank you @sundarj


strange that the (def ...) leaks out of its lexical scope… so be it!


def is only for creating top-level vars


it's not like JavaScript, where var is for both top-level and local variables


ie, its lexical scope is the ns


ah great … thanks for the help @sundarj and @dpsutton


any time 🙂


usually, when porting something from JS to Cljs, it should not be a literal port (if you have the time) and rather it should be re-thought in a functional context. A literal port would not be very idiomatic Cljs most of the time.


hi i'm completely new to clojure and am interested in doing some rapid prototyping for a project in this environment. Can anyone recommend a library or framework that provides off-the-shelf support for account creation/managment/user provisioning?


@jlee69 Clojure tends to avoid frameworks and instead focuses on small, composable libraries -- so you're not likely to find anything off-the-shelf for that use case.


If you're looking to jump start a small web application, a lot of people recommend Luminus (I haven't used it so I can't comment).


I can recommend Luminus. There is a well built and well documented leiningen template to help get you started as well as a very well documented approach to web apps. It’s a very good place to start!


@seancorfield @admay thanks for the responses, i'll check out luminus


No worries @jlee69! Good luck!


I really don’t know what is going on I’m trying to implement the reaload workflow of stuart sierra and I installed the reloaded.repl and once I try to refresh I’m getting the following error

#error {
 :cause "namespace '' not found after loading '/okivia/app/routes'"


[{:type clojure.lang.Compiler$CompilerException
   :message "java.lang.Exception: namespace '' not found after loading '/okivia/app/routes', compiling:(okivia/components/server.clj:1:1)"
   :at [clojure.core$throw_if invokeStatic "core.clj" 5656]}


when I run lein uberjar and after that java -jar okivia.jar it is working great


both refresh and refresh-all I’m getting the error above


what if you run lein clean before starting your repl?


uberjar can break refresh if you don’t clean


will try now


now, do you know why the uberjar break the refresh ?


yes, if clojure finds a class file and a source file, it prefers that class file


thus, your source file isn’t used, and the resulting skew (in particular if you have new source files that are loaded when you change them, plus old ones that are not)


supposing I — tab 1 * lein do clean, repl * (refresh) - work great — other tab lein uberjar — back to tab 1 * (refresh) why not use the pre-compiled uberjar class ?


I wonder - that could have to do with what refresh is doing, it might explicitly use the source file if it knows it came from one


eg. using load-file instead of require


if I want to change the state of a style is this correct? cljs (set! "something")?


Try something like

(set! (.. element -class -display) "something")

;; or 

(set! (.-display .-class element) "something")