Fork me on GitHub

if your DI is designed with testing in mind, it makes testing a real breeze


i havent designed clojure apps big enough for DI usage though. our company is still a java shop. and the DI is just there to mostly standardize how stuff works on 60+ applications on 200+ production server nodes. all are built the same way, all are deployed the same way.


horribly boring (they don't really have a personality in that sense) but efficient


would be horrible context switching otherwise for developers if they have to work on several different applications per day


for small applications i wouldn't do any of that dependency injection though 🙂 for tiny hobby stuff the service provider model works just as well.


Do you mean service locator? (Are they the same?)


How do they make testing simpler?


I think service locator pattern would look like more or less like this. Then you could have e.g mock versions of services in service-locator during the unit testing etc.

👍 4

But is that the same as a service provider? (Google was kinda unclear to me)


yes it's the thing i meant


where i stand on the topic - when i buy a new car then the DI assures that the car has fitting wheels when i get it. whereas a pretty common approach with the service locator is that i get into a new car, want to start driving, roll down the window and scream out that i need wheels, now. and whoever is the mechanic nearby runs out with any pair of wheels they have since they couldn't understand who is asking for them.


not all of them have this pattern of course, but it is common.


what a memorable analogy


it gets more tense if you are responsible for the db connector of your application and your teammates request it from service locator before application has loaded it's config or after you have closed down your connection pool 😉


overall DI and service locators both help you to sneak in mocks into your tests (for the external resources that you can't possibly pull up even with the help of docker containers).

Arto Kalishian11:10:09

What is the most reliable database engine document based that officially supports clojure integration? MongoDB doesn't guarantee write reliability as far as online reviews claim.

scknkkrer11:10:43, you can change your operations mode with more reliable mode. AFAIK, this will do the job.

👍 4
Arto Kalishian04:10:00

Good morning, I was searching online about MongoDB reliable mode, but I could not find it. Is there a more accurate term to the feature or it's just some best practice? If so, please share the references. @U3JJH3URY

jumpnbrownweasel03:10:32 I don't use Mongodb but I work on databases and I think you're looking for this: If you set the value 2 then 2 out of 3 nodes will have the data, which is considered reliable.

❤️ 4
Arto Kalishian05:10:27

Thanks a lot for sharing @UBRMX7MT7

Arto Kalishian05:10:33

I bookmarked it.


if I have a namespace aa which requires namespace bb :as b, is there a way to make it so that when namespace aa is loaded, its functions resolve the alias b to a namespace other than bb ?


or, even better, is there a way to require namepace aa in some other namespace in such a way that aa's b resolves to a namespace other than bb


like (require '[aa :as a :resolving {aa/b cc}])


or another way of saying it would be (require '[aa :as a :resolving {a/b cc}])


so that a's alias b resolves to cc not bb as required in aa, i.e. whereas before b/g in aa would resolve to bb/g, instead it would resolve to cc/g


can i define specs at run time ?


@abdullahibra Yep, you might have to get creative with how you evaluate things though


@emccue can you give example please?


well, assuming you are defining a spec the "easy way"


with (s/def :some-ns/my-spec predicate-fn)


(defn define-name-spec [name]
  (s/def (keyword "name-checker" name) #(= name %)))


that being said - this isnt great practice


the good practice should be defining spec outside function and use them as global vars inside the funcs?


honestly if you are making a predicate, just make a predicate


there isnt all that much reason to tie it into the spec mess


suppose i have application which will give the user space to define their specs to be used within validating their data, what do you think about this?


I think that you should rely on a standardized way of defining a data schema rather than use spec for that


spec is for validating flow through your program


so in my situation will be better to use formal clojure for that ?


well, it depends on what you want to provide to your users


is this a spark kinda situation?


for now No, but maybe later will be streaming service


or an ETL pipeline?


streaming data?


maybe there is a better argument out there - but I personally think that using a schema language that isnt specific to your application is alot better than making one up yourself


in the realm of user facing systems, that is


i know nifi uses avro, which was eh to work with


though that is unrelated to the technical feasibility of spec


that's good to know 🙂


If I have an api that exposes a multimethod which somewhat encourages it's methods be overridden as a means of extension/customization, is that a legitimate/good use of multimethods? or getting some degree of code-smelly?


that's one use of multimethods


if I understand you...expose a defmulti intended to be implemented by defmethods


why are you afraid it might be a code-smell ?


i think my main concern is that during playing with this I've had a few mishaps involving the ordering of requires becoming important, or otherwise getting into an unclear state of which method implementations I was using at a repl (after some time messing around at a repl)


I wouldn't be keen on that personally, I wouldn't trust things to work


that sounds like a problem with your REPL workflow rather than multimethods


Hi! I'm experiencing a weird error with specs generate and lein repl (clojure 1.10), it seems it doesn't find a file when I invoke the function:

lein repl       
nREPL server started on port 53282 on host - 
REPL-y 0.3.7, nREPL 0.2.13
Clojure 1.10.0
OpenJDK 64-Bit Server VM 11+28
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (clojure.spec.gen.alpha/generate 1)

Execution error (FileNotFoundException) at user/eval4978 (form-init10909052932822487799.clj:1).
Could not locate clojure/test/check/generators__init.class, clojure/test/check/generators.clj or clojure/test/check/generators.cljc on classpath.
Does anyone have any hint on why is this happening?


@manuelrascioni my first guess would be that you are missing a dependency in your Leiningen project.clj file, needed for that namespace to exist.


generator is part of the spec, it should be included with clojure core 1.10 😕

dpsutton15:10:43 > spec generators rely on the Clojure property testing library test.check.


ah so the lib is mandatory if I want to use the functions included in the main clojure dependency


that's a bit broad. its needed if you want to generate data with spec


yep, I said it wrong. But it seems very weird that you have to imort a lib to use a function included in the core 😕


{:dependencies [[org.clojure/test.check "0.9.0"]]}


I am pretty sure that test.check is not needed for all possible uses of Clojure spec -- I believe it is primarily for the uses that involve generating random data.


that's right, same in clojurescript where it's also an optional dep


@jjttjj I personally like apis like that so long as you provide every impl that your library provides through a single namespace

emccue17:10:51 is a good example


though more info about what you are doing is always helpful in barfing up opinions


Thanks! It's for my library which is an api client which wraps a stock broker's java api. Basically I turn a big data structure which represents a request into the java classes needed. And then do a similar thing to turn the java response into a data structure. at some point I tag everything in this data structure with a unique qualified keyword. Then the key/value pair is translated to or from the value the java api expects via a to-ib/`from-ib` multimethod which just dispatches on the qualified keyword. For example the java api returns dates as strings. My default implementation turns these strings into LocalDates. But I want to be able to allow users to use another date representation if they wish. Previously I rolled my own multimethod approach by just putting functions in a map. But I'm starting to get the sense that it would be better to stick with multimethods because they're "standard clojure". Here are the two approaches I'm considering:


Oh wow, is surprisingly relevant here


yeah - you might want to just extend that lib


like, include from-java and to-java then customize them however you need to


alot less stuff to roll yourself, and your impl for conversion is totally open


so if you don't keep up to date and they add a new field or something, someone using your library can replace relevant from/to pairs to keep their code working in the interim


And is actively maintained now (by me) so if you have questions or need enhancements, just reach out!


Yeah interesting stuff, thanks! I wish I heard of this sooner 🙂 Sill have to explore a bit


One distinction with my library is it also represents method invocations on a single api client class as data that looks and feels the same as the "beanlike" classes


so like

(ib/req client [:historical-data {:contract {:sec-type "STK"}]
would be translated to something sort of like
where Contract is its own class with a "secType" getter/setter


[But it might be good to separate the stuff that could be handled by and this more magical stuff]


Hello, I’m using to launch a shell program that does not terminate, I would like to forward its output to the repl printer. Any ideas on how to do that? thank you


don't use 🙂


instead just start process and redirect it's input stream to repl


redirect like that:

  (with-open [reader (io/reader input-stream)]
    (doseq [line (line-seq reader)]
      (println line))))


start process as in, but without (.waitFor proc), which blocks until process exits


Use processbuilder call inheritio


Hmm, this is unexpected.

(require '[java-time :as jt])
(require '[java-time.format :as jf])
(def ymd-format (jf/formatter "YYYY-MM-dd"))
=> #'user/ymd-format
(jf/format ymd-format (jt/local-date "2019-12-29"))
=> "2020-12-29"


Am I doing something wrong?


@manutter51 Looks like it needs to be yyyy in the format, not YYYY.


Ah, ok thanks much Sean!


is there a way to test macros that use &env using macroexpand?


What's the default value of assert


nil . The implementation of assert in Clojure/JVM is based on when, which returns nil when its condition is logical false, and when-not, which returns nil when its condition is logical true.


That is not promised in the doc strings, and I think the typical use of assert is for its side effect, and ignore its return value. Why would you want to rely on its return value?


Sorry, it was a slack mistyped, I typed *assert*


It just slack bolded it


I can't seem to find if *assert* defaults to true or false


It seems it defaults to true, but I'm having a hard time knowin if that's only true from a lein bootstrapped repl, etc.


Probably difficult to find because it is implemented in Java, here: . Looks like true (`T`)


Oh, I was looking at that line, and missed the T


Leiningen could do who-knows-what with that in its own code when you run lein test.


Wow, is that... hum interesting the use of T and not true in the source


Alright thanks. I had looked at that line, but I think the T meant I overlooked that it was being set to somethin


Sure. Single letter symbols can be invisible that way sometimes.


I don't know full reason for use of T there, but it is a Java Object, rather than a primitive, which might be part of the reason.


Ya, and Clojure's Java style is a bit esoteric, so I'm always extra confused 😛


Ya, it just seems someone didn't want to type Boolean.TRUE over and over


All these asserts defaults are a bit confusing, sine the spec assert defaults to false, but oh well

Alex Miller (Clojure team)20:10:41

I think it actually used to be a symbol originally like scheme, etc


Oh, that would make sense


Hum... no wait.. > If compile-asserts is false at compile time, compiles to x. Defaults to value of 'clojure.spec.compile-asserts' system property, or true if not set. > If (check-asserts?) is false at runtime, always returns x. Defaults to value of 'clojure.spec.check-asserts' system property, or false if not set. You can toggle check-asserts? with (check-asserts bool).


So compile-asserts default to true, but check-asserts? defaults to false?


So effectively, spec assert is disabled by default. Do I get that right ?


I believe that *compile-asserts* and *assert* are independent in Clojure, i.e. I don't think the value of one directly affects the other, but perhaps you were not expecting them to.


Ya, I don't expect them too, and they don't. though, I also feel like logically the could have. I'm more confused why the runtime check of spec defaults to false, but the compile time one defaults to true. Seems you'd set them both to default to the same