Fork me on GitHub
#clojure
<
2017-12-22
>
noisesmith00:12:34

yeah, profiling with actual runtime conditions is always called for if there are performance problems

noisesmith00:12:58

speculatively optimizing before you have something that works is a great way to waste a lot of energy

seancorfield02:12:24

It just occurred to me... we should update our multi-version testing to check code against clojure-1.10.0-master-SNAPSHOT now that 1.9 is released! šŸ˜†

sparkofreason02:12:30

When using pprint on a map containing namespaced keywords, long namespace prefixes are kind of a headache, pushing the output far to the right. Is there a way (short of writing my own formatter) of having it substitute aliases for the full namespace name?

seancorfield02:12:36

(set! *print-namespace-maps* false) perhaps?

seancorfield02:12:30

(not sure how you'd get an alias substituted in -- unless you wrote your own print-method for clojure.lang.IPersistentMap?)

sparkofreason03:12:50

*print-namespace-maps* is a little better, though it sort of shifts the readability problem. I guess I'll think on making a custom print-method that interrogates the current ns aliases or something.

qqq06:12:29

how expensive is the overhead of a vector with one element ?

qqq06:12:37

(compared to just storing that element)

arrdem07:12:06

~sizeof(Object[32]) IIRC

arrdem07:12:14

So probably not very

qqq09:12:25

Is there a builtin for:

(defn u-in [obj path f]
    (let [o          (get-in obj path)
          [nv & rst] (f o)]
      (into [(assoc-in obj path nv)] rst)))

  (u-in {:a   {:b 2}
         :foo :cat} [:a :b] (fn [x] [(inc x) :foo]))


qqq09:12:27

is there a better way to write:

(fn [[o f]] (f o))
it seems like a weird enough function there should be some weird name for it

burke10:12:11

(eval (rseq ....)) šŸ’£šŸ’„

qqq10:12:28

is there a 'stateful iterate' ? i.e. suppose (f x0) = [x1, v1] (f x1) = [x2, v2] (f x2) = [x3, v3] .... I want something where (g x0 3) = [x3, [v1 v2 v3])

qqq12:12:51

is there a way to ask cloc to count test code separately?

qqq12:12:01

basically, anything defined via (ct/...) where ct = clojure.test

qqq13:12:49

(def fapp (fn [[f & args]] (apply f args))) <-- wtf, is this function just #(apply apply %) ?

synthomat13:12:08

woah clojure is just incredible, there are plenty of different macros and then you think ā€œsuper handy - if there was only a way do slightly diverge from the default behaviorā€, and then you google a bit and there is for sure something build in šŸ˜„

MiÄ·elis Vindavs14:12:11

ah, didnā€™t notice you want all the vs

MiÄ·elis Vindavs14:12:29

(->> [0 []]
     (iterate (fn [[x vs]]
                (let [[x' v'] (f x)]
                  [x' (conj vs v')])))
     next
     (take 3))

cgrand14:12:57

@ghsgd2 a lumo version issuer. #unrepl is a better place for unravel issues

New To Clojure15:12:28

>In my case, startup time of the actual script went down to 80ms

sekao16:12:23

is there a way to make clj start the repl in a certain namespace?

joelsanchez16:12:07

:repl-options :init-ns

joelsanchez16:12:29

so, in project.clj, you could add: :repl-options {:init-ns user :port 4001 :nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}

sekao16:12:52

no i'm talking about clj which comes with tools.deps, not leiningen

Alex Miller (Clojure team)19:12:56

itā€™s a little cumbersome but you could do

Alex Miller (Clojure team)19:12:57

clj -e "(use 'clojure.set) (in-ns 'clojure.set)" -r

noisesmith19:12:36

my favorite golfing of require / switch ns is (doto 'clojure.set require in-ns)

jaysherby20:12:11

What would you call the value that peek returns? You can't call it "first" or "last" since that depends on the type you supply.

noisesmith20:12:26

not only that but first and last are functions you probably don't want to shadow

noisesmith20:12:40

for a stack, it would be the top value

jaysherby20:12:24

That's true. Doesn't really matter what the type of the structure is because chances are good you're using it as a stack or queue if you're using pop and peek.

jaysherby20:12:31

Thanks. I just needed a gut check on that.

jaysherby20:12:20

I needed an appropriate name for this convenience function I just wrote:

(defn update-top [coll fun & args]
  (conj (pop coll) (apply fun (peek coll) args)))

gcast20:12:56

does anyone know how to write to STDIN from clojure? I'd like to write a string to STDIN so that a process listening to *in*would be able to consume the string

gcast20:12:38

unorthodox, i know, but mostly for hacky purposes

scriptor20:12:22

@gcast are these 2 separate processes?

gcast20:12:39

well one of them is a repl and the other is a server receiving messages across a web socket

scriptor20:12:07

is the repl running in the same process as the server?

noisesmith20:12:17

AFAIK you need to resort to OS functionality to write to STDIN - it's something I wouldn't expect the jvm to abstract or provide for you

scriptor20:12:09

is the server listening on both stdin and the websocket?

gcast20:12:14

what is the interpretation of this (spit *in* some-string)

gcast20:12:27

server only listens to websocket

noisesmith20:12:46

you can't spit to *in*, that will just throw an exception; beyond the obvious *in* can be freely rebound, and the binding only has to support reading

scriptor20:12:08

which process is listening to *in*

gcast20:12:16

to rephrase my question: there is a websocket server running in a repl and I want the msg coming through the socket to be interpreted by the repl as if it was entered from STDIN

noisesmith20:12:26

you can easily start a repl that listens to a fifo or socket btw

noisesmith20:12:59

I'd start a repl on a new thread in the same process, and bind *in* to the input from the socket

noisesmith20:12:03

STDIN isn't special

gcast20:12:39

true. thats a good idea.

gcast20:12:43

thank you

noisesmith20:12:04

and you probably want it's *out* to send back to the client too, for that matter

noisesmith20:12:38

clojure has a built in socket repl class, but for a websocket you might need to write your own (also I'm sure you're aware this a security nightmare)

gcast20:12:57

yeah =/ other than an http request, websockets seemed the only way to talk to a remote repl from the browser

noisesmith21:12:20

right, the problem is that a repl effectively gives root because every single mainstream OS has local root holes that don't require physical access

noisesmith21:12:45

if you trust everyone who can load the web page to have root, that works out (I'd be very careful about who can visit the page of course)

gcast21:12:40

it would be internal to my company's network, but yes I understand the implication. Are jupyter notebooks with ipython kernels similarly insecure?

noisesmith21:12:42

I don't know python - but a good indicator would be how hard is it to make a shell call inside the python code... if they can run a system command then it's probably about the same

gcast21:12:27

indeed you can with little in the way. thats at least a bit comforting

yogthos21:12:32

@alexmiller have a quick question about clojure.java.classpath/classpath-directories with JDK 9

yogthos21:12:59

and traced it down to the fact that the behavior of classpath-directories changed when using JDK 9

yogthos21:12:40

when I run it with JDK 8 or below I see something like:

(#object[java.io.File 0x30efe7c "/Users/yogthos/src/migratus/test"]
 #object[java.io.File 0x70111841 "/Users/yogthos/src/migratus/src"]
 #object[java.io.File 0x51ee3ff3 "/Users/yogthos/src/migratus/resources"]
 #object[java.io.File 0x24a1e205 "/Users/yogthos/src/migratus/target/classes"])

yogthos21:12:54

however running on JDK 9 returns an empty seq

yogthos21:12:00

is this a bug?

yogthos21:12:09

looks like things break down here:

(map
  get-urls
  (take-while
    identity
    (iterate #(.getParent ^ClassLoader %) (clojure.lang.RT/baseLoader))))
=> (nil nil nil nil nil nil)

yogthos16:12:08

This does look like a bug, the Base ClassLoader is no longer derived from the URLClassLoader

yogthos16:12:44

so this code in clojure.java.classpath fails:

(defn get-urls
  "Returns a sequence of java.net.URL objects used by this
  classloader, or nil if the classloader does not sastify the
  URLClasspath protocol."
  [loader]
  (when (satisfies? URLClasspath loader)
    (urls loader)))

yogthos16:12:28

and looks like there is a JIRA task for this https://dev.clojure.org/jira/browse/CLASSPATH-8

Alex Miller (Clojure team)18:12:37

Seems like a bug. Patch welcome...

yogthos20:12:35

I'll let you know if I come up with anything

yogthos20:12:51

I'm going with ClassLoader/getSystemResource for my current use case

yogthos20:12:44

in the mean time it might be better to throw an unsupported exception in clojure.java.classpath/classpath when running under java 9

yogthos20:12:14

the current behavior of returning nil masks the problem and makes it difficult to figure out what happened

yogthos20:12:05

this affects any library maintainers who rely on this functionality

yogthos20:12:20

it would also be good to have a unit test for this šŸ™‚

qqq21:12:30

3 lines of unit test per line of code -- is this within reasonable limits, or is it ridicilous ?

noisesmith21:12:23

depends on how much logic you like to put on a line I guess

qqq21:12:12

here's an example of code + unit tests:

(do ;; stateful

  (def si        (fn [f s] (itr #(f (first %)) [s]))) 
  (def sic       (fn [f s n] (take (+ n 1) (siter f s)))) 
  (def sics      (juxt #(first (last %)) #(map second (rest %)))) 
  (def sis       (fn [f s n] (sics (sic f s n)))) 
  (def sfc       (fn [f c [o sf] i] (va [id #(c sf %)] (f o i)))) 
  (def smap      (fn [f o lst] (reduce #(sfc f conj %1 %2) [o []] lst)))
  (def swu       (fn [s t f] (if (t s) (recur (f s) t f) s)))

  (let [g0 (juxt inc #(* 2 %))
        g1 (fn [s i] [(+ s i) (+ (* 10000 s) i)])] 
    (ct/is (= (sic g0 0 3) [[0] [1 0] [2 2] [3 4]])) 
    (ct/is (= (sis g0 0 3) [3 [0 2 4]])) 
    (ct/is (= (smap g1 0 [1 2 3 ]) [6 [1 10002 30003]])) 
    (ct/is (= (swu 1 #(< % 10) #(+ % 2)) 11))))

phronmophobic22:12:54

while you can create new functions for various combinations of builtins, thereā€™s something to be said for writing most of your code in terms of more common functions

phronmophobic22:12:43

for example, if you us smap somewhere

phronmophobic22:12:59

to figure out what it does you have to then go and figure out what sfc does

phronmophobic22:12:13

which means you have to figure out what va does

phronmophobic22:12:27

and I donā€™t know what va does

noisesmith22:12:05

nothing like a codebase that forces you to master a language only used in Tolkien's Sylmarillion in order to understand it

qqq22:12:42

va = vector apply, (va [f g h] [v1 v2 v3]) -> [(f v1) (g v2) (h v3)]

qqq22:12:19

smap = "stateful map", standard map is: f :: a -> b stateful map is f:: [s, a] -> [s', b] so there is a "state variable" being threaded through

the2bears23:12:12

What exactly is the question, though? Do the tests cover all/enough of the cases? If yes, then they're enough. 3 lines of test per line of code is such an arbitrary value. How long is a piece of string?