Fork me on GitHub
#clojure
<
2017-06-01
>
andrewboltachev00:06:40

Hello. Are there any libraries which calculate diff between two Clojure data strtuctures?

josh.freckleton00:06:53

this seems weird:

(merge nil "")     ; => {}
(merge "" nil)     ; => error, string cannot be cast
(merge "" "")      ; => error, string cannot be cast
(merge nil "asdf") ; => error, char cannot be cast

josh.freckleton00:06:01

why does the first work?

john00:06:59

@andrewboltachev there's been some recent discussion about it. diff is a little slow. Some old solutions have some tradeoffs: https://github.com/brentonashworth/clj-diff https://github.com/brentonashworth/clj-diff

john00:06:52

no prob!

john00:06:11

I mean, differ looks the most recent

andrewboltachev00:06:03

yes good stuff. My task is a little modest at a time being, but I'd be happy to join a disussion in the future as well

tap00:06:13

Is there a core function or library out there do this? Kind of an extension of cond-> and cond->> where data is available in “test” as well? Something like this

(cond*-> {:a 1 :c 3}
  #(= (:a %) 1)  (assoc :a 10)
  #(= (:a %) 10) (update :a + 10)
  :b             (update :b + 5)
  :c             (update :c + 8))

;=> {:a 20 :c 11}

john00:06:31

The most intriguing solution I've seen actually leverages Clojure's MVVC persistent data structures, from this gist: https://gist.github.com/danjohansson/add5515b2067b3036044d450cbec08f3 but I was never able to get it to work.

john00:06:29

@tap a common solution is to put a thrush (thread) within a thrush, if you're willing to do that.

john00:06:11

@tap for instance,

(-> []
    (conj "first" "second")
    (->> (mapv str/upper-case))
    (conj "last"))

john00:06:37

That example was taken from Howard M. Lewis Ship's awesome recent blog post on thread macros here: https://medium.com/@hlship/confessions-of-a-threading-macro-addict-5a026dae4af7

tap00:06:04

@john Interesting, thanks.

tap00:06:26

So I can do something like this

(as-> {:a 1 :c 3} $
  (cond-> $ (= (:a $) 1)  (assoc :a 10))
  (cond-> $ (= (:a $) 10) (update :a + 10))
  (cond-> $ (:b $)        (update :b + 5))
  (cond-> $ (:c $)        (update :c + 8)))

john00:06:58

It's getting there

john00:06:30

as-> is probably the most powerful.

john01:06:22

all those cond->s look somewhat redundant, though, and to my eyes actually detract from from the readability of the form, which is the whole point of thrushes anyway.

seancorfield01:06:05

@tap We wrote our own condp-> and condp->> macros that thread through the predicate as well as the expression.

dpsutton01:06:31

@josh.freckleton did you get your answer?

dpsutton01:06:55

(when (some identity maps)
    (reduce1 #(conj (or %1 {}) %2) maps))
is the definition of merge

josh.freckleton03:06:23

dpsutton: thanks! ya, it's rather strange behavior I think, but I've been studying Haskell a bit lately, so many things are 🙂

dpsutton03:06:39

my friend and colleage just got back from the conference in denver and gave us a one hour lecture in category theory this morning

dpsutton01:06:14

i think its a coercion on ""

dpsutton01:06:48

but this is conj: ([coll x] (. clojure.lang.RT (conj coll x))) and i'm not sure how to follow it

dpsutton01:06:10

ok, that looks like it means

static public IPersistentCollection conj(IPersistentCollection coll, Object x){
	if(coll == null)
		return new PersistentList(x);
	return coll.cons(x);
}

dpsutton01:06:48

from RT.java. and IPersistentVector:cons will coerce x to a map$Entry

dpsutton01:06:49

and in APersistentMap, cons dictates that if its not a mapentry, or vector, try to seq it and then cast the first thing to a map entry and there's your kaboom

dpsutton01:06:18

so the final answer is (seq "") = nil which is a valid map entry

dpsutton01:06:51

does anyone know what RT stands for in clojure.lang.RT?

noisesmith01:06:07

I think it's run time

danielgrosse10:06:04

I load and parse a xml file with clojure.data.xml. Unfortunately the files linebreaks between the tags are also in the resulting structure and are recognised as nodes. How can I filter the linebreaks?

robert-stuttaford10:06:27

@danielgrosse sounds like something StackOverflow may be able to answer

mbjarland12:06:42

I have a potentially noobie question. I'm using thinktopic/lazy-map to cache various levels in a data structure which eventually reads things from disk when not cached. I have a function which returns an instance of the lazy map where when you access the map values they are realized, the disk is read (on first access) and values are returned. I would now like to find a way to make the returned map sorted by keys but retain the laziness of the thinktopic/lazy-map implementation. Just doing an (into (sorted-map) lazy-map) forces evaluation of the values and looses the laziness as all values are then realized.

mbjarland12:06:49

never mind, think I figured it out

MegaMatt13:06:30

I'm trying to connect to sqlserver and can't fix "no suitable driver found for jdbc:sqlserver" I've tried downloading the sqljdbc42 jar file and placing it in a half dozen different folders but I'm just kinda lost on this being a C# dev. Anyone be able to give me some pointers?

dominicm13:06:25

matthewdaniel: don't add it to any directory. You probably want to depend on it. [net.sourceforge.jtds/jtds "1.3.1"] seems to be the sql server dependency.

dominicm13:06:55

Oh, sorry. I didn't see the Microsoft official SQL server one. Oops

dominicm13:06:18

(Having said that, if the jtds one is suitable for you, I imagine it's far less hassle!)

MegaMatt13:06:54

i added that to my lein project config and it still give the same no suitable driver found error

dominicm13:06:19

You will need a different classname for the jtds

dpsutton13:06:50

i've used this to some success:

[org.clojure/java.jdbc "0.4.2"]
                 [com.microsoft/sqljdbc4 "3.0"]

dpsutton13:06:48

that java jdbc is outdated now so see what version is current, but that version from microsoft is on clojars and i haven't run into any issues. their later releases aren't deployed that way though

dpsutton13:06:10

(defn database-conn [conn]
  {:classname "com.microsoft.jdbc.sqlserver.SQLServerDriver"
   :subprotocol "sqlserver"
   :subname (get-in connection-strings [conn])})

MegaMatt13:06:06

promising results for that. I get a new problem with tcp/ip connnection failed

MegaMatt13:06:32

i'll tweak my connection properties and see if i can't get that to work

dpsutton13:06:43

also, it looks like you're using a microsoft version of the connection string. javas are a little different i think. google for java connection string with integrated security

dpsutton13:06:55

also, i've been in the same boat. .NET developer wading into the java ecosphere

dpsutton13:06:26

good luck to you and feel free to message me if you have questions

MegaMatt13:06:27

thanks a bunch.

dpsutton14:06:16

[org.clojure/java.jdbc "0.4.2"]
[net.sourceforge.jtds/jtds "1.3.1"]
and a usage:
(def sqlserver {:subprotocol "jtds:sqlserver"
                :classname "net.sourceforge.jtds.jdbc.Driver"
                :subname "//server/db;user=username;password=password"})

dpsutton14:06:14

note the different format of the connection string

MegaMatt15:06:17

getting there. i'm now getting I/O Error: SSO Failed: Native SSPI library not loaded

dpsutton15:06:43

ugh gross. https://stackoverflow.com/questions/13267764/i-o-error-sso-failed-native-sspi-library-not-loaded this stems from the integrated security i believe. Easy fix: switch if possible to a username and password logon. Harder fix, follow those steps to put the dependency in the right place

MegaMatt15:06:09

works, thanks for all your help

dpsutton15:06:42

spectacular. happy coding

cpmcdaniel13:06:32

… this is not actually referring to core.spec, I use a parameter in a lot of methods called spec

weavejester13:06:45

What does the file look like?

weavejester13:06:03

Or what does your ns declaration look like?

weavejester13:06:14

Hm, strange. That looks fine.

cpmcdaniel13:06:50

I tried commenting out an fn with #_

cpmcdaniel13:06:10

and paredit did something screwy and left me with unbalanced parens

cpmcdaniel13:06:45

So I’m guessing you get the Line 1/Column 1 error when you have an extra ) somewhere

cpmcdaniel13:06:05

I feel like the error message could be better in this case, but I know not how hard that would be

cpmcdaniel13:06:45

or rather, in this case it tried to resolve a symbol as if it were at the highest level of the ns

cpmcdaniel13:06:03

ok, maybe detecting that is harder than I thought

cpmcdaniel13:06:51

it basically saw this at the top-level: [spec {:keys [params error] :as vresp}]

cpmcdaniel13:06:23

but it eventually would have parsed a closing ) with no matching (

cpmcdaniel13:06:56

still, why did it say 1:1? Why not give me this line number?

dominicm13:06:59

I think it's to do with how the reader works in clojure, it doesn't quite store enough metadata.

weavejester14:06:00

@cpmcdaniel Maybe this is something joker could help with. Or perhaps it’s worth raising a JIRA issue for a better exception.

cddr16:06:52

Wondered if I could get some thoughts from the community about this PR https://github.com/sjl/metrics-clojure/pull/120 Basic idea is to get metrics per endpoint, but now I'm trying to integrate it into my own app, I'm finding it a little bit lacking. It's easy enough to wrap each route, but our application routes are collected into a single handler by compojure, and then a list of middleware is applied to that single handler. If I wrapped each one, the metrics would not record the time taken for global things like wrap-params, wrap-auth etc. I could refactor our app to accommodate but this seems like a reasonable pattern.

langmartin17:06:15

I'm having some trouble with a spec under stest/check, I think I may be using s/and incorrectly `

langmartin17:06:25

(s/fdef between
  :args (s/or :part (s/cat :a ::id :b ::id)
              :full (s/and (s/cat :choose ::choose :a ::id :b ::id)
                           #(not (pos? (compare-ids (:a %) (:b %))))))
  :ret  (s/nilable ::id)
  :fn   (fn [{:keys [ret args]}]
          (let [{:keys [a b]} (get args 1)]
            (between-ok? a b ret))))

langmartin17:06:46

it's generating failures where the :choose :a and 😛 are fine, but where a and b are out of order, and so fail the not pos? compare-ids predicate

langmartin17:06:01

my understanding is that s/and should generate lists of those arguments and then filter out the ones that fail the second test

langmartin17:06:03

and, naturally, as soon as I ask the question I figured it out! the :part branch is a 2 arity on version of the between function, which just provides a default :choose. the ordered? predicate has to go on both the :part and :full branches of the or

langmartin17:06:27

so

:args (s/or :part (s/and (s/cat :a ::id :b ::id) ordered?)
              :full (s/and (s/cat :choose ::choose :a ::id :b ::id) ordered?))
works

cddr17:06:36

I suppose that's one of the reasons people like their routers to be just data.

lilactown17:06:26

what's the best intro talk to spec?

captainlexington17:06:43

I just watched this one last night:

captainlexington17:06:09

It's almost two hours, tough. If you want something shorter, I don't know one.

lilactown17:06:15

great, thanks!

captainlexington17:06:09

I'm wondering a bit about how to really use spec in a project - do specs go in their own namespaces or in the namespaces of the things they're speccing? I understand it's programmer choice to a degree, but is there a best practice?

captainlexington17:06:21

Are there consequences between one or the other?

langmartin17:06:11

I've found the main consideration there to be cider support. jump to definition for specs doesn't exist yet

langmartin17:06:15

it's made me a little happier with specs in their own namespace, just because they're a little hard to find when you've got fspec and defn mixed in together

captainlexington17:06:56

Do you usually group all the specs together in, like, a spec directory, like we do now with test?

anmonteiro17:06:57

is there any way to type-hint something in a threading macro?

anmonteiro17:06:26

e.g.:

(-> x
  .somefn
  .someOtherFn
  (#(.getString ^MyAnnotation %)))

anmonteiro17:06:39

^ this works, obviously, but looks ugly

royalaid17:06:00

Maybe a let and pass the fn in?

royalaid17:06:08

(let [fun #(.getString ^MyAnnotation %)]
 (-> x
   .somefn
    .someOtherFn
    fun))

royalaid17:06:04

its good enough parrot

anmonteiro17:06:31

not really achieving anything more than what I have ¯\(ツ)

noisesmith18:06:30

I’m refactoring a part of the app that created a closure and then returned an anonymous function accessing data in the closure. To aid in refactoring I’m adding an arity that exposes all the data in the closure. Is it a total hack to just leave that around afterward for convenience?

hiredman18:06:04

maybe replace the closure with a defrecord that implements IFn, or a map with all the data and an entry with the function

noisesmith18:06:17

oh - that’s much nicer

noisesmith18:06:41

implementing IFn properly would mean it would still work while transitioning, thanks for the idea

langmartin18:06:25

@captainlexington I'm still experimenting with layout, but right now I've got a spec namespace in each module mixed in with src. a top level spec namespace might be nice, though

dhruv119:06:40

Question: Is it safe to use in-ns inside a macro to resolve functions defined in a different namspace.

(defmacro load-data
  [filename]
  (in-ns 'other-ns)
  (cons `do (for [k# (seq (file filename))]
              `(intern 'other-ns
                       '~(symbol (name (first k#)))
                       (into {} ~(second k#))))))
Explanation: i am working on a problem which requires me to read an edn file and the file has a clojure hash-map with leaves which define functions. ex: {:foo (fn1 "parameter1")} If i load the file in the namespace where fn1 function is defined, it works perfectly fine meaning the hash-map is loaded and fn1 function is resolved. However, if i load the file in a namespace where fn1 is not defined, i run into runtime exception fn1 cannot be resolved Due to business constraints, I cannot require the namesace fn1 is defined in, i cannot do (require [some-ns :as sn]) because then i would have to define the hash-map as {:foo (sn/fn1 "parameter1")} So I’m using (in-ns 'some-ns) to work around this problem. To me is doesn’t seem right to use in-ns. IS there a more idomatic solution to this problem?

noisesmith19:06:15

don’t change namespaces to resolve things

hiredman19:06:37

it sounds like you aren't just reading in the file, you are reading it in then sending it through the compiler

noisesmith19:06:23

yeah, that macro splices a function call to a function name read out of a file

hiredman19:06:33

the compiler resolves symbols and compiles functions calls according to how clojure the language works

hiredman19:06:53

if you read it in as data you can interpret it however you wish doing whatever with it

dhruv119:06:18

okay. right I am reading in the file and compiling the data. i need to use the functions defined in the file.

noisesmith19:06:36

wait, defined or referenced?

dhruv119:06:50

sorry referenced*

noisesmith19:06:41

my inclination is to use a weaker construct if possible

noisesmith19:06:15

for example, instead of emitting a call to the function in the line of code, you could emit a call to a function that explicitly looks for the definition of that name in the target namespace

noisesmith19:06:20

the resolve function would help here

noisesmith19:06:39

or ns-resolve since you know an explicit namespace you want to do the lookup in

dhruv119:06:12

@noisesmith are you talking about this line? (into {} ~(second k#))

noisesmith19:06:49

'~(symbol (name (first k#)) - this turns a string into a function and calls it

noisesmith19:06:41

@nvtf for starters putting a call to eval inside a macro is a sign you are making a mistake, almost always

noisesmith19:06:22

@dhruv you can replace that with a call to ns-resolve with the target ns, which returns the var corresponding to that string (if found)

nvtf19:06:30

yep, only "ugly hack" that came to mind though

dhruv119:06:47

@noisesmith thank you. let me try that out

noisesmith19:06:15

ns-resolve takes two symbols and returns a var, you can deref the var, or for a function, just call it

noisesmith19:06:14

@nvtf amongst other reasons not to use eval, eval doesn’t use values in your local scope, it only resolves at a namespace level

nvtf19:06:32

is there anything that resolves in local scope? (`resolve` seems to work that way as well)

noisesmith19:06:58

the right way to provide values at runtime is to create a function and supply them as arguments

noisesmith19:06:35

in fact, apart from wanting to intern a value with the metadata that defn creates, I don’t see any reason for that code to be a macro

devth19:06:38

@robert-stuttaford did you guys switch from Yeller to something else? i just noticed the blog post saying they were shutting down last year.

robert-stuttaford19:06:24

@devth sentry 🙂 works great

devth19:06:38

cool, thanks. that's what we're looking at too 🙂

niquola20:06:31

Hi all, how efficiently write big hash-map into edn file? I’ve tried pprint/write db :stream out - but it is slow 1.2M in 12 seconds 😞

ghadi20:06:20

pprint is slow

ghadi20:06:05

Have you tried plain prn?

noisesmith20:06:33

also, it’s an extra dep, but transit is super fast and super reliable in my experience, and handles a superset of edn

niquola20:06:58

@ghadi - yep it’s faster - 100ms 🙂

rickbutler20:06:09

is that a difference of java in memory writing whole map vs stream writer?

captainlexington20:06:10

It's probably the difference between pretty-printing and printing unformatted

captainlexington20:06:31

Presumably 1.2 MB edn file isn't meant for human consumption, so pretty-printing isn't important?

apbleonard21:06:10

Been bitten in production by this today: (into (sorted-map-by (constantly 0)) {:c 1 :b 2 :a 3}) ==> {:c 3} Ok, we didn't use (constantly 0) as our comparator but a bug made it similar for some values. Even so I would never expect that a function accepting a map and returning an equivalent one with its keys sorted would actually change the number of keys and mix what values were assigned to which keys - i.e. mangling the map. I've now read the clojure doc on avoiding comparator mistakes. Is this just a case of "Buyer beware"?

ddellacosta21:06:33

can you have a fulltext index as well as AVET index on an attribute?

ddellacosta21:06:14

I haven’t tried yet, just curious before I give it a shot--the docs don’t seem to suggest it’s not possible, based on what I’ve read so far

ddellacosta21:06:32

whoops, maybe I should have asked in #datomic

bfabry21:06:23

@apbleonard the documentation there certainly seems lacking, but yeah seems to me that's a consequence of how sorted maps work, the comparator needs to specify an absolute order

bfabry21:06:43

as assoc etc do all of their key comparison via this function https://github.com/clojure/clojure/blob/clojure-1.9.0-alpha14/src/jvm/clojure/lang/PersistentTreeMap.java#L325 which defers to the comparator. there's no logic for "ok the comparator says they're the same but are they really the same?"

dpsutton21:06:35

the comparer function is how it tells things apart

dpsutton21:06:53

you can get a constraint violation if you do the opposite, feed it a function that lies and says everything is different

dpsutton21:06:31

user> (into (sorted-map-by (constantly 1)) {:c 1 :b 2 :a 3})
{:c 1, :b 2, :a 3}
user> (into (sorted-map-by (constantly -1)) {:c 1 :b 2 :a 3})
{:a 3, :b 2, :c 1}
user> (into (sorted-map-by (constantly -1)) [[:a 1] [:a 2] [:a 3]])
{:a 3, :a 2, :a 1}

apbleonard21:06:41

@U11BV7MTK That last one is a bit scary isn't it? It returns a value that can't even be re-evaluated without throwing a duplicate key exception.....!

dpsutton21:06:28

yeah. gotta be careful with that comparator function ha. you told it what it means to be the same or different

dpsutton21:06:50

ha this is funny:

user> (into {} (into (sorted-map-by (constantly -1)) [[:a 1] [:a 2] [:a 3]]))
{:a 1}

dpsutton21:06:11

nevermind that's expected

pandeiro21:06:37

Has anyone evaluated the different DB migrations libraries (eg ragtime, drift, migratus) and formed strong opinions on any? It's hard to understand the actual differences and rationale behind so many similar libs

donaldball22:06:47

pandeiro: Not a strong opinion, but I’ve used ragtime and migratus and have a moderate preference for the latter. There is also a #sql room in which others may have opinions.

schmee22:06:14

what are some good Clojure test suites I can look at for inspiration?

schmee22:06:52

I’m coming from an RSpec background and I would venture that the “best practices” in Clojure testing are way different

schmee22:06:05

also, what are peoples experiences with https://github.com/slagyr/speclj? is it worth giving a shot?

bfabry22:06:59

@schmee my humble opinion is that you're best to stick to clojure.test with as few other dependencies as possible. that way you get the best tooling support, helpers when you need them, etc etc. clojure.test isn't very pretty, and can be fairly awkward, but it's worth just dealing with that to be using what everyone else is using here (your test framework shouldn't be what you distinguish yourself with)

bfabry22:06:28

my background for that is rails+rspec+cucumber -> rails+test::unit -> clojure+midje -> clojure+clojure.test

bfabry22:06:58

there might have been another ruby testing lib in there at some point, I forget

trptcolin22:06:59

fwiw speclj was sort of an rspec port. it feels really comfortable for me (coming from rspec) and i like the auto-runner a lot, but i’m not trustworthy, as i’ve contributed to it and have been using it for awhile.

joelsanchez22:06:12

I use clojure.test and venantius/ultra for readable output, may try midje one day

bfabry22:06:05

an example here is the cursive+clojure.test integration at this point is freakin amazing, I'm not sure if such is true for the other things

trptcolin22:06:50

afaik test.check only has clojure.test integration thus far

joelsanchez22:06:54

Using cursive and clojure.test, didnt even know integration existed...

bfabry22:06:37

really? it's pretty incredible. go to a test file (while you have a repl session running) and hit your intellij "run tests in file" key combo. try breaking one of the tests and see the data diff you get in the sidebar etc

schmee22:06:12

@trptcolin any issues in particular you’ve encountered with Speclj coming from RSpec?

trptcolin02:06:06

schmee: probably the biggest issue (which I think might be common among all the clojure testing ecosystem, but not sure) is not having a global place to do things like “don’t ever make HTTP requests” a la webmock. the good part of that is explicitness, but the bad part is it’s easy to miss a spot.

trptcolin02:06:36

i don’t have any particularly painful speclj-specific issues i can think of, but like i said, since i’ve been close to it for a long time, i suspect there are things i’ve forgotten about.

schmee06:06:58

yeah, I’m missing mocks as well 🙂 I’ll give Speclj a shot, thanks for the info!

metametadata10:06:18

@trptcolin circleci.test can do something like what you describe: https://github.com/circleci/circleci.test#test-isolation But I think this feature shouldn't be needed in the first place if one uses dependency injection. It is inherently impossible to make an http request unless http-client is explicitly injected into the unit under test first. Another upside of dependency injection is that no monkey patching is needed for mocking/stubbing (i.e. with-redefs). And that is good because it allows to parallelize tests safely in the future (monkey patching is not thread-safe).

metametadata10:06:52

@schmee for mocks/stubs I can recommend my lib: https://github.com/metametadata/clj-fakes But there's also a list of alternatives at the bottom of readme file 🙂

schmee10:06:40

@U06BDK9S7 that looks really nice, I’ll try it out this weekend!

schmee10:06:23

I’ve been trying out Shrubbery but it is lacking some features I want, mainly strict-by-default and mocking specific arguments

trptcolin15:06:49

@U06BDK9S7 agreed, i always want things injected, love having explicit dependencies

trptcolin15:06:25

unfortunately sometimes people forget or slam code in too quickly 🙂

trptcolin15:06:42

i’m loving the fact that clojars-web exists to show people

joelsanchez22:06:24

Yes, I'm reading the docs...amazing, I'm relatively new to Cursive...was using SublimeText with a REPL...never ever looking back

joshjones22:06:04

@apbleonard comparators are so easy to screw up that there's a dedicated guide to them: https://clojure.org/guides/comparators -- on the surface they seem so easy, but there are gotchas related to total ordering that are not intuitive

cfleming22:06:47

@bfabry @joelsanchez Improvements coming to that soon too, hopefully next week!

joelsanchez22:06:53

@cfleming Hey, how can I tell Cursive to indent hiccup with two spaces? Couldn't find anything about it

cfleming22:06:14

Currently under discussion here: https://groups.google.com/d/topic/cursive/OM4T_nPGkfA/discussion, feedback welcome, either on the ML or over in #cursive

cfleming22:06:54

@joelsanchez There’s no way to do that right now that I can think of - vectors are always considered data and indented one space.

joelsanchez22:06:26

@cfleming Guess I can live with that

cfleming22:06:11

Hiccup is an interesting one - there are a few things that would be nice to do with it, but it would always rely on some heuristic to identify it.

joelsanchez22:06:56

Frankly I'd like to have two-space indent everywhere, where do people find one-space indentation more readable?

cfleming22:06:26

The problem is that this would indent your let blocks like this:

(let [a 1
       b 2]
  ...)

joelsanchez22:06:04

What about "indent data with two spaces except in let blocks and other exceptions I can setup"?

cfleming22:06:11

It would probably do all sorts of horrible things to e.g. datomic queries, but I’m not familiar enough with them to cook up an example.

cfleming22:06:40

I think it would be a lot of exceptions.

joelsanchez22:06:53

I give up 🙂 better this way indeed

cfleming22:06:05

I’m afraid that one is going to be a living-with-it sort of situation 🙂

joelsanchez22:06:31

Can't have the indentation and eat it too

cfleming22:06:33

It’s the dark side of “everything is just data”

joelsanchez22:06:37

Yeah, that wasn't a very good idea after all, going back to PHP

lvh22:06:59

Am I using clojure.pprint/*print-miser-width* wrong? The following seems to have no effect:

(binding [pp/*print-miser-width* 1000]
  (pp/pprint …))
nested vars still get a newline per value

noisesmith23:06:45

@lvh what about *print-right-margin*

lvh23:06:33

@noisesmith that did it; thanks!

lvh23:06:40

there doesn’t seem to be an incantation that makes it spread a long vector across two lines

lvh23:06:27

(binding [pp/*print-right-margin* 120 pp/*print-miser-width* 100]
  (pp/pprint (range 100))) 
=> one per line

metametadata10:06:52

@schmee for mocks/stubs I can recommend my lib: https://github.com/metametadata/clj-fakes But there's also a list of alternatives at the bottom of readme file 🙂