#clojure log - Nov 03 2014

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

0:01 andyf: Twylo: Also, wouldn't you want two separate arguments to your map-once besides the sequence? One for the predicate function, and a separate function to calculate what to replace the matching item with?

0:02 Twylo: andyf: Great idea about looking at 'map'. And yeah, I think for general use I'd want two arguments, predicate and replacement function

0:03 andyf: Twylo: I just looked at clojure.core/map source, and there is an extra complicating factor in its implementation involving chunked sequences that you probably want to ignore. It is a performance optimization, not something for correct behavior.

0:04 kenrestivo: does compojure do something weird when defining routes? like... execute at compile time instead of runtime? because... this https://www.refheap.com/92630

0:05 andyf: Twylo: Ignore the 'then' part of the (if (chunked-seq? s) ...) expression. Remove that if, replacing it with its "else" part, which is simpler and works correctly in all cases.

0:06 kenrestivo: Someone else can probably give a more authoritative answer, but aren't compojure route definitions implemented as Clojure macros, not Clojure functions?

0:07 kenrestivo: they are

0:07 i'm macroexpand-1'ing right now tryign to figure out wtf

0:08 Twylo: andyf: Looking at it now. It's nice and simple.

0:08 kenrestivo: it's funny, just a few days ago someone was in here asking why not use macros. i'd say, this is why not.

0:10 andyf: kenrestivo: I don't know enough to give suggestions on what to change here, but in general it is good in Clojure to use functions when a function will do.

0:10 kenrestivo: yep. thanks. i've been around this block before with compojure and some other web things. it's just frustrating; i'll figure it out.

0:11 nestastubbs: the issue is not wether is it a macro or a function, in the case of compojure

0:12 Twylo: Huh, acutally I just noticed that "map" is defined recursively, but not using (recur). It just calls itself directly, no tail call optimization. Interesting.

0:13 nestastubbs: it's that the servers handler fn won't get updates

0:14 it would not matter if it was a macro or a function that defind the routes...

0:15 kenrestivo: i don't mind, this is something that needs to be fixed at start-time, meaning, at handler-define time

0:15 but not at compile time.

0:16 nestastubbs: if you restart the request handler...

0:16 sorry I can't be mroe specific, just nuked workstation with new OS install, and don't have any of my projects handy with code

0:17 kenrestivo: no prob, i appreciate the perspective. seems you have a bit more familiarity with the internals of compojure than i have

0:18 i'm looking at the macroexpand-1 and can't see any reason why this would not work, it looks fine. hmm.

0:19 i have seem some syntax-quote trickery in for example lein, which i should study up on, might fix this

0:19 nestastubbs: no it won't

0:19 how do you start your request handler?

0:20 your ring server...

0:21 kenrestivo: components start

0:22 Twylo: andyf: Pefect, I have a working function now. Thanks for your help

0:23 andyf: Twylo: np

0:24 Twylo: The lazy-seq in map makes the implementation lazy. Only as much of the answer will be computed as is 'demanded' by later code that tries to examine the result.

0:25 Twylo: I admit, that's sort of black magic to me. I'd like to understand lazy-seq better

0:26 kenrestivo: the baddness seems to be coming from the let-request macro, still tracing...

0:32 nestastubbs: kenrestivo: how is app-routes being called?

0:33 kenrestivo: nestastubbs: https://www.refheap.com/92632

0:34 the end game here is to have different html for :dev and :release :-/

0:36 nestastubbs: kenrestivo: so it's the mode check?

0:36 kenrestivo: there are 3 substitutions, yeah mode is the main one

0:37 i was thinking of blowing off stencil completely and just doing this all in hiccup

0:37 but i don't think stencil is the problem. it's some conceptual barrier i have with the way compojure operates

0:37 nestastubbs: I would expect that code to work 8)

0:38 what if you do (:playing-url settings)

0:38 instead of using the keyword binding

0:39 kenrestivo: are you calling make-handler every time you make an edit?

0:39 kenrestivo: ooh, interesting. will try.

0:39 nope, make-handler is called only at start/stop time (in components)

0:39 nestastubbs: ok, so what does make-handler return?

0:39 I'm being pedantic ... that is your problem

0:40 the handler that is serving up the web requests has an old value of app-routes

0:41 make-handler returns a function that wrapped the value that app-routes returned at the time it was called

0:41 not a fn that calls app-routes each time

0:42 kenrestivo: hmm

0:43 i actually do want to close over that stuff.

0:43 nestastubbs: this happens in our app dev all the time

0:43 kenrestivo: what's frustrating is that it isn't an old value. it's an EMPTY value. there's nothin in it

0:43 nestastubbs: when we want to add a new route

0:44 kenrestivo: mode, playing-url, chat-url, those are all nil at whatever time let-request is called

0:44 which is confusing me because everythign i thought about clojure's lexical scope is violated by this

0:44 nestastubbs: have you restarted your entire world yet?

0:44 kenrestivo: many times :-/

0:44 like, whole jvm restarts

0:45 nestastubbs: ok, if you have done that since you wrote the version of app-routes in the paste, then my theory is toast 8)

0:45 kenrestivo: the value of mode, at the time render-file is called, is nil.

0:45 whereas, at the time app-routes is called, mode has a value, and i can prove it with log output

0:46 so, macro magick

0:46 nestastubbs: nothign to do with macros

0:47 you are printing the value of settings

0:47 try accessing it (:mode settings)

0:47 kenrestivo: did that. didn't help.

0:48 was a good idea tho.

0:48 nestastubbs: ok, so it's not the destructuring

0:53 do you have reloading on?

0:53 if so, make sure you are saved out to disk

0:53 try changing the wording of the log message to confirm it's getting your latest edit

0:53 those are all the ways I have been hosed in the past 8)

0:56 ok, I'm out of ideas without checking out the whole project and trying, and I'm falling asleep 8)

0:56 good luck site!

0:56 sir!

0:56 see, I told you I was falling asleep

1:06 kenrestivo: nestastubbs: thanks, i think i got it sorted

1:07 it's working. i will have to look through my git thrash history to find out exactly WHY and HOW

1:08 i've gotten in the habit in recent months of generating tons of git branches with names like dead-end1, dead-end2, dead-end3, stash them go back to master, try something else, git checkout -b dead-end4, commit, back to master..

2:22 mindbender1: What's the fundamental difference between a library like d3.js and react.js?

2:26 borkdude: mindbender1 d3 works directly on the real DOM

2:26 mindbender1 and if focussed on data viz.

2:26 mindbender1 ReactJS is a general library that utilizes a virtual DOM

2:32 mindbender1: borkdude: ok

2:33 How does using them both sound?

2:35 When I read some part of d3 docs I tend to see functionalities that are typical of a full js framework

2:35 making me think of `or` rather than `and`

2:39 borkdude: mindbender1 some people use them both

3:20 dc_: would it be faster to use filter or to use reduce and build up objects with transients/persistents?

3:22 kind of a generic question and it probably depends on the circumstances, i know

3:24 cy: dc_: why not benchmark it?

3:25 dc_: alright, i'll try both and see

3:49 SagiCZ1: can i spread my namespaces into more folders without reflecting it in the ns name? or is it like in java where packages have to correspond with file path?

3:52 schmir: SagiCZ1: I think you could use clojure.core/load from within the namespace.

3:53 SagiCZ1: https://github.com/ztellman/potemkin#import-vars may be a better solution

3:53 SagiCZ1: haven't used any of those...so don't blame me.

3:59 SagiCZ1: schmir: no i want it to work out of the box, if it isnt possible i can stick to the regular structure

4:26 mbac: so does anyone do 3d graphics games in clojure?

4:26 i wrote something in quil to do 2d graphics and it was surprisingly slow

4:27 i had a draw function doing a bar graph in realtime over 800 points and the framerate dropped to about <10fps

4:41 ssideris: mbac: you could try opengl with penumbra (although it's no longer maintained as a library): https://github.com/ztellman/penumbra

4:46 Glenjamin: there's that new ClojureCLR unity thing

4:46 https://github.com/arcadia-unity/Arcadia

4:51 mnngfltg: I have a question about the typical workflow with core.async (on the server). As I understand it, using blocking calls should be avoided. However, SQL calls (jdbc) are always blocking. How can I make SQL queries from core.async-based code?

4:54 ddellacosta_: mnngfltg: where in the core.async workflow are you talking about?

4:55 mnngfltg: ddellacosta_, so I use http-kit's server to accept tcp connections

4:55 if I run an sql query using jdbc, that blocks the thread that is making the request

4:57 but isn't the whole point of running in an event loop (like with http-kit) that you eliminate all synchronous calls?

4:57 ddellacosta_: mnngfltg: I don't know why you are using core.async, or what the problem is with blocking. What is the problem you are trying to solve?

4:58 mnngfltg: and http-kit supports both modes

4:59 mnngfltg: ddellacosta_, I guess I'm not clear about the way you would typically implement a web service that does both http calls and sql queries

4:59 using node.js I suppose you would never do a blocking call, anywhere

5:00 I know that http-kit does both synchronous and async, but jdbc is synchronous only

5:02 so wouldn't it be useful to fire off (clojure.java.jdbc/query "....") in a non-blocking way? So your flow is resumed once the SQL query finishes.

5:05 ddellacosta_: mnngfltg: if you need to initialize a job that does something and immediately return to execution without waiting for the result, Clojure has many mechanisms to support that. I think it's confusing matters a bit to talk about http-kit in the context of how blocking and SQL queries work

5:06 mnngfltg: sorry, I'm a bit fuzzy on what you're trying to do--if you have a specific use-case I may be able to offer more help. As it is, I'm not sure exactly what the problem is that you're trying to solve.

5:08 mnngfltg: and as far as how you'd implement a web service, I don't see why synchronous execution is a problem

5:08 mbac: ssideris, thanks

5:14 dc_: cy: filter building vectors, nested under a reduce seems much much faster than using a reduce nested in a reduce.

5:15 i'm getting hamming-distance for lots and lots of data

5:17 like 2 orders of magnitude faster. wow

5:17 also, i set the hamming-distance to use recur and to terminate early if it passed the threshold of the distance i'm filtering on

5:29 mnngfltg: ddellacosta_, point taken, I'm a bit confused about the whole business :)

5:31 ddellacosta_: mnngfltg: re-reading your questions, it sounds a bit like you're conflating the synchronous/asynchronous modes of http-kit w/the threading model provided by the JVM. But consider that you can have a synchronous HTTP request trigger a job that asynchronously executes a SQL query, for example, the result of which you can check again using another synchronous HTTP request

5:32 (not that this is necessarily a good idea, but depends on your architecture I suppose)

5:34 mnngfltg: I suppose the bottom line is, Clojure gives you the tools to build a lot of different architectures, you aren't constrained to some thing like the "everything is a big event loop" or whatever it is that node provides (sorry, I know nothing about node really)

5:39 mnngfltg: yeah, I don't know much about node.js either

5:40 right now my code is perfectly synchronous, which is perfectly fine by me. However, I'm trying to add a feature that talks to other web services, and I expect that these calls block for 1000ms or more.

5:41 So I thought it would be a good idea to use clore.async's channels as a means to fire "background jobs"

5:42 ddellacosta_: mnngfltg: are you talking about the web server firing off jobs, or the web client?

5:42 mnngfltg: that is, where is the "talking to other web services" thing happening?

5:42 mnngfltg: a web server accepts HTTP requests, but then fires off a notification to another http host, in the background

5:43 it's all in the JVM, if that's what you're talking about

5:43 cbryan: is the response dependent on the notification?

5:43 ddellacosta_: mnngfltg: and then does something have to handle the response to that notification?

5:43 jinx

5:44 cbryan: haha

5:44 ddellacosta_: :-)

5:44 mnngfltg: no it's not, I can return the response without waiting for the result of the notification

5:44 cbryan: well then "fire and forget", yeah? :)

5:44 ddellacosta_: mnngfltg: so, what do you do with the result of that notification?

5:44 mnngfltg: cbryan, yes, except that I need to re-try a notification if it fails

5:45 so I can't just do (future (http-client/get "..."))

5:45 and I also need to write the result of the notification to a database

5:45 cbryan: (http-client/get) accepts a callback

5:46 http://http-kit.org/client.html#async

5:46 ddellacosta_: this seems like it happens entirely the HTTP request cycle though

5:46 mnngfltg: cbryan, but if I do that, does it create a new thread?

5:46 ddellacosta_: this doesn't have anything to do with the client, no?

5:46 oh, sorry, I misread that--sorry cbryan

5:47 yeah, mnngfltg, seems like what cbryan is proposing is perfect, no?

5:47 cbryan: mnngfltg: so you want to avoid creating a new thread, or? i might be misunderstanding your actual question!

5:48 mnngfltg: cbryan, yes that's what I mean, though maybe that not a sensible concern, Isn't it inefficient to fire off a new thread constantly like that?

5:49 hmm looking at https://github.com/http-kit/http-kit/blob/master/src/org/httpkit/client.clj it looks like it's using a worker pool

5:50 cbryan: mnngfltg: sounds like a case of premature optimization, honestly. try it and profile? :)

5:50 mnngfltg: a worker pool would be perfect actually :)

5:51 So actually I don't need core.async at all?

5:52 ddellacosta_: mnngfltg: well, the worker pool is just threads anyways, right? No, not sure you need core.async here, unless you have some higher level abstraction you want to implement using it

5:52 cbryan: http-kit is handling that for you, yeah

5:53 mnngfltg: ddellacosta_, it's threads, but it's a limited pool of threads, so I don't risk running out of threads if a lot of requests block for a long time

5:53 ddellacosta_: mnngfltg: ah.

5:54 mnngfltg: I'm just going to go with http-kit and see if it's enough

5:54 one more thing, I need to wait between notification requests (say 10 seconds, 30 seconds, 60 seconds)

5:55 Thread/sleep seems like it might end up blocking everything again

5:55 is there some way to block "asynchronously" for lack of a better term?

5:56 cbryan: http://http-kit.org/timer.html

5:56 ddellacosta_: yeah, schedule-task looks perfect, huh?

5:57 mnngfltg: right!

5:57 it is perfect :)

5:58 thanks !!

5:59 schedule-task uses a "Timer-service thread", so that's how that works

6:05 borkdude: is enlive pronounced as en-liv or en-lie-v

6:06 as in "I live" or "live performance"

6:31 kungi: borkdude: as far as I remember the talk about enlive it's pronounces as in "live performance"

6:39 borkdude: k

7:13 ucb: good day all

7:13 I'm trying to write a macro that'll take the body of the expression and use it as the key in a hashmap

7:13 however I'm not getting it quite right

7:13 clgv: ucb: example?

7:14 ucb: yes, creating it :)

7:14 1s

7:14 clgv: best with call example and desired expansion

7:16 ucb: here https://gist.github.com/ulises/b34d5bae94e8cf8006e9

7:18 clgv: ucb: ok, what exactly does not work? the fullqualified "do-more*" ?

7:19 ucb: the (quote ~f) actually gets evaluated

7:19 clgv: huh? not really

7:19 ucb: so instead of getting '(fn [] :foo) as a key, I get user$eval3687$fn__3692 as key

7:20 clgv: ,(defmacro thing [f] `(hash-map (quote ~f) ~f))

7:20 clojurebot: #'sandbox/thing

7:20 clgv: ,(thing (fn [] :foo))

7:20 clojurebot: {(fn [] :foo) #<sandbox$eval52$fn__53 sandbox$eval52$fn__53@1716c3d>}

7:20 clgv: looks about right

7:20 ucb: hrm

7:20 clgv: maybe do-more* confuses the parameters?

7:21 ucb: well, let me paste the do-more* equiv I'm working with

7:22 here https://gist.github.com/975b1843c13888a95ff7

7:23 oh, silly silly boy

7:23 clgv: ucb: why don't you use the same "quote" form there?

7:23 ucb: where?

7:23 clojurebot: where is log

7:24 clgv: in "rich-stream" first arg

7:24 ucb: how do you mean?

7:24 heh, it works now

7:24 clgv: it is constructing a list with 'quote as first arg and the evaluated function as second arg. line 15

7:24 ucb: it wasn't the macro that was the problem :)

7:24 yeah, list there is wrong

7:24 that's an old paste

7:24 clgv: ucb: did you change it to (quote ~f) as well?

7:25 ucb: yes

7:25 clgv: ok

7:25 ucb: the bug is here https://gist.github.com/ulises/975b1843c13888a95ff7#file-streams-clj-L10

7:25 assoc f

7:25 should be assoc name

7:25 clgv: haha ok ;)

7:25 ucb: thanks for prodding me!

8:21 nondisclosure: I'm trying to use a let with selenium to grab a value from the page i'm currently on, then proceed to the next page, then return that value. the let isn't storing that value until my function tries to return it. what's the best way to deal with this problem? i've tried using eval and doall to no avail.

8:22 justin_smith: nondisclosure: what does "the let isn't storing that value" mean?

8:23 nondisclosure: the let is pointing to a selenium function, so i'm under the impression it's storing that function unevaluated and then evaluating when i return that value

8:24 justin_smith: nondisclosure: let is greedy

8:24 or I should say, it is sequential, and is not itself lazy

8:24 is the function you are calling lazy?

8:25 nondisclosure: i'm actually not sure, so you're saying if i do (let [a (+ 1 1)]) let is storing a 2 rather than a (+ 1 1)?

8:25 justin_smith: right

8:26 nondisclosure: ahh i see

8:26 thanks, that points me in a good direction, i'll try to figure out what that function is doing

8:48 CookedGryphon: Does anyone know of a handy core.async/chan -> InputStream converter

8:49 I want to stream data to a javascript EventSource in a wrapped WebView through the WebRequestResponse api, in which I can give it an InputStream

8:49 I set it up with a PipedInputStream. PipedOutputStream, but that doesn't seem to do anything on the receiving end until the buffer fills up

8:49 and apparently has a number of other pitfalls

8:51 I'm trying to wrap the InputStream interface directly, but it doesn't quite fit with the core.async model, as it has an available() method which should return the number of bytes available, and then a separate read(byte buffer[], off, len)

8:51 so I can't just have read doing <!! available-data

8:55 jeffterrell: [news] Clojure is currently the highest-paid programming language, according to this analysis: http://bit.ly/13zeP2x . Relatively low demand, though.

8:55 justin_smith: CookedGryphon: yeah, it seems like you need an abstraction between the channel and the InputStream proxy

8:55 craigglennie: I get a ClassCastException trying to use one of my namespaces in nREPL. Subsequent attempts to use the namespace generate a “namespace […] not found” exception, and I have to restart nREPL to try again - is this normal? https://www.refheap.com/92645

8:55 Also using Cursive, if it matters

8:56 justin_smith: craigglennie: after a require throws an exception, you need to specify :reload for the require to rettry

8:56 *retry

8:56 as far as clojure is concerned, it already required it once, so it is done :)

8:56 (require 'my.ns :reload)

8:58 assumedly you fixed the "string isn't a regex" issue so the ns would actually load this time, of course

8:59 craigglennie: justin_smith: thanks, that worked!

9:15 clgv: I want to get a short string representation of a byte array similar to a hexadecimal representation but with more characters to reduce the length. is there something Java built-in I can use? some option to a formatter or similar?

9:18 justin_smith: clgv: what about base64?

9:18 the encoding returns a byte-array, but it is easy to apply String. to that

9:19 clgv: justin_smith: hmm would work I guess

9:19 justin_smith: did you have a clojure lib in mind for that?

9:21 justin_smith: ,(require '[clojure.data.codec.base64 :as b64])

9:21 clojurebot: #<FileNotFoundException java.io.FileNotFoundException: Could not locate clojure/data/codec/base64__init.class or clojure/data/codec/base64.clj on classpath: >

9:21 justin_smith: (b64/encode (.getBytes "hello"))

9:21 clgv: ok the contrib one ^^

9:21 justin_smith: that would work, if the previous did :)

9:21 well, really you want (String. (b64/encode (.getBytes "hello")))

9:22 in my repl that returns "aGVsbG8="

9:22 (.getBytes "hello") is just a placeholder for a byte array, of course

9:23 hyPiRion: urgh

9:23 clgv: damn two additional deps for debugging this strange error scenario...

9:25 justin_smith: you don't need the dep

9:25 ,(String. (.encode (java.util.Base64/getEncoder) (.getBytes "hello")))

9:25 clojurebot: #<CompilerException java.lang.ClassNotFoundException: java.util.Base64, compiling:(NO_SOURCE_PATH:0:0)>

9:25 justin_smith: wat

9:26 oh, that is new with java 8

9:26 so it works in my repl :)

9:26 clgv: yeah well, I have the dep now ;)

9:27 justin_smith: I was hoping there was a simple way to not need the dep

9:27 sveri: Hi, when creating a new project with leining, is there a way to add a generic namespace for all generated classes?

9:32 jzinedine: hey guys, I'm trying to build a simple pedestal service using stencil but got a weird exception, java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Associative

9:32 here is the complete stacktrace: https://gist.github.com/jzinedine/acc68a83e6164aa77b98

9:32 appreciate any help

9:34 clgv: justin_smith: yeah no problem I just added it

9:34 justin_smith: that exception means that someone is trying to treat a string as an associative datastructure (likely ussing assoc or get)

9:35 yeah, assoc-in is finding a string instead of a vector or map at some level

9:36 it looks like it is happening in the header creation

9:36 jzinedine: yeah, I'm trying to understand what's happening in ~/.m2/repository/io/pedestal/pedestal.service/0.3.1/pedestal.service-0.3.1.jar!/io/pedestal/http/secure_headers.clj

9:37 justin_smith: jzinedine: one guess - it is being handed a string rather than a response map?

9:37 jzinedine: (fn [{response :response :as context}]

9:37 (assoc-in context [:response :headers] (merge sec-headers (:headers response)))

9:38 justin_smith: so what is context? is it a string?

9:38 or perhaps headers is a string

9:38 jzinedine: it's a map actually

9:38 but response is string

9:39 justin_smith: there you go

9:39 response should likely be a map, with :body containing said string

9:39 jzinedine: clojure.trace is helpful for this kind of stuff in my experience

9:39 jzinedine: yeah maybe it should be a ring response map

9:40 thanks a bunch buddy for your help

9:40 justin_smith: jzinedine: yeah, tools like compojure will automatically turn a string into a response map I think, maybe pedastal is more finicky

9:40 jzinedine: I'm a clojure newbie and just trying to develop my first app using clojure

9:40 justin_smith: cool

9:41 daniel___: pedestal is pretty hard to get your head around, there aren't really many parallels with conventional frameworks in other languages

9:41 at least thats how it seemed to me

9:41 i don't know if it's worth it

9:41 justin_smith: I'll just reiterate tools.trace is great for finding out what is actually going on

9:44 jzinedine: daniel___ I think most of what it does remind me of spring aspects, here we have interceptors, a familiar idea, but I'm not good at language nor tools to debug and browse apis

9:45 daniel___: jzinedine: that might be the case, im really unfamiliar with Java frameworks

9:46 jzinedine: however I think when I get my head around it I can be very productive , yet everything is simple to understand

9:51 lazylambda: folks, I am currently using cider on emacs to work with clojure. Are there alternatives that provide better code formatting?

9:52 ARM9: what about clojure mode

9:53 mwfogleman: lazylambda: https://github.com/sanel/monroe/ is a new cider alternative. i haven't tried it, so i'm not sure about it's code formatting.

9:53 justin_smith: ARM9: cider uses clojure mode

9:54 mwfogleman: actually,

9:54 yeah

9:54 it uses clojure mode too :D

9:54 not sure about any clojure mode alternatives.

9:54 llasram: lazylambda: What do you mean by "better"?

9:55 lazylambda: llasram: well, I am happy with clojure-mode. I just like how slime indents code better

9:55 llasram: for example cond forms

9:55 justin_smith: mwfogleman: monroe does not replace clojure mode in any way

9:55 mwfogleman: yeah

9:56 lazylambda: sounds like it might be doing a compare and contrast between clojure mode and slime.

9:56 llasram: lazylambda: You may just be seeing differing standard formatting for CL vs Clojure?

9:56 mwfogleman: ah, that may be true.

9:58 schmir: lazylambda: https://github.com/schmir/.emacs.d/blob/master/lisp/setup-clojure.el#L17 may be relevant

9:58 lazylambda: schmir: that looks good. Thank you

9:59 mwfogleman: schmir: what exactly does your snippet do?

9:59 lazylambda: In general, is there a standardised way of formatting clojure code?.

10:00 mwfogleman: lazylambda: https://github.com/bbatsov/clojure-style-guide may be helpful

10:00 schmir: mwfogleman: it fixes cond formatting for me :)

10:00 mwfogleman: schmir: :) i tried evaling your code and looking at a before and after with a cond that i have locally, but i couldn't tell a difference.

10:01 schmir: I'm not sure if it's still needed...

10:01 mwfogleman: schmir: that's possible. it's also possible that I am blind, or that the eval needs to happen at boot or something.

10:03 schmir: mwfogleman: if I comment it out, cond formatting is broken for me

10:03 mwfogleman: schmir: interesting. maybe i'm blind then.

10:04 schmir: :)

10:04 mwfogleman: schmir: on the other hand, i really like your advice to cider-load-current-buffer.

10:04 schmir: that looks really handy.

10:04 lazylambda: my problem with the cond formatting is that if the action code is too long and I decide to put it on a separate line, it is placed right under and aligned with the action which makes it harder to read sometimes

10:04 mwfogleman: lazylambda: interesting. i'll try that out.

10:05 schmir: lazylambda: then try my code. it fixes that issue!

10:05 mwfogleman: lazylambda: with schmir's code ;) with the cond i was checking out, everything was on one line.

10:05 lazylambda: schmir: sweet, i'll give it a shot

10:08 mwfogleman: schmir: wow, that defadvice is great :D

10:22 jzinedine: sorry for bothering again, but anyone knows about a way to reload/auto-reload resource files (css/js/html) in repl?

10:24 mwfogleman: jzinedine: https://github.com/bhauman/lein-figwheel ?

10:24 not sure.

10:27 jzinedine: mwfogleman: thanks I'll check it out

10:28 seems to be a clojurescript plugin, don't know if I can use it in a clojure project

10:28 mwfogleman: jzinedine: i don't do anything with browser stuff right now, so that might not be what you're looking for.

10:28 jzinedine: right.

10:28 jzinedine: mwfogleman: yeah thanks anyway

10:29 I think I should look for a way to disable stencil caching in dev mode

10:32 yeah, I just need to eval this line in repl: (stencil.loader/set-cache (clojure.core.cache/ttl-cache-factory {} :ttl 0))

10:44 csd_: Does it make sense to incorporate macros into compojure views to factor out the (let [binding param]) stuff? I have a ton of it cluttering my code but am having trouble thinking of a good way to consolidate it

10:47 CookedGryphon: Can anyone think of a decent pattern for piping the string contents of a channel into an InputStream that stays open for a long time receiving occasional appends

10:47 as in a core.async channel with core.async take semantics

10:48 mr_rm: having trouble understanding the seed arguments to memo. if i try this: (def foo (clojure.core.memoize/memo + {[42 1] 99})) and then call (foo 42 1) I get an error trying to cast Long to Future. I thought the map value should simply be the return value. What am I doing wrong here?

10:48 CookedGryphon: I'm struggling to wire up appropriate input/output streams, tried implementing Inputstream directly myself and hit all sorts of snags

10:48 weavejester: csd_: Could you explain a little more what you mean?

10:48 klyed2: CookedGryphon: i know very little clojure, but cues maybe?

10:48 CookedGryphon: PipedInputStream and PipedOutputStream sort of work, but don't flush immediately, I need to fill the buffer before anything goes through

10:49 csd_: weavejester: sure

10:49 (defn add-link! [request]

10:49 (let [{session :session} request

10:49 {params :params} request

10:49 {link :link} params

10:49 {description :description} params

10:49 {username :username} session]

10:49 I have a ton of that

10:49 Bronsa: csd_: do you know about :keys?

10:50 (let [{session :session} request {params :params} request] ..) can be rewritten as (let [{:keys [session params]} request] ..)

10:50 weavejester: csd_: {{:keys [username]} :session, :keys [link description] :params}

10:51 Bronsa: ^ and they can nest

10:51 csd_: I guess my hangup is I feel like there should be a way to make a wrapper that makes it so that each view doesn't require a let statement to access request parameters

10:51 weavejester: I’d also be tempted to use Compojure’s binding forms

10:52 It’s often a good idea to restrict what data your functions have access to.

10:52 The less they know, the less that can affect them.

10:53 You can also make use of closures

10:53 csd_: By clojure binding forms you mean the binding during defroutes?

10:53 weavejester: No, the binding forms in GET, POST, etc.

10:53 csd_: I think that's what I mean

10:53 How would you do that in the case of multiple vars?

10:54 weavejester: Let me put together a gist

10:57 csd_: https://gist.github.com/weavejester/b7388f5626f5bfa512a5

10:58 There’s potentially a better way of getting the username from the session, I think…

10:58 Maybe dumping it into the request map

10:58 clgv: oh `gen/elements` from test.check behaves pretty badly for a list of 56 entities when performing 100 runs - in the last runs the only the last element of the collection is used

10:58 csd_: weavejester: Is that something that would need to be done on the library side?

10:59 weavejester: csd_: No, you could add the username to the request with middleware

11:00 csd_: But I’m considering improving the efficiency of the context macro when the route is “/“…

11:01 csd_: this gist is helpful, thanks

11:02 CookedGryphon: Does anybody know of an alternative to PipedInputStream/PipedOutputStream which doesn't wait for the buffer to be full/closed before it writes to the consumer?

11:03 mr_rm: CookedGryphon: can you call flush at opportune times?

11:05 justin_smith: CookedGryphon: isn't there one like that in java.nio somewhere?

11:06 mr_rm: having trouble understanding the seed arguments to memo. if i try this: (def foo (clojure.core.memoize/memo + {[42 1] 99})) and then call (foo 42 1) I get an error trying to cast Long to Future. I thought the map value should simply be the return value. What am I doing wrong here?

11:06 EvanR: ,({:a 1} :a)

11:06 clojurebot: 1

11:06 EvanR: ,(:a {:a 1})

11:06 clojurebot: 1

11:06 EvanR: o_O no wonder im having hard time remembering the order

11:07 mr_rm: EvanR: the second version won't give you nullpointerexceptions if you have no map though

11:08 ,(nil :a)

11:08 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0:0)>

11:08 mr_rm: ,(:a nil)

11:08 clojurebot: nil

11:08 EvanR: null pointer exceptions are good for you, they build character

11:08 mwfogleman: :D

11:10 arrdem: &(char nul)

11:10 lazybot: java.lang.RuntimeException: Unable to resolve symbol: nul in this context

11:10 arrdem: &(char nil)

11:10 lazybot: java.lang.NullPointerException

11:10 arrdem: ^ not building character

11:10 EvanR: lol

11:12 Glenjamin: hahaha

11:12 (inc arrdem)

11:12 lazybot: ⇒ 39

11:12 mr_rm: ((clojure.core.memoize/memo + {[42 1] 99}) 42 2)

11:12 ,((clojure.core.memoize/memo + {[42 1] 99}) 42 2)

11:12 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.core.memoize, compiling:(NO_SOURCE_PATH:0:0)>

11:13 mr_rm: ,(require 'clojure.core.memoize)

11:13 clojurebot: #<FileNotFoundException java.io.FileNotFoundException: Could not locate clojure/core/memoize__init.class or clojure/core/memoize.clj on classpath: >

11:13 mr_rm: ,((clojure.core.memoize/memo + {[42 1] 99}) 42 2)

11:13 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.core.memoize, compiling:(NO_SOURCE_PATH:0:0)>

11:16 justin_smith: ,(Character. nil)

11:16 clojurebot: #<NullPointerException java.lang.NullPointerException>

11:22 mr_rm_: *clojure-version*

11:22 ,*clojure-version*

11:22 clojurebot: {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}

11:26 mwfogleman: bots.

11:37 EvanR: ,(first nil)

11:37 clojurebot: nil

11:37 EvanR: ,(ffirst nil)

11:37 clojurebot: nil

11:38 justin_smith: ,(get-in nil [:we :must :go :deeper :inception])

11:38 clojurebot: nil

11:43 clgv: O_o

11:44 CookedGryphon: mr_rm_: flush doesn't seem to do anything at all, it still waits for the buffer to fill or the outputstream to close

11:44 justin_smith: not that I can find, and I have looked. Pointers appreciated

11:45 mr_rm_: http://clojure.github.io/core.memoize/#clojure.core.memoize/memo is there a bug in the documentation here? you can't actually provide just a simple number here as the return value. you need to use a (delay 42) or something similar

11:45 clgv: CookedGryphon: hmm usually .flush should do that

11:45 CookedGryphon: clgv: that's what I thought

11:45 I spent ages sending one message then a flush and thinking I didn't have it wired up correctly

11:46 but actually I just need to send ~1k messages and it all streams out

11:46 mr_rm_: i can see that the source code derefs the value and you can't do that on a simple number. the documentation is what threw me in the first place. simply wrapping those values in the seed map with a (delay) works fine

11:47 CookedGryphon: personally, i would suspect a bug in your code because that's how flush works :) maybe you're doing something with a lazy seq that isn't getting realized... or something

11:47 CookedGryphon: I'm literally calling (.write ostream (.getBytes "Hello" "UTF-8")) (.flush ostream)

11:47 clgv: CookedGryphon: do you use other streams wrapped around or within?

11:48 CookedGryphon: and if I do the same in a dotimes [n 10000] it comes through

11:48 nope, I have (let [istream (PipedInputStream.), ostream (PipedOutputStream. istream)] ...

11:48 handing the PipedInputStream to the WebView API

11:49 that's expecting an InputStream

11:49 I wonder....

11:50 let me make a gist, I just had a thought

11:51 https://gist.github.com/AdamClements/27948417027275d08f06

11:51 mr_rm_: does anyone else agree that the documentation of the seed values here is a bug because it shows using a simple number? i can submit a PR but i want to be sure i'm not just misinterpreting: http://clojure.github.io/core.memoize/#clojure.core.memoize/memo

11:52 clgv: CookedGryphon: looks good over here: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/io/PipedOutputStream.java#PipedOutputStream.flush%28%29

11:53 CookedGryphon: Is it that doing <!! waiting for more data in the same thread is not allowing the InputStream to be read because my thread is blocked or something?

11:53 Bronsa: mr_rm_: "where keys are a vector

11:53 mapping expected argument values to arity positions"

11:53 mr_rm_: it seems pretty clear to me that the numbers are example inputs

11:54 mr_rm_: Bronsa: if you use a number as the VALUE though, calling the memoized function will blow up (can't cast a Long to a Future)

11:54 EvanR: ,(first "foo")

11:54 clojurebot: \f

11:55 mr_rm_: Bronsa: that is, this will work: ((clojure.core.memoize/memo + {[42 1] (future 99)}) 42 1) but this won't: ((clojure.core.memoize/memo + {[42 1] 99}) 42 1)

11:55 Bronsa: mr_rm_: gotcha

11:58 mr_rm_: I'd say, rather than changing the docstring, the impl should change

11:58 https://github.com/clojure/core.memoize/blob/master/src/main/clojure/clojure/core/memoize.clj#L148-L152

11:58 CookedGryphon: I think it must be something to do with which thread I'm doing things on...

11:58 csd_: weavejester: I think there is an error in the gist you wrote. `username` actually appears to be the request map

12:00 Bronsa: mr_rm_: btw it expects an IDeref, not necessarily a future, you can use an atom/delay/var whatever

12:00 mr_rm_: Bronsa: i also feel it would be a simpler api if you could just pass the actual return value. that threw me at first when i was trying to use it as documented. feels artificial to have to pass a delay or something

12:00 weavejester: csd_: What do you mean?

12:00 csd_: I'm doing basically (str username) and it's returning the entire request map

12:01 mr_rm_: Bronsa: yes i figured that out afterward. i should have just looked at the source first but the doc seems to straightforward i thought i must be doing something stupid :)

12:01 weavejester: csd_: Could I take a look at your code? I don’t see how destructuring could fail like that

12:02 csd_: sure one sec

12:02 Bronsa: mr_rm_: http://dev.clojure.org/jira/browse/CMEMOIZE here's the bug tracker for core.memoize if you want to open a ticket reporting the bug

12:05 EvanR: function to get the only value out of a map known to have exactly one entry

12:05 ,(second (first {:a 0}))

12:05 clojurebot: 0

12:06 csd_: weavejester: sorry looks like i had a syntax error

12:06 weavejester: csd_: No problem :)

12:09 CookedGryphon: this is really infuriating. I tried moving the PipedOutputStream creation into the thread that's reading off the channel, no luck. It's still not getting read. I wonder if this is something wrong with the way the webview is reading the InputStream...

12:12 clgv: CookedGryphon: just try it, make a debug thread that just consumes and prints your input stream

12:14 mr_rm_: Bronsa: done. http://dev.clojure.org/jira/browse/CMEMOIZE-18 thanks for your response

12:19 csd_: weavejester: if keys aren't present in the request map but are being destructured, will that cause problems with route processing at all?

12:19 mr_rm_: ,(val (first {:a 0}))

12:19 clojurebot: 0

12:19 borkdude: what is the technical term for getting a value out of a map by key?

12:20 weavejester: csd_: I don’t believe so. Destructuring a missing key just ends up with nil

12:20 Bronsa: borkdude: looking up?

12:20 weavejester: ,(let [{{:keys [session]} :request} {}] session)

12:20 clojurebot: nil

12:21 csd_: weavejester: i'm really stumped at this point. my login function wasn't getting called anymore, so i stripped out all the parameters and made the response just a simple str, and then a print to console, and it doesn't even seem like it's getting called.

12:21 (POST "/login" [] (views/login))

12:21 only thing i can think of is that somehow the destructuring above is causing it

12:22 borkdude: Bronsa yeah ok

12:22 weavejester: csd_: Let me double-check I’m not mistaken about context

12:23 csd_: Hm, seems to work on my end

12:24 csd_: What does your code look like? And which version of Compojure/Ring are you using?

12:24 csd_: compojure 1.1.9; ring 1.3.1

12:25 i'll put on pastebin, one moment

12:25 weavejester: csd_: I don’t think there are any bugs in 1.1.9 that would cause a problem, but it might be worth updating to 1.2.1

12:27 EvanR: function to run a function on each value, which does IO, and get the list of results of each one, like a foreach which gives the results in a list/seq

12:28 csd_: weavejester: http://pastebin.com/yQeXDuHA

12:31 weavejester: csd_: There are a couple of odd things in that code. You’re using the deprecated handler/site *and* wrap-defaults simultaneously.

12:31 justin_smith: mr_rm_: EvanR: how about ##(first (vals {:a 0}))

12:31 lazybot: ⇒ 0

12:31 EvanR: ##?

12:32 justin_smith: ## is just inline lazybot syntax

12:32 weavejester: csd_: You also have a parameter called “session”, which leaves me to think that’s a mistake?

12:32 mr_rm_: justin_smith: sure, why not? :)

12:32 cbryan: it's a super-anonymous function, duh

12:32 csd_: session is in there because the function i'm passing it to needs to be able to add :username to the session

12:32 justin_smith: mr_rm_: I like it because it does not rely on implicit seq / map overloading

12:33 csd_: i don't know how else to do the assoc otherwise

12:33 as for handler/site, can i just remove it since i'm using wrap-defaults?

12:34 mr_rm_: justin_smith: not sure i understand... vals basically turns it into a seq of values right?

12:34 then you're just using a seq function

12:34 weavejester: csd_: You can remove handler/site, because you’re using wrap-defaults instead.

12:35 mr_rm_: justin_smith: whereas my way is just getting the first MapEntry and then retrieving the val of that entry

12:35 weavejester: csd_: The context destructuring looks okay, but maybe try updating your Compojure version to the latest one?

12:35 mr_rm_: justin_smith: not that i think it makes much diff :)

12:35 csd_: ok

12:35 weavejester: csd_: The session binding you have just binds to a *parameter* called session, not the actual session.

12:35 EvanR: i think doall map is what im trying to think of

12:36 weavejester: csd_: For that you’d want :as {:keys [session]}

12:36 csd_: Or take advantage of Compojure’s handling of returned functions

12:36 csd_: how do you mean?

12:37 mr_rm_: EvanR: maybe reduce?

12:37 weavejester: csd_: (GET “/“ [] (fn [req] (assoc (:session req {}) :foo “bar”)))

12:37 justin_smith: mr_rm_: vals is a function that takes a map and returns a seq - that is what it explicitly does. first when called on a map returns a map entry, but this is less explicit. For example imagine reading the code in a context where the map was not a literal, but was an argument passed in - with first vals I would know to expect a map in that place, with val first it's slightly more ambiguous

12:37 weavejester: csd_: Well, that won’t work exactly because the return value is wrong…

12:38 mr_rm_: justin_smith: this is why i'm slightly uncomfortable with dynamic languages :)

12:38 weavejester: csd_: But the idea is that you can return a function and using that to regrab the request map, without needing to pull in the request map explicitly.

12:38 justin_smith: mr_rm_: my discomfort grows

12:38 csd_: which do you view as being better style?

12:39 EvanR: im going with first vals for that, it makes sense

12:39 and easier to read

12:39 without already knowing all the clojure tricks

12:39 weavejester: csd_: Returning a handler function that modifies the request would be my choice, I think.

12:39 EvanR: ,(de-dupe [1 1 2 2 1 1])

12:40 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: de-dupe in this context, compiling:(NO_SOURCE_PATH:0:0)>

12:40 EvanR: ,(dedupe [1 1 2 2 1 1])

12:40 clojurebot: (1 2 1)

12:40 weavejester: csd_: Although I’m not sure it’s necessary - I typically just keep a user identifier in the session, so there’s only ever one value anyway.

12:41 mr_rm_: EvanR: (reduce #(conj %1 (do (prn %2) 99)) [] ["hi" "there"])

12:41 csd_: weavejester: yeah i think its just more an issue of setting it though--i only set session with user too

12:42 weavejester: csd_: {:session {:username username}} then

12:42 EvanR: mr_rm_: doesnt doall already do this

12:42 mr_rm_: EvanR: added a (do) just to get a return value more interesting than nil :)

12:43 EvanR: i thought you wanted it to collect the return values from the i/o function

12:43 Glenjamin: anyone around familar with reagent (this may apply to Om too) - if i redef a component in the repl, but it's in a part of my UI tree that shouldComponentUpdate is false - is there a way to reload it?

12:44 EvanR: mr_rm_: the io function already returns the result, and im applying it to a list of inputs, so (doall (map proc) inputs) ?

12:44 er

12:44 mr_rm_: the io function already returns the result, and im applying it to a list of inputs, so (doall (map proc inputs)) ?

12:44 csd_: java.lang.IllegalAccessError: rfn does not exist, compiling:(route.clj:1:1)

12:45 EvanR: ,(sort [1 3 2 1])

12:45 clojurebot: (1 1 2 3)

12:45 bordatoue: hi can anyone please help me, I'm trying to read some funtion written in a txt file using read-string and using eval create a fn which i invoke dynamically. The problem is it works in repl but when i run it outside repl all the string losses its quotes

12:45 is there any way accomplish this using read-string

12:47 ohpauleez: bordatoue: You are reading in the file using `slurp`?

12:47 bordatoue: yes

12:47 mr_rm_: EvanR: map is really better for applying pure functions to data.

12:47 bordatoue: ohpauleez: yes

12:47 EvanR: mr_rm_: yeah, that would make sense

12:49 make it seems like this would work and theres no alternative, and if there was one would be indistinguishable from map

12:49 bordatoue: ohpauleez: actually i got my main clj program which reads a txt file ; the txt file contains some fn defined in clj. I read in the txt file using (eval (read-string (slurp "text")) ==> fn

12:49 EvanR: s/^make //

12:49 ohpauleez: bordatoue: You should be able to pass that directly to `read-string`

12:50 mr_rm_: (reduce #(conj %1 (myfunc %2) [] inputs) would be ok right?

12:50 ohpauleez: bordatoue: Be careful though, you want to make sure you that text file is fully trusted

12:50 bordatoue: ohpauleez: but read-string seems to get rid of all the quotes , so when i have something in the function "." using read-string it becomes .

12:50 EvanR: mr_rm_: right, you can also implement map the same way

12:51 map and reduce to me same equally as "pure"

12:51 bordatoue: ohpauleez: I really don't care about trust , I just want the implementation to work

12:51 EvanR: seem*

12:51 mr_rm_: EvanR: yes, agreed. it just feels icky to use map to generate side effects. side effects are always messy :)

12:52 EvanR: it feels icky to produce it with reduce, actually side effects are icky. however in this case i am dealing with non-side effects, they are the main point of this computation ;)

12:52 Bronsa: EvanR: you should prefer doseq to map to iterate over a sequence performing side-effects

12:52 mr_rm_: EvanR: the problem is you want to both generate the effects AND collect up the results so it's ugly no matter what

12:52 EvanR: front effects

12:53 Bronsa: but i dont get the results right

12:53 Bronsa: EvanR: ah you want the results, ok

12:53 EvanR: mr_rm_: head scratch, why is that more icky than throwing the results away? IO actions often result in a response value

12:53 Bronsa: EvanR: sorry I mix dorun and doall in my head every time

12:54 borkdude: history question: what led to clojurescript one being abandoned

12:54 EvanR: yeah so doall seems the most appropriate, it even has a do in the name

12:54 ohpauleez: borkdude: The creation of Pedestal App (just a guess)

12:55 borkdude: ohpauleez can pedestal app be seen as the successor of clojurescript one?

12:55 ohpauleez: I'd imagine so, to some degree

12:55 borkdude: ohpauleez interesting, didn't know that

12:55 EvanR: where is dedupe defined ...

12:56 cbryan: in 1.7 ;)

12:56 ohpauleez: Lineage looks like Brenton on CLJS:One, Chris on Pinot, Myself on Shoreleave

12:56 EvanR: ff

12:56 s

12:56 ohpauleez: Brenton then doing Pedestal App (with others), Pinot being broken up

12:56 justin_smith: $source dedup

12:56 lazybot: Source not found.

12:56 cbryan: http://crossclj.info/fun/clojure.core/dedupe.html

12:57 ohpauleez: Then walking away from Pedestal App to collect our thoughts on React and core.async some more

12:57 mr_rm_: EvanR: what throws the results away?

12:57 EvanR: but yeah... probably best to have doall on the outermost call to make it obvious

12:58 bordatoue: is there any alternative to read-string

12:58 how do i know which name same read-string belong to

12:59 justin_smith: bordatoue: there is clojure.edn/read-string

13:01 EvanR: that dedupe code is now stoled

13:03 ohpauleez: borkdude: You can also just use `read`

13:03 and you already said it worked in the REPL, right?

13:03 so if it works in the REPL, it'll work in your file. It's unclear what you're really trying to do

13:04 but you're essentially doing the same thing the repl does (Read, eval)

13:04 EvanR: volatile! not defined...

13:04 justin_smith: ohpauleez: I think you meant to reply to bordatoue

13:04 ohpauleez: justin_smith: borkdude: bordatoue: Yes, sorry about that

13:04 :)

13:06 EvanR: gah getting stuck on this dedupe thing, using old clojure strikes back

13:07 {blake}: OK, I need some help with partition-by. Like, maybe I'm misusing it. I'm using hiccup to convert a collection ("FieldName1" {:thing "value1" :group "group1"}, "FieldName2" {:thing1 "value3" :group...) into a Bootstrap table. This works.

13:08 But I now want to partition the controls by the ":group" key in the associated map. So I use "(partition-by #(:group(val %))" which returns a list of lists for each partition.

13:09 justin_smith: {blake}: are you sure you want partition-by and not group-by?

13:10 partition-by is for ordered things, maps are not ordered

13:10 {blake}: justin_smith, I think so. Besides :group, I also have a :row. The controls have to come out in row order, but they need to break by group. (Which, theoretically, should be continuous.)

13:10 justin_smith: oh, I misunderstood, that is not a map

13:10 sorry

13:10 {blake}: justin_smith, Well, maybe that's where I'm going wrong.

13:11 ohpauleez: bordatoue: you can also look at `load-file` - http://clojuredocs.org/clojure.core/load-file

13:11 {blake}: justin_smith, Well, it =could= be. I'm not even sure why it's a list, actually. The field names are unique.

13:11 justin_smith: (partition-by (comp :group second) (partition 2 coll)) ?

13:11 {blake}: Oh, I know why: because I sort it.

13:11 justin_smith, The partition-by works. The problem is I can't figure out how to work with the results.

13:12 Like, when it's just a straight list, I have "(map input-to-control inputs)". Easy

13:12 justin_smith: (for [inputs partitioned input inputs] (input-to-control input))

13:12 {blake}: Once it's partitioned, I've got (first (map #(map input-to-control %) inputs) to get the FIRST group. But I can't figure out how to apply that to ALL the groups.

13:12 bordatoue: ohpauleez: but load-file is from repl, what if i want to work output side of repl

13:13 ohpauleez: Nothing is repl-specific

13:13 You have access to whatever piece of Clojure code you want

13:13 {blake}: justin_smith, There it is. Thanks.

13:21 bordatoue: ohpauleez: clojure.core/read-string works in repl but outside of repl it doesn't parser double quotes so "abcd" become abcd

13:21 i don't know why that is

13:22 justin_smith: bordatoue: I don't think that is true

13:22 bordatoue: how are you verifying this?

13:22 bordatoue: well ;you create a clj project read some fn from an external file with double quotes using read-string

13:22 it gets messed up

13:23 justin_smith: bordatoue: is the function definition inside double quotes?

13:23 bordatoue: justin_smith: no

13:23 justin_smith: and what does "messed up" mean?

13:23 TimMc: You're saying that if I create a file with these 3 characters: \" \a \" and call slurp and read-string on it, I will get... what?

13:24 bordatoue: justin_smith: it means all the double quotes are gone so if i have a (.split "abcd" ".") it becomve (.split abcd .)

13:24 TimMc: I would expect String "a"

13:24 {blake}: (inc justin_smith)

13:24 lazybot: ⇒ 114

13:24 TimMc: bordatoue: Please create a SSCCE. This doesn't seem right/

13:24 justin_smith: bordatoue: how do you know that happened?

13:25 Bronsa: bordatoue: http://sprunge.us/bdVi

13:25 bordatoue: i printed it to the console

13:25 justin_smith: bordatoue: that's your problem

13:25 use prn

13:25 ,(print "abcd")

13:25 clojurebot: abcd

13:25 justin_smith: ,(prn "abcd")

13:25 clojurebot: "abcd"\n

13:25 justin_smith: I knew it

13:25 TimMc: ,(print 'abcd)

13:25 clojurebot: abcd

13:26 TimMc: ,(prn 'abcd)

13:26 clojurebot: abcd\n

13:26 bordatoue: justin_smith: ok will use prn

13:32 success: Hi

13:33 under downloads there is lot of stuff

13:33 what do I need to do to just test some clojure

13:33 justin_smith: success: most projects use lein

13:33 success: and either lein test or lein midje will run the tests in most clojure projects, if you literally mean running the unit tests

13:34 if you mean "try using clojure" just download lein and run lein repl

13:36 lynaghk: hiredman: I've been looking at your datalog implementation (https://github.com/hiredman/datalog): do you have any writeups or references about the algorithm it uses?

13:37 bbloom_: is there any notion of an optional dependency?

13:37 lynaghk: hiredman: I just did a naive bottom-up implementation, but yours is about twice as fast on my toy dataset---not sure if it's a difference in algorithm or just some well placed code optimizations. I'm having a hard time following the code, so I thought I'd pop in and ask = )

13:37 bbloom_: ie do one thing if some dependency is available, do something else otherwise

13:38 justin_smith: bbloom_: you could hack something with resolve I guess...

13:39 cbryan: ,(if (nil? (find-ns 'blah)) (println "nope, do A") (println "ok do something, B"))

13:39 clojurebot: nope, do A\n

13:39 bbloom_: justin_smith: i'm trying to figure out how to structure a development environment for a multi-component system. i don't want to require every dev run every service all the time while developing

13:39 justin_smith: bbloom_: yeah, makes sense

13:39 find-ns is a nice idea for that too

13:40 bbloom_: (doc find-ns)

13:40 clojurebot: "([sym]); Returns the namespace named by the symbol or nil if it doesn't exist."

13:40 bbloom_: hm

13:40 cbryan: bbloom_: my example was for you ;)

13:40 justin_smith: so you could wrap code in find-ns / resolve

13:40 you still need resolve, or the compilation will fail

13:41 bbloom_: thanks, i'll think about this a bunch

13:41 cbryan: justin_smith: why would resolve be needed?

13:41 nestastubbs: bbloom_: use a services/component model at runtime

13:41 cbryan: (not saying it wouldn't, i just don't immediately see why)

13:41 nestastubbs: bbloom_: and provide mocks/stubs

13:41 justin_smith: cbryan: because your attempt to call things in that ns would fail at compilation time

13:41 nestastubbs: for the components

13:41 bbloom_: nestastubbs: in past projects i've relied on dns, hosts files, etc

13:41 cbryan: justin_smith: oh, duh. ha

13:42 bbloom_: nestastubbs: jetty configs, etc

13:42 justin_smith: cbryan: it's not enough that the code referencing it not be called, it is still looked for when compiling

13:42 nestastubbs: sure, you could have teh system builder look at those to decide how to proceed

13:42 we use sfnks

13:42 bbloom_: well, i have the added problem of evolving a relatively monolithic app

13:42 nestastubbs: and then a configuration map and a service definition map are combined to make the running system

13:42 justin_smith: bbloom_: when I have made similar things, I opted for passing everything in explicitly rather than using things via their ns.

13:42 clojurebot: Excuse me?

13:42 justin_smith: bbloom_: which is clumsy in its own way

13:43 nestastubbs: bbloom_: highly localized solution then 8)

13:44 bbloom_: would be nice to have only one jvm running, if i can help it

13:45 since it's all clojure and repl-friendly

13:47 cbryan: what's the difference between a function and a "special form"? I assume special forms do something that works with the innards of clojure? http://clojure.org/special_forms#Special Forms

13:47 justin_smith: cbryan: special forms are implemented in java

13:47 Bronsa: cbryan: they have custom evaluation semantics

13:47 cbryan: makes sense. thanks!

13:48 Bronsa: justin_smith: some functions are too though

13:48 e.g. in-ns

13:48 justin_smith: Bronsa: good point, thanks

13:52 success: lein is short for leiningen

13:53 justin_smith: yes, the executable is called lein

13:55 mi6x3m: Bronsa: hey, in tools-analyzer, would resolve-var return nil if the symbol is not a variable?

13:56 Bronsa: mi6x3m: no. resolve-sym would have been a better name but it's too late to change now

13:57 mi6x3m: Bronsa: well what would it do if the symbol is not a var?

13:57 just return nil to the caller?

13:58 Bronsa: mi6x3m: not sure I understand what you're asking

13:58 mi6x3m: hm, this won't make any sense actually

13:58 no, wait, was just a bit mind-blurred

13:59 Bronsa: mi6x3m: resolve-var returns whatever the symbol maps to in the namespace

13:59 mi6x3m: if it doesn't map to anything, it will return nil

13:59 mi6x3m: in case of t.a.jvm, resolve-var can return a Var or a Class

14:00 mi6x3m: yes, this was the issue more or less

14:00 about classes

14:01 Bronsa: mi6x3m: what's the issue? just test with `var?`

14:01 mi6x3m: resolver_"var" is really tricky name :)

14:02 Bronsa: mi6x3m: yes, definitely. it used to actually resolve Vars only back when t.a and t.a.j were still a single entity

14:02 mi6x3m: in the process of making t.a modular & host agnostic foreseeing the implementation of t.a.js resolve-var was changed to return whatever the mapping was but the name remained the same

14:04 mi6x3m: yes that clarifies it

14:04 it returns a mapping, not a var

14:04 for jvm :)

14:04 Bronsa: mi6x3m: well in the docstring I talk about a var, not about a Var

14:05 mi6x3m: that's the truth!

14:05 success: should I really put lein in ~/bin and make it executable? i dont know much about security yet, I use ubuntu.

14:06 cbryan: yeah, you can trust it

14:06 as long as you got it from https://github.com/technomancy/leiningen i should say

14:07 also, ubuntu has it in its repos. try "apt-get install leiningen"

14:07 success: http://leiningen.org/

14:08 will sudo apt-et install leiningen put it under bin?

14:08 justin_smith: success: cbryan: ubuntu's version is old isn't it?

14:10 amalloy: suuuuper old

14:10 cbryan: [...] Version: 1.7.1-

14:10 eesh

14:11 amalloy: success: download lein from github. putting stuff in ~/bin is a pretty normal thing to do and doesn't have any security issues i'm aware of

14:11 cbryan: ^ yeah, ignore the apt-get line :)

14:11 justin_smith: amalloy: well the security issue would have to do with the provenance of the thing you put in ~/bin

14:12 csd_: spending over an hour getting frustrated until realizing i need to `lein clean`, priceless

14:12 justin_smith: but we all use the lein from technomancy's github, so there's that

14:12 cbryan: technomancy's playing the long game

14:12 ;)

14:13 amalloy: justin_smith: well, that's more an issue of putting stuff anywhere on your PATH, not of ~/bin

14:20 justin_smith: amalloy: right

14:22 success: why are there 3 places to download it from+github?

14:22 + packet manage si mean

14:23 cbryan: to try to make it easy as possible to get started

14:23 s/easy/as easy

14:25 success: what editor is the most popular? please dont say emacs :)

14:25 hfaafb: emacs

14:27 amalloy: success: well, if you didn't want emacs as the answer, you asked the wrong question

14:27 success: no eclipse plugin?

14:27 amalloy: the question you may have meant is "what editor should i use?", which has quite a different answer

14:27 Bronsa: success: cursive clojure is great

14:27 cbryan: i use sublime text personally

14:27 joshuafcole: If you really don't want to go with emacs, Light Table isn't nearly as popular (it's very young and has a few rough edges to iron out), but it has a really solid feature set for working with clj/cljs

14:27 hfaafb: LIGHT TABLE

14:27 success: how do i quit the repl

14:27 cbryan: ctrl + d

14:28 joshuafcole: Sublime Text is also popular, though it wasn't flexible enough for my tastes

14:28 justin_smith: (System/exit 0) works too

14:28 cbryan: yeah, im planning to learn emacs asap

14:29 amalloy: success: use whatever editor you're already comfortable with. as long as it's not notepad.exe, there's decent clojure support for it

14:29 and you don't really *need* any editor support anyway: you can load files from the repl, or copy-paste snippets to it, whatever

14:30 the important thing is to have as little irrelevant nonsense in the way of learning clojure, and there's little benefit to picking the editor used by clojure experts if you don't know how to use it

14:32 success: how do I run my clojure file as a program rather than run the repl?

14:33 cbryan: https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md read that

14:35 dbasch: success: the easiest way is probably “java -cp path/to/clojure.jar clojure.main yourfile.clj”

14:35 but it’s much better to have a leiningen project

14:36 success: yeah, using leinengen bow

14:36 ty all

14:36 unforetuneately the status of clojure on android is depressing

14:36 mwfogleman: Yeck, refactoring a file has exposed a circular dependency.

14:42 dbasch: clojure jobs supposedly pay well these days: https://msgooroo.com/GoorooTHINK/Article/16225/Programming-languages--salaries-and-demand-October-2014/17081#.VFfalfTF8a4

14:43 justin_smith: success: yeah, clojure is great but it is kind of resource-hungry

14:43 Glenjamin: interesting, i'm surprised to see fortran so low

14:43 left-side skewed by lack of data i guess

14:51 EvanR: nice clojure stats there, most expensive, nearly lowest demand

14:52 can i haz average clojure weight salary plz

14:52 borkdude: EvanR 60 euros per gram

14:53 mi6x3m: good one

14:54 EvanR: can imagine most job ads literally saying c/c++ which would account for the coincidence of C and "C++ Developer"

14:55 wonder where Swift is ;)

14:55 mi6x3m: EvanR: this is non-sense anyhow. a proper job ad should say "experienced developer with some common sense" without mention of any languages

14:55 amalloy: mi6x3m: "strong background in english recommended"

14:55 mi6x3m: hehe

14:56 AimHere: Alternatively other job adverts could follow suit. "Housepainter required. Must have had 3-5 years experience of brown paint"

14:56 borkdude: "should be able to port clojure's persistent vectors in C "

14:56 joshuafcole: (inc AimHere)

14:56 lazybot: ⇒ 3

14:56 joshuafcole: heh

14:57 EvanR: "if programming languages were colors of paint"

14:58 does polka dot, striped, and plaid count

14:58 borkdude: Hackers and Painters

14:59 cbryan: what if i've mixed other colors together and it ended up brown, but i've never really worked with brown directly...?

15:00 EvanR: 3-5 years spaghetti code

15:00 dbasch: https://www.dropbox.com/s/dn6fktq73fxzapk/Screenshot%202014-11-03%2011.59.06.png?dl=0 “if programming languages were…"

15:00 csd_: is spaghetti code still bad if you are working for food service companies

15:01 joshuafcole: heh

15:01 Depends on the ratio of meatballs

15:01 borkdude: spaghetti's no problem if you can just cut right through it

15:01 joshuafcole: even in the food industry, if it's all spaghetti you're not doing to hot

15:01 csd_: i like my code al dente, mostly

15:01 joshuafcole: s/to/too

15:02 teslanick: That would be a good food service industry startup name: SpaghettiCode.

15:02 joshuafcole: quick tip: If you add a sprinkle of salt to the water before adding the code to the pot, you get improved security for free.

15:02 csd_: haha

15:04 mwfogleman: huzzah, i have resolved this circular dependency. how does everyone here prevent and handle prevent circular dependencies?

15:05 dbasch: mwfogleman: modular design?

15:06 EvanR: refactor

15:06 ,(distinct [1 1 2 2 1 1])

15:06 clojurebot: (1 2)

15:07 success: (defn -main

15:07 "I don't do a whole lot."

15:07 [& args]

15:07 (println "Hello, World!"))

15:07 Java is still a good bet, I mean Clojure might be high in pay but it is low on#jobs

15:08 cbryan: mwfogleman: if i'm where i am now, with incomplete structs :(

15:09 m1dnight_: +go info

15:09 sorry 'bout that

15:10 success: org.apache.maven:super-pom:pom:2.0

15:10 justin_smith: mwfogleman: usually, by pulling commonalities into something more abstract, like a protocol or defmethod that both sides can refer to

15:11 mwfogleman: or when things are super bad (like fixing someone else's code and things are way tangled and wanting to alter as little as possible while still cleaning up) I may use resolve. It feels dirty when I do that though.

15:12 dbasch: resolve, courage and determination are useful when cleaning other people’s code

15:13 EvanR: luck

15:13 dbasch: luck is useful even when not cleaning someone else’s code

15:13 justin_smith: heh

15:14 Glenjamin: integration/acceptance tests are also handy

15:14 mgaare: it's like cleaning a hotel room after a rock band has been there

15:14 SagiCZ1: hi, anyone know clj-time? i have a datetime object, and i want to have a copy of that object just with a different minutes for example 1970-1-1-16-36 ->1970-1-1-16-n. How can i do that?

15:14 mgaare: if you're lucky, it wasn't John Bonham

15:15 success: after installing lein, how do i install all the necessary java stuff?

15:15 1 required artifact is missing.

15:15 for artifact:

15:15 org.apache.maven:super-pom:pom:2.0

15:15 3

15:16 justin_smith: success: lein does it. If it doesn't work then the project.clj or your .lein/profiles.clj should be fixed

15:16 EvanR: SagiCZ1: you can add a number of minutes equal to the difference of 36 and n

15:17 success: 1 required artifact is missing.

15:17 for artifact:

15:17 org.apache.maven:super-pom:pom:2.0

15:17 oops

15:17 (defproject app "1.0.0-SNAPSHOT"

15:17 :description "FIXME: write description"

15:17 :dependencies [[org.clojure/clojure "1.3.0"]])

15:17 mgaare: SagiCZ1: either add or build a new object from your old one d like, (date-time (year d) (month d) (day d) (hour d) n)

15:17 SagiCZ1: EvanR: i know, but the difference is what i want to find out.. i have one date, and i want to know how many minutes till some n number of minutes. I can use t/interval for that, but i dont know how to construct the other day

15:17 Bronsa: success: it loks like you're using a super old version of lein if it defaults to clojure 1.3

15:17 SagiCZ1: mgaare: yeah thats what i figured, but thats so ugly

15:18 EvanR: SagiCZ1: the literal difference in minutes if given by subtracting one minutes x from the other minutes x

15:18 ah but thats another story entirely

15:19 SagiCZ1: i am basically trying to implement "rounding" of dates to some predefined time periods.. (like tens of minutes, days.. etc) .. cant believe joda doesnt have it

15:19 EvanR: SagiCZ1: if you convert to unix time, truncate mod 60, 3600, or 86400 then this might get you closer

15:19 llasram: (inc EvanR)

15:19 lazybot: ⇒ 2

15:20 llasram: Just what I was about to suggest

15:20 mwfogleman: (inc EvanR)

15:20 lazybot: ⇒ 3

15:20 mgaare: SagiCZ1: you can also drop down to java, to set: .withMinuteOfHour

15:20 mr_rm: SagiCZ1: use the plus function?

15:20 mwfogleman: justin_smith: can you say more about how resolve is helpful in such a situation?

15:20 mgaare: SagiCZ1: joda has more stuff than clj-time exposes directly

15:20 SagiCZ1: EvanR: that's not a bad idea.. some math though :)

15:21 justin_smith: mwfogleman: it's a hack - resolve takes a keyword and returns the var it reresolves to, so you can call something that was not defined when your code was compiled

15:21 SagiCZ1: mgaare: sounds good

15:21 justin_smith: mwfogleman: it's a sign of bad design, but it can just make things work

15:21 EvanR: hopefully .withMinuteOfHour doesn't modify the Date object in place

15:22 SagiCZ1: doubt it.. isnt joda all about how traditional java date is horrible because it is mutable

15:22 mgaare: EvanR: it does not.

15:22 EvanR: SagiCZ1: to find the number of minutes between to timestamps, you do a time diff, which gives a number of seconds, and round to nearest 60 (div by 60, times 60)

15:22 er, forget the times 60

15:23 give or take one minute

15:23 mgaare: btw, cider's inspect functionality is great for this kind of thing

15:23 SagiCZ1: EvanR: i know i can find out the difference between two timestamps, but first i have to generate the other timestamps.. for example if i want to round to quarter hours, i have to take the timestamp i want to round, and generate the same timestamp with 00 15 30 45 minutes, then i can do the diff and find the minimal

15:24 mwfogleman: justin_smith: i tried to use resolve to get around the bug i was bumping into with user.clj and defrecord. it was not sustainable.

15:25 joshuafcole: Hmm you can get the minutes, take the mod of the interval as previously recommended, then scale it to 1 and round it

15:25 to get the nearest

15:25 EvanR: SagiCZ1: what are the special times you are diffing against?

15:25 quarter hours?

15:25 joshuafcole: (or just (> (mod minutes interval) (/ interval 2))

15:25 SagiCZ1: EvanR: they are passed as parameter.. it can be anything.. 1 minute, 5 minutes, 15 minutes, 1 hour, 5 hours, 1 week.. so on

15:26 EvanR: integer math on the seconds should work fine

15:26 joshuafcole: I think it still works without focusing on minutes if you use it as a timestamp like mentioned

15:26 EvanR: the next 15 minute timestamp after t is ((t / (15 * 60)) + 1) * (15 * 60)

15:27 (integer division)

15:27 SagiCZ1: where t is number of seconds?

15:27 EvanR: yeah

15:27 csd_: ,(let [m {:a {:aa 1 :ab 1} :b 2}] (assoc (:a m) :c {:b (:b m)}))

15:27 clojurebot: {:c {:b 2}, :aa 1, :ab 1}

15:27 justin_smith: mwfogleman: well, yeah, resolve would help with vars but I don't think it would help for classes

15:28 arrdem: Why is NaN not a reader sybol...

15:28 EvanR: SagiCZ1: the 15*60 can be your parameter, 1 minute is 60, 1 hours is 3600 etc

15:28 Bronsa: arrdem: it is in tools.reader :3

15:28 justin_smith: ,Double/NaN

15:28 clojurebot: NaN

15:28 arrdem: Bronsa: and it is in Oxlang too :P

15:28 EvanR: SagiCZ1: "1 week" works, but note that "1 month" doesnt really

15:28 Bronsa: arrdem: also [+-]Infinity

15:29 llasram: Bronsa: yay!

15:29 EvanR: technically, neither does a year ;)

15:29 llasram: That one has also hit me in the past

15:29 SagiCZ1: EvanR: i am not sure i understand the formula, how did you come up with it?

15:29 EvanR: seems robust though

15:29 Bronsa: llasram: arrdem http://dev.clojure.org/jira/browse/CLJ-1074 vote!

15:29 arrdem: Bronsa: pretty much convinced this is worthless but sure

15:30 Bronsa: arrdem: me too but it never hurts

15:30 llasram: Bronsa: I need to remember what other tickets I voted for and remove my votes from there first....

15:30 EvanR: SagiCZ1: well, it relies on properties of integer division

15:30 Bronsa: llasram: I voted so many tickets my vote is worth nothing right now

15:31 TEttinger: EvanR, so it would need some changes from the / fn in clojure

15:31 EvanR: SagiCZ1: maybe you should study the formula (t / d) * d

15:31 rplaca: SagiCZ1: man, it seems a whole lot easier just to stay in joda time and not switch to unix time

15:31 EvanR: TEttinger: guess so

15:31 rplaca: joda time has all the primitives that you need

15:31 TEttinger: ,(div 15 60)

15:31 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: div in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:31 SagiCZ1: rplaca: really? i dont think you are correct.. since i need to handle kinds of time units

15:31 TEttinger: ,(quot 15 60)

15:31 clojurebot: 0

15:32 SagiCZ1: *all kinds of

15:32 EvanR: ,(quot 1234 60)

15:32 clojurebot: 20

15:32 EvanR: ,(quot-rem 1234 60)

15:32 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: quot-rem in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:32 SagiCZ1: rplaca: i would need to have different cases to call different functions if i wanted to stick to joda primitives

15:32 TEttinger: looks like quot is what we're after

15:32 EvanR: ,(rem 1234 60)

15:32 clojurebot: 34

15:32 rplaca: SagiCZ1: joda time has primitives for that, look at DateTimeFieldType

15:33 and the use .withField

15:33 EvanR: rplaca: i think that makes his job harder

15:34 rplaca: SagiCZ1: do what feels best to you, though, but rounding to arbitrary units should be really easy

15:34 EvanR: "the next even time mod X" isnt just about zeroing out a field

15:35 rplaca: EvanR: of course. joda has aggregates.

15:36 SagiCZ1: the approach evanR suggested solves all overflows pretty well

15:36 rplaca: but if you feel more comfortable converting to seconds and rounding, go for it

15:37 justin_smith: woo, almost done verifying everything in lazybot/plugins/util.clj

15:37 success: how did you instsall cider?

15:37 mr_rm: will simple rounding work for cases like leap year, daylight savings time, etc?

15:37 EvanR: its not really rounding, but doing this field by field is like trying to do decimal arithmetic by specifically checking the ones place, tens places, etc rather than treating the numbers as an arithmetic field of their own, which timestamps are

15:37 arrdem: success: M-x package-install RET cider RET

15:37 EvanR: mr_rm: yes

15:37 success: nope

15:38 arrdem: success: you'll also need to add cider to your .lein/profile.clj

15:38 success: no match

15:38 arrdem: success: what emacs package repos do you have?

15:38 TEttinger: success, did you type out RET or actually hit newline?

15:38 success: hiw enter

15:38 TEttinger: k

15:39 andyf: Bronsa: arrdem: Alex Miller has said that he often looks at unweighted vote counts on tickets, too, so no need to unvote when voting unless you really want to

15:39 arrdem: Bronsa: yo do you still have ns->sym kicking around somewhere? I seem to have lost it

15:39 EvanR: mr_rm: leap years is a detail of a calendar, this is about time diffs. DST is about certain local times, but i assume hes doing this all in UTC

15:40 arrdem: Bronsa: nvm got it

15:41 Bronsa: andyf: yeah I don't unvote tickets

15:42 andyf: Bronsa: I look at those reports when I regenerate them, so was fully aware :-)

15:42 Bronsa: heh

15:44 mr_rm: EvanR: i missed part of the conversation so sorry if i missed the relevant pieces but it seems like zeroing out the low order fields and using clj-time.periodic does what he wants. or using the plus function after starting from (now). i wasn't sure what you were rounding

15:45 EvanR: mr_rm: which fields are the low order fields?

15:45 mr_rm: anything below the one he wants to use to iterate on

15:46 EvanR: seems like a roundable way to go about it

15:46 roundabout

15:48 arrdem: Bronsa: andyf: is there an open ticket for Named over c.l.Namespace?

15:49 success: threading is with Java thread?

15:49 mr_rm: EvanR: it can be but then every leap year and every switch to and from DST seems to cause a lot of issues in large companies where i've worked. sometimes it's actually simpler to just use a well-debugged library.

15:49 EvanR: mr_rm: well, depending on what you think is supposed to happen during DST, my way might be more robust and obviously has less code

15:50 attempting to operate on the mixed-base 6-place local time rep as if it was arithmetic could land you directly in an invalid or ambiguous time value

15:50 Bronsa: arrdem: didn't you open one this summer?

15:50 arrdem: Bronsa: that's Named over Vars

15:50 EvanR: mr_rm: and leap years do not apply at all

15:50 success: how would I override a java method from clojure?

15:51 Bronsa: arrdem: ah

15:51 cbryan: success: i would run through this great guide: braveclojure.com

15:51 andyf: arrdem: Not that I recall. Your ticket for Named on vars is the only one related to Named that comes to mind. Caveat: despite rumors to the contrary, I don't have all the tickets in my head :-)

15:51 Bronsa: arrdem: I don't think named over namespace makes sense either :P

15:51 arrdem: there's already ns-name

15:51 * arrdem facedesk

15:51 mr_rm: EvanR: depends on whether you are trying to manually roll over hours, months, years, etc. but if you're doing it manually you're probably doing it wrong :)

15:51 arrdem: (inc Bronsa)

15:51 lazybot: ⇒ 66

15:52 EvanR: mr_rm: head scratch. if the question is how long until X, then theres no rolling over anythin

15:53 SagiCZ1: EvanR: so how would converting time from unix to some joda time handle leap years? why should that be an issue? i assumed it would just work

15:53 mr_rm: EvanR: well he did say he was trying to generate something like a periodic sequence from the current time

15:53 EvanR: SagiCZ1: so far, you havent seemed to need to convert from unix time to joda time

15:54 mr_rm: oh i see... nm... you're going from the epoch, moving it to and from a joda object

15:54 EvanR: SagiCZ1: heh, are you doing a recurring event calendar / scheduler ;)

15:54 SagiCZ1: EvanR: i tested the method you offered but it's not exactly what i need

15:55 for example this (align (t/date-time 1970 1 1 15 31) (* 60 5))

15:55 results in this #<DateTime 1970-01-01T15:36:00.000Z>

15:55 but when i specify period of 5 minutes, i mean 00 05 10 15 20 25 30 35 ... etc

15:55 EvanR: well, what i suggested wouldnt be doing that

15:56 SagiCZ1: https://www.refheap.com/92663

15:57 EvanR: you cant literally use /, thats floating point division

15:57 try quot

15:58 SagiCZ1: EvanR: oh.. now its better

15:58 amalloy: SagiCZ1: are you doing something like https://github.com/flatland/chronicle ?

15:58 EvanR: align as you defined it would give you the next such timestamp, aligned to period, in UTC

15:58 arrdem: technomancy: is there a good trick for dropping a REPL in a plugin's dependency injected context rather than in the leiningen bootstrap context?

15:59 SagiCZ1: EvanR: it works well, thank you.. it looks very elegant and robust. i would introduce too many bugs if i went another way

15:59 (inc EvanR)

15:59 lazybot: ⇒ 4

15:59 EvanR: that chronicle thing also looks good, letting the user specify something more complex

15:59 but make sure you understand what happens during DST

16:00 and days 29-31

16:00 SagiCZ1: amalloy: Actually, this is an alignement of candlesticks on a stock chart.. i need to always align the first candle to some whole number of periods

16:00 EvanR: i think the correct thing happens

16:01 EvanR: hehe the correct thing regarding period across dst change ;)

16:01 whatever that is

16:01 i think most crons do something unexpected, and no one cares

16:02 SagiCZ1: EvanR: i will test it in the production, no worries ;)

16:11 ,(disj #{:A :B :D :W} #{:D :W :M})

16:11 clojurebot: #{:A :W :D :B}

16:12 SagiCZ1: why doesnt it remove :D and :W ?

16:12 llasram: (doc disj)

16:12 clojurebot: "([set] [set key] [set key & ks]); disj[oin]. Returns a new set of the same (hashed/sorted) type, that does not contain key(s)."

16:12 justin_smith: SagiCZ1: maybe you want clojure.set/difference

16:12 llasram: SagiCZ1: Try (apply disj ...)

16:12 noonian: SagiCZ1: because you are trying to remove an element which *is* a set

16:12 justin_smith: or that

16:13 SagiCZ1: oh i see.. thanks

16:17 TEttinger: ,(apply disj #{:A :B :D :W} #{:D :W :M})

16:17 clojurebot: #{:A :B}

16:17 SagiCZ1: TEttinger: yeah, i used that

16:17 TEttinger: cool

16:20 mr_rm: (disj #{:A :B :D :W} :D :W :M)

16:20 ,(disj #{:A :B :D :W} :D :W :M)

16:20 clojurebot: #{:A :B}

16:20 mr_rm: you are supposed to supply 1 or more keys after the set

16:20 EvanR: SagiCZ1: drawing markers are regular intervals comes up a lot when drawing guis, its easy with integer arithmetic. i just realized all that stuff has not much to do with time ;)

16:22 SagiCZ1: EvanR: i realized the formula is really elementary math, i hope i would be able to come up with that if i focused on unix time... yeah im glad there is incanter so i won't be drawing any ticks on axises by hand

16:30 success: can I not use println with recur?

16:30 SagiCZ1: success: how would you want to use it? println returns nil btw

16:32 success: if (cond) ((println val) (recur (+ val 1))) (println "done"))

16:32 justin_smith: success: you have an extra set of parens

16:32 amalloy: success: () is not a grouping construct; it calls functions

16:32 justin_smith: otherwise it looks decent

16:32 maybe you want (do ...)

16:32 SagiCZ1: try this (if (cond) (println val) (recur (+ val 1)) (println "done"))

16:33 justin_smith: depends if it should print before every recur, it's ambiguous

16:33 amalloy: SagiCZ1: no. (if cond (do (println val) (recur (inc val))) (println "done"))

16:34 yes, i suppose SagiCZ1's is a possible interpretation. it seems unlikely to me, but it's not impossible

16:34 SagiCZ1: sorry, i meant it amalloy's way

16:37 success: http://lpaste.net/113712

16:37 the println i is never printed

16:37 and then i get a nullpointerexception

16:37 http://lpaste.net/113712

16:38 amalloy: success: the NPE is because main is trying to use () for grouping again

16:39 dbasch: success: you’re calling the value of (println …) which is nil

16:39 actually run-thread

16:39 no, println on run-thread

16:39 (nil (run-thread))

16:40 success: so how should I do?

16:40 dbasch: success: why do you have that ( on line 25?

16:42 success: Ok that got rid of the nullpointer

16:42 but the value of i is never written

16:43 dbasch: success: you never increment i

16:43 noonian: success: thats because in thread-loop, you only recur if i equals 10, so i never is 10 and you just print done

16:44 success: hehe oops

16:44 now it works

16:44 dbasch: success: btw, you want dotimes in that situation

16:50 sdegutis: Are there any functionality in Clojure that can't be performed reliably when you deploy the app as an uberjar?

16:51 nestastubbs: reliably?

16:51 not sur what that means

16:51 crashes?

16:51 Glenjamin: you can't set jvm opts via project.clj

16:51 nestastubbs: you have to make sure you access resources and not files

16:52 noonian: thats the biggest thing i've ran into

16:52 borkdude: sdegutis logging to a directory outside resources

16:53 just logging, to a configurable directory that is

16:54 Glenjamin: stdout 4 life

16:54 success: so how is STM better than locking? you cant have deadlocks?

16:55 SagiCZ1: success: there are no locks

16:56 sdegutis: When I asked that question, I had dynamic features in mind.

16:56 justin_smith: success: it can be faster, because in the common case there is no concurrent change so little overhead

16:56 sdegutis: Such as finding namespaces dynamically at runtime via constructed strings and loading them.

16:56 I am very fond of the convention-over-configuration approach and find it to be very senseful, thus I wish to applicate it to my website.

16:56 llasram: sdegutis: That will work fine as long as the namespace source is actually there

16:56 sdegutis: OTOH, ewwwwwww

16:57 success: justin_smith, you mean that most of the time when you use locks there will be very few times where it will actually block another thread but it still locks?

16:57 sdegutis: llasram: I too once preferred explicit-over-implicit as the Clojure community favors.

16:57 llasram: But over time, though, I have seen the merit in not writing nearly so much code.

16:57 success: is acquiring a lock expensive? isnt it just reading a bit or two?

16:58 justin_smith: success: a write that can be seen by other threads is expensive, the fewer of them the better

16:59 sdegutis: ,(def transdeuce transduce)

16:59 clojurebot: #'sandbox/transdeuce

16:59 justin_smith: success: with a ref, you read, optimistically perform the calculation, compare, (set or retry) - there is only one cross thread visible write

16:59 dbasch: success: if you’re asking that question, you may want to read about locks http://en.wikipedia.org/wiki/Lock_(computer_science)

17:00 sdegutis: ,(transdeuce (comp (filter odd?) (map inc)) + (range 10))

17:00 clojurebot: 30

17:01 sdegutis: From an API point of view, I don't see why (transduce) isn't just (reduce).

17:01 Glenjamin: (doc transduce)

17:01 clojurebot: "([xform f coll] [xform f init coll]); reduce with a transformation of f (xf). If init is not supplied, (f) will be called to produce it. f should be a reducing step function that accepts both 1 and 2 arguments, if it accepts only 2 you can add the arity-1 with 'completing'. Returns the result of applying (the transformed) xf to init and the first item in coll, then applying xf to that result and the 2nd item, etc. If

17:02 Glenjamin: sounds like reduce :s

17:02 justin_smith: except for the xform arg

17:02 Bronsa: sdegutis: there's no "transducer" type, reduce wouldn't be able to understand whether it had to act like transduce or like reduce

17:02 sdegutis: Ok.

17:05 SagiCZ1: is something wrong with

17:05 ,(doall (concat (conj [1 2 3 4] 42) [99 101]))

17:05 ?? can it do anything unexpectd? like not adding the [99 101] coll for some reason?

17:05 clojurebot: (1 2 3 4 42 ...)

17:05 SagiCZ1: ,(doall (concat (conj [] 42) [99 101]))

17:05 clojurebot: (42 99 101)

17:07 noonian: ,(doc concat)

17:07 clojurebot: "([] [x] [x y] [x y & zs]); Returns a lazy seq representing the concatenation of the elements in the supplied colls."

17:07 noonian: SagiCZ1: you don't need the doall unless you are printing it or something

17:08 you don't need to worry about lazy seqs losing data if thats what you are asking

17:09 SagiCZ1: noonian: i need the doall, because this call is in a recur and i was getting a stack overflow without it.. i guess the lazinnes was chaining and then tried to explode it in the end..... i found my mistake though, it was something else, thanks

17:10 amalloy: SagiCZ1: just use into instead of concat, and then the doall problem never arises

17:10 SagiCZ1: amalloy: cool, forgot about into

17:11 Bronsa: amalloy: gah I suck at regex

17:11 SagiCZ1: amalloy: into is also 6 times faster than doall concat

17:12 EvanR: gotta love constant factor speed up ;)

17:13 amalloy: Bronsa: do you know about the ?x flag? it can help you organize your thoughts a bit, by adding whitespace and comments to hairy regexes

17:14 eg, https://github.com/Factual/drake/blob/develop/src/drake/core.clj#L34-L43

17:14 Bronsa: ah, nice

17:20 amalloy: i forget how you actually include a \space character in ?x mode, actually. i wonder if it's just `\ `

17:20 Glenjamin: [ ] ?

17:21 amalloy: ,(re-find #"(?x)[ ]" " ")

17:21 clojurebot: #<SecurityException java.lang.SecurityException: denied>

17:21 Glenjamin: what

17:21 amalloy: WHAT

17:21 &(re-find #"(?x)[ ]" " ")

17:21 lazybot: java.util.regex.PatternSyntaxException: Unclosed character class near index 6(?x)[ ] ^

17:21 amalloy: &(re-find #"(?x)" " ")

17:21 EvanR: regex security you know

17:21 lazybot: ⇒ ""

17:21 amalloy: oops

17:21 Glenjamin: i guess it's not [ ]

17:21 amalloy: &(re-find #"(?x)\ " " ")

17:21 lazybot: ⇒ " "

17:22 amalloy: Glenjamin: no, that would be no good. it's supposed to ignore whitespace so you can put it in whenever you want

17:23 Bronsa: arrdem: FYI not all dynamic Vars have :dynamic true :/

17:23 ,(remove (comp :dynamic meta) (filter #(and (var? %) (.isDynamic %)) (vals (ns-map *ns*))))

17:23 clojurebot: (#'clojure.core/*source-path* #'clojure.core/*command-line-args* #'clojure.core/*read-eval* #'clojure.core/*file* #'clojure.core/*use-context-classloader* ...)

17:24 TimMc: Are those the early ones in core?

17:24 arrdem: Bronsa: I'll take a patch :P doing testing rn

17:24 Bronsa: TimMc: I believe those are the ones set as dynamic in Compiler.java or RT.java, I don't remember

17:25 arrdem: trying to coordinate three artifacts into simultaneous releases...

17:26 TimMc: ,(filter #(and (var? %) (not (.isDynamic %)) (:dynamic (meta %))) (vals (ns-map *ns*)))

17:26 clojurebot: ()

17:27 Bronsa: TimMc: :dynamic implies .isDynamic, it's the opposite that's not true

17:28 amalloy: Bronsa: well, you can go the other way as well, by altering the metadata to have dynamic after compilng the var as not-dynamic

17:28 i don't know if that happens in clojure.core, but i've definitely seen people make that mistake

17:28 success: why is thread 1 only printing stuff? http://lpaste.net/113717

17:29 Bronsa: amalloy: you mean like (def a 1) (defn x [] a) (alter-meta! #'a assoc :dynamic true) ?

17:29 amalloy: Bronsa: yeah

17:29 Bronsa: ah, I guess that's easy to do with declare

17:30 justin_smith: success: the argument to Thread should be callable

17:31 arrdem: fuck yeah lein-grim totally works from 0.1.0 on Clojars

17:31 justin_smith: success: thread-loop is callable, but (thread-loop) does not return a callable I don't think

17:31 Bronsa: uhm, declare might not be problematic after all

17:31 arrdem: okay. Bronsa. you were telling me I'm wrong.

17:31 justin_smith: success: similarly with calling thread-1 with an arg

17:31 Bronsa: arrdem: was I?

17:31 arrdem: something dynamic vars...

17:31 Bronsa: arrdem: ah, pr incoming

17:32 justin_smith: success: so what is happening is that clojure runs your funciton - and the return value of that function is passed to Thread as its constructor argument

17:32 and I think you just want to pass the function itself as the constructor of the thread

17:33 in the case of (thread-1 r) #(thread-1 r) is a zero argument function that should do what you want

17:33 ,'#(thread-1 r)

17:33 clojurebot: (fn* [] (thread-1 r))

17:34 Bronsa: arrdem: let me know if you want different indentation

17:34 arrdem: Bronsa: that makes no functional change.

17:35 well unless you have a dynamic var with a fn value..

17:35 fine

17:35 Bronsa: arrdem: I have no idea what that code is used for, feel free to reject the PR if it's useless :P

17:36 arrdem: Bronsa: it may be functionally dead code :P

17:36 success: justin_smith, ty that worked

17:37 Glenjamin: is there a good way to remove a single item from a vector?

17:37 SagiCZ1: what function would write datastructures to a file, so i could later load them back?

17:37 postpunkjustin: By value or index?

17:37 Bronsa: amalloy: altering :dynamic meta should still make isDynamic return true though, it's just that compiled code won't use it as a dynamic var

17:38 SagiCZ1: (some-write-foo {:a 0 :b 1} "filepath") --- > (def m (load "filepath"))

17:38 Glenjamin: by index ideally

17:39 justin_smith: success: np

17:39 SagiCZ1: (spit "some-file.edn" (pr-str data))

17:39 SagiCZ1: justin_smith: and the loading?

17:40 justin_smith: (clojure.edn/read-string (slurp "some-file.edn"))

17:40 SagiCZ1: justin_smith: thank you

17:40 justin_smith: np

17:40 amalloy: Glenjamin: best solution is time-travel back to before you decided to use vectors

17:40 since they are not good at this

17:40 Glenjamin: i'm just pondering that myself

17:41 this is for a todomvc sample for a cljs workshop

17:41 so trying to keep things simple :s

17:41 amalloy: although, really, any time you use indexes in clojure is a giant honkin' code smell

17:41 Glenjamin: if i use a map/sorted-map then i have to generate keys

17:42 TEttinger: ordered map?

17:42 uses a lib, but hey

17:43 Glenjamin: i'd still need a key though

17:43 i need append, random-access modify & random-access delete

17:44 so map + key is probably sensible

17:44 EvanR: you dont have a key?

17:44 is this some sort of queue of values

17:44 Glenjamin: its this: http://todomvc.com/examples/react/#/

17:44 EvanR: possible dups

17:45 {blake}: I'm trying to figure out how hiccup-bootstrap's wrap-bootstrap and include-bootstrap routines manage to point to a particular version of bootstrap (2.2.2) that I don't seem to actually have.

17:45 I presume they must be pointing to somewhere on that Internet the kids are all hopped up on, but I can't figger it out.

17:45 EvanR: Glenjamin: so these todos, they are just strings. but surely theres some sort of key associated with them in this framework?

17:46 Glenjamin: i can make one, but there's nothing intrinsic, it's just a client demo

17:46 EvanR: ok

17:46 Glenjamin: i suppose in a server-driven app there'd be an autoinc, so i should do that

17:47 {blake}: What's especially weird is that hiccup-bootstrap-3 ALSO seems to point to 2.2.2, which makes me think that it must be something I've put in somewhere.

17:47 EvanR: and i would imagine a list of todos is... a list. but clojure may have its own sensibilities here. literally lists seem to be unpopular

17:48 Glenjamin: list would work, but edit/remove is then O(n), which implies lists aren't a great fit

17:48 EvanR: theres the presentation and the data storage, among others. they dont all have to be the same

17:50 SagiCZ1: justin_smith: i am getting Underadable form exception when trying to read the file

17:50 justin_smith: SagiCZ1: you probably put objects in the form that are not valid edn

17:50 Glenjamin: bah, now i need fmap

17:50 justin_smith: SagiCZ1: you may want to filter and turn unprintable objects into a placeholder?

17:50 SagiCZ1: some things just can't be read in by the clojure reader

17:50 SagiCZ1: justin_smith: oh i totally did.. joda timestamp object cant be serialized like this

17:50 amalloy: Glenjamin: eh? when are you mapping over a bunch of todos?

17:51 Glenjamin: tick-all

17:51 justin_smith: SagiCZ1: right, but a java.util.Date can be

17:51 SagiCZ1: cool

17:51 justin_smith: SagiCZ1: so you may want to convert before / after saving

17:51 Glenjamin: todos are apparently the worst data-structure

17:51 SagiCZ1: thanks, i could do that

17:51 justin_smith: Glenjamin: clearly a todo should be a prioqueue

17:51 s/todo/todo-list

17:52 EvanR: do you have to update the priority when inserting ?

17:52 SagiCZ1: justin_smith: btw is there a way to dynamicly find out if the object is unprintable?

17:52 EvanR: on a lot of elements?

17:53 Glenjamin: (defn fmap [f m] (reduce-kv (fn [k v] [k (f v)]) m m)) ; is that reasonable?

17:54 justin_smith: SagiCZ1: (try (read-string (prn x)) true (catch Exception _ false))

17:54 which is terrible because exceptions should not be control flow

17:54 but I can't think of any other reliable way to do it?

17:55 EvanR: check if it satisfies the printable interface

17:55 cespare: How can I detect whether something is a function for the purposes of multimethod dispatch?

17:56 noonian: cespare: you can use the fn? and ifn? functions, i'm not sure how that applies to multimethod dispatch

17:57 Bronsa: fn? is not that useful

17:58 justin_smith: EvanR: which interface is that?

17:58 cespare: can someone direct me to the docs for fn?

17:58 it's not really googleable

17:58 EvanR: justin_smith: yeah i dont know

17:58 noonian: ,(doc fn?)

17:58 clojurebot: "([x]); Returns true if x implements Fn, i.e. is an object created via fn."

17:58 noonian: ,(doc ifn?)

17:58 clojurebot: "([x]); Returns true if x implements IFn. Note that many data structures (e.g. sets and maps) implement IFn"

17:59 EvanR: Glenjamin: for insertion into a long list there is the finger tree based list, though im not sure if it applies to however your framework does lists

18:01 justin_smith: is there a way to check if a multimethod has an impl for a specific arg?

18:01 the thing wanted is the print-dup multimethod

18:01 amalloy: justin_smith: kinda. there's get-method, which usually turns out not to be what you want

18:03 justin_smith: (get-method print-dup java.util.Date)

18:03 ,(get-method print-dup java.util.Date)

18:03 clojurebot: #<instant$fn__6393 clojure.instant$fn__6393@5a311d>

18:03 justin_smith: ,(get-method print-dup Object

18:03 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

18:03 justin_smith: ,(get-method print-dup Object)

18:03 clojurebot: nil

18:03 justin_smith: looks good!

18:04 Glenjamin: in case anyone was wondering, that was not a correct implementation of fmap

18:04 justin_smith: ,(defn is-readable [x] (or (nil? x) (boolean (get-method print-dup (class x)))))

18:04 clojurebot: #'sandbox/is-readable

18:04 amalloy: haha, no, i guess it wasn't, was it, Glenjamin

18:04 justin_smith: ,(is-readable (java.util.Date.))

18:04 clojurebot: true

18:04 amalloy: looked good, though

18:04 Glenjamin: very close

18:04 justin_smith: ,(is-readable (Object.))

18:04 clojurebot: false

18:04 justin_smith: ,(is-readable 1)

18:04 clojurebot: true

18:05 justin_smith: ,(is-readable {)

18:05 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

18:05 justin_smith: ,(is-readable {})

18:05 clojurebot: true

18:05 Glenjamin: somewhere between the (reduce-kv) and the (into) version

18:05 justin_smith: EvanR: looks like the above def for is-readable is the right thing

18:05 amalloy: justin_smith: you're assuming that printable things are also readable? that's questionable

18:05 justin_smith: amalloy: print-dupable

18:05 that's the point of print-dup

18:06 EvanR: justin_smith: wasnt it "is printable" ?

18:06 what is "fmap" ?

18:06 justin_smith: EvanR: anything can be printed, we want the things that can be read in again from a pr form

18:06 Glenjamin: (defn fmap [f m] "Given a map `m`, apply `f` to each value, maintaining keys" (reduce-kv (fn [acc k v] (assoc acc k (f v))) m m))

18:06 ,(defn fmap [f m] "Given a map `m`, apply `f` to each value, maintaining keys" (reduce-kv (fn [acc k v] (assoc acc k (f v))) m m))

18:06 clojurebot: #'sandbox/fmap

18:07 amalloy: mmmm, print-dup is very rarely used, justin_smith

18:07 usually it's just print-method

18:07 Glenjamin: (fmap inc {:a 1 :B 2})

18:07 ,(fmap inc {:a 1 :B 2})

18:07 justin_smith: amalloy: it's the basis for prn

18:07 clojurebot: {:B 3, :a 2}

18:07 amalloy: justin_smith: no it's not

18:07 justin_smith: amalloy: he was talking about using prn to a file

18:07 $source clojure.core/pr-on

18:07 lazybot: clojure.core/pr-on is http://is.gd/jApwbc

18:08 amalloy: right. and *print-dup* is ~never set to true, so it always goes to print-method

18:08 justin_smith: oh

18:09 amalloy: ,(binding [*print-dup* true] (prn [1 2 3]))

18:09 clojurebot: [1 2 3]\n

18:09 amalloy: ,(binding [*print-dup* true] (prn {1 2}))

18:09 clojurebot: #=(clojure.lang.PersistentArrayMap/create {1 2})\n

18:09 justin_smith: ahh, OK

18:09 amalloy: some of these #= methods emitted by print-dup don't even work anymore. the code has moved on, methods in clojure.lang have been renamed, but the print-methods remain

18:10 justin_smith: thanks, so I guess there is no good heuristic for whether a value could be read in after prn

18:10 amalloy: justin_smith: no, not really. i mean, print-dup isn't a terrible guess

18:11 dbasch: justin_smith: I don’t have all the context, but why would you want to “serialize” via prn?

18:12 justin_smith: dbasch: to output a data structure as edn

18:12 amalloy: dbasch: it's kinda the default way to serialize stuff

18:13 dbasch: I usually serialize stuff via java objectoutputstream

18:13 amalloy: for srs?

18:13 dbasch: usually = the few times I needed to serialize huge maps

18:33 justin_smith: .*clojure-version*

18:33 anybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

18:33 justin_smith: WOO

18:33 lazybot working with clojure 1.7 and the updated irclj

18:33 without clojail failing

18:34 * justin_smith gives anybot a HUGE high-five.

18:34 justin_smith: @botsnack

18:34 anybot: justin_smith: Thanks! Om nom nom!!

18:34 arrdem: @botsmack

18:35 justin_smith: @guards

18:35 anybot: SEIZE HIM!

18:35 arrdem: @gourds

18:36 justin_smith: I think I haven't fixed and whitelisted the "silly" plugin yet

18:36 @bf ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.

18:36 anybot: {:ptr 6, :cells {6 10, 5 33, 4 87, 3 100, 2 72, 1 0, 0 0}}

18:36 [72 101 108 108 111 32 87 111 114 108 100 33 10]

18:36 Hello World!

18:37 justin_smith: (depending on definitions of silly)

18:37 arrdem: lols

18:37 amalloy: there's only one silly plugin?

18:37 justin_smith: amalloy: why of course!

18:38 amalloy: so I had some issues where refs were treated as associative (I think this is a clj version thing?) but clojail just worked

18:38 amalloy: justin_smith: refs treated as associative?

18:38 justin_smith: in lazybot's codebase

18:38 amalloy: you mean like, (get (ref 1) 0)?

18:39 justin_smith: like (get (ref {:a 0}) :a)

18:39 amalloy: i don't think that's worked in any version of clojure

18:39 justin_smith: or maybe something else entirely was going on...

18:39 yeah, probably

18:39 amalloy: it might just be a coincidence

18:39 like, lazybot does that, and it fails silently, but everything keeps working

18:39 justin_smith: I probably misunderstood the source of some bug

18:39 postpunkjustin: I've seen something like that work before with refs

18:39 It was weird and upsetting.

18:40 amalloy: @bf +[]

18:40 postpunkjustin: But it was definitely a ref pointing to a map that was being implicitly dereferenced

18:40 anybot: Execution timed out.

18:40 justin_smith: amalloy: it's here https://github.com/Raynes/lazybot/blob/master/src/lazybot/irc.clj#L19 irc is a ref

18:40 amalloy: aw, good boy, anybot. i wasn't sure if that was inside the timeout context

18:41 justin_smith: amalloy: it's *all* inside the timeout context :)

18:42 postpunkjustin: thanks for the validation - I was lost in the version update bugs when it happened

18:42 dbasch: @bf >++++++++++>>+<+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<]>.>[->[

18:42 <++>-[<++>-[<++>-[<++>-[<-------->>[-]++<-[<++>-]]]]]]<[>+<-]+>>]<<]

18:42 postpunkjustin: ,(let [foo (ref {:bar "baz"})] (foo :bar))

18:42 clojurebot: "baz"

18:42 Bronsa: justin_smith: look what you've done now

18:42 dbasch: @bf >++++++++++>>+<+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<]>.>[->[<++>-[<++>-[<++>-[<++>-[<-------->>[-]++<-[<++>-]]]]]]<[>+<-]+>>]<<]

18:42 justin_smith: dbasch: Caused by: java.lang.Exception: invalid commands: missing ]

18:42 haha

18:42 Bronsa: sorry

18:43 arrdem: lol

18:43 anybot: Execution timed out.

18:43 arrdem: Bronsa: hey man it's just fun with a stack machine :D

18:43 what to name a test artifact...

18:43 amalloy: justin_smith: what makes you think irc-map is a ref there? it should be the dereffed value

18:44 justin_smith: amalloy: it may be an incompatibility with what we got back from irclj now that I think about it

18:44 amalloy: but it's certainly rather muddy and i can believe the wrong thing might be happening

18:44 Bronsa: wtf refs are actually IFn like Var

18:44 TIL

18:44 dbasch: arrdem: cattiest fart

18:44 postpunkjustin: Yeah, I have no idea why refs implement IFn but atoms do not

18:44 justin_smith: arrdem: the ark of foo

18:45 Bronsa: postpunkjustin: I wouldn't wish atoms implemented IFn tbh

18:45 arrdem: heh

18:46 postpunkjustin: I agree! But I think the inconsistency is even worse.

18:46 justin_smith: &(let [a (ref {:a 0})] (a :a))

18:46 postpunkjustin: I hate this: ,(let [foo (ref {:bar "baz"})] (foo :bar))

18:46 lazybot: ⇒ 0

18:46 Bronsa: well I guess I'll continue to ignore refs as I've done til now

18:46 justin_smith: postpunkjustin: jynx

18:46 postpunkjustin: haha

18:46 amalloy: Raynes: we should remove the brainfuck plugin. that implementation from rosetta code doesn't look super good

18:46 postpunkjustin: but yours worked. I'm not super familiar with this lazybot thing.

18:46 Bronsa: yeah well, they are IFn but not ILookup or IKeywordLookup or whatever the interface

18:47 Raynes: amalloy: We should remove like all of them

18:47 justin_smith: postpunkjustin: ##(println "hi")

18:47 anybot: ⇒ hi nil

18:47 lazybot: ⇒ hi nil

18:47 justin_smith: haha

18:47 Bronsa: lol

18:47 bbloom_: amalloy: too bad you can't have a befunge plugin. would need 2D irc input

18:47 amalloy: bbloom_: i would rather have a snusp interpreter. more fun than befunge

18:48 arrdem: OOH QUICK DOES anybot ignore lazybot?

18:48 bbloom_: http://esolangs.org/wiki/SNUSP

18:48 craziness ^^ amalloy

18:48 justin_smith: amalloy: there is a syntax extension to haskell that looks remarkably like snusp

18:48 haha

18:48 arrdem: ##(println "##(println :foo)")

18:48 anybot: ⇒ :foo nil

18:48 lazybot: ⇒ :foo nil

18:48 arrdem: damnit

18:49 amalloy: bbloom_: i know. https://github.com/amalloy/clusp

18:49 arrdem: well played bots, well played

18:49 bbloom_: amalloy: haha weee

18:49 justin_smith: arrdem: there may be some trick you could pull with int / char conversion and building the trigger string

18:49 amalloy: wrote that on the plane back from the 2011 conj, iirc

18:49 justin_smith: or even just str to fool the regex

18:49 joshuafcole: justin_smith: http://scrambledeggsontoast.github.io/2014/09/28/needle-announce/ ?

18:49 bbloom_: amalloy: a befunge interpreter was one of my first C programs

18:50 arrdem: ##(println \# \# "(println :foo)")

18:50 anybot: ⇒ # # (println :foo) nil

18:50 lazybot: ⇒ # # (println :foo) nil

18:50 arrdem: ##(println (str \# \# "(println :foo)"))

18:50 anybot: ⇒ ##(println :foo) nil

18:50 lazybot: ⇒ ##(println :foo) nil

18:50 anybot: ⇒ :foo nil

18:50 lazybot: ⇒ :foo nil

18:50 arrdem: HAHA

18:50 I wonder if you could quine that..

18:50 justin_smith: joshuafcole: yeah, that is the one

18:51 joshuafcole: Looked fun to play with, though I imagine refactoring it in a text-based interface might not be. :)

18:51 Raynes: arrdem: I will hurt you physically.

18:51 justin_smith: joshuafcole: that's the kind of code where you want a point-and-click editor for sure

18:51 arrdem: Raynes: if you fly out to Texas to do so, beer's on me

18:51 Raynes: That's illegal.

18:51 I'm calling the cops.

18:52 arrdem: <3 Raynes

18:52 justin_smith: Raynes: ##(println *clojure-version*)

18:52 anybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier alpha1} nil

18:52 Raynes: <3

18:52 joshuafcole: He's got you there, this chat room is logged and you just offered alcohol to a minor.

18:52 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} nil

18:52 Raynes: Literally got the FBI on the line right now

18:52 amalloy: ##(println (str \# \# "(println :foo)"))

18:52 anybot: ⇒ ##(println :foo) nil

18:52 lazybot: ⇒ ##(println :foo) nil

18:52 Raynes: Also, I'm not a minor.

18:52 anybot: ⇒ :foo nil

18:52 * arrdem waves to the NSA & other feds

18:52 Raynes: Just (dec 21)

18:52 amalloy: arrdem: lazybot ignores anybot now

18:52 you were too slow

18:52 justin_smith: heh

18:52 arrdem: amalloy: lol

18:53 amalloy: I have yet to write my own quine anyway 's k

18:53 amalloy: $logout

18:53 lazybot: You've been logged out.

18:53 technomancy: incf

18:53 oops, wrong window

18:53 * technomancy backs away quietly

18:54 justin_smith: really, a bot should probably have an ignore on #".*bot$"

18:54 technomancy: you didn't see that

18:54 amalloy: justin_smith: that sounds like it would lead to a scunthorpe problem

18:54 mwfogleman: anyone doing exercism in clojure?

18:55 justin_smith: mwfogleman: I've had some fun on 4clojure, but not actively doing it now

18:55 oh, exirorcisms, I misread

18:55 mwfogleman: justin_smith: no worries. that's http://exercism.io/

18:56 i've done a bunch of 4clojure, although i too have stopped for now.

18:56 postpunkjustin: I've done some exercism problems

18:56 It was fun, but there's not much activity there on the Clojure side, which makes it kind of sad

18:56 amalloy: mwfogleman: the fact that i can't see anything useful on their website without logging in means i will just never do anything there

18:57 it's great that they support github login, i was very pleased to see that. but it's just user-unfriendly to make me log in right away

18:57 dbasch: amalloy: it says that you can check out the command line client if you don’t want to log in

18:57 amalloy: yes, i saw that too

18:58 but that's about ninety times harder than clicking a link

18:58 mwfogleman: amalloy: yes, their ui is pretty cruddy. still, it's already a great companion to 4clojure (implicit hat tip)

18:58 dbasch: amalloy: I’d expect the exercises to be 100x harder than checking out the cli

18:58 or I’d be disappointed

18:58 amalloy: that's okay. if i go to that site it's because i *want* to do exercises, or at least to read them

18:59 i don't *want* to clone some github project and run code i know nothing about

18:59 mwfogleman: amalloy: they are careful to prevent you from looking at code for problems you haven't solved yet

18:59 **solutions to

18:59 dbasch: amalloy: also you can donate money without logging in

18:59 amalloy: hah

19:00 mwfogleman: anyway, i just asked because i'm working on the beer problem and was wondering if anyone had finished it.

19:00 dbasch: mwfogleman: you have a beer problem?

19:00 amalloy: the problem of someone having finished your beer?

19:00 mwfogleman: i knew that was coming. generating x-y verses of the song 99 bottles of beer.

19:00 e.g. 99 to 0

19:02 klyed2: ...but don't you go to the store and buy some more?

19:02 anybot: java.lang.RuntimeException: Unable to resolve symbol: ..but in this context

19:02 amalloy: go home, anybot, you are drunk

19:02 mwfogleman: :D

19:02 amalloy: srsly though justin_smith, i'd rather you didn't bring in-development versions of lazybot in here except for the briefest of demos. i test mine out in #4clojure or #()

19:02 justin_smith: OK

19:03 amalloy: thanks. the default config conflicts with lazybot and clojurebot bindings, as you saw

19:03 justin_smith: amalloy: it was going to be a brief demo and then the whole part the channel part kind of slipped my mind

19:04 amalloy: yeah

19:04 i forget why now, but i have my lazybot instance set its nick to buttered-toast

19:05 dbasch: amalloy: so that it lands butter-side down?

19:05 justin_smith: I don't really plan on running it long term, really this is about updating the clojure version / irclj version so lazybot is better at staying online

19:06 amalloy: yeah

19:06 dbasch: amalloy: semi-relevant https://www.youtube.com/watch?v=Z8yW5cyXXRc

19:09 amalloy: ugh, i left my lazybot-dev configuration at my last job

19:10 justin_smith: I bet they were all like "anybody lose a lazybot?" and then nobody claimed it and then it ended up in the drawer with the left-behind tupperware

19:11 every workplace has that drawer, right?

19:11 $dict hello

19:11 lazybot: justin_smith: interjection: Used to greet someone, answer the telephone, or express surprise.

19:11 justin_smith: TIL

19:12 amalloy: i'm surprised you managed to get by for so long without knowing about "hello"

19:12 justin_smith: $dict foo

19:12 lazybot: justin_smith: noun: A metasyntactic variable used to represent an unspecified entity. If part of a series of such entities, it is often the first in the series, and followed immediately by bar.

19:13 dbasch: $dict dict

19:13 lazybot: dbasch: noun: A saying; a dictum.

19:13 joshuafcole: I think lazybot wins this round

19:13 dbasch: $dict dictum

19:13 lazybot: dbasch: noun: An authoritative, often formal pronouncement: "He cites Augustine's dictum that 'If you understand it, it is not God'” ( Joseph Sobran).

19:13 dbasch: lazybot has spoken

19:14 justin_smith: $should I keep demonstrating random lazybot commands?

19:14 lazybot: justin_smith: Very doubtful.

19:14 justin_smith: OK

19:15 amalloy: justin_smith: i like the unix-jokes

19:16 justin_smith: especially because they are easy to find accidentally

19:16 amalloy: usually it's just echo and ls that get triggered in here

19:16 but the one time someone actually typed "mutt"...that was glorious

19:17 joshuafcole: Built in unix jokes?

19:17 {blake}: OK, so, it looks like both bootstrap and bootstrap-3 link to a particular web version of bootstrap rather than a local one.

19:17 joshuafcole: Time to get this running in #lighttable so I have something to banter with

19:17 {blake}: Though I still don't see where.

19:18 Oh, wait, they include their own versions which are hidden. Duh.

19:18 Crap.

19:19 I wonder how disastrous it would be to shoehorn 3.3 in there.

19:20 justin_smith: $will ##(do :it :yes) evaluate?

19:20 lazybot: justin_smith: It is certain.

19:20 ⇒ :yes

19:26 TEttinger: $will ##(doto (JFrame. "Minor Annoyance") (.setSize 400 300) (.setVisible true)) spawn a window?

19:26 lazybot: TEttinger: My sources say no.

19:26 java.lang.IllegalArgumentException: Unable to resolve classname: JFrame

19:26 TEttinger: $will ##(doto (javax.swing.JFrame. "Minor Annoyance") (.setSize 400 300) (.setVisible true)) spawn a window?

19:26 lazybot: TEttinger: Outlook good.

19:26 java.awt.HeadlessException: No X11 DISPLAY variable was set, but this program performed an operation which requires it.

19:27 TEttinger: ha

19:27 joshuafcole: it was doing so well

19:27 justin_smith: nice try

19:27 TEttinger: it spawned one on my lapserver before I fixed the vulnerability using clojail

19:27 I can send you the changes I made, if you want it to run on non-headless servers

19:30 justin_smith: TEttinger: just tried that, it did seem to create a jframe, but I don't see it anwhere

19:30 TEttinger: weird

19:30 it might have deleted it

19:30 justin_smith: https://www.refheap.com/92669

19:31 TEttinger: can you def, currently? like with clojurebot

19:31 justin_smith: nope, security exception

19:32 amalloy: that feature does exist in clojail, lazybot just doesn't enable it

19:32 justin_smith: TEttinger: it's on ##anyone if you want to poke at it, but that's where I am testing so expect banal spammy stuff in that room

19:32 (and frequent bot reboots, of course)

19:35 amalloy: do you recall what the "embedded" plugin does? I got a weird error when I try input based on trying to reverse engineer what the regex expects

19:36 amalloy: justin_smith: it's supposed to let you do commands like $will inline

19:37 like uh, $#will this work?#$, i dunno if it's enabled in lazybot

19:37 justin_smith: yeah, the version I have macroexpands to a form which calls second with two args and just stacktraces

19:38 ,(macroexpand '(->> x second (-> @bot :config :prepends first str) (assoc irc-map :message) registry/try-handle))

19:38 clojurebot: (registry/try-handle (assoc irc-map :message (-> (clojure.core/deref bot) :config :prepends first ...)))

19:39 amalloy: yeah. it looks broken

19:39 justin_smith: ,(macroexpand '(-> (clojure.core/deref bot) :config :prepends first str (second x)))

19:39 clojurebot: (second (str (first (:prepends (:config (clojure.core/deref bot))))) x)

19:39 amalloy: which is fine, nobody uses it or wants to

19:39 justin_smith: heh

19:43 $addfortune You would have inherited a larg sum, but the will was stored in mongodb.

19:43 lazybot: Fortune cookie eaten.

19:44 justin_smith: $fortune

19:44 lazybot: Difficulty at the beginning usually means ease at the end...except in bed

19:45 joshuafcole: Ah, good point lazybot

19:45 dbasch: justin_smith: but mongodb is a document store, it doesn’t get much more document-y than a will

19:45 joshuafcole: I think I'll write my next webserver in whitespace

19:46 justin_smith: dbasch: it was meant to be a bit of cleverness about "fortune" and the way the fortunes are stored

19:46 amalloy: justin_smith: s/larg/large, though

19:47 dbasch: justin_smith: :)

19:48 justin_smith: oops!

20:16 razum2um1: how can i insert macros-1 into another macros-2 expanding 1st with for 2nd' given body?

20:19 justin_smith: razum2um1: did you use a macro to construct that question?

20:20 dbasch: is this a meta question about the two previous questions?

20:20 justin_smith: razum2um1: can you rephrase that? I had a hard time parsing the question

20:21 razum2um1: justin_smith: https://gist.github.com/razum2um/16e285945288089dd07a

20:22 dbasch: razum2um1: why is the first one a macro?

20:24 razum2um1: dbasch: it's simplification, it's way longer ))

20:24 but the aim is the same, i want to have try-safe version of the m1

20:27 dbasch: razum2um1: post the whole code, because as it is there isn’t enough information

20:27 or at least a reproducible case

20:49 justin_smith: amalloy: Raynes: do you guys know anything about this socrates api in lazybot? lazybot.plugins.knowledge - did it ever work? where does one look for an api key? I'll keep moving on to check other plugins, but I am at a loss with that one

20:50 Raynes: It did work

20:50 amalloy: justin_smith: Raynes wrote that, i think. he probably committed his API key to github at least once

20:50 justin_smith: heh

20:50 Raynes: Die in a fire

20:50 I don't think I did write that one

20:50 Anyways

20:50 Don't worry about it

20:50 amalloy: "die in a fire" is probably his current password

20:50 Raynes: If it were it'd be in github somewhere by now.

20:50 justin_smith: Raynes: OK, just doing due dilligance before calling this done

20:51 TEttinger: hm, let's check this against lazybot

20:51 ,(doto (java.awt.Robot.) (.keyPress java.awt.event.KeyEvent/VK_CONTROL) (.keyPress java.awt.event.KeyEvent/VK_C) (.keyRelease java.awt.event.KeyEvent/VK_CONTROL))

20:51 clojurebot: #<CompilerException java.lang.ExceptionInInitializerError, compiling:(NO_SOURCE_PATH:0:0)>

20:52 amalloy: hm, weird. the current lazybot instance does have a username and password for $know, but when i ask him questions he just times out

20:52 TEttinger: ##(doto (java.awt.Robot.) (.keyPress java.awt.event.KeyEvent/VK_CONTROL) (.keyPress java.awt.event.KeyEvent/VK_C) (.keyRelease java.awt.event.KeyEvent/VK_CONTROL))

20:52 lazybot: java.lang.SecurityException: You tripped the alarm! clojail.testers.ClojailWrapper@474528f5 is bad!

20:53 TEttinger: nice

20:53 amalloy: $know who is the current president?

20:53 lazybot: Execution timed out.

20:54 hiredman: ~apropos president

20:54 clojurebot: President of Chile is a Presidential office. (http://www.freebase.com/view//m/0hqlf)

20:56 nestastubbs: confused by the state of clojure results, specifically "what has been most frustrating"

20:56 future staffing concerns?

20:56 language viable over long term?

20:57 availability of editors?

20:58 there is no shortage of hackers who want to learn clojure, and there are good ones out there too

20:58 I guess hiring QA, and support staff?

21:14 arrdem: nestastubbs: "good hackers" are not always cultural/budget fits :P

21:14 amalloy: nor are there a limitless supply of them

21:21 yedi: so what do yall think of boot

21:21 amalloy: seems good if your feet would otherwise get wet

21:23 dbasch: amalloy: but you’d need two, or exceptional hopping skills

21:24 yedi: -______-

21:25 dbasch: yedi: why the long face?

21:25 yedi: hahahhah aiight that gets a pass

21:25 amalloy: +b dbasch

21:31 reiddraper: i have a generator that produces a list of things, like integers, and then i'm fmapping a function over that generator, which just maps over those integers and inc's them all. however, i now want to insert an arbitrary letter after each number which is divisible by ten (silly simplification, not my actual generator)

21:31 i see how i could do this by switching from fmap to bind, and then reducing over the list with more calls to bind, most of which just terminate in return, but some of which use a generator for letters

21:33 but that seems like an awful lot of manual plumbing in the calls to bind. is there something like (sequence :: (Monad m) => [m a] -> m [a]), such that i can just mapcat over the list, returning N generators, and let sequence bind them together for me?

21:36 man, sequence is the first dang function in clojure.test.check.generators. but i didn't notice it because it's private

21:37 okay well thanks for writing it; consider this a feature request to expose it, i guess

21:40 kenrestivo: someone has written an alternative to lein? :-0

21:52 Raynes: kenrestivo: lol we did that once

21:54 We called it cack or cork or something like that

22:09 justin_smith: $max

22:09 lazybot: The most users ever in #clojure is 831

22:11 rpaulo: that's a lot of people

22:23 justin_smith: $metacritic movie alien-re-release

22:23 lazybot: I'm a little drunk. Can't find my keys.

23:21 dgellow: hi guys

23:22 is there a way to pprint from within a defrecord method ?

23:24 sm0ke: dgellow: using `pprint` directly has problems?

23:24 amalloy: dgellow: i mean, you just call pprint like you would anywhere. is there something you've tried that doesn't work?

23:25 sm0ke: dgellow: you would need to import it though

23:25 i think its only available in repl, not in core ##(pprint 1)

23:25 lazybot: java.lang.RuntimeException: Unable to resolve symbol: pprint in this context

23:25 dgellow: Yeah, i'm already using pprint but I cannot see any output

23:27 justin_smith: sm0ke: that's because you have to require or use pprint

23:27 gfredericks: dgellow: are you sure it's an issue with defrecord?

23:27 justin_smith: ,(use 'clojure.pprint)

23:27 clojurebot: nil

23:27 sm0ke: justin_smith: yes thats what it said

23:27 dgellow:

23:27 amalloy: my guess is your code is running on some other thread which doesn't have *out* bound to anything

23:28 sm0ke: or may be he is printing nil

23:28 dgellow: I'm using pprint. it works. But, when I'm using it from within a method implemented in a defrecord, I cannot see any output. I think there is something to do with the stdout ?

23:28 justin_smith: dgellow: is this running in a thread other than your top level repl thread?

23:29 dgellow: amalloy: How can I check that, as I cannot pprint *out* ?

23:29 gfredericks: (.println System/out ...) is one way

23:29 justin_smith: *out* is thread local

23:29 gfredericks: you can also do side-effecty things with atoms, for example

23:30 ,(def my-outs (atom [])) (then later) (swap! my-outs conj *out*)

23:30 clojurebot: #'sandbox/my-outs

23:31 sm0ke: dgellow: does normal `print` works?

23:33 dgellow: sm0ke: nop

23:34 sm0ke: dgellow: how about a `log/info` if you have it?

23:35 and for record reloading new changes into a running rep wont work

23:37 justin_smith: dgellow: you should be able to explicitly pass in or bind *out* (for example in the way gfredericks suggests, or make it an argument passed to the function) and then use (binding [*out* out-target] ...) or use the optional second arg (pprint val out-target)

23:38 sm0ke: i highly doubt the code is being reached at all, why would the stdout be not binded

23:38 justin_smith: sm0ke: it is common for it to be bound to a place you are not looking

23:38 especially in emacs, for example

23:39 and println / pprint don't use stdout, they use *out*, which is a dynamic var, these things act can unintuitively when you have threads

23:40 sm0ke: ,*out*

23:40 clojurebot: #<StringWriter >

23:41 sm0ke: yeah well it is better to use loggers, but if its simple enough case this should not happen

23:41 you are assuming he is using emacs and spwaning threads

23:42 justin_smith: emacs is an example - any env where you aren't directly in the owning console can have the same issue

23:43 and yes, I could be wrong, just suggesting a way to deal with it if that is the case

23:44 quizme: Is it possible to use defmethod to make clojure.data.json/write-str to know how to print clj-time.core/now ?

23:44 justin_smith: quizme: there is a protocol you can extend

23:44 quizme: or you can convert the value to a java.util.Date - it knows how to handle that iirc

23:45 quizme: justin_smith: ow... how do i do it by extending the protocol ?

23:46 justin_smith: https://github.com/dakrone/cheshire/blob/master/src/cheshire/generate.clj#L17

23:46 cheshire.generate.JSONable

23:46 has one method, to-json

23:47 there is a convenience function for that: https://github.com/dakrone/cheshire/blob/master/src/cheshire/generate.clj#L229

23:47 add-encoder

23:47 nestastubbs: oh, that reminds me

23:47 Anyone have a nice clj abstraction for a event based JSON parser?

23:48 kinda like SAX for JSON

23:48 the idea is to manipulate parts of a stream of json without having to parse it all into a clojure object

23:48 justin_smith: nestastubbs: cheshire can parse streams lazily

23:49 nestastubbs: lazily won't quite cut it here

23:49 justin_smith: parse-stream

23:49 OK

23:49 nestastubbs: I want to avoid consing massive objects

23:49 I eventually have to pass the entire stream thru, so lazy won't do it

23:49 sm0ke: nestastubbs: how do you define a `part` in json without actually parsing it?

23:50 nestastubbs: don't treat it as an object, treat is a a sequence of transition events

23:50 justin_smith: nestastubbs: tigris does stream-to-stream escaping https://github.com/dakrone/tigris

23:51 nestastubbs: objec_start, key, sep, value ... object_end ....

23:52 the idea is you pass thru the events (which have the original string attached to them

23:52 sm0ke: intriguing idea

23:52 nestastubbs: and only muck with the ones you want to change

23:52 so, if it's a key i want to filter out, I ditch that key event, and then the sep and value event after it...

23:52 sm0ke: but is still think you have parsd it already when you say "objec_start, key, sep, value ... object_end ...."

23:53 nestastubbs: that's a sequence of events, not a list itself

23:53 you ever used a SAX parser for XML?

23:53 it's like that

23:53 SAX parsers didn't produce ELEMENT objects

23:53 anyways, we throw around large JSON documents, I need one. I guess I'll write one

23:54 the cost of parsing, manipulating, and then re-JSONing is high

23:54 same reason why I don't use enlive for large HTML documents

23:54 use JSoup instead, way faster

23:54 sm0ke: yep i got that part but not quite convinced how you will get those events just by reading a json string

23:55 nestastubbs: by writing a parser?

23:55 sm0ke: nestastubbs: :D

23:55 doesnt that defeat the whole purpose

23:56 nestastubbs: well, I suppose it's really more of a lexer

23:56 haha

23:56 actually, a lexer would be sufficient

23:57 sm0ke: yep then a regex-seq should be good enough

23:57 nestastubbs: wonder if writing it in ragel would be performant

23:57 speaking of regex-seq...

23:58 re-seq would not be sufficient

Logging service provided by n01se.net