#clojure log - Oct 30 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:55 kenrestivo: why do so many people use (alter-var-root #'system component/start)) instead of (defonce system (atom nil)) (swap! system component/start) ?

0:55 is there any real advantage to using alter-var-root instead of a clojure ref type?

1:39 pyon: How do I case-analyze a sequence, depending on whether it's empty, or it has a head and tail?

1:45 TEttinger: if you mean for a function checking its args, there's pre and post conditions

1:45 in general, checking for empty is done with

1:46 ,(if (seq []) "it has stuff in it" "it's empty")

1:46 clojurebot: "it's empty"

1:46 TEttinger: ,(if (seq [:a]) "it has stuff in it" "it's empty")

1:46 clojurebot: "it has stuff in it"

1:46 TEttinger: the head and tail stuff is more interesting

1:47 justin_smith may have used preconditions before, or quite a few other people I'm sure

1:50 pyon: Ah!

1:50 TEttinger: thanks!

1:53 TEttinger: ,(defn checker [coll] (if (and (seq coll) (rest coll)) "it has a head and tail in it" "it has one or fewer elements"))

1:53 clojurebot: #'sandbox/checker

1:53 TEttinger: ,(checker [])

1:53 clojurebot: "it has one or fewer elements"

1:53 TEttinger: ,(checker [:a])

1:53 clojurebot: "it has a head and tail in it"

1:53 TEttinger: ah I screwed up

1:53 ,(rest [:a])

1:53 clojurebot: ()

1:53 TEttinger: ,(defn checker [coll] (if (and (seq coll) (seq (rest coll))) "it has a head and tail in it" "it has one or fewer elements"))

1:53 clojurebot: #'sandbox/checker

1:53 TEttinger: ,(checker [])

1:53 clojurebot: "it has one or fewer elements"

1:53 TEttinger: ,(checker [:a])

1:53 clojurebot: "it has one or fewer elements"

1:53 TEttinger: ,(checker [:a :b])

1:53 clojurebot: "it has a head and tail in it"

1:54 pyon: :-O

1:54 TEttinger: rest will return an empty seq if there's nothing to get after the head

1:54 calling seq on an empty sequence returns nil (which is considered false in conditions)

1:55 but the empty sequence itself is not nil. most clojure core fns use that idiom of calling seq on any collection they are given to ensure it is treated as a seq (not some arbitrary type) but also to make sure it isn't empty

1:56 pyon: Ah, makes sense!

2:03 In Emacs' clojure-mode, what's the command for firing the REPL?

2:22 Is there any pastebin site with Clojure highlighting? Which pastebin site is preferred here?

2:33 I'm trying to translate a toy program to symbolically compute derivatives of monomials and polynomials from Haskell ( http://lpaste.net/144231 ) to Clojure ( http://lpaste.net/144242 ), but the translated version doesn't work. Could anyone explain to me why?

2:36 I'm representing polynomials as sequences of monomials (summands), and monomials as sequences of symbolic factors.

2:56 neoncont_: pyon: one thing that stands out to me is the second argument to map. It seems like from your base case, mono returns a seq, however map takes a function and a coll

2:56 pyon: Oh.

2:56 What's the difference?

2:57 neoncont_: I'm still getting used to this myself. It's a big difference from other lisps: http://clojure.org/sequences

2:57 pyon: Checking. :-)

2:57 Also, it strikes me as weird that a seq isn't a coll.

2:57 Aren't sequences particular kinds of collections?

2:59 neoncont_: That's a good point, actually. I would expect seq to be a subtype of coll, now that you mention it

3:01 Dang. My cafe's closing now and I gotta go. I'm curious the answer myself :)

3:49 owlbird: Is there some tools that can generate SQL like mybatis' OGNL ?

3:52 which can switch on/off SQL segments with a set of k/v pair

4:27 TheBrayn: hi

4:31 TEttinger: hi TheBrayn

4:37 pyon: How do I get a string from a sequence of characters?

4:38 oddcully: clojure.string/join or apply str

4:38 pyon: Thanks!

4:38 oddcully: ,(apply str (seq "zerg"))

4:39 clojurebot: "zerg"

4:42 Glenjamin: hi all, anyone know if there's a way to get lein to shut up about repositories in profiles.clj?

4:43 TEttinger: technically, rm -r /*

4:44 it would also make everything else shut up, but still

5:27 yenda: (apply max '(1 2 3 1))

5:27 is it better than (reduce max '(1 2 3 1)) ?

5:31 Bronsa: yenda: apply max still ends up using reduce max internally

5:34 Schrostfutz: Is there a syntax to put the individual values of a sequence to parameters?

5:35 So that I can do (max [1 2 3])

5:35 spradnyesh: getting the following "failure" when using expectations (lein autoexpect)

5:35 in expected, not actual: [{:close 94.2, :low 92.1, :open 93.6} {:close 95.2}]

5:35 in actual, not expected: [{:open 93.6, :close 94.2, :low 92.1} {:close 95.2}]

5:35 any idea what might be going wrong? i'm stumped

6:30 spacepluk: Schrostfutz: apply?

6:32 hyPiRion: spacepluk: might be a floating point issue

6:33 pyon: I want to make a macro that's used like this: (deffoo bar [[0 :a :b] [1 :c :d] [2 :e :f]]), and expands into (defstruct bar0 :a :b) (defstruct bar1 :c :d) (defstruct bar2 :e :f). How do I do this?

6:36 (Well, it doesn't have to be exactly like this. But, in general, what I want is the ability to “append suffixes” to identifiers, as in bar0, bar1, bar2.

6:36 )

6:38 hyPiRion: pyon: something like (defmacro [prefix & elems] `(do ~(map (fn [[suffix & items]] `(defstruct ~(symbol (str prefix suffix)) ~@items)))))

6:38 pyon: hyPiRion: Thanks!

6:40 hyPiRion: hm, that didn't work as expected

6:40 pyon: Mmm...

6:41 hyPiRion: pyon: (defmacro deffoo [prefix & elems] `(do ~@(map (fn [[suffix & items]] `(defstruct ~(symbol (str prefix suffix)) ~@items)) elems)))

6:41 Then (deffoo bar [0 :a :b] [1 :c :d] [2 :e :f]) should expand into (do (clojure.core/defstruct bar0 :a :b) (clojure.core/defstruct bar1 :c :d) (clojure.core/defstruct bar2 :e :f))

6:42 pyon: Trying.

6:42 Is there a reference explaining what `, ~ and @ mean?

6:44 hyPiRion: pyon: there's a long text on it here: http://www.braveclojure.com/writing-macros/

6:44 pyon: hyPiRion: Thanks, will read.

6:44 hyPiRion: But essentially, ` is like '. Inside a `, a ~ will actually be evaluated, and ~@ will be evaluated and sliced in

6:45 so `(foo ~(+ 1 2)) == '(foo 3) and `(foo ~@(map inc [1 2])) == '(foo 2 3)

6:45 spliced in*

6:47 It's good to try it out with macroexpand and macroexpand-1

6:47 pyon: :-O

6:58 Can I call the fields of a struct :0 :1 :2 etc.?

6:58 (This basically means “I don't want users to directly set these”.)

7:02 powered: users of the library?

7:03 pyon: Yeah.

7:16 What exactly does this syntax mean? (defmulti area (fn [share & _] shape))

7:17 What I don't understand is what the anonymous function there is for.

7:19 oddcully: s/share/shape/ right?

7:20 the result of this function call is used to pick the according defmethod

7:20 pyon: oddcully: Oh, yes, share was a typo

7:21 What is the function applied to?

7:21 The argument list?

7:23 oddcully: pyon: http://clojure.org/multimethods

7:23 powered: the function is applied to the arguments of the original function call I think

7:49 pyon: Is there any more direct way to access the elements of a struct than ((accessor foo :bar) my-foo) ?

7:49 s/elements/fields/

7:51 rarebreed: pyon you mean get a field from a defstruct?

7:52 pyon: Yeah.

7:52 rarebreed: if you're using a defrecord, you can treat it like a map: (:bar my-record)

7:53 defstructs have kind of been superceded by defstructs, but I believe they are the same

7:53 pyon: defstructs by defstructs?

7:53 rarebreed: defrecords are kind of the replacement for defstructs. they implement PersistentHashMap, but you can attach defprotocols to them

7:54 and under the hood, they are more performant

7:54 pyon: Oh.

7:54 rarebreed: since they actually create a Java class (which is why you create a defrecord with (MyRecord. foo bar baz)

7:55 pyon: What does `defrecord` look like?

7:55 I mean, usage.

7:55 rarebreed: (defrecord Character [intelligence Strength Dexterity])

7:55 (Character. 10 15 13)

7:56 oops

7:56 (def character (Character. 10 15 13))

7:56 pyon: Ah, nice. :-)

7:56 Thanks.

7:56 rarebreed: (println "strength is:" (:strength character))

7:56 Empperi: not a proper D&D character!

7:56 missing wisdom, charisma and endurance!

7:56 rarebreed: I'm old skool Empperi, I haven't played D&D since 1st ed

7:57 :p

7:57 Empperi: I've played D&D from 1st ed to 5th ed

7:57 :)

7:57 and even 1st ed had six attributes :)

7:57 pyon: Can I give the fields of a record numeric names?

7:57 rarebreed: I bought Pathfinder, but never played it :p

7:57 frenata: Endurance...?

7:57 Empperi: constitution

7:57 sorry :)

7:57 Schrostfutz: spacepluk: thanks

7:57 pyon: I'm going to autogenerate lots of records in a macro, I can't possibly come up with “normal” names for their fields.

7:58 rarebreed: pyon, you mean have a numeric type for the field? never tried...but it should be

7:58 pyon, you could always "keywordize" them. (keyword some-symbol)

7:58 pyon: `(keyword 0)

7:59 Anyway, (keyword 0) returns nil.

7:59 Ditto (keyword n) for any number n.

7:59 oddcully: ,(->Character 1 1 1)

7:59 clojurebot: #error {\n :cause "Unable to resolve symbol: ->Character in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: ->Character in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: -...

7:59 pyon: Oh, it was ,.

7:59 ,(keyword 0)

7:59 clojurebot: nil

8:00 rarebreed: interesting, I didn't know that with keywords

8:00 also, you can pass a map to a defrecord

8:00 (map->Character {:strength 10 :intelligence 12 :dexterity 15})

8:01 oddcully: ,(map->Character {:strength 18/00})

8:01 clojurebot: #<ArithmeticException java.lang.ArithmeticException: Divide by zero>

8:01 oddcully: there! no dnd!

8:01 rarebreed: that's really old skool oddcully :)

8:02 pyon: I guess I could always prepend some fixed string, like `field`, to the field's names.

8:02 field0, field1, field2...

8:03 rarebreed: it's a hack, but you could do this: (keyword (str 0))

8:03 pyon: :-O

8:04 oddcully: arent those then just indices and is all your struct/type/record just a vector?

8:04 why name it, it the name has no relevance?

8:04 rarebreed: I think you can't keyword a bare number, because a number by itself is not a valid symbol (the parser would have to interpret it as a literal)

8:05 pyon: oddcully: Well, sometimes I want two structs to have the same number of fields. Even then, I want to treat them as different entities.

8:05 That's why I can't use vectors.

8:05 rarebreed: which i think is why you also cant do (keyword '0)

8:05 pyon: Though I guess I could use a struct containing a single vector.

8:05 Anyway, this thing really has to be amenable to code generation.

8:09 I've updated my Stack Overflow question: http://stackoverflow.com/q/33431224/46571

8:09 This is assuming that I've understood multimethods right.

8:12 tommo: hi guys, i'm using prismatic schema to define a simple schema, but i'm not sure how to validate a schema-in-a-schema, can anybody help out?

8:13 rarebreed: pyon I only skimmed your SO question. Is defpoly generating a bunch of vars? ie, is step-n2-0 a var that gets defined by step?

8:14 if so, then yeah, your defmulti and defmethods looks ok

8:15 pyon: defpoly is generating structs

8:15 Oh, I want all the multimethods to be generated by `defderiv`.

8:16 defpoly probably also needs to generate an auxiliary var, saying which struct fields are r's and a's.

8:17 Otherwise defderiv couldn't work.

8:17 rarebreed: so, if you use defrecords instead of defstructs, defrecords actually create a type

8:17 so for your dispatch function, instead of second...I would make the dispatching function type or class

8:17 pyon: Ah!

8:17 rarebreed: then you can dispatch based on the type...ie step-n2-0 (if it's a defrecord) is actually a concrete type that you can match on

8:18 pyon: I only need to dispatch on the class of the second argument, though.

8:18 So, would it be (comp class second) ?

8:18 rarebreed: yeah you could do something like that

8:19 or if you want to be more performant....create a defprotocol that has a method....undo-step

8:19 and make all your defrecords implement it

8:20 (defprotocol Derive (undo-step [this]))

8:20 (defrecord step-n20 [...]

8:20 Derive

8:20 (undo-step [this] ...))

8:21 pyon: I'd be happy if it works at all. I'll worry about performance later.

8:21 rarebreed: hehe...Donald Knuth "premature optimization is the root of all evil" :)

8:21 pyon: :-)

8:52 steerio: Hi! I've started having NoClassDefFoundErrors for an extend-type out of nowhere. It has worked so far, and I haven't changed anything around it.

8:52 I am using the clojure.data.json/JSONWriter protocol, and it doesn't find the underlying interface.

8:52 Haven't updated the library.

9:02 solved. :)

9:05 pyon: Classes can be used as keys in maps, right?

9:05 I mean, classes themselves, not instances of them.

9:13 mpenet: ,(hash java.util.Date)

9:14 clojurebot: 1173145383

9:14 mpenet: if it has a hashCode it can I guess

9:19 pyon: What does the following mean? “CompilerException java.lang.RuntimeException: Can't create defs outside of current ns, compiling:(NO_SOURCE_PATH:70:1) ”

9:44 snowell: pyon: It means you have a (def) outside of your (ns) declaration

9:50 pyon: Just to be sure, this macro is okay, right? (defmacro data-ctor [name & args] `(defstruct name ~@(map (comp keyword str) (take (count args) (range)))))

9:50 It's supposed to be used like this: (data-ctor foo :a :b :c)

9:50 And it's supposed to expand to (defstruct foo :0 :1 :2)

9:52 magopian: hello there, I'm having a real hard time configuring my environment to have: 1/ figwheel 2/ vim connect to the repl (using vim-fireplace)

9:52 what i've tried so far: launching "lein repl", and trying the method in https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl (but I get FileNotFoundException Could not locate figwheel_sidecar/repl_api__init.class or figwheel_sidecar/repl_api.clj on classpath.

9:53 oddcully: magopian: do you have this problems since figwheel 0.4.x?

9:53 magopian: uncommenting the ":nrepl-port" figwheel option in my project.clj (I can connect my vim to it, but I can't evaluate anything)

9:53 oddcully: magopian: also there is #clojurescript

9:53 magopian: oddcully: i'm a noob, I'm just trying to set all that up (I've started from https://github.com/bhauman/lein-figwheel and wandered quite a bit to investigate/test various options)

9:54 oh, maybe I should be asking in #clojurescript then, thanks :)

9:54 oddcully: no problem. there is much overlap with both channels, but it's more of a cljs problem

9:55 pyon: I have a sequence of length n. What's the shortest way to turn it into :0 :1 :2 :3 ... :(n-1) ?

9:55 oddcully: magopian: i use a pachted fireplace for figwheel and i had to add some cider-stuff in my configs since 0.4.0

9:55 pyon: I came up with (map (comp keyword str) (take (count original-sequence) (range)))

9:56 But there has to be something smaller.

9:56 oddcully: shorter: (range (count n))

9:56 pyon: Ah!

9:57 magopian: oddcully: sounds painful :/

9:58 pyon: What's the easiest way to map a macro, rather than a function, to the elements of a list?

9:58 oddcully: magopian: well i just submoduled another fireplace into my ~

9:59 magopian: and it takes about 5 lines of changes to the default figwheel to have it going

9:59 pyon: s/map/apply/

9:59 I want something like (apply some-macro some-list)

10:00 magopian: oddcully: well, ok, thanks :)

10:00 i'll try downgrading to figwheel 0.4.0 then?

10:00 or before?

10:01 gfredericks: pyon: what's your use case?

10:01 magopian: 0.3.9

10:01 pyon: gfredericks: let me create a paste

10:01 gfredericks: http://pastebin.com/nRJt082V

10:02 If another pastebin site is preferred here, please do tell me.

10:02 oddcully: magopian: the patched fireplace was needed before

10:02 magopian: oh

10:02 man, this is sad :/

10:03 oddcully: magopian: https://github.com/tpope/vim-fireplace/pull/222

10:03 magopian: i was working on a "show and tell" demo, to show my colleagues about clojurescript, and how easy it is, and how powerful with the connected repl and everything

10:03 but seems it's not quite there yet

10:03 snowell: pyon: Lots of us like refheap.com, mostly because it has good clojure support

10:03 oddcully: clearly cljs fault ;P

10:04 magopian: oddcully: that's not what i'm saying:)

10:04 just saying that i'm not sure i'll be able to demonstrate how easy and shiny it is (right now :)

10:04 pyon: snowell: Nice, will take that into account. :-)

10:04 oddcully: well there are a) other means to connect vim to a repl and b) other editors

10:05 gfredericks: pyon: you might be able to replace (apply data-ctor ctor) with `(data-ctor ~@ctor)

10:05 also (cons `data-ctor ctor)

10:05 whichever you find more readable

10:07 oddcully: also i think fighweel/devcards power lessens the need for e.g. fireplace. you are one save away to see the whole world unfold in your browser (with devcards even parallel universes)

10:07 magopian: oddcully: indeed

10:07 pyon: gfredericks: Ah, nice, thanks!

10:07 magopian: i need to try devcards, haven't looked into it yet

10:07 connecting the repl has nice advantages though, like querying for the source or docs

10:13 pyon: I have a list, whose elements I can transform into key-value pairs. How do I make a map from this list?

10:13 Say, I have the list '(1 2 3), which I want to transform into the map {:1 1 :2 2 :3 3}.

10:14 gfredericks: ,(into {} (for [x '(1 2 3)] [(keyword (str x)) x]))

10:14 clojurebot: {:1 1, :2 2, :3 3}

10:14 pyon: ty :-)

10:16 jweiss: anyone know a library that will union and normalize intervals of integers? eg [[6 10] [1 7] [12 15]] -> [[1 10] [12 15]] ?

10:17 i looked at clojure.core.logic.fd, but i don't see how to union. it has a normalize function but it depends on the intervals being sorted already.

10:18 gfredericks: jweiss: I wrote some code for test.chuck that handles integer intervals

10:18 I don't know about normalizing them, as it might assume everything is always normalized

10:19 looks like it's about unicode codepoints, but could be adapted for integers: https://github.com/gfredericks/test.chuck/blob/master/src/com/gfredericks/test/chuck/regexes/charsets.clj

10:21 I guess the abstraction is about sets of integers, internally represented as ranges

10:27 jweiss: gfredericks: right, the idea is to not have to enumerate a set of 1..1000000

10:28 i think core.logic.fb/normalize is just buggy, or wasn't meant for this purpose

10:28 (fd/normalize-intervals [(fd/interval 8 9) (fd/interval 1 10)]) -> [<interval:8..10>]

10:29 i'm not sure what question it's giving me the answer to :)

10:30 i guess this shouldn't be that hard to write myself, just might not be very efficient

10:32 oddcully: jweiss: there where a SO question about something similar. might be useful: http://stackoverflow.com/questions/32520176/list-processing-in-clojure-tail-recursion-needed/32521995#32521995

10:33 jweiss: oddcully: i'll check that out, thanks

10:37 oddcully: works for me, thanks!

10:37 magopian: oddcully: ok, so if I understand correctly, it's the connection of vim-fireplace with a _cljs_ repl that is having issues

10:45 oddcully: magopian: no, i'd say, that the problem is figwheel centric. the patch for fireplace there tries to eliminate all "piggiebacking" that assume a regular cljs repl

10:46 magopian: oh

10:46 oddcully: magopian: but don't take my word for granted here. i just found a way to make it work, that is good enough for me

10:46 magopian: eh

10:46 oddcully: magopian: i totally dig, why othere have forsaken this route and just bang text over the repl

10:46 magopian: my favorite thing about vim-fireplace is "gf"

10:47 (which worked this morning, and doesn't anymore, maybe I'm doing something wrong)

10:47 and then the "K" to display the doc for the string under the cursor

10:48 maybe "gf" is only available when you have vim-classpath too... but i found it to slow/freeze vim on startup/quitting

10:48 which is unbearable to me

10:56 jmolet: jweiss: hows it going man!? :) you still have access to https://clojars.org/test_clj.testng i had to fork/rename it for an update

11:01 rarebreed: btw, I'm jmolet's partner in crime at RH :)

11:01 jweiss: ^

11:01 jweiss: how's it going rarebreed

11:02 rarebreed: not too bad :) I'm writing some of the tests in clojure as we speak

11:02 or rather, I should say I'm fixing some of them

11:03 jweiss: let's take this to #clojure-redhat rarebreed jmolet

11:09 pyon: Can I have an empty struct (without fields) ?

11:34 noncom: https://twitter.com/OmanReagan/status/659778175216558081/photo/1

11:34 pyon: afaik structs are obsolete. deftype and defrecord are the way to go

11:34 pyon: Ah!

11:36 noncom: pyon: and specially for such occasions there's a ritual pictogram: http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

11:38 pyon: Checking.

11:53 taylan: one with a larger font would have been great

12:30 irctc: Hi everyone.

12:30 I'm trying to use reagent inside my project that I created in compojure, but I keep getting errors when I try loading it.

12:32 Following instructions from: https://github.com/reagent-project/reagent I inserted [reagent "0.5.1"] into my dependencies and I put [reagent.core :as r] in my namespace, however I still get the error. Am I importing reagent the wrong way?

12:37 Does anyone have any experience using reagent?

12:39 oddcully: irctc: you could gist/pastebin/refheap the error you see somewhere. first guess: you require it in a cljs files (no clj file!), right?

12:41 irctc: oddcully, I have never had any experience with cljs. I thought I would just insert a cljs snippet of code directly into my clj file just to test out the simplest functionality that reagent can offer.

12:43 This is the function I wanted to test out.

12:43 http://pastebin.com/UDMduVWD

12:43 I thought it would work just as well in a plain clj file.

12:43 Nothing special about it really.

12:44 So my handler would just point to that function and create a new page based on that.

12:44 I thought that's how I could quickly test reagent functionality.

12:45 oddcully: well maybe i miss the finer points of compojure here, but clj and cljs are two separate things

12:46 if you want to have some cljs/reagent app, you would compile your cljs down to js and send this js over to the client. the client then executes it

12:50 dstockton: i have a few TB of data and growing across many columns and want clients to be able to drill down across as many columns as they like and do sum() and avg() type aggregations in a few seconds

12:50 right tool for the job?

12:50 hadoop, spark, hbase, onyx...

12:51 it takes far too long in postgres on a single server and postgres isn't too easy to scale

12:51 irctc: Thanks oddcully. I'll do that then. I thought I could just do this quickly to test it out. Well back to work it is then. :)

13:07 xemdetia: dstockton, you could check out the (recently) open sourced greenplum? it's postgres based to an extent so existing expertise might be able to carry over?

13:09 dstockton: xemdetia: thanks, definitely will

13:49 justin_smith: with http-kit, the client-loop thread - is that something that you would expect, when profiling, to see constantly open?

13:50 noncom: justin_smith: isn't client-loop always waiting for clients?

13:51 justin_smith: noncom: yeah, looks like it. At first I thought my app was spending way to long on an http-client read. But it's a false alarm.

13:52 now to figure out what the fuck my app was doing....

13:52 (like - it looks like it was sitting there for an hour and then resumed - but it must have been waiting on something....)

13:55 noncom: justin_smith: probably. in usual ip comms, like tcp or udp for multiclient servers there's always one socket waiting for a connection. when it happens, it registers and stores the channel and keeps waiting for more

13:55 acceptor socket it is called if remember correctly i

13:56 justin_smith: is this app open to the outer world? someone connected?

13:57 idk really, have no clue.. not sure even if it was the client-waiting socket...

14:03 justin_smith: noncom: this is a client, not a server

14:04 noncom: hmmm

14:04 justin_smith: noncom: this app reads http, but does not accept connections

14:04 (it basically does some very curated web crawling as part of its work)

14:04 noncom: so, it connected via http and hung for an hour?

14:05 or it simply acted like if it did that?

14:05 justin_smith: noncom: it has a thread that stays open for many hours, which turns out to be an implementation detail of the clj-http client

14:05 noncom: ah, maybe.. yeah..

14:06 justin_smith: noncom: the real problem, is why a single request being handled pauses processing for like an hour - then continues

14:06 like - I'm trying to profile and see what happens to make that hour long pause happen

14:06 noncom: and you see nothing special?

14:06 justin_smith: and the http-client thread (which showed as running) was a false lead

14:06 not yet!

14:07 noncom: could it be a hang on the server side?

14:07 justin_smith: this is the server

14:08 noncom: you just said:

14:08 justin_smith: if I had a connection open to some other server - sure

14:08 noncom: [21:00:41] <justin_smith> noncom: this is a client, not a server

14:08 :D

14:08 justin_smith: haha, in the http context, sure

14:08 but there is no http connection active during this period of time

14:08 noncom: ah

14:09 justin_smith: it's a task processor that does a bunch of http requests, and db reads/writes, then does a bunch of CPU / RAM intensive graph analysis

14:09 and I'm trying to figure out why it just *takes a nap* in the middle of a job, lol

14:09 noncom: yeah, i got the taste of the strangeness, but the details of the wokring of the app seem to be very involved

14:10 OR it is a http-kit implementation detail....

14:11 justin_smith: I have a lot of factors I am checking out - it looks like no thread is actually reading an http socket (first guess was some server slowing us down with a lot of data on a slow connection)

14:11 noncom: so you don't even know in what place of the code exactly it's stopping

14:12 justin_smith: noncom: well, it's not even stopping - just pausing - the job completes

14:12 I want to figure out why it seemingly stops doing work in the middle

14:12 and it doesnt' always do this, it's for a specific query that this happens...

14:12 noncom: probably it does not stop in the middle, but it stopes in a specific place

14:12 justin_smith: usually a job is done in about ~10 minutes

14:12 this one takes more like 5 hours

14:13 the question is why

14:13 noncom: wow, serious things you have there

14:13 justin_smith: it's not a larger job. But now I'm just thinking out loud about the problem, the specific question I had (about http-kit client) is answered

14:14 noncom: so does it receive the data in full and start processing before it pauses?

14:14 is the pause related to data retrieval or data processing?

14:15 justin_smith: noncom: thats the weird part -it's doing neither!

14:15 the CPU is inactive, no thread is doing anything interesting, and no remote connections are feeding us data

14:15 noncom: so it waits even before *starting* to receive the data

14:15 justin_smith: and then later, suddenly we are doing work again

14:16 and this all happens in the middle - we parse a bunch of xml (rss feeds) and then dead time, then we are calculating our graph analysis

14:17 xemdetia: justin_smith, is your process swapping?

14:17 justin_smith: xemdetia: nope, ram usage is stable...

14:17 noncom: so it 1) received full data, 2) stops for long, 3) processing

14:18 xemdetia: sounds like you just need to hook a profiler when it happens :(

14:18 unless you have some sort of job log

14:18 justin_smith: noncom: exactly (though there are complications to this story - it does also get some data later, this is a very parallelized process)

14:18 xemdetia: I am analyzing a profiler dump now, the answer is somewhere in these hundreds of threads

14:18 noncom: justin_smith: looks like it is waiting for disconnect or something

14:19 justin_smith: what if you repeat the quesry with curl?

14:19 justin_smith: noncom: which query?

14:19 noncom: http query...

14:19 justin_smith: which http query?

14:19 we have thousands

14:19 but none of them are running when the dead time happens

14:20 noncom: http://www.http-kit.org/timer.html ?

14:20 ah, i'm just asking you a bunch of info and do some wild guesses...

14:20 justin_smith: we do have some requests with timeouts on them, but they are like 30 second timeouts

14:20 noncom: sure, I appreciate that

14:21 this feels less like coding and more like forensics

14:22 noncom: heh :) it also looks like i am working with javascript

14:23 xemdetia: justin_smith, I like that stuff though but in this case it sounds like a log problem. Do you stream events to some sort of receiver via udp or something?

14:23 or do you generate these pretty graphs via xvfb or something wacky?

14:24 kenrestivo: if i wanted to store a clojure maps (k-v) in a database with the minimum of ceremony (meaning: no ORM, no SQL), what would you recommend?

14:24 noncom: kenrestivo: mongo

14:24 kenrestivo: or datomic

14:24 kenrestivo: one that stores data to a disk

14:24 i love datomic but it's too heavyweight for running on a vps

14:24 noncom: kenrestivo: orient?

14:25 kenrestivo: ooh, cool, never heard of that one, will look into it, thanks.

14:25 noncom: kenrestivo: i'd go with mongo or orient then

14:25 justin_smith: xemdetia: the graphs are not visuals, they are data graphs in memory (as in the mathematical concept of graph)

14:25 xemdetia: the server is connected to other servers via kafka

14:26 kenrestivo: thanks noncom

14:26 xemdetia: justin_smith, sorry that was me projecting my problems with graphs and reports

14:26 justin_smith: :)

14:26 xemdetia: I mean this smells like a shared resource not releasing the lock in a timely fashion,

14:27 justin_smith: right, but the profiler shows when threads are waiting on locks

14:27 and it isn't showing this

14:27 xemdetia: do you have some sort of deadlock prevention mechanism? Something that would just force restart and get the system going again after 5 hours?

14:28 justin_smith: something in onyx could have restarted something....

14:28 hmm

14:28 xemdetia: I mean sometimes many problems in constantly running systems are resolved by the power of init restarts

14:28 (aka something else killing it)

14:29 lnostdal: hi guys, i see this: :dependencies [[org.immutant/core _] mentioned in some project.clj file .. just wonder what's meant by the underscore

14:30 tcrawley: lnostdal: I suspect you are looking at Immutant itself - it uses lein-modules (https://github.com/jcrossley3/lein-modules) to build

14:30 lnostdal: tcrawley, that's right .. i'll check the link out, thanks

14:31 tcrawley: in that particular case, the _ will get replaced by the version specified in the top-level pom for all sub-projects in the org.immutant group

14:31 lnostdal: right

14:33 noncom: justin_smith: anyway, what else can i say..... i usually apply the println-explosion tactics for similar cases... helps locating the spot..

14:33 idk if it is possible in this case...

14:33 WorldsEndless: Stupid question, but why doesn't (#("hi")) return the string "hi"?

14:33 justin_smith: noncom: fair enough - right now I'm narrowing down the best places for printlns

14:34 WorldsEndless: it attempts to call the string hi with no args

14:34 ,'#("hi")

14:34 clojurebot: (fn* [] ("hi"))

14:34 justin_smith: maybe the expansion helps

14:34 noncom: WorldsEndless: sane problem withh happen with #([]) and its variants

14:34 WorldsEndless: Ah; there are a pair of parens I didn't count on

14:35 justin_smith: right, #() would be weird if it did not provide those parens

14:35 lnostdal: looks like immutant.web needs potemkin 0.4.1 to compile on recent clojure 1.8.x versions

14:35 noncom: i often want to return a [], but am forced to write (fn ..)

14:35 justin_smith: ,(#(println "OK")) ; would have to become (#((println "OK"))) otherwise

14:35 clojurebot: OK\n

14:36 tcrawley: lnostdal: thanks for the report, we haven't built with 1.8 lately, I'll take a look. or you could provide a PR if you like

14:38 WorldsEndless: thanks justin_smith and noncom

14:38 lnostdal: tcrawley, it's just https://www.refheap.com/111219 .. seems to compile and run fine on latest clojure 1.8.0 from git after this

14:41 kenrestivo: hmm, orient looks cool, but because it's a java thing, it wants like 8GB of RAM to itself. might as well use datomic in that case.

14:41 i might be the only person trying to run java apps on a vps.

14:41 (a 2GB vps, specifically)

14:42 yenda: how do I include a file in my uberjar ? I had an edn file at the root of my project which was working fine during development in repl, and now that I'm trying to start the uberjar I get a stacktrace no such file or directory

14:42 justin_smith: yenda: a file must be on your classpath / source-paths / resource-paths to end up in an uberjar

14:43 yenda: also, unless you are guaranteed the jar will be extracted, you need to make sure you are using io/resource rather than file oriented ops. If you had been using io/resource, your code would not have worked (since root of the project is not on the classpath)

14:45 tcrawley: lnostdal: here you go: https://github.com/immutant/immutant/commit/b703138bc5b9bd425cb0312f7543cceec1cf0816

14:50 lnostdal: tcrawley, cool, it works here

14:50 tcrawley: lnostdal: good deal. I just added 1.8.0-beta2 to the CI matrix as well

14:51 lnostdal: if you have immutant-specific questions, feel free to join us in #immutant

14:53 noncom: yenda: yeah, there's resource-paths param for the lein project

14:59 yenda: justin_smith: noncom: isn't the resources directory already in the resource-paths param ?

15:04 justin_smith: yenda: yes, but the root of your project directory is not

15:05 yenda: ok I put my file in resources and used (slurp (io/resource filename))

15:05 and it works now

15:05 thanks

15:23 eraserhd: Is the nrepl protocol specified anywhere? All I've found so far is that it uses bencode.

15:24 justin_smith: eraserhd it's described pretty thoroughly in the nrepl project (nrepl is not part of clojure, of course) https://github.com/clojure/tools.nrepl

15:26 eraserhd: justin_smith: Oh. I was looking at the wikis and finding disclaimers about everything being out of date. Got it now.

15:29 mattroman: hey all, New to boot-clj having problems creating a runnable uberjar.

15:30 Exception in thread "main" java.lang.IllegalAccessError: tried to access method clojure.lang.RT.classForNameNonLoading(Ljava/lang/String;)Ljava/lang/Class; fr

15:30 om class ring.util.response$loading__5340__auto____261

15:31 that's the error I get. Anyone have any experience? If so I'll post code. Thanks.

15:58 amalloy: kenrestivo: i run several clojure servers on my linode

15:59 which only has a couple gigs

16:02 xemdetia: amalloy, are you running 2gb ones or one of the 4gb ones

16:03 amalloy: $ cat /proc/meminfo MemTotal: 3063952 kB

16:04 i've had the server for several years and it's gone through a few upgrades, i'm not sure what plan it's closest to now

16:04 xemdetia: I have the same problem :V

16:05 I wish they had some sort of storage solution

16:07 amalloy: kenrestivo: anyway i don't know about the specific program you were thinking of, but java servers can be run in much smaller footprints than the default size the jvm allocates; you just have to be specific about what limits you want to set

16:16 kenrestivo: i guess i'm just not comfortable enough with jvm tuning to know what all the knobs and levers are. i've messed around with Xms and Xms, and on one app i kind of cargo-culted -XX:MaxMetaspaceSize=128m and -XX:-OmitStackTraceInFastThrow in an attempt to keep stuff from crashing

16:18 but honestly i don't have a clue what those mean and it scares me to have to thrash around with those just to keep something running.

16:20 amalloy: the one you want is -Xmx to set the max heap size

16:21 like lazybot runs via: $ java -XX:ReservedCodeCacheSize=6m -Xms10m -Xmx120m -cp `lein classpath` clojure.main -e "(use 'lazybot.run) (-main)"

16:22 kenrestivo: wow, that's small!

16:22 amalloy: which is obviously not ideal; an uberjar would be better than lein

16:22 4clojure and refheap are both smaller than that

16:22 kenrestivo: nice...

16:22 and i guess visualvm to determine what it really needs?

16:22 amalloy: eh

16:23 kenrestivo: what scares me away is i see posts like this: http://blog.sokolenko.me/2014/11/javavm-options-production.html and i don't understand what all those flags mean

16:23 amalloy: run it with 40M, and if it refuses to start up or crashes try with 60. that's what i did

16:23 just ignore all that junk for running a simple server

16:23 justin_smith: visualvm can help find where memory is being wasted

16:23 kenrestivo: amalloy: cool, thanks!

16:24 what does ReservedCodeCacheSize do?

16:25 better question: where are all these flags documented?

16:27 justin_smith: kenrestivo: these are all java 8 command line flags right? oracle documents them pretty extensively

16:28 amalloy: tbh i don't know why reservedcodecachesize is set for lazybot. probably Raynes copied it from somewhere too

16:28 it would be fine without that

16:29 kenrestivo: yeah, it seems that the defaults are like 240mb on java 8... i haven't found official docs yet on all these

16:29 oddcully: kenrestivo: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

16:29 kenrestivo: also glad to see i'm not the only one with jvm tuning flags who doesn't understand what they are or why they're there :)

16:30 oddcully: oh duh, thanks, they're in the freakin man page http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

16:30 * kenrestivo hides face in shame

16:32 {blake}: I'm using seesaw to make a GUI with twelve repeating components and I'm having a hard time figuring out how to cycle things. This is one row: (ss/config! p :items [(make-left-panel) (make-right-panel)])

16:33 justin_smith: {blake}: sounds like you want a sequence of items, each like p, then a doseq where you config! each one to contain a row?

16:34 and that sequence of items would stack top to bottom of course

16:34 {blake}: justin_smith: Yeah, I could do that.

16:34 That'd probably be easier.

16:34 I was trying to figure out how to make :items a vector of 12 left & right panels.

16:34 At least one I could get config! to accept, that is.

16:35 Like: (ss/config! p :items [(make-left-panel) (make-right-panel)(make-left-panel) (make-right-panel)(make-left-panel) (make-right-panel)])

16:35 Doesn't that seem like a job for cycle?

16:35 justin_smith: {blake}: that would line them all up side by side

16:35 but sure, cycle could do that

16:36 {blake}: I'm using mig-layout: make-right-panel returns has a "wrap"

16:36 justin_smith: except cycle is for immutable values, and I think seesaw wants different mutable things in each position

16:37 {blake}: I've tried a number of things without success, and it seems like it should be very simple.

16:37 justin_smith: well, cycle is going to return that same panels over and over

16:37 {blake}: (Which usually means I'm forgetting something basic.)

16:37 justin_smith: and you likely want new ones

16:37 {blake}: justin_smith: Well, that ain't gonna work. Yeah, I need to actually call those functions one after the other.

16:37 I think I started with dotimes.

16:38 justin_smith: ,(interleave (repeatedly rand) (repeatedly rand-int))

16:38 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/rand-int>

16:38 justin_smith: ,(interleave (repeatedly rand) (repeatedly #(rand-int 10)))

16:38 clojurebot: (0.9898270533245493 1 0.05506501946454245 6 0.300150269264995 ...)

16:38 justin_smith: something like that?

16:39 {blake}: maaaybe....I didn't try interleave.

16:39 justin_smith: you would want the (repeatedly n f) version of repeatedly

16:42 {blake}: Yeah, I've hung up my REPL more than once.

16:46 Damn.

16:46 AH! Got it!

16:48 (inc justin_smith)

16:48 Still no lovebot.

17:01 magopian: so, I follow https://github.com/boot-clj/boot#install to install boot on mac osx with brew (so "brew install boot-clj")

17:02 then I do a "boot -h", and it pulls a bunch of jars, and ends with "Please download latest Boot binary: https://github.com/boot-clj/boot#install"

17:02 and now, whatever I do (boot -u, boot -h, boot repl -h), it gives me the very same message

17:02 am I doing something wrong?

17:03 boot -u gives me https://www.refheap.com/111223

17:05 oddcully: magopian: when on a boot 2.0.0 version and using boot -u i got the same error. i had to fetch the recent boot.sh

17:06 magopian: boot.sh?

17:06 oddcully: then renamed to boot

17:08 magopian: so you're saying I should use https://github.com/boot-clj/boot#unix-linux-osx ?

17:09 oddcully: except the /usr/local/bin thing - unless you want to

17:09 well that fixed it for me on linux - ymmv on osx

17:10 magopian: thanks a lot for your answer, i'll try that

17:10 oddcully: but i have all my tools installed in ~/bin (sdkman, lein, boot) since distributions hand you down archaic versions

17:10 magopian: ahhhh, it does seem to work better :)

17:13 nice

17:38 g00s: hello, was reading about clojure on android here https://blog.swiftkey.com/what-makes-clarity-keyboard-tick-clojure/ ... they mention skummet; does clojure 1.8 have anything in the way of android specific optimizations - or will skummet be needed for the forseable future?

17:42 postpunkjustin: g00s: I haven't seen anything in the recent release notes for 1.8 that mention Android

17:42 g00s: postpunkjustin ok thanks !

18:19 irctc: Hi everyone. :)

18:20 Is it possible to use core.async without using clojureScript so I could display some text on my page until the back end process is ready to display its results?

18:21 So in short I would like to use core.async only in Clojure but I don't know how it's done.

18:24 When I try to do this in my views, my application still blocks until the results return from the process.

18:30 amalloy: irctc: have you thought about how this is going to work in terms of networking, http, html, and so on? completely brushing aside what core.async is going to do inside your server. how is your server going to return a response to the client and then later somehow update it?

18:30 irctc: That's what I would like to figure out. I'd like to do everything in Clojure but I have the same question you posed.

18:31 TEttinger: s/in Clojure/in real life/

18:33 irctc: Right now I am annoyed with clojure script tutorials, because I am new to clojure script, and clojure in general. The tutorials fro clojure script are often too specific to a certain combination of tools and I find that I spend way too much time figuring out what each of those tools does and how that affects the application than actually learning how to use clojure scipt. Taht's why I'd like to try doing everything in clojure.

18:33 amalloy: my point is, forget about clojure. pretend your server is operated by an omnipotent genie, who can produce any HTTP responses you want. what do you wish it could return? is there any HTTP response you could provide that would cause the user's client to behave the way you want? if no, you can give up on the project completely; if so, then you can start thinking about how to actually implement that genie

18:35 irctc: Well for a newbie like me it would probably be even harder to implement that genie.

18:35 TEttinger: I'm leaning toward the "this isn't a disney movie" approach

18:35 irctc: ?

18:36 Right, the no genie approach. Sorry it's a little late where I am. :)

18:36 TEttinger: heh

18:37 I mean, there's some approaches on the client side

18:37 you could stick the whole page in an iframe, make the iframe part request at some interval

18:38 irctc: Ok, about clojure script... Some have suggested I use reagent, but I don't know how to set it up. I guess I keep missing some steps or I don't quite get the concept...

18:39 I'm not a big fan of iframes. I'd like to use reagent if only I could figure out the idea behind it.

18:39 Basically right now I have a compojure application which works just fine. It does what it's supposed to do, but when a user uses the search box it blocks the user for about 6-7 seconds and I'd like to avoid that.

18:40 First I looked into core.async, but then I thought how am I going to implement this only in clojure, so naturally clojureScript came as an approach and Reagent (which is supposed to help set everything up).

18:41 Then I imported reagent dependencies through project.clj, but after that it all falls apart.

18:42 What is the next step after I put reagent in my project.clj :dependencies?

18:42 TEttinger: when you build with lein it should download the deps

18:42 irctc: Do I create a special cljs folder in which I create a cljs file and I import reagent in its namespace?

18:43 It downloads the deps in my Eclips/counterclockwise editor/plugin.

18:43 So that's all good. I would guess.

18:45 I tried to put reagent in my clojure files namespace thinking I would create a small cljs function within them, but that didn't work. So do these cljs files need to be separate and do they need to then import reagent in their namespaces?

18:56 manualcrank:

19:01 didibus: Anyone can explain to me the convention of fn*

19:01 I see some functions like let* and list*

19:01 what's up with the * character at the end of them

19:05 irctc: https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0CCMQFjABahUKEwjIkrzkpuvIAhXl_nIKHWNuA8o&url=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F5082850%2Fwhats-the-convention-for-using-an-asterisk-at-the-end-of-a-function-name-in-clo&usg=AFQjCNHoOQCS4i_DjBX7OsAWBHgcQODTPA&bvm=bv.106379543,d.bGQ

19:05 didibus that's what I found for the asterisk

19:06 justin_smith: btw that top 0 point answer is wrong

19:06 all of those answers are pretty shitty

19:06 amalloy: justin_smith: imo fix your stackoverflow sorting so that 0-point answer doesn't show first

19:07 irctc: For me it shows as the last one.

19:07 justin_smith: didibus: the versions with * at the end are implementation details, and arguably should have been private

19:07 amalloy: yeah, with no custom settings that one's last

19:07 justin_smith: amalloy: interesting

19:08 irctc: Btw, how do I compile my cljs files when I use reagent?

19:08 justin_smith: irctc: with cljsbuild, like you would otherwise

19:08 irctc: And how do I set up a path where they'll be compiled?

19:08 amalloy: interestingly i upvoted that 0-point answer for some reason, 4 1/2 years ago

19:08 justin_smith: via the cljsbuild options in project.clj

19:08 irctc: Oh, ok, so reagent doesn't do anything special there.

19:08 amalloy: it really is awful

19:09 justin_smith: amalloy: even the comment correcting him is wrong

19:09 amalloy: yeah

19:09 justin_smith: the wrong is everywhere

19:10 technomancy's answer is closest to being helpful

19:10 irctc: And where do you usually put your cljs files? In resources folder?

19:11 Fregion: This is probably more helpful http://stackoverflow.com/questions/31661187/difference-between-let-and-let-in-clojure?lq=1

19:11 justin_smith: irctc: in my sources, and then I compile the js to output to resources

19:12 irctc: O, ok. Thanks. :)

19:12 didibus: Uh, ok I see.

19:14 irctc: I'm off to bed. Thanks fo your help everyone.

19:14 Take care and have a good weekend. :)

19:16 justin_smith: Fregion: yes, that one is much better, and the other one should be deleted and just redirect to that one

19:23 didibus: justin_smith: If a macro is important for ease-of-use, expose the function version as well. Open question: should there be a naming convention here? A lot of places use "foo" and "foo*"

19:23 I think this explains why they were not made private

19:24 justin_smith: but let* and fn* are not functions, they are special forms

19:24 which are effectively macros, minus some implementation details

19:24 definitely not functions

19:25 didibus: Ya, it's slightly stretching the defenition, but I believe it's the same idea. Some other macro might want to use them, so they were exposed

19:56 pyon: How do I make a definition (function, macro, whatever) local to a file?

19:57 justin_smith: pyon: this is what the :private metadata is intended for (see also defn- which is like defn but it adds the :private metadata to the var), but it's a convention and quite easy to circumvent if that matters

19:57 (doc defn-)

19:57 clojurebot: "([name & decls]); same as defn, yielding non-public def"

19:57 pyon: Oh.

20:08 What's the proper way to format docstrings spanning multiple lines?

20:08 Never mind, already found it, thanks.

20:13 sdegutis: ,(def at-least max)

20:13 ,(-> 4 (- 2) (at-least 3))

20:13 clojurebot: #'sandbox/at-least

20:13 #error {\n :cause "Unable to resolve symbol: at-least in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: at-least in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: at-leas...

20:14 sdegutis: um

20:14 ,(-> 4 (- 2) (at-least 3))

20:14 clojurebot: #error {\n :cause "Unable to resolve symbol: at-least in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: at-least in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: at-leas...

20:14 sdegutis: YOU JUST DEFINED IT

20:14 * sdegutis scratches head?

20:15 justin_smith: sdegutis: the "every 15 minute reset" isn't a reset 15 minutes after your def, it's a whole new sandbox every 15 minutes

20:15 sdegutis: ,(def at-least max)

20:15 clojurebot: #'sandbox/at-least

20:15 sdegutis: ,(-> 4 (- 2) (at-least 3))

20:15 clojurebot: 3

20:15 sdegutis: Oh.

20:15 So I literally put those right between the cut-off.

20:16 The first time.

20:16 Right?

20:16 justin_smith: yup

20:16 sdegutis: Cool.

20:16 Anyway at-least is a fun name for max.

20:16 (def at-most min)

20:16 ,(def at-most min)

20:16 clojurebot: #'sandbox/at-most

20:16 sdegutis: That too.

20:16 (-> 5 (at-most 3))

20:16 ,(-> 5 (at-most 3))

20:16 clojurebot: 3

20:16 sdegutis: ,(-> 2 (at-most 3))

20:16 clojurebot: 2

20:16 sdegutis: I like it.

20:17 justin_smith: ,(at-most 4 3 42 -10 2)

20:17 clojurebot: -10

20:20 pyon: How do I undefined something I previously defined in the REPL?

20:47 sdegutis: justin_smith: it only works when using -> with numbers

20:47 which turns out to be very useful for basic arithmetic

21:15 htmldrum: Happy Halloween, spooky clojure peeps.

21:23 michaels: To you as well, htmldrum!

22:02 pyon: How could I make a macro like `defrecord`, but where fields are indexed by numbers (0,1,2...) rather than by names?

22:03 One way I thought I could do it is to just use a sequence, whose first element is the “type”, and whose remainder are the fields' values. But it would be too easy for users to inspect this representation.

22:14 justin_smith: pyon: there's an argument to be made that information hiding becomes much less useful when your datatypes are immutable

22:16 pyon: remember that in clojure you can only have methods via an existing protocol or interface. Instead of hiding the implementation of methods, document that your protocol should be used and not the concrete type, then implement the protocol using whatever details you like in a defrecord or deftype

23:21 TEttinger: (doc undefine)

23:21 clojurebot: It's greek to me.

23:21 TEttinger: (doc undef)

23:21 clojurebot: Titim gan éirí ort.

23:21 TEttinger: huh

23:22 I thought there might be one

23:22 justin_smith: TEttinger: do you want ns-unpmap?

23:23 TEttinger: unmap ?

23:23 I guess

23:23 it was to answer pyon

23:23 pyon: TEttinger: Ah, thanks!

23:23 TEttinger: thanks justin_smith!

23:24 pyon: None of (undef foo), (undefine foo) or (unmap foo) works in the REPL, thoguh.

23:24 though*

23:24 TEttinger: ns-unmap

23:25 justin_smith: err, unmap

23:27 heh, my internet is super slow right now

23:31 ,(def foo 2)

23:31 clojurebot: #'sandbox/foo

23:31 justin_smith: ,foo

23:31 clojurebot: 2

23:31 justin_smith: ,(ns-unmap *ns* 'foo)

23:31 clojurebot: nil

23:31 justin_smith: ,foo

23:31 clojurebot: #error {\n :cause "Unable to resolve symbol: foo in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: foo in this conte...

23:38 pyon: Can normal `def`s have docstrings the same way `defn`s and `defmacro`s do?

23:38 justin_smith: absolutely

23:38 ,(def foo "this is a foo" 2)

23:38 clojurebot: #'sandbox/foo

23:38 justin_smith: ,(doc foo)

23:38 clojurebot: "; this is a foo"

23:39 pyon: Sweet! :-)

Logging service provided by n01se.net