#clojure log - Nov 25 2014

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

0:06 kenrestivo: ah, the dark dot is use/used, the pale dot is transitively use/used

0:07 if the code is on github, i should submit a patch that shows that as a mouseover on those circles

0:07 bbloom_: do any former common-lispers know enough about how CL implementations handle line numbers? i'm curious where/how they store line numbers for stack traces w/o general purpose clojure-like metadata

0:08 kenrestivo: speaking of stacktraces, here's what youtube is showing: https://www.refheap.com/93921

0:08 it's not base64, apparently

0:09 bbloom_: could be url-safe base64

0:09 probably encrypted :-P

0:09 ggreer: they just changed + and / to - and _

0:09 and yes, it's encrypted

0:20 bbloom_: as best i can tell, line numbers are calculated from "code-location" on the "compiled-frame" structs -- seems that that's calculated from the program counter in the compiled code output, such that only compiled forms get line numbers

0:21 i guess if you eval some definition later, you either won't get a line number or it will be the location of the eval, not the place that produced the forms, since the objects themselves can't have metadata really

0:21 interesting....

0:21 sorry, i meant to add: that's in SBCL

0:22 which google suggested has line numbers in backtraces, unlike many other CL impls :-)

4:13 agumonkhost: cglv: the issue with remote lein repl was that by default lein listens to 127.0.0.1, so one needs to lein repl :host 0.0.0.0 :port ... to enable remoting

4:13 rritoch: Does clojure.core/require automatically reload sources if the source code has been modified since it was last loaded (clojur.core/load)?

4:14 SagiCZ1: rritoch: no, you have to call require again

4:14 or otherwise reload the file using your repl tools

4:15 agumonkhost: cglv: pretty much 'duh' but alas. this was offered to me by the RTFM association.

4:15 rritoch: SagiCZ1: But every time you call require it checks if the file has been modified?

4:17 SagiCZ1: Currently I'm using ns-find & load to load namespaces in this particular case, but I'm looking for the easiest solution to reload if the file has been modified since it was last loaded.

4:18 ucb: it seems like cider comes with a set of keybindings for reloading namespaces and their dependencies

4:18 I've pressed them by chance (trying to switch buffers, etc.) but never really found what they are

4:18 anybody knows what they are? ^_^

4:21 rritoch: SagiCZ1: Ex. (if (not (find-ns 'my.namespace)) (load "my.namespace")) but I'm looking for something that will also re-load the namespace if the sources have been modified since it was last loaded.

4:25 SagiCZ1: rritoch: i see, i am not sure how to do that from the program itself, but other people might know

4:32 mavbozo: e

4:41 agumonkhost: hey back

4:42 with this project.clj http://pastebin.com/y4wCxqk0 , lein deps fetching core.async (found in ~/.m2/*), yet (require '[core.async ...]) fails with "FileNotFoundException Could not locate core/async__init.class or core/async.clj on classpath ..."

4:46 clgv: agumonkhost: the full namespace is "clojure.core.async" right?

4:46 yeah it is, I checked

4:47 agumonkhost: hi clgv IIRC I tried both, time to try again

4:54 clgv: ok, wrong path for running lein, thus no deps, thus no async

4:54 thanks

4:55 clgv: yeah you must be within the project ;)

5:10 agumonkhost: clgv: I'm ashamed of my own nooberie here

5:10 clgv: agumonkhost: no problem, now you will remember it better ;)

6:13 the_frey: has anybody used the JavaMail mboxstore in a clojure project?

6:19 clgv: how do I specify which protocols jetty can use and must not use? is there an option in "ring"?

6:20 weavejester: clgv: By default the Jetty adapter will just use HTTP unless you supply a keystore

6:20 clgv: weavejester: yeah, I already have it running HTTPS

6:20 weavejester: clgv: I tend to use nginx to handle SSL, however.

6:20 clgv: weavejester: that is not an option in that scenario.

6:21 weavejester: clgv: If you have it running HTTPS, I'm not sure I understand your question.

6:21 clgv: weavejester: I want to configure which protocols are allowed, e.g. forbid SSLv3 and previous versions

6:22 weavejester: clgv: Oh I see

6:22 clgv: That might require some Jetty black magic :)

6:23 clgv: weavejester: ok, I gotta check the jetty api

6:23 weavejester: clgv: 'fraid so

7:00 ordnungswidrig: clgv. http://wiki.eclipse.org/Jetty/Howto/Configure_SSL is pretty complete, I think

7:01 clgv: ordnungswidrig: thanks :)

7:02 ordnungswidrig: though I need to configure it via API for my embedded jetty

7:03 ordnungswidrig: The XML maps directly to the API, IIRC

7:03 In the beginning jetty could only be configured by the API

7:08 pandeiro: if i have portions of my project.clj that are repeated in different sections, can i (def repeated-part [...]) and then reference that instead of repeating the vector in different places?

7:10 hellofunk: does core.logic recognize basic math as part of unification for doing things like solving a system of equations?

7:13 ordnungswidrig: pandeiro: you can do this with profiles to some extend

7:14 pandeiro: ordnungswidrig: stick it in a profile, then make an alias that uses that profile to do some task? that sort of thing?

7:16 ordnungswidrig: more like thath: https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md#composite-profiles

7:19 pandeiro: ordnungswidrig: ok thanks

7:38 SagiCZ1: ~lazy-logs

7:38 clojurebot: lazy-logs is http://logs.lazybot.org/

8:54 skratl0x1: I have a macro that takes a vector, I want to pass this vector to a function during macro expansion time, but it contains forms that need to be evaluated, how do I do that?

8:57 gfredericks: skratl0x1: actual examples would be helpful here

8:59 ordnungswidrig: skratl0x1: you cannot expand the forms during macro expansion, at that time it's only lists of lists and symbols

9:00 skratl0x1: no eval?

9:01 gfredericks: you can technically call eval but that has all sorts of edge cases and is not how macros are meant to work

9:03 hyPiRion: fear no eval

9:07 llasram: Premature optimization is the root of all eval

9:09 sqd: any idea why my usage of [serial-port “1.1.2”] with (serial/on-byte port f true) gets messages with a delay, compared to using the built-in serial monitor from the arduino IDE?

9:10 Jker: someone here is a programmer ?

9:10 ToxicFrog: Jker: I suspect most are.

9:11 Jker: who is ?

9:11 sqd: or: is there a recommended way to get notified of the last byte read from a serial port?

9:12 Jker: someone here is a unity 3d programmer ?

9:34 edw: Is there any way to get the this of a function? I'd like to be able to write a function that accesses its own metadata.

9:35 hyPiRion: ,(^:foo (fn f [] (meta f))) ; <-- edw

9:35 clojurebot: {:foo true}

9:35 edw: Ah! Duh. Thanks!

9:54 visof: hi guys

9:54 ,(into {} [{:a {:hello :World}} {:a {}}])

9:54 clojurebot: {:a {}}

9:54 visof: ,(into {} [{:a {}} {:a {:hello :World}}])

9:54 clojurebot: {:a {:hello :World}}

9:54 gfredericks: oh geez

9:54 visof: how can i get the same last effect for all situation?

9:54 jeremyheiler: ,(-> {} (assoc :a 1) (assoc : b))

9:54 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: :>

9:55 jeremyheiler: ,(-> {} (assoc :a 1) (assoc :b 2))

9:55 clojurebot: {:b 2, :a 1}

9:55 jeremyheiler: ah

9:55 gfredericks: ,(reduce into {} [{:a {:hello :World}} {:a {}}])

9:55 clojurebot: {:a {}}

9:55 jeremyheiler: nvm

9:55 visof: gfredericks: the values gone

9:55 gfredericks: oh um

9:55 visof: the logic here is not clear

9:56 jeremyheiler: visof: my point is that the last one wins because it's like your associating a new value of the old

9:56 clrnd: he wants to keep "truthy" values in a dict

9:56 gfredericks: {} is truthy

9:56 clrnd: then he is just confused :P

9:56 gfredericks: ,(apply merge-with merge [{:a {:hello :World}} {:a {}}])

9:56 clojurebot: {:a {:hello :World}}

9:56 clrnd: sorry I thought this was #javascript

9:57 gfredericks: visof: is maybe that ^ what you're going for?

9:57 ,(apply merge-with merge [{:a {:hello :World}} {:a {:other :entries}}])

9:57 clojurebot: {:a {:other :entries, :hello :World}}

9:57 gfredericks: has ^ that behavior

9:57 visof: ,(apply merge-with merge [{:a {:hello :World}} {:a {}} {:a {:clojure :nice}}])

9:57 clojurebot: {:a {:clojure :nice, :hello :World}}

9:57 visof: gfredericks: great, thanks!

9:58 gfredericks: np

11:00 crash_ep: opinion question: should a transducer serve purely as a transformation of its inputs, or is it idiomatic for a transducer to have externally-visible side effects?

11:00 (note I am not talking about the inherent statefulness of certain kinds of transducers, like `partition`)

11:02 clrnd: that's almost a philosophical question, but I'd argue that they should be pure

11:04 clgv: crash_ep: transducers are intended for channels as well, or does that not count as side effect?

11:05 crash_ep: clgv: that's the use case I am asking after. Should I write a transducer that can "do something" to the values that are sent through a channel? Or are transducers intended purely for stream transformations.

11:06 an example of a side-effecting transducer like the one I am asking about is in this blog post: http://www.martinklepsch.org/posts/using-coreasync-and-transducers-for-direct-s3-upload.html

11:06 which does an excellent job of explaining how to use transducers. I'm just curious because it's the first time I've seen them used this way.

11:07 clgv: crash_ep: the transducer write-ups and videos usually name channels as another scenario where the general functionality defined via a transducer is useful

11:07 so you can have eager, lazy and channel ops with the same transducer definition

11:09 crash_ep: clgv: I may be misunderstanding what you are saying, but that sounds orthogonal to what I'm after? :)

11:19 clgv: crash_ep: I am not entirely sure what you are after ;)

11:21 crash_ep: clgv: imagine I create a transducer using this code: (map #(write-to-file my-file %))

11:21 clgv: and then I give that transducer to a channel that delivers strings or input streams

11:22 clgv: That would result in writing the strings or input streams to my-file every time the channel delivers a new value.

11:22 l1x_: hi

11:22 crash_ep: clgv: but is that the intended use case for transducers?

11:23 l1x: what is the best way to send data for processing to async/threads ?

11:24 i was thinking either have 1 channel across everything and threads are listening to their on thread-name or have N channels one for each thread

11:25 justin_smith: l1x: why do you care which thread takes your task? why not just let them all listen to the same channel

11:26 l1x: hmm ok

11:26 justin_smith: and you can't listen to a channel but only take certain messages, core.async does not work that way

11:26 l1x: no selective receive? :)

11:26 justin_smith: no, not an option

11:26 l1x: ok

11:27 how do i make sure my "producer" does not overload the channel?

11:27 aka how do you do flow control

11:27 justin_smith: l1x: by making a channel with no buffer

11:27 teslanick: justin_smith: doesn't filter work like that? Pipe a channel through a filter (getting a new channel), messages that obey the filter are drained from the input channel.

11:28 l1x: justin_smith: and what happens than?

11:28 justin_smith: teslanick: and other messages stay on the channel? or do they get discarded?

11:28 l1x: the write waits for the read?

11:28 teslanick: justin_smith: True, you'd need a 'blowoff valve' to pull messages that don't match the filter off the input channel.

11:29 justin_smith: teslanick: yeah, my point is - you take all the channel gives you if you take at all, and it is your job to decide how to handle things that "aren't for you" - or you only read channels that are for you

11:30 l1x: yeah, the channel will block the message coming on if it isn't buffered

11:30 stuartsierra: There's also pub/sub, which lets you do some filtering.

11:30 teslanick: Understood. So if you need a subset of a channel "just for you", you want to use a topic-based chan

11:30 l1x: ohh

11:30 teslanick: Yeah, a pub/sub

11:30 l1x: justin_smith: thanks!! this is really useful

11:30 i wish there was better doc around core/async

11:31 teslanick: BTW, I've found these two pieces very useful for the not-well-documented features of core.async

11:31 http://yobriefca.se/blog/2014/06/04/publish-and-subscribe-with-core-dot-asyncs-pub-and-sub/

11:31 http://yobriefca.se/blog/2014/06/01/combining-and-controlling-channels-with-core-dot-asyncs-merge-and-mix/

11:31 justin_smith: teslanick: stuartsierra: right, but that's a whole other can of worms, because then everybody sees all the published contents

11:31 daniel___: everytime anyone says teslanick, my irssi lights up

11:31 justin_smith: modulo the filtering and topics of course

11:32 teslanick: daniel___ ??

11:32 lazybot: teslanick: What are you, crazy? Of course not!

11:32 teslanick: lazybot: quiet you.

11:32 justin_smith: lazybot - can you even help it??

11:32 lazybot: justin_smith: Definitely not.

11:34 teslanick: justin_smith: Do you mean that you can "duplicate" messages by subbing multiple channels to the same topic?

11:35 justin_smith: right - if your logic is "which listener gets each of these messages on onechannel" then you need all your filters on your subscribers to be mutually consistent, or you get messages acted on twice or more, or dropped

11:36 so the real fix is - read a channel, act on every message you get. And design other things around that.

11:36 teslanick: (aside, "duplicate" as a verb is an awkward word)

11:37 justin_smith: so, as I initially suggested, if you want threads working on tasks in parallel, put all tasks on one channel, and have all threads listening to that channel, each message will go to a thread that is ready

11:37 much simpler

11:40 l1x: justin_smith: and when the "consumer" reads the queue it blocks it too

11:40 right?

11:40 so I could have N threads with while true; read queue

11:41 or there is a more idiomatic way to do that?

11:41 teslanick: thanks!

11:41 daniel___: there it goes again

11:43 justin_smith: l1x: yeah, if all threads are doing the same thing, just have each one reading from the same channel and executing on what they get, in a loop

11:44 if they do different things, give them each a channel, and decide which channel to put onto based on what you want done

11:45 d0ky: hello how can i achieve that when i insert into hash-map new hash-map item: (into path new-path) i need to have new-path to be the last item in path ... i know that vector would do the job but hash-map suitable for working with it , thanks for any help

11:45 justin_smith: d0ky: hash-maps are not ordered

11:46 d0ky: so the only way is to use vector ?

11:46 justin_smith: or a sorted-map, but that is sorted by key and sort function, not insertion order

11:46 l1x: justin_smith: thanks, this is very helpful

11:47 Glenjamin: https://github.com/amalloy/ordered would work

11:47 Bronsa: there is an ordered map somewhere

11:47 ^ there

11:47 justin_smith: I don't know if there is anything off the shelf that respects insertion order, and also allows ~constant time lookup

11:47 oh, nice!

11:47 Glenjamin: ordered just wraps a map + vector together

11:47 justin_smith: (inc Glenjamin)

11:47 lazybot: ⇒ 10

11:47 justin_smith: makes sense :)

11:48 d0ky: Glenjamin: justin_smith: thanks you both

11:49 cityspirit: anyone have any strong opinions on korma vs yesql?

11:50 clgv: crash_ep: sounds totally reasonable

11:51 justin_smith: cityspirit: korma is semi-abandoned at this point, right?

11:51 also, I like yesql because sql is already a good dsl for doing sql :)

11:53 mikos: yesql is ace

11:53 did i read somewhere that it will support passing a hashmap soon?

11:53 cityspirit: justin_smith: is it? I wasn't aware. I like yesql a little better too, but with yesql you'd probably want to integrate like c3p0 on your own right?

11:54 justin_smith: cityspirit: that's fairly easy actually, but yeah.

11:55 cityspirit: callen/bitemyapp, who was the last really active maintainer of korma I know of, kind of hates Clojure now. But I don't follow korma closely so there well may be more going on than I know of.

11:56 mikerod: Does leiningen have some "default" repositories it looks in for artifacts?

11:56 e.g. If I have a :plugins dependency, I have noticed it is fetched without me specifying any :repositories

11:57 technomancy: mikerod: sure; clojars and central

11:57 justin_smith: cityspirit: and regarding c3p0, the way to do that with yesql is to provide a :datasource key in your db-spec, which has the c3p0 object in it. There are interop libs, but it is straightforward enough to use the class directly.

11:57 mikerod: technomancy: I figured that was the case. I was just curious what the defaults were.

11:57 cityspirit: justin_smith: great, thanks for the info. I'll give that a whirl

11:58 mikerod: I suppose leiningen has some tool to show the "effective" project configuration map for a given project?

11:58 Similar to the idea of the "effective pom" in Maven

11:58 this is a better google question

11:59 technomancy: mikerod: check out the lein-pprint plugin

11:59 justin_smith: cityspirit: you may want org.tobereplaced.jdbc-pool - that makes it really easy

11:59 technomancy: `lein pprint :repositories`

11:59 justin_smith: cityspirit: but if you look at the lib, it also doesn't have a lot of meat to it :)

12:00 mikerod: technomancy: thanks for the info. I'll check that out.

12:00 justin_smith: cityspirit: very simple https://github.com/ToBeReplaced/jdbc-pool/blob/master/src/org/tobereplaced/jdbc_pool.clj

12:01 crash_ep: clgv: thanks!

12:04 sdegutis: weavejester: sorry to bother you by being over-playful about your secret project

12:05 weavejester: anyway we guessed it's some sort of Clojure code reformatter

12:05 weavejester: sdegutis: It's not really secret, just not ready for release, and it is indeed a Clojure code formatter.

12:05 I wanted something like gofmt

12:06 sdegutis: Who is the intended audience?

12:06 cityspirit: justin_smith: thanks! I might just use that as example code to work off of

12:06 justin_smith: weavejester: awesome idea, I look forward to trying it when it is ready

12:06 weavejester: sdegutis: Me ;)

12:06 sdegutis: I personally just do C-x h M-q TAB

12:06 weavejester: sdegutis: Or anyone who happens to need a Clojure formatter.

12:06 justin_smith: cityspirit: he is using some macro magic to derive setter methods for map keys

12:06 sdegutis: that won't insert line breaks

12:07 sdegutis: justin_smith: true

12:07 weavejester: sdegutis: Sure, but that won't work with CI

12:07 sdegutis: weavejester: true

12:07 Glenjamin: the problem's i've had with formatters are mostly deciding when to line break, and with-* style methods that don't start with with-

12:07 weavejester: I want to be able to say: lein clofor :check

12:07 justin_smith: weavejester: technically you can script with emacs - but who wants command line emacs in their CI

12:07 weavejester: And then for it to fail CI if the code isn't formatted right

12:07 Glenjamin: so if you can solve those two, great job :D

12:08 weavejester: justin_smith: Yeah, but the clojure-mode indenter isn't really intended as a full code reformatter

12:08 justin_smith: right

12:08 so that's the real issue - it won't do smart line breaks, etc.

12:08 weavejester: Yep. I want something which can tell me if a Clojure source file is formatted according to the Clojure style guide.

12:09 Something extensible, with optional formatters, in the same way Eastwood has optional linters

12:09 sdegutis: There are some times when I want a ")" on its own line, namely when I have a really long defroutes.

12:09 I don't know how to tell a code formatter that one pattern.

12:09 :(

12:10 Glenjamin: weavejester: how have you approached it knowing that GET/POST etc are binding forms ?

12:10 weavejester: Glenjamin: It'll be extensible, so you'll be able to add more rules.

12:10 Glenjamin: I haven't figured out all the details yet, but I think they might be similar to Clojure's routes.

12:11 i.e. just a long list of rules. if a rule returns nil it's ignored.

12:11 Hard to do it any other way with things like backtracking indents

12:11 justin_smith: Glenjamin: if you look at clojure mode, it has a small set of rules (representing various macro / special form types and how they differ) and then a bunch of symbols are assigned to be indented according to each of those rules

12:11 weavejester: sdegutis: Fortunately I'm happy never having a ) on it's own line.

12:12 sdegutis: :)

12:12 justin_smith: sdegutis: ITYM :

12:12 )

12:12 weavejester: But the rules will be customisable.

12:12 Glenjamin: justin_smith: yeah, i was thinking of that as 1 rule, which there'd need to be a way to add more symbols to

12:12 technomancy: weavejester: the one exception I can think of is when you have a long list of data and you want to make it easy to insert a new entry

12:12 Glenjamin: always add in the second-last position :p

12:12 technomancy: haha, yeah not bad

12:13 Glenjamin: also helps for avoiding merge conflicts, add into a random position

12:13 justin_smith: technomancy: Glenjamin: clearly this calls for a new paredit command

12:13 technomancy: this is actually condoned in the hallowed text of riastradh's style guide

12:13 weavejester: technomancy: I personally care more about the appearance of the source than the diffs :)

12:13 justin_smith: "add new item at end of this list on its own line"

12:13 technomancy: weavejester: it's not the diff; it's hunting for the right number of parens to split off

12:13 http://mumble.net/~campbell/scheme/style.txt

12:14 "Exceptions to the Above Rule Concerning Line Separation"

12:14 weavejester: technomancy: paredit surely solves that problem?

12:14 technomancy: weavejester: hm, true. what about the comment one though?

12:15 weavejester: technomancy: #_ ?

12:15 technomancy: I guess just always use #_?

12:15 right

12:15 that sucks because you don't get font-lock

12:15 Glenjamin: maps are annoying in that sense

12:15 justin_smith: technomancy: paredit already fixes ; to add a line break for closing parens to work

12:15 weavejester: Anyway, I figure the rules can be customisable.

12:15 technomancy: justin_smith: yup yup. but it breaks the rules

12:15 weavejester: So you can set the rules you want in your project.clj file

12:16 Glenjamin: ,{:a 1 :b 2 #_(:key val)} ; i guess

12:16 clojurebot: {:b 2, :a 1}

12:16 weavejester: Or use two #_#_

12:16 Glenjamin: what

12:16 technomancy: the formatter will certainly encounter ;; etc etc \n)) and needs to behave gracefully in its presence

12:16 Glenjamin: ,{:a 1 :b 2 #_#_:key val}

12:16 clojurebot: {:b 2, :a 1}

12:16 Glenjamin: oh wow, i had no idea

12:17 weavejester: technomancy: it could be smart about it

12:17 I have a few ideas about smart formatting.

12:17 Like automatically adding in threading if a form is too deep.

12:17 justin_smith: Glenjamin: you can make really weird obfuscated code with stacked #_#_#_ without much effort

12:17 if you are trying to obfuscate, at least

12:17 weavejester: Smart newlines to split up lines over 80 chars

12:17 etc.

12:18 justin_smith: weavejester: reiterating my interest :) godspeed

12:18 weavejester: I figure the first step is just to get something on parity with clojure-mode though

12:18 Then add a lein plugin

12:19 With a :check and :fix option

12:19 So it can be used in CI to validate that a person's commit adheres to the project's format.

12:20 Glenjamin: if it can run as a server of some sort it'd be a neat way to negate the startup time

12:20 assuming you're writing it in jvm clojure

12:20 weavejester: Incidentally, we need a protocol for reporting tests/linting. Currently we just have STDOUT

12:20 Yeah, it's in jvm clojure.

12:20 But it might work okay with lein-auto

12:20 Because it doesn't do a project eval

12:21 So "lein auto format :check"

12:21 Which again means that a protocol for reporting tests/lints would be nice.

12:21 Glenjamin: auto format :fix would be trickier i imagine

12:21 weavejester: That just sounds like a bad idea :)

12:22 Better to follow the slamhound route for that, I think

12:22 Glenjamin: being able to curl some text to a local server and get new text back would be neat

12:22 weavejester: Hm, I guess so

12:22 Formatting as a service

12:23 Glenjamin: alias format='curl localhost:1234 -d @$1 > $1' or however you get pipes to rewrite a file

12:33 clgv: weavejester: using :configurator to modify (setIncludeProtocols) the SslContexFactory of the SslSelectChannelConnector instances of the jetty instance worker

12:34 weavejester: clgv: okay

12:34 sdegutis: weavejester: your auto-threading idea could be very problematic if any of the subforms are non-comformative

12:35 weavejester: sdegutis: What do you mean?

12:35 sdegutis: weavejester: unless I'm horrifyingly mistaken, there are several times when a form cannot be threaded based on whether the form is a macro or a function which can only be known at runtime

12:36 technomancy: it has to be ...

12:36 thread-safe

12:36 ( •_•) ( -_-)~⌐■-■ (⌐■_■)>

12:36 weavejester: technomancy: :P

12:36 Glenjamin: oh dear, i laughed heartily at that

12:36 sdegutis: (alter technomancy + 1000000000)

12:36 weavejester: sdegutis: Do you have an example? Threading is a source transformation, so I don't see why it isn't safe.

12:37 sdegutis: weavejester: there are also things like (fn [] ...) which can't be put into a threading macro directly, but those are more easily spottable at the source level

12:37 weavejester: not off the top of my head

12:37 I was kind of hoping saying it might jog someone else's memory (mine is not very good) and they would jump in.

12:37 weavejester: The only way I can think of threading being unsafe is if it was in another source transformation macro.

12:38 sdegutis: Oh right, that's it.

12:38 You can't embed -> into ->>

12:38 Or compojure.core/GET too iirc.

12:39 Essentially any arbitrary form might happen to be a source-transforming macro.

12:39 Bronsa: ,(-> [1 2] (->> (map inc) (reduce +)) inc)

12:39 weavejester: You can, you just need to be aware how it transforms the code.

12:39 clojurebot: 6

12:39 weavejester: There's nothing special about (fn []) or (GET ...) that would stop them from being threaded

12:39 The rules are always the same

12:40 luxbock: ,((->> coll (map inc) (fn [coll])) [1 2 3])

12:40 clojurebot: (2 3 4)

12:40 sdegutis: weavejester: right, so unless I'm hideously mistaken, it would require a whitelist of known good forms, or at the very least a blacklist of known bad forms, when doing auto-threading

12:40 weavejester: Not really...

12:40 sdegutis: ok :)

12:40 Glenjamin: if it can be written as (f (g (h x))) it should always work as ->

12:41 technomancy: just make all your code point-free always

12:41 weavejester: Formatters don't need to be fullproof, firstly, especially if they're optional.

12:41 sdegutis: :)

12:41 weavejester: I'm sure I could write something that would break any formatter with macros if I tried.

12:41 Unless the formatter was macro aware I guess

12:41 sdegutis: I have been known to be insidiously mistaken in the past, so I'll assume I'm wrong here.

12:42 weavejester: I agree it's possible, but since a formatter is just an aid, it shouldn't matter that I can craft a form that breaks it.

12:42 Off the top of my head, I can't think of any deeply nested code transformation where you can't use threading.

12:43 teslanick: As long as crafting the form that breaks the formatter causes it to fail loudly

12:43 Glenjamin: i get this with my current lint tool, sometimes a rule breaks on some code where i disagree, occasionally i'll write my code differently because i still want the rule in general - or sometimes i'll go turn off the rule

12:43 sdegutis: weavejester: your lib sounds neat im curious to see how it plays out good luck

12:44 technomancy: yeah, glad to see this happening =)

12:45 weavejester: Glenjamin: yeah, I figure I'll take a similar approach with the formatter

12:45 Glenjamin: i've been very happy with eslint recently

12:45 sdegutis: what about eastwood?

12:45 Glenjamin: the level of configuration it provides is great

12:45 per-file overrides are awesome too

12:46 weavejester: I'll try and get something released by this weekend. I just have defun-style indents and backtracking (i.e. protocol, type, proxy, reify) indents to sort out.

12:48 sdegutis: $dict great

12:48 lazybot: sdegutis: adjective: Very large in size.

12:48 sdegutis: Glenjamin: oh

12:49 Glenjamin: oh?

12:49 justin_smith: I am going to regret showing sdegutis the dict command

12:50 sdegutis: $dict going

12:50 lazybot: sdegutis: noun: Departure: comings and goings.

12:50 sdegutis: justin_smith: oh

12:51 justin_smith: cya when you get back then i guess

12:51 justin_smith: $dict lol

12:51 lazybot: justin_smith: interjection: Alternative form of LOL.

12:52 weavejester: $dict decomplect

12:52 lazybot: weavejester: Word not found.

12:52 sdegutis: $dict inorite

12:52 lazybot: sdegutis: Word not found.

12:52 weavejester: lazybot, you disappoint me

12:52 $dict complect

12:52 lazybot: weavejester: verb-transitive: To join by weaving or twining together; interweave.

12:52 weavejester: lazybot knows only how to complect things.

12:53 jaaqo: $dict transducer

12:53 lazybot: jaaqo: noun: A substance or device, such as a piezoelectric crystal, microphone, or photoelectric cell, that converts input energy of one form into output energy of another.

12:53 sdegutis: Wow lazybot. So wrong.

12:53 justin_smith: I may at least update that plugin to tell you other def's exist

12:53 sdegutis: justin_smith: but hopefully not to access them?

12:54 weavejester: lazybot should have a Clojure definition dictionary that it prefers

12:54 sdegutis: $dict have

12:54 lazybot: sdegutis: verb-transitive: To be in possession of: already had a car.

12:54 clojurebot: Titim gan éirí ort.

12:54 justin_smith: weavejester: yeah, right now it just does a simple wordnick api call

12:54 sdegutis: oh

12:55 justin_smith: $wotd

12:55 lazybot: justin_smith: abactinal: Pertaining to the surface or end opposite to the mouth in a radiate animal.

12:55 sdegutis: $wotd = perilous

12:55 lazybot: sdegutis: abactinal: Pertaining to the surface or end opposite to the mouth in a radiate animal.

12:55 sdegutis: It seems broken.

12:57 weavejester: I assume the word of the day is fixed

12:57 per day

12:57 alpheus: I'm destructuring deeply nested maps where the keys (and structure) aren't known until run time. The code's getting cumbersome. Is there something that would help me do this?

12:57 justin_smith: https://www.wordnik.com/

12:58 alpheus: get-in

12:58 Glenjamin: alpheus: use let & get-in instead of destructuring?

12:58 alpheus: Yes, that's probably what I missed. Thanks!

12:59 sdegutis: weavejester: oh right, immutable; blech

12:59 we need a mutable subclass of WOTD

13:00 Glenjamin: WOTD is an identity that changes over time

13:00 * alpheus thinks if you're working too hard in Clojure, you're doing it wrong.

13:01 justin_smith: &(let [data {:a 0 :b 1 :c {:d {:e 3}}} path '(:c :d :e)] (get-in data path))

13:01 lazybot: ⇒ 3

13:01 sdegutis: alpheus: Clojure's motto is "work smaerter not harder"

13:01 alpheus: Clojure's motto is "use streams not recursion"

13:01 llasram: $dict smaerter

13:01 lazybot: llasram: Word not found.

13:01 sdegutis: alpheus: Clojure's motto is "immutable decomplection"

13:02 weavejester: I think Clojure's more about aggressive simplification.

13:02 technomancy: I thought it was "simple yet powerful"

13:02 or is that just the sdegutis motto

13:02 sdegutis: alpheus: Clojure's motto is "simple, yet powerful"

13:02 Glenjamin: i thought it was "always be decomplecting"

13:02 sdegutis: technomancy: no, it's just that probably about 2/3 of all projects have that phrase in their readme

13:02 alpheus: alpheus's motto is "I'm not smart like you people are"

13:02 teslanick: alpheus: That's my motto too.

13:02 weavejester: Power comes from simplification, I think :)

13:03 Glenjamin: aha, here we go: https://pbs.twimg.com/profile_images/1630228544/fakerichhickey.jpg

13:03 sdegutis: llasram: oh sorry, i meant smærter

13:03 danielcompton: Rich is nice so we are nice?

13:03 technomancy: my motto http://www.funnyjunk.com/funny_pictures/1906060/I

13:03 sdegutis: danielcompton: no that is not our motto

13:03 weavejester: The new transducers are effectively a simplification, by factoring out the conj

13:03 sdegutis: alpheus: Clojure's motto is "Rich is hipster so we are hipster"

13:03 teslanick: I'm curious if this is an insane idea: I want to put to a channel and get some value back when a consumer processes the message I sent it. I played with callback functions and a "callback channel" -- is there an idiomatic way of doing something like this?

13:04 sdegutis: weavejester: well they're also a decomplexion

13:04 justin_smith: teslanick: pass in a channel to put the result onto

13:04 weavejester: Or return a channel, perhaps

13:04 mdrogalis: weavejester: Maybe 2 steps forward in terms of simplicity, 1 step back. You still need to be aware of stateful transducers in certain contexts.

13:04 weavejester: (<! (do-something foo))

13:05 Like a promise

13:05 mdrogalis: Yes, maybe.

13:05 mdrogalis: Not complaining though. :)

13:05 sdegutis: I want to add a maybe-monad to Clojure.

13:05 teslanick: Ok. I wrote a function called putback! that takes a channel to put to and a value. It returns a channel upon which a result will be passed. The other side knows how to interact with the "chan-back"

13:06 * sdegutis goes back to listening to Graduation (Friends Forever) by Vitamin C

13:07 * hellofunk remembers he needs to take some vitamin C

13:07 weavejester: Monads are a bit tricky without dispatch on return.

13:08 technomancy: you need pattern matching or it's just going to be super tedious

13:11 sdegutis: At about 3:07 into it, the Graduation song gets really epic.

13:12 It goes on until about 3:34... It may be needful to put that sub-section on repeat a few times for maximum effect.

13:12 Anyway, I'm abusing Clojure metadata within defn.

13:13 I've got a meta-handler which looks at a route fn's metadata, so that I can just define (defn ^:login view-page-route [] ...) and it requires the user to login first, or redirects them.

13:14 weavejester: sdegutis: Why not use middleware?

13:14 ticking: does anybody know at the to of their head if nRepl is designed to handle multiple evals in parallel in one session?

13:15 sdegutis: weavejester: That's what I mean by a metahandler :)

13:16 weavejester: sdegutis: But why not apply the middleware directly to the routes?

13:17 sdegutis: weavejester: you mean instead of putting ^:login on the end-point route handler fn's var?

13:18 weavejester: because unless I'm appallingly mistaken, wrapping a route in the middle of a routes-chain is going to short-circuit the rest of the routes if it matches it halfway but not the remainder of the way

13:18 weavejester: sdegutis: Yes, you could wrap-requires-login over the group of routes that require logins.

13:18 sdegutis: I don't understand what you mean by that.

13:20 sdegutis: weavejester: for example, I have (defroutes foo (GET "/" ...) (wrap-require-admin (GET "/admin" ...)) (GET "/cart" ...)) -- this is going to prevent /cart from ever being valid for non-admins, even though it's outside wrap-require-admin, unless I'm disgustingly mistaken

13:20 justin_smith: ticking: I don't know this for a fact, but my expectation is that it would not parallelize for one session (connection) but if you opened another connection on the same server, that would run in parallel -- checking now

13:20 sdegutis: I ran into this a year ago and tracked it down to something like that.

13:23 justin_smith: https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/server.clj#L43 ticking: the logic is here - each connection is in its own future, and each message in the handler is also a future in a block that uses (recur) after spawning the request in a future.

13:23 I used "future" one too many times describing the handler, but the code should be clear (see accept-connection and handle)

13:23 ticking: justin_smith: nice thanks, so sending many :op :eval in succession should not break nrepl right?

13:24 justin_smith: doesn't look like it from that code

13:24 ticking: unless you send enough requests to starve the thread-pool I guess...

13:24 ticking: justin_smith: I'm currently trying to add interrupt to gorilla repl, it's really about time :D

13:25 justin_smith: nice

13:25 ticking: so thanks a lot :D

13:25 weavejester: sdegutis: You can use the `wrap-routes` function in Compojure to wrap *inside* of routes.

13:25 sdegutis: weavejester: Thanks.

13:25 weavejester: sdegutis: It was made specifically with the idea of authentication failing in mind, though it's applicable for a lot more.

13:30 sdegutis: weavejester: That is a very useful feature.

13:31 weavejester: sdegutis: I thought so, but I don't know anyone who's using it yet :)

13:31 sdegutis: weavejester: I would have used it a year ago except I didn't know it existed, and when I found it in the source, I didn't understand how/why/when to use it.

13:32 weavejester: sdegutis: I didn't think it was a year old...

13:32 sdegutis: Oh maybe not?

13:32 weavejester: And right now I'm not sure I can use it, because I've restructured my app to decomplect the route handling function from the route itself.

13:34 weavejester: Currently I have a list of tuples which I transform into handlers (partially using (make-route)) and then pass to (apply routes).

13:35 It allows me to write a routes.clj file very similarly to a routes.rb file, containing [[:get "/" :home/show-home-page] [:get "/videos" :home/redirect-to-home-page] [:get "/admin" :admin/show-admin-page]] etc

13:41 weavejester: sdegutis: Hm, okay, but why would that stop wrap-routes from working?

13:41 sdegutis: weavejester: because I would need to wrap a subset of them -- oh wait, I can manipulate collections in Clojure.

13:44 weavejester: bbl

14:56 andyf: Bronsa: Clj-1591 comment discussion had a small test case that has symptoms like clj-1241 even after that fix was applied. No need for you to look at it, but in case you are interested ...

14:58 Different exception, so not identical symptoms, but var that is bound without aot is unbound when using aot

14:59 Bronsa: andyf: ah, AOT is involved. might be a completely different issue then, I'll take a look

15:00 andyf: Tom Crayford created the test case, linked in comments

15:17 daniel___: i wonder if anyone can help me with a friend problem https://gist.github.com/danielstockton/649ceff075b793007e27 ?

15:17 my workflow ring handler is never called

15:17 and i can't work out why

15:18 im trying a POST to the /api/session endpoint

15:22 justin_smith: daniel___: that call to run-jetty won't see redefinitions of app, but if you change it to (run-jetty #'app ...) it will

15:22 daniel___: not that that neccissarily caused your problem though

15:23 daniel___: that includes redefinitions of middleware and things that make up app?

15:23 i seemed to be seeing changes when i made them further up without needing a restart

15:23 justin_smith: right, it won't see any of those redefinitions

15:23 hmm...

15:26 daniel___: justin_smith: changed it, now it logs all the calls to static resources

15:26 justin_smith: OK, I guess that's proof it's reloading.

15:27 daniel___: interested in why thats the case, but dont want to detract from my friend workflow issue

15:28 justin_smith: frankly, I have only been confused by friend and never got it working

15:28 hopefully someone else can help you

15:28 daniel___: i read through the documentation when i had some time earlier, away from the code, and i thought i got the concepts

15:29 but apparently not

15:30 "Incoming requests are always run through the configured workflows prior to potentially being passed along to the secured Ring application" mine don't seem to be..

15:36 raboid: what does @() do in Clojure? Having a hard time finding any documentation for it

15:37 joegallo: looks for deref

15:37 llasram: raboid: It's a reader macro:

15:37 andyf: raboid: @form turns into (deref form)

15:37 joegallo: ,`@foo

15:38 llasram: ,`(@example)

15:38 clojurebot: (clojure.core/deref sandbox/foo)

15:38 ((clojure.core/deref sandbox/example))

15:38 llasram: Yeah, joegallo's was better

15:38 (inc joegallo)

15:38 lazybot: ⇒ 6

15:38 andyf: Clojure cheatsheet has a section on these

15:39 Which could be better at linking to more details

15:40 raboid: Okay thanks ya'll

15:44 Could anyone familiar with aleph explain why this only handles the first request sent to it? https://gist.github.com/raboid/b9629fc24f3524fbdec4

15:44 Works perfect on the first request, but after that it never seems to call the handler anymore?

16:02 Bronsa: andyf: I have a fix

16:03 andyf: Bronsa: Your awesomeness level is up to its usual high, then :-)

16:04 Bronsa: andyf: it requires generating 7 more instructions for every interned Var though :/ but I don't think there's another way to fix it

16:05 andyf: Tom says he will be creating a separate ticket for this issue, perhaps today, but mgr may not mind if you do

16:05 It does seen independent of original ticket

16:05 Bronsa: yeah it's unrelated-ish

16:06 ah I think I can make this better.

16:12 aaelony: I am reading data from a file that contains delimited text, one column of which is JSON. Using cheshire.core/parse-string on the JSON column gives me an error like "com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'I': was expecting 'null', 'true', 'false' or NaN ". I'm able to copy/paste a raw line from the file, then replace " with \" and run parse-string just fine. Wondering how to correctly prepare JSON data column such t

16:12 hat parse-string will read it correctly.

16:13 I've tried clojure.string/escape but that hasn't helped yet...

16:13 e.g. (clojure.string/escape s { \" "\"" } )

16:13 any help appreciated

16:14 notostraca: ~refheap

16:14 clojurebot: refheap is a sufficiently large margin

16:14 notostraca: ~pastebin

16:14 clojurebot: Cool story bro.

16:15 notostraca: sigh

16:15 clojurebot: refheap |is| a pastebin. https://www.refheap.com/

16:15 clojurebot: Roger.

16:15 notostraca: clojurebot: pastebin |how about| refheap? https://www.refheap.com/

16:15 clojurebot: Ik begrijp

16:16 notostraca: ~pastebin

16:16 clojurebot: pastebin how about refheap? https://www.refheap.com/

16:16 Bronsa: yup andyf http://sprunge.us/XNNg?diff -- creating a ticket now

16:16 notostraca: aaelony, can you pastebin a line of sample data?

16:17 aaelony: sec, almost done

16:17 https://www.refheap.com/93968

16:21 I wish I could pastebin a line of sample data, but I'm not allowed to do that :(

16:21 I think it's a matter of escaping the incoming string

16:22 for example, if I manually replace " with \" at the repl for a line of data, parse-string works just fine

16:23 the input text contains valid json in all cases, but some of the fields within quotations may contain crazy characters...

16:24 I understand that it's hard to help without seeing the data...

16:44 Bronsa: andyf: http://dev.clojure.org/jira/browse/CLJ-1604

17:11 cfleming: Bronsa: I had a question for you

17:11 Bronsa: I'd dearly love forms like reify and deftype, but which allow me to extend abstract classes

17:12 Bronsa: Not being able to do that kills me in Cursive

17:12 Bronsa: cfleming: you can either change like 3 lines in the Compiler to allow that or you'll need to use genclass/proxy

17:12 cfleming: Bronsa: To do that in Clojure proper I'd have to fork and modify the compiler - could I do that with tools.* in a macro?

17:13 verma: what's the difference between :hello and ::hello ?

17:13 cfleming: It's only 3 lines? I'd assumed I'd need new forms for that.

17:13 weavejester: verma: ::hello includes the current namespace

17:13 ,::hello

17:13 clojurebot: :sandbox/hello

17:13 verma: oh what? nice

17:13 TIL

17:13 thanks weavejester

17:13 (inc weavejester)

17:13 lazybot: ⇒ 11

17:13 Bronsa: cfleming: no I mean, you can make deftype/reify extend an abstract class rather easily

17:14 weavejester: verma: You can also use it to include namespace aliases as well

17:14 verma: So ::str/foo might become :clojure.string/foo

17:14 ,::str/foo

17:14 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: ::str/foo>

17:14 verma: oh

17:14 weavejester: Looks like lazybot doesn't include clojure.string

17:14 verma: as long as str can be resolved?

17:14 weavejester: yeah

17:14 justin_smith: &(require '[clojure.string :as s])

17:14 lazybot: ⇒ nil

17:14 cfleming: Bronsa: Interesting, that might be a good approach since I can bundle my own Clojure. In fact I'd only need to use that for compilation, right? Since I'm AOT'ing.

17:15 justin_smith: &s/foo

17:15 lazybot: java.lang.RuntimeException: No such var: s/foo

17:15 justin_smith: &::s/foo

17:15 lazybot: java.lang.RuntimeException: Invalid token: ::s/foo

17:15 justin_smith: erm

17:15 weavejester: &(do (require '[clojure.string :as s]) ::s/foo)

17:15 lazybot: java.lang.RuntimeException: Invalid token: ::s/foo

17:15 Bronsa: cfleming: or you could do that with t.a/t.e.jvm withouth forking yeah but I'd just patch the Compiler if I were you

17:15 justin_smith: weird

17:15 weavejester: Probably because they're in the same form.

17:15 And the separate forms are sandboxed

17:15 Bronsa: cfleming: right. I actually already implemented that years ago, let's see if I can find that patch

17:15 verma: brewing up a repl and trying it

17:15 weavejester: It works in an actual Clojure file anyway ;)

17:16 cfleming: Bronsa: Ok thanks - a patch would be fantastic, if not I can probably work it out.

17:16 verma: so I would use to create a namespaced keyword sort of?

17:16 justin_smith: &(namespace ::foo/bar)

17:16 lazybot: java.lang.RuntimeException: Invalid token: ::foo/bar

17:16 cfleming: Bronsa: I'm also going to modify them to allow requiring their namespace in clinit.

17:16 justin_smith: wat

17:16 verma: test.clj -> ::hello is the same as :test/hello in a separate file?

17:16 justin_smith: &(namespace :foo/bar)

17:16 lazybot: ⇒ "foo"

17:17 justin_smith: verma: yes, it is precisely making a keyword that has a namespace

17:17 verma: nice

17:17 got it

17:17 (inc justin_smith)

17:17 lazybot: ⇒ 147

17:17 cfleming: Bronsa: Of course, it'll need more work to allow superclass method invocation.

17:17 Bronsa: cfleming: https://github.com/Bronsa/clojure/commit/915aadc0cb8a604b6ef4976d2f19a2b1dfb994f5

17:17 don't know if that still applies

17:18 cfleming: Bronsa: That's fine, I can modify it - thanks so much, that might just save my life.

17:21 Bronsa: I'm still not sure what a good syntax would be for superclass invocation, but I don't always need to do that.

17:21 Bronsa: Just being able to extend is really helpful.

17:23 Bronsa: cfleming: yeah with that patch only it'll only work for abstract classes that don't declare a constructor -- it simply invokes the no-arg super ctor

17:26 cfleming: Bronsa: Ohhh... right, I'll definitely need the super constructor call. I'd have to add syntax similar to proxy for that, but that's probably a pretty simple modification to your patch.

17:28 Bronsa: If I decide I do want a separate form, t.a/t.e.jvm should allow it in a macro, right? Does t.e.jvm support AOT compilation yet? I know that wasn't there a while back.

17:30 Bronsa: cfleming: we're not there yet unfortunately. I still have a major bug to fix in t.a.jvm before I get to start playing with t.e.jvm again

17:31 cfleming: I'll be honest, right now it's probably less work to patch Compiler.java than implement that by extending t.e.jvm (without patching it)

17:32 augustl: in the name of interop and legacy, is there a way to get a servlet handler object implementation from a ring handler function?

17:33 weavejester: augustl: You can get the ServletContext, Request and Response objects when running in a servlet container.

17:33 augustl: weavejester: the other way around, so to speak :) I'm in a setting where I have some servlets and map them to a servlet context with Java code, and want to do that with a ring handler as well

17:34 l1x: is there a way to get to know the name of the thread I am in that was created with (async/thread ... ) ?

17:34 weavejester: augustl: Oh, well you can create a servlet object using the ring/ring-servlet library.

17:34 augustl: weavejester: ah, nice. Thanks!

17:34 Bronsa: cfleming: it's not summer and I have lessons now, I don't have the time to actively work on all the 5 tools.* libraries so I gave priority to t.a/t.a.jvm since those are the more useful -- t.e.jvm is on the bottom of the list i.e. I'll work on it when there will be no more issues with the other libs.

17:34 weavejester: augustl: There are functions for creating a servlet via a proxy, and via gen-class

17:35 justin_smith: ,(.getName Thread/currentThread)

17:35 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to find static field: currentThread in class java.lang.Thread, compiling:(NO_SOURCE_PATH:0:0)>

17:35 augustl: weavejester: very nice

17:36 justin_smith: &(.getName (Thread/currentThread))

17:36 lazybot: ⇒ "Thread-5691"

17:36 justin_smith: l1x: ^^^

17:37 l1x: thanks!

17:37 justin_smith: your suggested way of dealing with concurrency works

17:37 i am testing it on stage now

17:37 cfleming: Bronsa: Sure, no problem - just wondering where it was at. Thanks for the help!

17:37 justin_smith: l1x: cool, it has worked for me in that past :)

17:37 cfleming: Bronsa: I'll fix the compiler since I more or less understand that.

17:38 Bronsa: "fix" :) let me know if you have any issues -- happy to help

17:38 l1x: justin_smith: i might poke you to review my code (few lines really) if you have time because it is opensauce

17:39 justin_smith: l1x: I am in and out today (at a pub on my laptop right now) but happy to look at it if yo catch me at a good time

17:39 l1x: :d

17:39 nice tahnks

17:40 Bronsa: cfleming: btw don't know if this could help but I wrote https://github.com/Bronsa/neurotic a while ago. IIRC ztellman also has a lib that does something similar.

17:40 l1x: Cannot find field currentThread for class class java.lang.Thread

17:40 hmm

17:40 ohh

17:40 TEttinger2: aaelony: still there?

17:40 my connection is not great

17:41 aaelony: TEttinger2: hi

17:41 justin_smith: l1x: notice my second example, the one that worked

17:41 l1x: not a static field, but a method call

17:41 l1x: yes! :)

17:41 TEttinger2: (clojure.string/escape "hello there, \"friend-o\"" { \" "\"" } )

17:41 ,(clojure.string/escape "hello there, \"friend-o\"" { \" "\"" } )

17:41 clojurebot: "hello there, \"friend-o\""

17:42 TEttinger2: ,(clojure.string/escape "hello there, \"friend-o\"" { \" "\\\"" } ) ; may be what you want

17:42 clojurebot: "hello there, \\\"friend-o\\\""

17:42 aaelony: TEttinger2: I was playing around with clojure.string/escape but I didn't try that exactly. Let me give it a shot.

17:42 TEttinger2: ,(println (clojure.string/escape "hello there, \"friend-o\"" { \" "\\\"" } ))

17:42 clojurebot: hello there, \"friend-o\"\n

17:42 TEttinger2: ,(print (clojure.string/escape "hello there, \"friend-o\"" { \" "\"" } ))

17:42 clojurebot: hello there, "friend-o"

17:43 TEttinger2: substituting "\"" for \" is the same as "\"" for "\""

17:44 aaelony: TEttinger2: Actually, looking at the things I had tried, what you mention was among them.

17:45 TEttinger2: and produces the error "com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'I': was expecting 'null', 'true', 'false' or NaN"

17:45 TEttinger2: can you just make up some names-changed sample data?

17:45 like change any keys like :name to :foo

17:46 aaelony: TEttinger2: I call (last) on the line before, I think that may not always be valid. In any case, it is something silly in the data that is causing this. It will be found...!

17:48 TEttinger2: null, true, false, or NaN should probably mean that it's trying to get a boolean and it's getting something like "I wish I had a pony", just with the quotes not read correctly

17:48 cfleming: Bronsa: That does look really useful, thanks - I'll investigate that too.

17:50 TEttinger2: if ztellman and Bronsa combined their powers we'd have an unstoppable Clojure juggernaut

17:54 andyf: That has already occurred

17:55 aaelony: perhaps I can hint it to expect a string....

17:57 dbasch: aaelony: do you know if your json is well formed? i.e. if you paste into a json validator does it validate?

17:58 it looks like you’re reading a string that’s missing a quote, so the parser doesn’t know what to make of it

17:58 aaelony: dbasch: it is well formed for the rows I have tried. If I manually replace " with \" for the cases I have tested, it works just fine

18:00 hiredman: github's highlighting seems to thing most of the code in tools.reader is a string literal :/

18:00 dbasch: aaelony: what happens if you try to parse {"a":1,"b":2}

18:00 bbloom_: hiredman: i think they've switched github's highlighter to use the same codebase as atom as a ploy to get ppl to contribute better highlighting for their editor

18:01 TEttinger2: aaelony, so there are strings like this in your data: "key": "Quoth the raven, "Nevermore." And he was totes right."

18:01 aaelony: It is certainly true that the data contains semi-colons, punctuation, and all sorts of stuff. I'm in the process of adding things to escape as I find them.

18:01 hiredman: bbloom_: :|

18:02 TEttinger2: semicolons are fine in strings... how are you parsing this...

18:02 aaelony: TEttinger2: There are strings like "a":"Out out darn spot. ;)"

18:03 TEttinger2: that shouldn't be any problem

18:03 aaelony: at some level, it's likely true that some kind of preprocessing or cleaning will have to act on this before the json parser will work.

18:04 TEttinger2: that should parse as the string "Out out darn spot. ;)"

18:04 aaelony: it's just not easy to identify from the error messages what the offending problem strings are

18:04 dbasch: aaelony: it’s either well formed json or it’s not. If it is, it should parse

18:04 aaelony: I will half the data until it works. then backtrack.

18:04 dbasch: you should not need to escape anyything

18:05 aaelony: I've used this library before, without issues.

18:05 dbasch: which library?

18:05 aaelony: It's a data thing. Thanks guys. I'll just hunt for the data problem.

18:05 jackson

18:05 dbasch: if it’s not well-formed json and you say it is, we can’t help you

18:06 aaelony: dbasch: thanks

18:07 There are multiple foreign languages in the data as well that may be interfering as well.

18:07 dbasch: aaelony: it’s either json or it isn’t

18:08 aaelony: thanks dbasch: It is supposed to be. I didn't produce it. I'll take this offline now. thanks to everyone.

18:09 dbasch: aaelony: keep in mind that foreign characters have nothing to do with it

18:10 aaelony: there may be lots of things in there, unicode, etc... I'm not as certain as you are.

18:11 dbasch: aaelony: unicode is absolutely fine. I hate to repeat myself, but your json is well-formed or malformed and the rules are pretty simple.

18:12 aaelony: I'm leaving this conversation now

18:18 dbasch: {"a":"v̛̼̰̳͎̟̹ͥ̈ͅo̡͗ͩ́͏̘̰̳̲͎k̵̨͕̩ͬͥ̉̌̓̏͐ḛ̫̟̠̳̖͎͇ͭ́ͭ̌̾̈́͟ ̷̭̲͙̤̯͙͓̄̄͡t̡̞̿̿ͯͪ͌͋̌͡h̵̯̒ͬ͌̌ͪ̇̀͘e̡̥̹͉͆̍̈́̏ͮ̿ͬ̀ ̵͓̫̥̱̌̈̌̈́ͅh̩̪̭̰ͩ̏̎̀͛̅̓̚i͓̝̦̎̈́ͤͦ̅̑̔ͫv̞͖̜̓̅ͥ̍e̶̮͈͒̆͌̎̉͆̋̒̚-̥͎͂̽͋̓̒ͨ̊̌m͇̱̭͈̹͇͕͌ͨ̓ͬ͡ͅi͙ͣ̍n̸͚̖ͧ͛̋̔͌͜d̪̈́͂ͬ͆͂̓

18:18 {"a":"v̛̼̰̳͎̟̹ͥ̈ͅo̡͗ͩ́͏̘̰̳̲͎k̵̨͕̩ͬͥ̉̌̓̏͐ḛ̫̟̠̳̖͎͇ͭ́ͭ̌̾̈́͟ ̷̭̲͙̤̯͙͓̄̄͡t̡̞̿̿ͯͪ͌͋̌͡h̵̯̒ͬ͌̌ͪ̇̀͘e̡̥̹͉͆̍̈́̏ͮ̿ͬ̀ ̵͓̫̥̱̌̈̌̈́ͅh̩̪̭̰ͩ̏̎̀͛̅̓̚i͓̝̦̎̈́ͤͦ̅̑̔ͫv̞͖̜̓̅ͥ̍e̶̮͈͒̆͌̎̉͆̋̒̚-̥͎͂̽͋̓̒ͨ̊̌m͇̱̭͈̹͇͕͌ͨ̓ͬ͡ͅi͙ͣ̍n̸͚̖ͧ͛̋̔͌͜d̪̈́͂ͬ͆͂̓

18:18 {"a":"v̛̼̰̳͎̟̹ͥ̈ͅo̡͗ͩ́͏̘̰̳̲͎k̵̨͕̩ͬͥ̉̌̓̏͐ḛ̫̟̠̳̖͎͇ͭ́ͭ̌̾̈́͟ ̷̭̲͙̤̯͙͓̄̄͡t̡̞̿̿ͯͪ͌͋̌͡h̵̯̒ͬ͌̌ͪ̇̀͘e̡̥̹͉͆̍̈́̏ͮ̿ͬ̀ ̵͓̫̥̱̌̈̌̈́ͅh̩̪̭̰ͩ̏̎̀͛̅̓̚i͓̝̦̎̈́ͤͦ̅̑̔ͫv̞͖̜̓̅ͥ̍e̶̮͈͒̆͌̎̉͆̋̒̚-̥͎͂̽͋̓̒ͨ̊̌m͇̱̭͈̹͇͕͌ͨ̓ͬ͡ͅi͙ͣ̍n̸͚̖ͧ͛̋̔͌͜d̪̈́͂ͬ͆͂̓

18:19 {"a":"v̛̼̰̳͎̟̹ͥ̈ͅo̡͗ͩ́͏̘̰̳̲͎k̵̨͕̩ͬͥ̉̌̓̏͐ḛ̫̟̠̳̖͎͇ͭ́ͭ̌̾̈́͟ ̷̭̲͙̤̯͙͓̄̄͡t̡̞̿̿ͯͪ͌͋̌͡h̵̯̒ͬ͌̌ͪ̇̀͘e̡̥̹͉͆̍̈́̏ͮ̿ͬ̀ ̵͓̫̥̱̌̈̌̈́ͅh̩̪̭̰ͩ̏̎̀͛̅̓̚i͓̝̦̎̈́ͤͦ̅̑̔ͫv̞͖̜̓̅ͥ̍e̶̮͈͒̆͌̎̉͆̋̒̚-̥͎͂̽͋̓̒ͨ̊̌m͇̱̭͈̹͇͕͌ͨ̓ͬ͡ͅi͙ͣ̍n̸͚̖ͧ͛̋̔͌͜d̪̈́͂ͬ͆͂̓

18:19 {"a":"v̛̼̰̳͎̟̹ͥ̈ͅo̡͗ͩ́͏̘̰̳̲͎k̵̨͕̩ͬͥ̉̌̓̏͐ḛ̫̟̠̳̖͎͇ͭ́ͭ̌̾̈́͟ ̷̭̲͙̤̯͙͓̄̄͡t̡̞̿̿ͯͪ͌͋̌͡h̵̯̒ͬ͌̌ͪ̇̀͘e̡̥̹͉͆̍̈́̏ͮ̿ͬ̀ ̵͓̫̥̱̌̈̌̈́ͅh̩̪̭̰ͩ̏̎̀͛̅̓̚i͓̝̦̎̈́ͤͦ̅̑̔ͫv̞͖̜̓̅ͥ̍e̶̮͈͒̆͌̎̉͆̋̒̚-̥͎͂̽͋̓̒ͨ̊̌m͇̱̭͈̹͇͕͌ͨ̓ͬ͡ͅi͙ͣ̍n̸͚̖ͧ͛̋̔͌͜d̪̈́͂ͬ͆͂̓

18:19 sdegutis: How did you know?

18:20 dbasch: not even 20 minutes before you did that, someone else did that in #swift-lang

18:20 Is that just spreading across IRC right now?

18:20 dbasch: sdegutis: what, zalgo?

18:21 oops, I pasted it too many times

18:21 sdegutis: dbasch: yeah

18:21 dbasch: but each line is parseable json

18:21 sdegutis: ,{"a":"v̛̼̰̳͎̟̹ͥ̈ͅo̡͗ͩ́͏̘̰̳̲͎k̵̨͕̩ͬͥ̉̌̓̏͐ḛ̫̟̠̳̖͎͇ͭ́ͭ̌̾̈́͟

18:21 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: :>

18:22 sdegutis: ,(def s "Z̷̡̥̹̗͉̖ͨͬͥA̬͍̲ͪ̌̂̕͟L͖͕̯̳͚̜͖͙͍̉͑̄͐ͯ̆̚G̢̪͙̬̤̦̺̍͒ͧ̄̉̐Ō̻̥͉̼̃̋̿̍̀͟!̲̻̰̳͊̐ͥ̎̎͢͜͠")

18:22 clojurebot: #'sandbox/s

18:22 sdegutis: ,s

18:22 clojurebot: "Z̷̡̥̹̗͉̖ͨͬͥA̬͍̲ͪ̌̂̕͟L͖͕̯̳͚̜͖͙͍̉͑̄͐ͯ̆̚G̢̪͙̬̤̦̺̍͒ͧ̄̉̐Ō̻̥͉̼̃̋̿̍̀͟!̲̻̰̳͊̐ͥ̎̎͢͜͠"

18:22 llasram: Huh

18:23 sdegutis: idunno

18:24 llasram: "Huh" -> "Not what I expected to see in my terminal Emacs session upon returning to it"

18:24 I imagine something is lost in the rendering

18:25 andyf: I'm amazed it renders so far outside of a normal line's "boundaries" in so many rendered

18:25 Renderers, that is

18:29 sdegutis: llasram: this is all i see https://www.dropbox.com/s/ms1q0byzn27gquq/Screen%20Shot%202014-11-25%20at%205.27.46%20PM.png?dl=0

18:30 llasram: i imagine there are secret words hidden in there which are evil or inappropriate or something

18:30 llasram: Wow

18:31 technomancy: the sepiroth

18:31 dbasch: that is what Pi looks like if you start reading it from the other end

18:32 gfredericks: :)

19:55 marcuscreo: #clojure

19:55 oops

21:15 danielcompton: ,s

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

21:16 danielcompton: does Clojurebot reset it's vars after a while?

21:16 verma: does the bot clearup stuff

21:16 ?

21:16 :)

21:16 danielcompton: clojurebot: do you?

21:16 clojurebot: Huh?

21:16 danielcompton: clojurebot: answer the question

21:16 clojurebot: excusez-moi

21:16 verma: clojurebot: kind sir, did you just take a shower?

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

21:17 verma: can I copy that weird text

21:17 ,(def s "Z̷̡̥̹̗͉̖ͨͬͥA̬͍̲ͪ̌̂̕͟L͖͕̯̳͚̜͖͙͍̉͑̄͐ͯ̆̚G̢̪͙̬̤̦̺̍͒ͧ̄̉̐Ō̻̥͉̼̃̋̿̍̀͟!̲̻̰̳͊̐ͥ̎̎͢͜͠")

21:17 clojurebot: #'sandbox/s

21:17 verma: zelol

21:18 Z̷̡̥̹̗͉̖ͨͬͥ

21:18 L͖͕̯̳͚̜͖͙͍̉͑̄͐ͯ̆̚

21:18 L͖͕̯̳͚̜͖͙͍̉͑̄͐ͯ̆̚

21:21 kenrestivo: what is this, unicode torture day?

21:21 danielcompton: kenrestivo: international unicode torture day

21:31 take your unicode child to work day

21:39 kenrestivo: i've been having strange problems with clojure.tools.namespace.repl/refresh blowing "namespace not found" errors

21:39 where, the namespaces are definitely there, the source is all there, and i can load them manually no problem

21:49 akkad: anyone here using newrelic with clojure?

21:51 devn: Given {:foo [{:bar 1} {:bar 2}], :baz [{:bar 3} {:bar 4} {:bar "hello"}] ...}, I want [[1 3] [1 4] [1 "hello"], [2 3] [2 4] [2 "hello"]]

21:52 kenrestivo: someone just asked almost that exact question yesterday

21:52 i think it was a reduce-kv answer

21:53 justin_smith: something like (map #(map bar %) (vals data)) I think

21:53 makes those mapvs if you really need vectors

21:54 err wait

21:54 there is structure there I did not notice, never mind, that is wrong

21:54 brb

21:55 kenrestivo: the :foo and :baz seem almost superfluous.

21:55 devn: you can treat them that way, sure

21:56 mgaare: I don't know what I'm doing wrong with cljx. I've got a .clj ns that requires a .cljx ns, and it complains it can't find it and exceptions out even of the lein cljx once task

21:58 danielcompton: mgaare: do you have code samples you can share?

21:58 andyf: kenrestivo: Shot in the dark: do any of your source files contain namespace names that do not correspond to the file names? Eastwood can quickly tell you if so (1st check it does)

21:59 mgaare: danielcompton: yeah, hangon

21:59 kenrestivo: andyf: ooh, cool, will try. i'm pretty sure not because lein-check is copacetic

21:59 andyf: I don't think Lein check will tell you that

21:59 kenrestivo: but running it through the eastwood/kibit gauntlet sounds like a fine idea

22:00 danielcompton: kenrestivo: kibit will blow up if you're doing anything too weird so there's that

22:00 andyf: It is a not uncommon mistake that can lead to subtle problems or un executed tests

22:05 kenrestivo: wow, eastwood is pretty damn cool.

22:05 tho it is very upset about timbre log/info, complaining about: (clojure.core/not= file__5335__auto__ "NO_SOURCE_PATH")

22:06 specifically constant-test: Test expression is always logical true or always logical false: (clojure.core/not= file__5335__auto__ "NO_SOURCE_PATH")

22:06 andyf: kenrestivo: I just verifies that Lein check does not catch all cases of file name / namespace mismatch. It did on a core.clj file in a new project I created , but not on another file I created with bad namespace

22:06 mgaare: danielcompton: https://gist.github.com/mgaare/7118a0975c13099ef29d

22:08 kenrestivo: eastwood also complained about a missing var, which wasn't. i had (:require [foo.bar :as bar]) and then (bar/baz ...) later, and it complained that bar was not found

22:08 andyf: kenrestivo: Yeah, since it macro expands first then does its checks, some macros lead to too many warnings. I have a thought on a semi-convenient way to selectively shut those off, but not yet implemented

22:08 kenrestivo: it thought bar was a var not a namespace alias

22:09 danielcompton: mgaare: what happens if you remove literal

22:09 andyf: kenrestivo: Open source project? If so, a github issue would be welcome

22:09 mgaare: danielcompton: remove as a dep from jena?

22:10 kenrestivo: no, sadly, not. if i can get a minimum repro i will tho

22:10 andyf: Was bar/baz inside back quoted form ?

22:11 kenrestivo: nope

22:11 danielcompton: mgaare: I mean just remove the file

22:11 kenrestivo: hmm, actually, it was first arg to swap! so maybe there's some macro magick in swap!

22:11 danielcompton: mgaare: temporarily delete it

22:12 andyf: Ok. Then it might be a case I haven't seen before.

22:13 kenrestivo: andyf: cool tool though. if it wasn't blowing so many spurious warnings about constant-test, i'd probably run it often

22:14 andyf: I'll create a test case like that - could be significant. Swap! is not a macro, but I am often finding new cases I have not seen before like this

22:15 mgaare: danielcompton: ok, I just removed all references to .cljx namespaces from .clj namespaces, ran lein cljx once, reinstated the references, and now a repl starts up properly.... this doesn't seem like how cljx is spose to work though

22:15 andyf: I tend to err on the side of "warn if not sure" and then quiet down new cases that are too noisy as I discover them

22:15 danielcompton: mgaare: did you try doing a lein clean before the lein cljx once?

22:15 mgaare: yea

22:16 andyf: Sorry, I guess not much help on the tools.namespace weirdness, though

22:18 kenrestivo: yeah, it's very odd. it's dying on every required namespace

22:19 andyf: Do you have example timbre logging call that gives warning for me to reproduce ?

22:21 kenrestivo: it's just log/info

22:23 andyf: You can now disable constant-test linter globally in your project either on cmd line or in project.clj file. E.g. Lein Eastwood '{:exclude-linters [:constant-test]}'

22:23 kenrestivo: interestingly, the namespace problem goes away if i gut ALL the files, removing everything except the ns decl :-/

22:23 mgaare: ah, I think user.clj was at fault

22:23 kenrestivo: so now it's a house-of-cards situation, i'll start adding stuff in do a bifurcation check to find where it breaks

22:24 andyf: The part in quotes can be value of :eastwood key in your project.clj file

22:24 kenrestivo: oh cool

22:26 zRecursive: Is it convenient using Clojure to create a Maxima-like software ?

22:29 andyf: Probably as convenient as it would be in scheme, Common Lisp, etc

22:29 Still work :-)

22:29 zRecursive: hope so

22:31 andyf: There is a library called expresso on github that is a start, but not sure how much is there

22:32 zRecursive: thanks

Logging service provided by n01se.net