Fork me on GitHub
#clojure
<
2017-12-04
>
tbaldridge00:12:44

except those pre/post conditions often come with a performance hit

vemv07:12:53

Sure, I turn them off in production in clj and cljs - (set! *assert* false) / :elide-asserts true respectively

seancorfield00:12:01

@bravilogy You need (-> (client/get uri {:headers {"apisign" sig} :as :json}) :body :result) -- You are trying to get the :result element out of the :body of the client/get response.

seancorfield00:12:32

The conversion to text happens when Ring is rendering the result.

arrdem01:12:31

Random brain firing - is there a way to capture the current function's actual object instance? There are some recursion patterns which would be a lot easier to implement if you could just recursively pass the current function with its closure and all.

arrdem01:12:47

Or is the "right way" to do this some partial/y-combinator trickery

noisesmith03:12:44

@arrdem I'm probably misunderstanding, but does this help?

+user=> (defn foo [] foo)
#'user/foo
+user=> (= (foo) foo)
true

noisesmith03:12:26

does it need to be a way to automatically capture the current fn where you can't know the name (or even work in a case where a name is impossible like comp or partial) ?

arrdem03:12:40

oh iiiiinteresting

arrdem03:12:50

user=> (def a (fn [x] (fn foo [] (println x) foo)))
#'user/a
user=> ((a 1))
1
#object[user$a$foo__135 0x542e560f "[email protected]"]
user=> (((a 1)))
1
1
#object[user$a$foo__135 0x1d730606 "[email protected]"]
user=> 

arrdem03:12:14

named lambdas can refer to themselves by instance using their name.

arrdem03:12:38

guess I didn't need to patch the compiler to add this as an implicit local 😛

noisesmith03:12:51

oh no I have become a tool of evil

arrdem03:12:08

Oh no this is great

arrdem03:12:20

totally happy to not have to run some goofy patchset to get what I want

arrdem03:12:28

(it was a nice patchset tho)

sumit05:12:19

Hi, can anyone suggest me some small learning project which would give me some idea about handling concurrency in clojure. Something which can be finished in a week.

vemv07:12:46

A small 'simulation' program where you model a world, with interacting 'actors' (not in the Erlang sense) of some sort. - A toy factory, where many workers work independently and collaborate - An aquarium, where creatures eat each other / survive / reproduce - etc Those are particularly suited for concurrency. For parallelism, try doing either a CPU-bound (math? parsing?) or IO bound (web crawling?) workload as efficiently as possible

sumit10:12:47

@U45T93RA6 thanks for the reply, this seems interesting.

vemv11:12:37

I can take a look at the project as you progress on it, why not

sumit11:12:38

thanks that would be great help, I have done some projects like parser & interpreter in clojure but nothing related to concurrency

qqq06:12:01

I'm writing a macro in a *.cljc file. Is there a way to make it expand to different things depending on whether it is being expanded in CLJ or CLJS code ?

metasoarous06:12:59

Long story short is its a bit of a pain

qqq07:12:23

actually, how is it painful?

(defmacro str->int [s]
  #?(:clj  (Integer/parseInt s)
     :cljs (js/parseInt s)))
looks straightforward -- and I was already doing this, without even realizing it

vemv07:12:53

Sure, I turn them off in production in clj and cljs - (set! *assert* false) / :elide-asserts true respectively

ikitommi09:12:33

@qqq I think you example macro is not right, it’s evaluating the expression at compile-time.

ikitommi09:12:53

You should return the code to do the work instead.

ikitommi09:12:11

e.g. this fails:

(let [s "1"] (str->int s))

ikitommi09:12:43

also, you need to know what you are emitting from the macro: clj or cljs. There are hacks to get this info. And a awesome lib hiding the details: https://github.com/cgrand/macrovich

metasoarous19:12:37

Good to know about this!

qqq10:12:25

(defn select-rename [m ks]
  (into {}
        (for [[old-k new-k] ks]
          [new-k (get m old-k)])))

(select-rename
 {:a 20
  :b 30
  :c 40} [[:a :foo] [:c :bar]])
Is there a builtin for this ?

p-himik10:12:20

@qqq There're two functions - rename-keys and select-keys.

the-kenny10:12:23

there's clojure.set/rename-keys and select-keys

the-kenny10:12:11

Also note that you can implement this without an intermedia seq by using a transducer: (into {} (map (fn [[old new]] ...)) ks)

qqq10:12:46

@the-kenny: I agree that unnecessary intermedaite seqs are bad. Can you clarify where my code is generating it ?

qqq10:12:51

(= 2 (+ 1 1))
(comment
 true)

(= (int-array [2])
   (int-array [(+ 1 1)]))
(comment
 false)
I'm okay with the int-array returning false. My question is: is there a way I can overload/hack equality so it returns true if they're elementwise equal ?

ido10:12:00

What is the best way to run all unit tests (assuming that they are in different namespaces) in a project, without requiring them first, from the repl?

ido11:12:21

@stuartsierra any idea ? ☝️

dominicm11:12:42

@ido why don't you want to require them?

dominicm11:12:02

You can't run a test, without require the namespace that test is in.

ido11:12:58

@dominicm say I have 10 test namespaces.

dominicm11:12:58

@ido tools.namespace will require all namespaces it can find.

dominicm11:12:17

This should solve your problem if you perform a refresh before running your tests.

borkdude11:12:03

Count result of a transduction, which one is preferable?

;; 1
(count
   (sequence (map identity)
             [1 2 3]))
  ;; vs
;; 2
  (transduce (map (constantly 1))
             +
             [1 2 3])

dominicm12:12:30

@borkdude the first one makes more sense to me. I think you could use eduction in place of sequence if this is the exact usage, as it will be faster.

borkdude12:12:17

I get count is not supported on eduction

dominicm12:12:42

Really? I figured count worked on any reducible.

dominicm12:12:42

@borkdude What are you optimizing for here? Performance or readability?

dominicm12:12:55

In that case, use sequence if it's not fast enough, benchmark the transduce (but I wouldn't expect that to be faster, it's potentially slower!)

dominicm12:12:48

last but not least, use eduction with a fold to parallelise the count, if your resulting collection will be large enough. Also benchmark this approach.

borkdude12:12:18

@dominicm This is just #adventofcode related, so I guess readability is slightly more important. I’ll go with sequence.

0atman12:12:39

sorry for the crosspost - has anyone seen this before? https://clojurians.slack.com/archives/C075TNSSC/p1512387863000190

New To Clojure12:12:34

it tells how to get certificate for your url and to import into Java cert store to trust it

0atman13:12:55

thanks, but I'm just trying to use boot or lein

0atman13:12:23

which seems like it should work? it's not my servers

New To Clojure13:12:55

@tristram those instructions are to be done at client computer

New To Clojure13:12:05

i. e. at your work machine

New To Clojure13:12:15

it's not required for it to be a server

New To Clojure13:12:00

to successfully run Portecle app, to get http://github.com certificate by it and to import that certificate to local cert store

0atman13:12:30

well, I fixed it by uninstalling and reinstalling openjdk-8-jdkconstantly throughout the day

0atman13:12:32

¯\(ツ)

0atman13:12:24

FWIW, the last line I ran, from having no jdk installed, was

sudo apt install openjdk-8-jdk

borkdude13:12:51

@dominicm using net.cgrand.xforms: (x/count xform input)

dominicm13:12:20

@borkdude Yep, xforms is always the correct answer in these cases.

dominicm13:12:39

I'l have to remember that xforms has a count

matan14:12:56

Any rumors about 1.9's stability and its final release? 🙂

bronsa14:12:29

1.9.0-RC2 is pretty much what 1.9.0 should be in a short while

alexmiller17:12:06

I expect 1.9.0-RC2 is exactly what 1.9.0 will be :)

mbertheau18:12:03

(let [a (if editing? edit-a (-> data :foo :bar :a))
      b (if editing? edit-b (-> data :quux :b format-b-for-display))
      c (if editing? edit-c (-> data :otherkey :c))]
  [1 2 a b c 3 4])
Can I write this more concise without repeating (if editing?) so often?

mbertheau18:12:08

(Without repeating the 1 2 3 4.)

mbertheau18:12:02

I want to keep the readable [1 2 a b c 3 4] at the end.

curlyfry18:12:16

Using vectors and destructuring perhaps?

(let [[a b c] (if editing?
                [edit-a edit-b edit-c]
                [(-> data :foo :bar :a) (-> data :quux :b format-b-for-display) (-> data :otherkey :c)])]
  [1 2 a b c 3 4])

seancorfield19:12:11

@matan Re: stability -- we've had all the 1.9 Alpha and Beta builds in production for ages. We have RC1 in production right now with RC2 going to production at 2pm Pacific today.

plins19:12:28

whats the main difference between float? and double?

plins19:12:21

i want to validate input from a string and check if its content is a valid double

noisesmith19:12:09

to use either float? or double? here you’d need to do some conversion first. clojure.edn/read-string? will never return floats, only doubles

noisesmith19:12:52

if what you want is to know if a string is a valid floating point number, I think the best option is (try (Double/parseDouble %) (catch Exception _)) - it’s ugly but it works - either a number or nil comes out

matan19:12:52

@seancorfield sounds good. but did you have a specific agenda in chasing the bleeding edge like that? I mean 1.8 was good and stable. care to clarify the motivations for this chase? I just can't help but wonder as most people won't go that far (or fast :) I guess..

seancorfield20:12:56

We've pretty much always used Alphas in production as they become available for over six years: because we want access to the latest features. We're using clojure.spec heavily in production, for example.

tbaldridge19:12:38

@matan there's really not a reason not to. Clojure alpha/beta versions very rarely break existing features. Most of the time I upgrade, run the test suite, and if those tests pass we're good.

tbaldridge19:12:41

Last time I remember Clojure "breaking" something critical was when they changed the hashing algorithm back in 1.6. But even that wasn't Clojure's fault since order of items in sets is undefined (hence why they are unordered sets). So that was a bit painful to fix, but it was considered a code cleanup since the problem was in the code that used Clojure.

tbaldridge19:12:07

But I can't even think of a time I've had my correct code break from a Clojure upgrade.

dpsutton19:12:18

weren't there some issues with 1.2 -> 1.3

dpsutton19:12:29

i wasn't around back then so i don't know but i thought i remember hearing about that

tbaldridge19:12:37

well yeah, I'm not going that far back. and I joined Clojure right when 1.3 was released 😉

tbaldridge19:12:28

That was back in 2011, lol

dpsutton19:12:19

well there's a good answer then. there haven't been breaking changes in an upgrade for 6 years or so

andy.fingerhut20:12:07

There are times where there were perhaps legitimate questions whether a change in a release was breaking or not, such as the hash change in 1.6 also leading to hash inconsistency between Java sets and Clojure sets that were clojure.core/= before and after, but no longer had the same hash any more.

andy.fingerhut20:12:42

Which then causes sets or maps containing those things not to be clojure.core/= any more.

andy.fingerhut20:12:12

Such questions usually lead to refinements in the definition of what was promised, and what wasn't.

bfabry20:12:02

adding validation to the ns macro which subsequently stopped (ns foo (use bar)) being acceptable is another one of those things

bfabry20:12:34

no one said it would work, but it did, and now it doesn't. given the low number of people affected and how easy it was to fix I'm glad they went with locking it down though

bmaddy20:12:28

Hmmm,

> (println '(and "foo"))
(and foo)
I would expect that to print (and "foo"). Does anyone know why it doesn't? Is there a way to include the quotes?

bmaddy20:12:11

Indeed, thanks!

bfabry20:12:19

ya, println tries to be human friendly. prn is for serializing data

seancorfield20:12:56

We've pretty much always used Alphas in production as they become available for over six years: because we want access to the latest features. We're using clojure.spec heavily in production, for example.

seancorfield20:12:39

ISTR 1.4 "broke" some stuff around numeric overflow / representation? (didn't affect us) and 1.5.0 had a memory leak (fixed in 1.5.1 -- we were spared that as we were on a pre-release of 1.5 in production at the time, before the leak was introduced, and we went straight to 1.5.1 because of our release schedules at the time). And the hash code change in 1.6 didn't bite us either (I'm still not clear on how widespread that breakage was?).

seancorfield20:12:18

We started with Clojure 1.3 (Alpha 7 or 8 in production) because we wanted to skip ahead of the big 1.2 -> 1.3 Contrib split and the AOT compatibility issues around that. It's also how I ended up maintaining clojure.java.jdbc -- because clojure.contrib.sql needed a maintainer to bring it across the 1.2/1.3 divide 🙂

seancorfield20:12:28

We test our apps against Clojure's master SNAPSHOT as well as whatever version we're going to production with so we get a heads up of any breakage.

matan21:12:20

@tbaldridge @seancorfield thanks for the perspectives and explanation ― I sure learned something new

matan21:12:49

As someone who does not maintain a clojure core library, I might be a bit more conservative myself 🙂 but testing against Clojure's master snapshot sure sounds nice (especially if it doesn't break the test suite very often)

seancorfield21:12:00

One of Clojure's strengths, in my opinion, is how stable it has been across versions. The Clojure/core team are very serious about accretion rather than breakage 🙂

matan22:12:55

Something else ― roughly one week ago I asked about writing code for stream-processing of data, which gave rise to a short discussion suggesting that although collections are sufficiently lazy (only up to 32 items may be realized under the covers at any point in time), transducers should be strictly preferred for a streaming application. In streaming I mean, mainly, processing an input file using only a constant memory footprint, rather than consuming the entire (potentially humongous) file into memory and such. Then also processing the stream forward through whatever few processing steps, in a similar way, for the same reason. Do folks here agree to that suggestion, about preferring transducers over plain lazy collections?

phronmophobic22:12:12

lazy collections and transducers aren’t mutually exclusive

phronmophobic22:12:39

transducers are a good option for describing and composing the individual steps

phronmophobic22:12:02

they also are useful for streaming because they don’t care about the source or the sink

hiredman22:12:50

in general, for streaming processing, you are going to be working with folds (a tree shaped process, the degenerate shape of which is a linear reduce)

phronmophobic22:12:17

as far as processing data with constant memory requirements, you can use lazy sequences, but there are other good options as well

hiredman22:12:06

once you are working folds, using transducers and transduce is pretty much a no brainer

phronmophobic22:12:15

there are also a lot of stream processing libraries to choose from that help provide a good story for how to put everything together

hiredman22:12:08

when you are using a fold like reduce (or transduce) you also get a pretty clear scope for managing resources (like closing db connections, or files, or whatever) which lazy-seqs don't really give you

tbaldridge22:12:56

@matan I prefer transducers in this case simply beacause it's really hard not to hold onto the head of a seq with lazy seqs. And with transducers its pretty much impossible to shoot yourself in the foot this way.

tbaldridge22:12:02

I've built too many systems that work fine until you get about 2GB of data through them then they fall over due to some sort of lazy-seq related memory "leak"

Adam Faraj23:12:45

Hello Everyone. Are there any good resources to learn Clojure quickly and efficiently?

andy.fingerhut23:12:58

If you don't mind paying some $, Clojure Programming is a good book: http://shop.oreilly.com/product/0636920013754.do There are other fine books to learn from, also.

Ryan Radomski23:12:02

@faraj.9798 I will also add Clojure for the Brave and true https://www.braveclojure.com/ If you are looking for raw time to workflow, then brave clojure has the advantage there IMHO. If you want a more in depth resource, then the O'Reilly book is always a really safe bet. It just depends on where your priorities are.

seancorfield23:12:25

Or Living Clojure by Carin Meier, or Programming Clojure 3rd Edition... 🙂

seancorfield23:12:06

Clojure Programming is good for the basics but a little outdated now (it targets Clojure 1.5 I think?).

seancorfield23:12:10

Nope, 1.4 (examples work on 1.3 and 1.4). So I'd be cautious to recommend Clojure Programming at this point (although I love it as an all-round introduction to the language and some common libraries -- it's clojure.java.jdbc section is outdated, due to lots of improvements in that library... I'm not sure it's example even work with recent clojure.java.jdbc versions).

seancorfield23:12:21

@faraj.9798 If you're new to Clojure, you'll find the folks in the #beginners channel are super helpful.

Adam Faraj23:12:14

I'm interviewing at a company that uses Clojure and React. I'm comfortable with React, just need to increase skills with Clojure.

seancorfield23:12:08

Cool. Good luck with the interview! Are they using Clojure on the server or ClojureScript with React on the client?

Adam Faraj23:12:03

I think Clojure on the server? They never mentioned ClojureScript.

seancorfield23:12:48

'k ... we're React on the front, Clojure on the back too ... it's a good combination.

Adam Faraj23:12:51

Where do you work....? Haha

Ryan Radomski23:12:39

@seancorfield Is that React without clojurescript? If so, what were the motivators for that decision?

Adam Faraj23:12:41

Thanks everyone for your help.