Fork me on GitHub
#clojure
<
2017-03-21
>
tbaldridge00:03:00

Always got to qualify statements of "x is faster than y"....apply vs not apply doesn't really matter in the face of something like (assoc {} :a 42)

tbaldridge00:03:44

A lot of stuff we do in Clojure is orders of magnitude more expensive than apply

noisesmith00:03:58

thanks for the perspective

Alex Miller (Clojure team)00:03:53

apply was optimized in 1.9 and is often much faster now btw

Alex Miller (Clojure team)00:03:23

But not faster than not using it :)

devn05:03:32

I wish there were a first that threw when there was not exactly one item in the coll.

bja06:03:39

@devn you mean like this: (defn evil-first [coll] (if (= (count coll) 1) (first coll) (throw "not exactly 1 item in coll")))

bja06:03:05

I have no idea why you'd want that, but it seems easy enough to have

hit02306:03:07

A simple explanation for 'set!' ?

slipset07:03:47

Your periodic reminder regarding fast and slow code: 1) Unless you've proven that a certain piece of code is the bottleneck, optimize for readability, not speed. 2) If your code "goes over the wire" you've lost and the only thing to optimize is how many times you're going over the wire. 3) this might not apply if you're writing a library where use cases are unknown or if you're the creator of Clojure.

camdenclark07:03:18

@slipset: what do you mean by “goes over the wire?” Haven’t heard that turn of phrase before.

leena07:03:20

This is now a superstupid question, but: I have a clojure hashmap and want to have it in json format. Using cheshire.core generate-string, it is all in string then naturally and all quotes are escaped. How can I get a better json representation without the escaped quotes?

slipset07:03:05

@camdenclark for frontend, I mean contacting the server, for your server contacting e.g. a database. Going over the wire then means accessing the network.

camdenclark07:03:22

I see, that’s what I thought but wanted to make sure.

m07:03:05

@leena ... What do you mean by 'better json representation?' To me it looks like JSON needs the double quotes around its keys. If you write a json string "{\"FOO\":\"bar\"}" to a file, the escape backslashes are gone...

leena07:03:58

My use case is pretty daft as well 🙂 Playing with REPL, and just want to get the json copied from there

m07:03:04

@leena ahh. You could easily write it to a file (spit "myfile.json" "{\"FOO\":\"bar\"}") and then copy it from there..

leena07:03:18

Yes, just did that, but seems a bit silly to have to do that 😄

leena07:03:09

But thank you 🙂

slipset07:03:42

@leena have you tried clojure.pprint/pprint on your json?

m07:03:52

(println "{\"FOO\":\"bar\"}") has the same effect... maybe more convenient..

m07:03:29

right, or even pprint..

akond08:03:23

is there a book about john mccarthy? a bio or something.

akond08:03:21

or should I be asking in the off-topic channel?

hit02309:03:03

Can anyone explain the presence of/usage of 'edn' in clojure ? How to use them? When to use them? Basically, what are they?

jjl09:03:21

edn is a data format, a subset of clojure syntax that is only data

maxp09:03:36

what is the right way to provide source line/file for loggers? (logback for example)

weltan13:03:21

hey just curious, anyone out there using Clojure right now for API / service bus work? if so, ping me!

Matt Butler13:03:13

Whats the most performant/idiomatic way of join a sequence of sub-sequences? ((1 2 3) (4 5 6)) => (1 2 3 4 5 6)? mapcat where you return the element?

gmcramm13:03:36

The first thing I’d jump to would be apply concat

gmcramm13:03:52

eg (apply concat '((1 2 3) (4 5 6)))

gmcramm13:03:04

But there might be a better way I don’t know about

mpenet13:03:36

I guess (into [] cat coll),

mpenet13:03:21

not measured anything tho

Matt Butler13:03:05

Okay, ill try benchmarking these methods, both seem more expressive.

mpenet14:03:26

concat returns a lazyseq tho, so not really equivalent

Matt Butler14:03:13

Very true, in this instance, laziness is not required, dealing with small sizes of coll, but ran often.

mpenet14:03:37

you could swap into for sequence if that mattered

mpenet14:03:49

yeah small size apply concat will likely win

caryfitzhugh14:03:30

Anyone have any insight into progress being made on a statically compiled CLJ program? I'm imaginign it would be implemented underneath in golang, so I already have an extension

.cljg
In my environment - I need stand-alone that aren't too large. I was imaginging that one could create a clojure-go program that would compile into a static binary. any ideas - any google search topics? I did a little searching, but... Maybe it's an intractable idea?

bja14:03:51

@caryfitzhugh If you're willing to package your app like an old-style java app (i.e. deal with setting up the classpath outside of your application in some shell script in the deployment environment), you can have a rather small jar.

caryfitzhugh14:03:49

Still requires java I believe?

caryfitzhugh14:03:20

When I am making docker containers there is the desire to keep them teeny tiny. Hence my desire to static compile it...

bja14:03:54

Isn't sharing the JRE enough?

bja14:03:41

if not, you could create two layers to your docker container. One with the base java layer, one with your dependencies layer, and then deploy your clojure app on top of that

bja14:03:58

that way your java layer and dependencies layer can remain static over time

bja14:03:31

Docker should reuse those static layers each time

bja14:03:42

the way your build task would end up, you'd have the java container, and then whenever your project dependencies changed, your dependency layer would get rebuild, and then you'd have an application layer that would change often (but shouldn't be very large, seeing as it's just your resources and clj files)

caryfitzhugh14:03:59

There are a number of approaches, but to sell it to the team, putting the jre on the machines is probably a non starter. Or downloading to a client machine. Oh well. Maybe I will win the lottery and have a year to implement. :P

bja14:03:35

good luck. tbh, the boot script or leiningen task for what I described shouldn't really take more than a day or two if you have some familiarity with docker

bja14:03:52

but it sounds like the initial java layer is more of a hangup than the docker parts

caryfitzhugh14:03:13

Me doing it isn't the problem. I can do it. Yes, exactly. The external dependency is the kicker.

caryfitzhugh14:03:31

Because people have a tool with no dependencies. So it is hard to sell another tool which does have one

wasamasa14:03:36

You could try resurrecting gcj for this, but I only know of pdf-tools using it.

tbaldridge16:03:13

Even if you could compile Clojure to Go, I doubt it will be fast. There's a lot of stuff required by a functional language that Go just simply doesn't have.

tbaldridge16:03:44

I could imagine something like that really stressing Go's virtual dispatch and GC past the limits for which it was designed.

ghadi16:03:52

JVM is such an unbelievably dynamic environment

ghadi16:03:47

I made a small JDK 9 linked-module app that gutted clojure.core a bit -- runs as a static executable, 45MB

ghadi16:03:58

but it only included the java.base module

ghadi16:03:17

But I really have to question your problem constraints @caryfitzhugh

tbaldridge16:03:18

Hence my favorite saying: "You say X is faster than the JVM? Is it parallel, GC'd, dynamically JIT'd, dynamically typed, capable of handling tens of GB of data? If not...it's apples to oranges..."

ghadi16:03:28

I like go for the most part, but it doesn't do dynamic load, which is nearly necessary for Clojure

ghadi16:03:17

No tool has 0 dependencies -- at least a container is a way of encapsulating them properly

caryfitzhugh16:03:12

Not saying it would be golang. Just exploring trying to combat an objection people will bring up. Dropping a go binary on a 5mb alpine image is pretty lightweight. And downloading a go binary to a user's machine is light. Just wondering about any progress or not in that arena.

ghadi16:03:33

Maybe give people the benefit of the doubt with respect to their prejudice. Most appropriate tool for the job should be the one employed. If that's clojure, great

tbaldridge16:03:41

If you had everything Clojure offers in a go binary it wouldn't be 5mb

tbaldridge16:03:15

the reason go binaries can be so small is that they don't contain a lot of logic. Start adding in persistent structures and that gets pretty big pretty quick

ghadi16:03:23

comparing binary sizes is not a great way for you to get clojure used

ghadi16:03:42

I'd focus on reliability and long-term avoidance of complexity

tbaldridge16:03:37

memory and HDDs are cheap...my time is not

ghadi16:03:01

I personally enjoy light containers... But 250MB and 5MB are in the same order of magnitude for me.

qqq17:03:08

https://www.tensorflow.org/api_docs/java/reference/org/tensorflow/package-summary <-- apparenlty tensorflow now supports java. anyone working on a clj library for it?

noisesmith17:03:20

@caryfitzhugh what about a minimized cljs app and a small js runtime?

noisesmith17:03:41

that’s probably less work and more results than most alternatives if you want something relatively lightweight with clojure features

noisesmith17:03:05

there’s also a great tiny language called pixie that is its own vm and is not compatible with clojure, but very similar

noisesmith17:03:28

it’s about the size of bash

caryfitzhugh17:03:24

it's fine - not trying to boil the ocean. 🙂 I may take a look at pixie though. I'm working in a group that wants to do micro-services and really likes their minimal images - while I agree on the ideas of developer time, etc. I'm not the one that needs convincing... 😛 thanks for the comments.

noisesmith17:03:26

yeah- pixie is very simple, has immutable data structures, it is probably right up your alley (except not nearly as much library support unless you start doing host interop with your OS libs…)

caryfitzhugh17:03:47

immutable FTW 🙂

greg_arcara17:03:10

is there a way to do bitwise operations on bigints?

noisesmith17:03:12

also it prints out a pretty fractal in ascii when you compile it

greg_arcara17:03:30

@noisesmith thanks, just wanted to verify I wasn't missing something

noisesmith17:03:29

it has a toBigInteger method to make biginteger, which does have bitwise methods http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html

noisesmith17:03:58

the source for the conversion makes it look like the conversion is super cheap - I guess the bigint class must exist for hash and eq reasons

greg_arcara17:03:00

yes, I think I read that it's for hash and eq reasons

tbaldridge17:03:39

Pixie is also in the 16MB range last I checked, and if you run a significant program it can easily hit 100-200MB of memory usage.

dragoncube20:03:34

@tbaldridge btw, why Pixie, but one more Clojure like ClojureScript or Clojure CLR?

tbaldridge20:03:08

A lot of pixie was a deep-dive into how far we could leverage immutable data in a custom VM. Turns out it's really hard, (due to quite a few things that would take too long to go into here). So from the start the idea was that I wanted to be able to warp Clojure semantics where it was advantageous to the JIT.

dragoncube20:03:32

I see, but does it makes sense to have it just on top of Python runtime?

souenzzo20:03:57

rly interested in "Clojure py - clpy"

jeff.terrell20:03:25

@tbaldridge - I'm interested to know more about why that's hard. Is there a blog post or something about that somewhere?

tbaldridge20:03:01

So the problem is this: Tracing jits work best on straight-line code where one branch of an if is almost always taken, or where the type in a given position is almost always the same.

tbaldridge20:03:08

and realize that assoc on a PHM node is polymorphic, so you end up with something like 5-6 conditional jumps per assoc, where each and every one of them are true or false based on the number of items in the assoc.

tbaldridge20:03:31

So it turns out the type of JIT that works best for that sort of work....looks a lot like HotSpot.

jeff.terrell20:03:36

Interesting, thanks for explaining! I don't have much background on JITs (and hadn't heard of a tracing JIT until just now), but I see what you mean about conditionals making things difficult.

tbaldridge20:03:55

I think Clojure on top of the PythonVM is possible, and I've done some work in that area, but I just don't have time (or energy) for the work anymore.

akjetma21:03:06

Is there a way to automatically shut down a repl that hasn't had any input or output for some period of time?

noisesmith21:03:38

sounds like a fun weekend hack nrepl plugin

akjetma23:03:25

Oh hello there! Yes, looks like we might be doing that

josh.freckleton23:03:31

in my project.clj I have :repositories [["private" {:url "s3://..."}]] and I have a checkouts folder with a sym link to a dependency which I develop locally but when I lein repl, it tries to load my local dep from the "private" repo... how can I force it to look in checkouts?

hiredman23:03:22

that is how checkouts work

hiredman23:03:58

checkouts don't replace a dependency, they make it easier to work on code from a dependency at the same time as code from your project