#clojure log - Dec 31 2014

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

0:10 sm0ke: in java.jdbc api if i have a dbspec like {:connection-uri "jdbc:...." :password ".."} it does not work

0:10 is there a way around this?

0:11 i can append password to uri but the delimiters are not same for every vendor

2:20 yedi: do you ever just.. absentmindedly wander through a codebase and kinda just like gaze at the code?

2:20 is that a thing?

2:20 Empperi: everyone does

2:20 rhg135: It is

2:20 Empperi: everyone has brainfreezes every now and then

2:37 rritoch: Do leiningen projects require a subversion? I have a project with version "3.7-SNAPSHOT" but when I try to use it as a dependency it isn't being added to the classpath

2:38 rpaulo: channels with transducers look scary with regards to memory usage

2:42 rritoch: Oops, I miss-interpreted the problem. The dependency isn't showing up on the classpath for a leiningen plugin that I'm developing, so when I run lein mytask ... I'm getting a class not found exception, but the class is provided by a dependency.

2:51 rpaulo: Tranducers don't block, are you sure you didn't do something crazy like pumping a few million transducers onto your channel? I've run into problems before when using non-blocking code with channels.

2:52 rpaulo: I was just watching Rich's talk

3:08 rritoch: I found my problem, my plugin's project is using :eval-in-leiningen true but it is being ignored, when I added :eval-in :leiningen to it the problem repaired itself.

3:20 dysfun: rritoch: that changed a while back

3:21 rritoch: dysfun: I never noticed. This is my first plugin with a dependency

3:25 dysfun: I'm trying to integrate sablecc with leiningen, so far so good but the integration is a bit messy, many of the functions I need are private so I'm calling the apps main function to access private features, like the license and usage docs.

3:27 dysfun: oh i remember sablecc

3:27 used it as part of the perl5-on-jvm project

3:29 rritoch: What about geting rid of this warning notice; Warning: compile already refers to #'clojure.core/compile ... I added (:refer-clojure :exclude [compile]) to my ns declaration but it's still giving a warning.

3:30 dysfun: where are you seeing this?

3:30 rritoch: dysfun: Well, this is my first sablecc project, it doesn't look like it should be too painful, but things will go a lot smoother if I can develop the extensions and actions in clojure.

3:31 dysfun: yeah, clojure was a bit less well developed when i was using sablecc :)

3:31 rritoch: dysfun: I haven't published any of this yet so I really can't point it out, I'm using clojure 1.5.1

3:31 dysfun: i.e. i hadn't even heard of it yet

3:31 any reason you're not on 1.6.0?

3:31 rritoch: dysfun: No, I'll try that

3:32 dysfun: I always use 1.5.1 for anything that doesn't require the newest features... It is just a habbit

3:36 dysfun: 1.6.0 version didn't remove the warning though

3:39 dysfun: I've made a task sablecc with 3 subtasks (license, usage, and compile), license and usage are working but they're throwing that warning. I haven't made it to compile yet since I need to figure out where grammers should come from, and where the generated sources should go.

3:40 dysfun: Eventually, if possible, I'd prefer doing it as a hook on javac but to start with these subtasks should be good enough

3:42 dysfun: you can add a hook with the robert.hooke library that comes with leiningen

3:43 and i suspect your problem is one of inherited environment. as part of its setup, leiningen does a bunch of stuff before running your plugin

3:43 the quick fix is to s/compile/build/

3:44 i managed to do what i needed without writing the leiningen plugin last time, so i can't help much with debugging it

3:48 rritoch: dysfun: I'm working with sablecc 3.7 which doesn't seem to utilize anything relevant from the environment.

3:48 augustl: justin_smith: haha, will yell "concurrency" the next time someone tells it, thanks :)

3:50 rritoch: dysfun: I think I'll just add a :sablecc-source-paths and scan for *.scc 's and gen to target/compiled_sources, though getting those compiled to target/classes may still be a challenge.

3:51 dysfun: i thought sablecc just spat our java files? /me can't remember, it's been a while

3:52 rritoch: dysfun: I'm using sablecc-maven-plugin as a model

3:52 * dysfun didn't

3:52 dysfun: i'll be interested to use it when you get it worked out though :)

3:52 rritoch: dysfun: It does, but it should be transparent, and put somewhere that developers know they can't mess with, like the target folder.

3:53 dysfun: well, if it only exists as a hooked thing, hard for them to mess with it :)

3:53 say, a hook just before javac runs

3:54 rritoch: dysfun: That is one of the things I want to add, but avoiding recursion may be a mess since the generated sources need to be compiled, and they won't be in the :source-paths

3:55 dysfun: yes, but you can temporarily add them to :source-paths

3:59 rritoch: dysfun: That may work, set :source-paths to [target/generated_sources] and run javac, then run javac again with the original source paths.

3:59 dysfun: If I do it within the hook that would probably avoid a recursion

4:00 dysfun: For debugging purposes though I'm starting with tasks to make sure there aren't any problems with the process

4:01 dysfun: I haven't made a hook yet, so tasks are what I know

4:01 rpaulo: was server-socket from clojure-contrib put in core.async?

4:03 rritoch: dysfun: There also doesn't seem to be an official release of sable on maven, so I also need to make a custom distribution on clojars that builds with leiningen.

4:04 dysfun: I've already done that, but I need to re-do it as a fork from their project on GIT hub.

4:04 err: sablecc

4:05 dysfun: yay

4:05 nothing like a stack of yaks, eh?

4:08 rritoch: "stack of yaks"? I'm originally from NY and have no idea what that means

4:10 dysfun: shaving yaks. yaks breed (like rabbits?) and suddenly you have a stack of them to shave before you can solve your real problem

4:11 rritoch: dysfun: hehe, exactly

4:12 dysfun: A lot of work just to get to the fun part of making an interpreter

4:12 dysfun: six weeks ago i had one active project. now i have 16

4:13 some of them are variations on one theme, but they're on the list of stuff i'm doing because they're interesting

4:13 and if you can't spend your time developing doing interesting things, why bother?

4:17 rritoch: dysfun: hehe, I don't really think most of my projects are interesting. The only common theme is making difficult things easier, and breaking current limitations.

4:18 dysfun: breaking limitations is cool, you get lost in the possibilities of what you can do with the new power

4:18 rritoch: dysfun: breaking being the operative word because it often involves a lot of collateral dammage

4:18 dysfun: meh. programming is all tradeoffs

4:22 rritoch: dysfun: I honestly don't worry much about the economics of my apps, I've run into way too many bottomless pits where there is no end to the possiblities. Instead I just target an option that gets the job done with as few negative side-effects as possible.

4:23 dysfun: there's something to be said for "the simplest thing that works"

4:24 rritoch: dysfun: A bit like code-golf and optimization, you can spend weeks to sequeeze out a few extra cpu cycles, but it isn't always worth it.

4:24 dysfun: oh i rarely look at performance these days. clojure is really 'fast enough' for all my purposes even if i wrote really crappy code (and i haven't been nearly drunk enough for that this year)

4:25 not until there's a problem

4:27 also i wish postgres were as straightforward to deal with as clojure

4:29 yocapybara: dysfun: agreed - am dabbler with pg and clojure and found dealing with hstore etc bit confusing

4:30 dysfun: my favourite is json columns

4:31 https://gist.github.com/jjl/8124490

4:31 but that's just the clojure side

4:35 yocapybara: dysfun: had to adapt some code I found to convert hstore to map (and vice versa) also if I remember right, which was a nice modification

4:35 pg does inspire me with more confidence than mysql even though I have a lot more experience with mysql

5:02 dysfun: yocapybara: yeah, the switch was hard for me at first, but it's much better

5:03 yocapybara: dysfun: just the hstore is a revalation for me. Storing some json too but have't used any of the real json capabilities yet

5:04 dysfun: 9.4 was released just before christmas with binary json support

5:08 yocapybara: that's right - I haven't quite got straight what that enables you to do in practice - more efficient storage of json?

5:08 dysfun: pretty much

5:08 speed is amazing considering the dynamism

5:09 they've massively improved the index support for it as well

5:09 they're now smaller and faster

5:11 yocapybara: hmm interesting, just looked it up, so for operations in the DB concerning JSON, better to use JSONB. Interesting though some logic I perform in the program, looks like I might be able to push some of that into the DB with greater speed if I save it as JSONB

5:12 rritoch: dysfun: I have sablecc generating the sources, but they're not compiling, I'll upload the code to github so you can see it. The compilation phase isn't where I expected problems, but that's where I'm at.

5:13 dysfun: yocapybara: just be aware where you're making tradeoffs. the database is a handy place to arbitrate whether some data is suitable, but doing so can make write-heavy workloads suffer

5:15 yocapybara: dysfun: thanks - I'll have to have a good read up of the tradeoffs. Mostly any JSON interaction I do is just retrieving, and I might be able to push some of what I do after the retrieval down to pg. Fingers crossed :)

5:15 dysfun: that's less of a problem because you can spin up many slaves

5:15 read-heavy workloads can be made to work pretty well on postgres to pretty huge scale

5:16 rritoch: dysfun: can you take a look and let me know if you can see why this isn't compiling the generated sources into the target/classes folder https://github.com/rritoch/lein-sablecc/blob/master/src/leiningen/sablecc/compile.clj

5:16 yocapybara: dysfun: I'm just on one instance, is there getting to be concensus on how to do clustering with pg these days?

5:19 dysfun: yocapybara: if you can assume 9.4, lots of cool stuff just got added regarding that

5:19 yocapybara: they've paved the way for doing master-master setups pretty well

5:19 rritoch: my browser crashed, give me a few minutes

5:19 yocapybara: dysfun: ooh that is awesome I will check it out

5:20 rritoch: Ok, no problem. The compiler code is (lein-compile/compile (assoc project :java-source-paths [target-path])) where lein-compile is the leiningen.compile namespace

5:21 and target-path is where the sources where generated

5:32 dysfun: rritoch: just started looking. you could use if-let around line 9 to make that shorter

5:36 rritoch: dysfun: These compile problems have been hauting me a lot lately, when I type lein compile my java sources don't compile, they don't compile until I do lein repl or lein run

5:37 dysfun: I'm not sure if this problem is related or not

5:37 dysfun: you need to opt-in to it i think

5:40 rritoch: dysfun: What doyou mean by opt-in?

5:41 dysfun: i don't remember the mechanism, but i think you don't get java compilation completely for free

5:43 * dysfun checks the code out

5:44 rritoch: My test project is :aot :all, so :aot will already be set in the project parameter in the test that I've done

5:44 But I don't know what else I need to do to force java source compilation

5:45 My test project doesn't have any refrences to the generated sources in clojure though, that may have something to do with it, but I'm not sure.

5:47 I'll try using the javac task, maybe that will help

5:48 Yeah, that should have been self-evident, they're all compiling now, I'm just going to add that optimization you suggested

5:53 Ok, I uploaded the changes, the plugin is now functional so I just need to figure out how to do this automatically via a hook and this plugin will be ready for release

5:54 dysfun: for that, you'll want the robert.hooke namespace

5:54 rritoch: The license function doesn't work due to a problem with the available dependency, but that's beyond the scope of this plugins responsiblity.

5:55 I've been able to get license to work with a custom dependency, but it isn't extremly critical at this point.

5:58 dysfun: The documentation says the hooks are opt-in

5:59 dysfun: Does that mean there's no way to get them automatically implemented when the plugin is in use?

5:59 dysfun: er it doesn't mean like that, no

6:00 you put the plugin and config in your project.clj and you use the hooks you need

6:00 there's a guide on the wiki i think

6:03 daniel`: anyone have an example of a liberator resource using put! and an implementation of the new? decision?

6:10 dysfun: there have been a lot of liberator questions recently. is it really popular or really complicated?

6:17 ticking_: dysfun: maybe the httop rest foo is really complicated :D

6:17 dysfun: doing it right can be :)

6:17 mi6x3m-alt: any way to call a constructor with reify?

6:18 rritoch: As expected the hook method has recursion problems

6:18 I'm trying a var/binding to see if that resolves it

6:18 dysfun: rritoch: easy, dynamically bound variable

6:21 rritoch: dysfun: Well that didn't completely solve the problem, it's still generating sources too many times. I'm switching to an atom to solve it.

6:23 daniel`: dysfun: its a bit unusual and it seems to be popular, at least i never see any other REST frameworks being mentioned

6:24 rritoch: dysfun: the atom worked, I just need to clean this code up and try a few more tests

6:24 daniel`: the documentation is a bit overwhelming and there aren't dont seem to be many real world examples

6:24 i can follow the decision points and see where things are going wrong but i don't know if im doing things the 'right' way

6:25 dysfun: is liberator the one that shows you the decision graph?

6:26 it looked cool if so, but i've been too busy needing to ship to play with it

6:26 ticking_: mi6x3m-alt: reify is mostly for interfaces or protocols, what you want is probably proxy

6:26 see http://stackoverflow.com/questions/4368332/provide-a-constructor-with-clojure-reify

6:26 mi6x3m-alt: ticking_: yes I am using proxy for such situations, I got confused since proxy seems not to be handling protected methods well

6:27 daniel`: dysfun: yes, that one

6:39 rritoch: dysfun: Ok well making the hook wasn't too painful, I've uploaded the changes and added some brief usage instructions to the readme

6:41 dysfun: Oops, one more change, I left some obsolete code in the compile task that isn't needed anymore

6:41 mi6x3m-alt: Clojure, what should I do if proxy is no overriding a method as requested?

6:45 rritoch: dysfun: Ok, I think this plugin is compete, it seems to work either via a hook or via, lein sablecc compile .

6:47 Dysfun uploading it to clojars now (as a snapshot since it isn't well tested)

6:47 If I don't run into any more bugs I'll release it

6:52 hellofunk: (inc dysfun)

6:52 lazybot: ⇒ 3

6:52 hellofunk: (inc rritoch)

6:52 lazybot: ⇒ 3

6:52 hellofunk: happy new year fellas

6:52 or ladies

6:55 daniel`: hny

6:56 rritoch: Happy new years :) Hellofunk

6:57 I must admit this is the first time on IRC for new years, I guess I've officially earned the "geek" title. I'm in GMT+8 so its midnight in 4 hours.

6:59 luxbock: rritoch: philippines?

6:59 hellofunk: rritoch: HK, Singapore, or Philippines?

6:59 rritoch: Philippines

6:59 kungi: Short question: "Clojure's primitve data structures" the 's is correct in this case?

6:59 hellofunk: rritoch: nice, my wife is in manila right now. almost feel like hopping on a plane myself

6:59 kungi: rritoch: Happy new year! :-)

7:00 yguan: happy new year!!!

7:00 rritoch: hellofunk: ofw?

7:01 hellofunk: rritoch: which of these do you mean: http://www.urbandictionary.com/define.php?term=OFW

7:01 rritoch: Overseas Filipino Worker

7:01 hellofunk: rritoch: oh, no i'm not

7:02 rritoch: I suppose technically I'm an OFW according to the urban dictionary, but I'm a permanent resident here with my wife... Better than dealing with U.S. immigration, and as a programmer I prefer this weather to the snow in NY

7:03 hellofunk: rritoch: i hear you.

7:04 rritoch: i think i could live fine in a place like Makati

7:06 rritoch: hellofunk: Well, I'm in visayas, it isnt' that bad if you have a generator and water pump (which we do).

7:06 hellofunk: rritoch: no doubt. life in phils is def a different style than most might expect

7:10 rritoch: hellofunk: From what I hear its not much different than life on most islands, you need to be very self-sufficient and plan ahead. Having a good lawyer also helps :)

7:17 luxbock: I'm trying to create my own binary format with ztellman's Gloss

7:18 I have a 1326 element array of floats and I'm trying to figure out when it makes more sense to store them as sparse arrays then normal arrays where elements missing are just zeros

7:19 is this correct: 1326 * 4 = n * (2 + 4) + 2, n = 883.666... ?

7:21 so either it's 1326 elements that take 4 bytes each, or it's n, the amount of elements present in the array, times 2 bytes for the index of the element and 4 for the float of the value, plus 2 bytes to indicate how many elements there are in the sparse array

7:28 dysfun: rritoch: sweet :)

7:29 rritoch: luxbock: If the array is always the same size why not just use something like {(int) nvalues, byte[] bitmask[166], float[] values } where each bit in the bitmask represents if the value is presant or not? That would probably be more efficient than a sparse array.

7:30 the nvalues is of course so you can calculate ahead of time how large the values array is

7:31 luxbock: rritoch: I have to read up on bitmasks

7:33 rritoch: luxbock: Just look at your actual data, if the number of items with a value is > 87 => 87 = (166/4) + 4, than a bitmask uses less storage space.

7:34 err, 166/2 which brings you to an equivalent number of indexes.

7:35 luxbock: rritoch: my data is a tree-structure which I'm storing as a list-view, where each node contains a handful of these 1326 element float arrays, so when serializing my plan was to check for each node how many elements it has and then use the sparse/full representation with a prefix to distinguish which one it's using

7:36 my other goal besides saving space is to be able to memory-map the file so that I can look up a nodes value from its index without reading the whole file into memory at once

7:40 rritoch: luxbock: Memory is really the least of your problems, you have to consider that most operating systems read files in blocks, typically 4096 bytes each

7:41 luxbock: Reading from a disk is slow

7:42 luxbock: So which option gives you the best chance of having all your data in one block, and you may as well just read the entire array into a cache to reduce the need to re-read the same data as much as possible.

7:44 luxbock: I'd be reading one node at a time, where each node has 4-20 of these float arrays and a few other things

7:45 and I plan on serving these nodes over http to a web app which visualises the data for the client

7:45 the client requests the node id and gets served the data for that node

7:46 but I mostly don't know what I'm doing and I'm learning as I go so if you have any feedback on my plan then I'd love to hear it :)

7:46 rritoch: luxbock: If you enable gzip compression on your http server you may as well just deliver the raw arrays, gzip should compress out all of your zeros

7:46 luxbock: At least for dealing with the transport layer

7:47 luxbock: At the disk level your probably better off with a bitmap format, and in memory your probably best with a sparse array

7:47 luxbock: rritoch: cool thanks

7:49 what do you think of the plan to use a different data format for each node depending on how many elements there are in one array? since one node has many arrays, and all of the arrays in a node have the same amount of elements, then I think this could save me some space

7:57 rritoch: luxbock: That would depend on your server load, if your server load is low < 50%, than that would be fine, but there's alot more logic involved when you start typing your nodes.

7:58 luxbock: The bottleneck of most web servers is the disk usage, most web servers hover arround 99% most of the time.

7:58 luxbock: Especially if the server has a lot of database usage on it

8:03 If your only maintaining a few of these files and they're not modified as often as they're read you could keep the entire file in memory using memcached and your processing would be almost instant.

8:05 That depends on their size, but in the common case, 1 mb file, 10-100 requests per second, your problem is that youdon't want to multiply that 1mb by 10-100, but if your processing is faster because you don't need to wait for the data to be read you really don't end up multiplying your memory usage because it's released quickly.

8:06 If it takes you 10 seconds to read the file, and your getting 10 requests per second, than you can multiply ram usage by about 100, but if it takes 0.1 seconds to read the file, and your getting 10 requests a second, there's no ram usage multiplicaaation.

8:08 mi6x3m-alt: llasram: are you available by any slight chance?

8:08 rritoch: It is why memcached is so popular, it makes servers more efficient.

8:08 mi6x3m-alt: or someone with knowledge on proxy?

8:08 I have a public method not being overriden

8:12 rritoch: If there is no memcached available, you can of course still do it from most clojure technologies as you should be able to store persistent data someplace, such as inside the servlet.

8:41 luxbock: rritoch: sorry was afk for a bit

8:42 rritoch: I don't need to modify these files once they have been written

8:43 and they will be computed by a different computer than the one running the web server

8:43 so the whole file might not even fit into the memory of the machine that runs the web server at once

8:43 which is why I'd like to use memory mapping

8:58 rritoch: luxbock: In that case disk reads are going to be your bottleneck, anything you can do to compress the data structure, including typing your nodes, will probably provide significant performance improvements, you can even try gziping the individual nodes if you think it may help.

8:58 luxbock: rritoch: oh yeah I had thought of gzipping the whole tree (in case it's small enough to fit in memory at once) but I hadn't thought of gzipping individual nodes

8:59 rritoch: what do you mean by 'typing your nodes'?

8:59 rritoch: luxbock: You suggested using different formats depending on the size of your array

9:00 luxbock: That will require a type field to determine the type of the array

9:00 luxbock: anyhow, I have to go, have a good new year and good luck.

9:01 luxbock: thanks, happy NYE :)

9:17 sm0ke: ,(str "A " (apply str (repeat 10 "very ")) "Happy New Year to Clojure community :D!")

9:17 clojurebot: "A very very very very very very very very very very Happy New Year to Clojure community :D!"

9:42 gfredericks: you could do that with all symbols

9:43 ,(concat '(A) (repeat 10 'very) '(Happy New Year to Clojure community :D!))

9:43 clojurebot: (A very very very very ...)

9:43 gfredericks: oh well

9:44 SagiCZ1: isnt :D a keyword though?

9:44 ,(map type '(hello :D))

9:44 clojurebot: (clojure.lang.Symbol clojure.lang.Keyword)

9:45 gfredericks: yeah I spoke sloppily

10:28 SagiCZ1: happy new year #clojure.. thank you all for your patience, help and for being almost always here!

10:29 teslanick: SimpleDateFormat. tells me it's been 2015 since Monday.

10:32 gfredericks: there was a lot of talk about that recently. not sure why I haven't heard of it before, you'd think it'd be an annual tradition

10:33 mi6x3m-alt: a bug with SimpleDateFormat?

10:34 gfredericks: I think it's just a misleading naming convention or something

10:34 there's this weird alternate definition of the year

10:34 I have no idea what the use of it is

10:34 mi6x3m-alt: teslanick: can you show us your format?

10:34 teslanick: Yeah, I was referencing stuartsierra's warning from yesterday, I thought it would be cute.

10:34 mi6x3m-alt: I myself had an issue with YYYY accepting 2 digits also

10:34 teslanick: stuartsierra: user=> (.format (SimpleDateFormat. "yyyy-MM-dd") (Date.))

10:34 stuartsierra: "2014-12-30"

10:34 stuartsierra: user=> (.format (SimpleDateFormat. "YYYY-MM-dd") (Date.))

10:34 stuartsierra: "2015-12-30"

10:34 mi6x3m-alt: but this is documented

10:35 teslanick: It's a joke. -_-

10:36 mi6x3m-alt: ,(.format (java.text.SimpleDateFormat. "yyyy-MM-dd") (java.util.Date.))

10:36 clojurebot: "2014-12-31"

10:36 mi6x3m-alt: ,(.format (java.text.SimpleDateFormat. "YYYY-MM-dd") (java.util.Date.))

10:36 clojurebot: "2015-12-31"

10:36 mi6x3m-alt: indeed

10:37 teslanick: Because YYYY is the year for the current week, while yyyy is the year for the current day.

10:37 mi6x3m-alt: teslanick: no, this is correct actually

10:37 YYYY is the next week year which is 2015

10:40 teslanick: I never said it was incorrect. I was making a cute joke that apparently has fallen flat.

10:41 mi6x3m-alt: somewhat but it's still funny :)

10:43 teslanick: You know what they say about explaining jokes: it's like dissecting a frog. Nobody laughs and the frog dies.

10:52 mi6x3m-alt: teslanick: I am sorry I have put you through this horrible experience :>

10:52 teslanick: ;)

11:03 llasram: mi6x3m-alt: did you figure out your proxy issue?

11:04 mi6x3m-alt: llasram: still sweating over it :)

11:04 a legit method is not recognized

11:04 llasram: mi6x3m-alt: code gist?

11:08 mi6x3m-alt: Also, are you sure the method is "legit" and not merely "dope"?

11:08 </humor-joke>

11:10 mi6x3m-alt: llasram: hehe, yes :)

11:10 sent you a PM

11:15 TimMc: gfredericks: I'd expect about half the years would have it, but only in clumps of about 7.

11:16 AlwaysBCoding: Anybody know how I can run one single test with clojure.test ... Like not all tests in a namespace like (run-tests) does, but just one deftest at a time?

11:16 llasram: AlwaysBCoding: If you're aren't using fixtures, you can just invoke the test var

11:16 AlwaysBCoding: What if you are using fixtures?

11:17 TimMc: &(mod 365 7)

11:17 lazybot: ⇒ 1

11:17 llasram: AlwaysBCoding: Then you should stop -- it's not a great feature. ;-) I think there's a function in clojure.test which helps though... one sec

11:19 AlwaysBCoding: haha now that I'm thinking about it, I guess it makes sense to just do your setup / teardown inside of an individual test so you can run it in isolation... isn't really a need to use fixtures

11:20 llasram: AlwaysBCoding: I think this should work: (clojure.test/test-vars [#'your-test-var])

11:20 The more-convenient-looking `test-var` function unfortunately does not run fixtures -- `test-vars` is what handles that

11:23 TimMc: &(letfn [(fmt [f y] (.format (java.text.SimpleDateFormat. f) (java.util.Date. (- y 1900) 11 31)))] (filter #(= (fmt "YYYY" %) (fmt "yyyy" %)) (range 1990 2020)))

11:23 lazybot: ⇒ (1994 2005 2011 2016)

11:23 TimMc: &(letfn [(fmt [f y] (.format (java.text.SimpleDateFormat. f) (java.util.Date. (- y 1900) 11 30)))] (filter #(= (fmt "YYYY" %) (fmt "yyyy" %)) (range 1990 2020)))

11:23 lazybot: ⇒ (1994 1995 2000 2005 2006 2011 2016 2017)

11:24 TimMc: So the last couple days in December *usually* show a mismatch.

11:25 llasram: It's still pretty weird. What are the circumstances where you'd want the week-year behavior?

11:26 andyf: ,(* 100.0 (/ 8 30))

11:26 clojurebot: 26.66666666666667

11:27 AlwaysBCoding: IIasram: thanks got it to work, much better already :)

11:27 llasram: AlwaysBCoding: np

11:28 TimMc: llasram: payroll or something

11:28 llasram: You *never* want YYYY-MM-dd -- you combine YYYY with some other date thing like "week number".

11:31 &(.format (java.text.SimpleDateFormat. "YYYY-ww") (java.util.Date.))

11:31 lazybot: ⇒ "2015-01"

11:53 dagda1_: is there a shorter way of selecting from a vector than this (first (filter #(not= :something %) my-vector))

11:55 arrdem: what are you trying to do precisely?

11:56 Bronsa: ,(some #{:something} [:a :b :something :c])

11:56 dagda1_: ^

11:56 clojurebot: :something

11:56 Bronsa: oh uhm, you want the opposite

11:56 arrdem: Bronsa: complement

11:57 Bronsa: arrdem: no, that'd return a bool

11:57 ,(first (remove #{:something} [:something :something :a :something]))

11:57 clojurebot: :a

11:57 Bronsa: meh.

11:57 arrdem: bah

11:58 clearly we need a complement set type that contains everything and can only be subtracted from.

11:58 justin_smith: arrdem: unset

11:59 it would make sense to conj to an unset, but only after having removed the item previously

11:59 (similarly to disj on sets...)

11:59 arrdem: disj on an unset would work, conj on an unset would be silly

12:00 assuming that you started with the empty unset at least

12:00 andyf: as silly as doing disj on an empty set

12:00 justin_smith: andyf: exactly

12:00 mi6x3m-alt: llasram: I'm back

12:01 andyf: arrdem: I think you should submit a JIRA ticket on Apr 1 2015

12:01 arrdem: andyf: oddly specific :P

12:02 unsets are actually a structure I've wished for more than once..

12:02 andyf: Wait, if we could get about 5 fun ideas ready by Apr 1, and submit them all on that day ....

12:02 just a set that negates the answer for membership tests?

12:04 arrdem: no, because disj on a ∁set is conj on the underlying set, conj on a ∁set is disj on the underlying set, union/subtraction should then trivially work.

12:05 I suppose ¬set is a better name than ∁set

12:06 andyf: but you can also just think of it as a 'set of things I don't want', and reverse the uses of conj/disj on it?

12:06 I guess that is inconvenient in your use cases?

12:07 arrdem: you could do the logical negation manually and I think that's what I wound up doing

12:07 forget what I was up to that this seemed like a good idea. it was a while ago.

12:07 andyf: don't ever try to do a union of one with a regular set :)

12:16 justin_smith: &(contains? #{Double/NaN} Double/NaN)

12:16 lazybot: ⇒ false

12:16 arrdem: nope

12:16 justin_smith: so would we get a similar but complementary behavior from ¬set ?

12:17 AimHere: (= Double/NaN Double/NaN)

12:17 ,(= Double/NaN Double/NaN)

12:17 clojurebot: false

12:17 justin_smith: &(= Double/NaN)

12:17 lazybot: ⇒ true

12:17 andyf: I think you might have to implement Java first

12:18 Hmmm. My copy and paste of the complement symbol before the word "Java" failed

12:18 justin_smith: haha, makes more sense now :)

12:18 someone should totally make ¬Java

12:19 (almost) nothing is an Object

12:19 everything is a first class value, except Objects

12:20 Bronsa: invoking a method on any object throws a NPE, except for nil?

12:21 well, null

12:22 justin_smith: it would look like you were calling thunks as if they were varargs ml functions (terminating arg is always ())

12:32 TimMc: java.net.URL bites again

12:34 Random program hang tracked down to something iterating over a bag of stuff and calling .equals on things. Turned out there was a URL in there and it was trying to do name resolution and failing.

12:34 Just terrible.

12:34 justin_smith: java.net.URFucked

12:35 yeah, side effects on .equals is batty

12:35 bacon1989: Was wondering if there's any info on Feature Expressions in clojure 1.7, i'm interested in maybe contributing some time converting some things to CLR

12:37 arrdem: I don't think that there's anything really official out besides the design page on the dev wiki

12:38 Bronsa: and the patches in the clj+tools.reader issue trackers

12:38 arrdem: http://dev.clojure.org/display/design/Feature+Expressions

12:38 dysfun: what's the easiest way to discover namespaces inside of a namespace? i want people to be able to drop scripts in a directory and them be picked up when a utility is run

12:38 arrdem: Bronsa will know the jira stuff better than I do.

12:39 Bronsa: but afaik those tickets don't necessarily implement the solution that will eventually be picked

12:39 justin_smith: dysfun: "namespaces inside of a namespace"? what does that mean?

12:39 arrdem: dysfun: tools.namespace

12:39 Bronsa: arrdem: I believe all the tickets are linked in that design page

12:39 dysfun: justin_smith: "get me namespaces foo.*" would return foo.bar, foo.baz.quux

12:39 arrdem: ty

12:40 justin_smith: dysfun: oh. namespaces are not meaningful heirarchical except in name (though you probably already know that)

12:40 dysfun: indeed

12:40 justin_smith: *meaningfully

12:40 bacon1989: arrdem: yeah, i've been looking at that. I found an article outlining some cljs work with th experimental branch

12:40 however, I haven't seen anything with regards to clojureCLR, so I was wondering if there were other resources

12:41 I think it would be a great way to make some libraries more portable

12:41 justin_smith: dysfun: if what you care about is not loading a particular namespace (require) but rather all files in a given directory, why not just iterate and call load on each one?

12:43 dysfun: justin_smith: whatever the means, it all equates to much the same. but in this case they belong as part of the codebase and will run in the build so it feels right to make them namespace. and new things should be picked up properly etc.

12:47 andyf: bacon1989: If there is nothing there about Clojure/CLR, it is likely no one has done anything for that yet. Probably David Miller is waiting until the dust settles.

12:48 bacon1989: andyf: Interesting, I just noticed the proposal came out pretty recently.

12:49 I'm just interested because my company deals mostly with .NET, and hardly touches java. the clojure community would probably expand a tad bit more if clojureCLR got more libraries part of the same domain of libraries as clojure and clojurescript

12:50 andyf: well that wiki page for feature expressions was created in 2012, I think, but Alex Miller has been editing it heavily over the past several months as they get closer to deciding on what to do.

12:52 bacon1989: Ah I see

12:57 OscarZ: was thinking about static vs. dynamic typing.. Clojure is obviously dynamically typed language at its core.. but have you guys ever hoped for some static typing when doing Clojure programming? would it be possible to add some aspects of static typing to Clojure, i mean.. it has support for metadata etc..

12:58 justin_smith: OscarZ: there is core.typed

12:58 OscarZ: or is static typing considered evil in the clojure community? :)

12:58 TimMc: There are folks working on it.

12:59 Not evil. :-)

12:59 OscarZ: cool, i wasnt aware of that :)

12:59 justin_smith: OscarZ: also, I find prismatic/schema for runtime type assertions / static documentation of expected "shapes" of data to be quite useful

13:00 ie. even if I don't turn on the runtime checks, it's nice to have an explicit declaration of what keys should be in a map etc.

13:00 OscarZ: not that i specifically ran into something that i'd need it.. i think i got drawn into clojure because of its clean syntax and i guess static typing always brings its own verbosity into play

13:00 justin_smith: OscarZ: core.typed does inference

13:00 OscarZ: justin_smith, yeah thats good.. i actually ran into that :)

13:03 is it an impossible dream to have kind of layer on top of untyped language that you could use optionally? i dont have enough experience to know what kind of problems you run into.. i guess you can do all sorts of things at least compile time

13:04 justin_smith: once again, core.typed does not require types for your whole program

13:04 (though if something is typed, all the things it uses need type declarations)

13:05 OscarZ: yeah i got that.. but arent there any downsides for this approach vs. languages that are "natively" typed?

13:05 justin_smith: sure, using libs can be clumsier, since you often need to declare their types (or use them from untyped code)

13:08 OscarZ: what about performance? one could naively think that typed languages could make more "ready" low- level code and there would be more "ad-hoc" dynamic checking when you add some layer on it .. but i dont really know if thats a problem

13:09 justin_smith: OscarZ: well, the point of static typing is that it happens at compile time. Dynamic typed langs already do all sorts of runtime type checking.

13:09 (as opposed to untyped langs which don't do any checking at compile OR runtime - ie. forth)

13:10 ,(+ () 1) ; not untyped

13:10 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to java.lang.Number>

13:10 OscarZ: true :)

13:11 in many cases, i dont care about performance hit by dynamic typing.. i guess one of the nice things would be to have some kind of syntax highlighting/autocomplete in the editor as you code

13:12 but that is surely something that can be done in core.typed etc

13:13 dnolen_: http://swannodette.github.io/2014/12/31/the-old-way-the-new-way/

13:14 justin_smith: OscarZ: cursive has core.typed integration

13:14 OscarZ: i wonder if its nicer to program a code highlighting editor in Clojure as its "homoiconic"

13:14 justin_smith, cool! i need to check that out

13:14 justin_smith: dnolen_: cool! thanks - these clojurescript improvements all look great by the way.

13:15 mi6x3m-alt: OscarZ: in the beginning I was a knight of the static typing order as well :)

13:15 OscarZ: ah dont have IDEA.. planning to check that out though.. maybe now its a good time

13:15 mi6x3m-alt: but some experiments in clojure changed my idealism

13:15 TimMc: OscarZ: No, the homoiconicity doesn't extend to things like comments and whitespace.

13:16 arrdem: TimMc: but it could :D

13:16 OscarZ: mi6x3m-alt, im not a knight really.. im bored of Java and i like Clojure very much.. was just thinking if some of the good things in static typing could be brought in

13:16 mi6x3m-alt: arrdem: a comment considered by homoiconicity woudn't be a comment, no?

13:17 TimMc: arrdem: There's alway sa sheen of surface syntax.

13:17 OscarZ: i have looked into Scala too.. but somehow Clojure seems to be more interesting

13:17 arrdem: mi6x3m-alt: iff it's visible to the evaluator/macros then yes

13:17 mi6x3m-alt: some langs (.net family) read whitespace, comments as form metadata for refactoring support.

13:17 OscarZ: TimMc, i see..

13:17 mi6x3m-alt: OscarZ: no wonder, scala is just java with pseudo-functional syntax

13:18 justin_smith: mi6x3m-alt: if that was all it was, it would be a lot simpler

13:18 mi6x3m-alt: it's a lot of things (but that subset is quite usable)

13:18 OscarZ: well, first i got into functional programming and learned some Haskell.. i like that a lot too

13:18 but need a JVM language to get closer to real world as it stands for me

13:18 (work)

13:19 justin_smith: OscarZ: Ocaml is another good one if you want something with faster compile times, static typing, and very fast compiled code

13:19 OscarZ: the Haskell type system is pretty cool though

13:19 mi6x3m-alt: yes OCaml is great

13:19 but macros are the charm of lisp

13:20 justin_smith: ocaml-java is in alpha :) maybe someday it will be an option

13:20 OscarZ: justin_smith, i see.. i have heard of it

13:20 mi6x3m-alt: doubt it, clojure already has a megaton of software

13:20 justin_smith: (and imho it would likely turn out to be what scala should have been if they do it right)

13:20 mi6x3m-alt: everything you need is here

13:23 OscarZ: this prismatic schema thingy, does it have IDE support as well ?

13:24 justin_smith: OscarZ: I don't think so. It's more about validating data at runtime, but I find the schema annotated code nice to work with.

13:25 TimMc: &(/ (* 1e6 2000) 2.2 1000)

13:25 lazybot: ⇒ 909090.9090909091

13:28 TimMc: &(/ (* 1e6 2000) 2.2046)

13:28 lazybot: ⇒ 9.071940488070397E8

13:28 TimMc: mi6x3m-alt: That's... almost a teragram of softare!

13:28 OscarZ: justin_smith, ok.. maybe i should look into that.. been looking for some nice open source project

13:29 mi6x3m-alt: TimMc: whatever keeps the boat moving :)

13:29 TimMc: or 845 gibigrams

13:29 since really the mass of software should be measured in base-2 metric.

13:30 llasram: TimMc: Measuring software progress by weight is like measuring aircraft progress by lines of code

13:30 TimMc: :-)

13:30 in that they're both good ideas

13:31 mi6x3m: TimMc: these words probably don't get said a lot :)

13:35 EvanR-work: how do you remove an element from a set

13:35 justin_smith: disj

13:35 ,(disj #{1 2 3} 2)

13:35 clojurebot: #{1 3}

13:37 andyf: EvanR-work: You are welcome to ask here, but consider using the cheatsheet for similar questions: http://jafingerhut.github.io

13:39 EvanR-work: you dont like showing off your knowledge so much faster than i can google it?

13:39 jk

14:25 mi6x3m-alt: llasram: still here?

14:25 llasram: mi6x3m-alt: Yep

14:25 WHat's up?

14:25 mi6x3m-alt: llasram: look here https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_proxy.clj#L340

14:26 it seems as if the proxy is constructed before the method map is extracted

14:26 does this make sense?

14:28 yes this seems to be the case

14:28 llasram: Unless something unexpected happens in `generate-proxy`, I think you're right...

14:28 Wow, that is a pretty big gotcha

14:28 mi6x3m-alt: major flaw, ye

14:34 llasram: I wonder if there's already an issue open for this...

14:34 mi6x3m-alt: think it's an issue?

14:34 might be a hidden feature

14:36 llasram: Hmm. You have a point, kind of. It isn't explicitly documented, but if you start thinking through the actual mechanics of it, I think it wouldn't actually even be possible to make the replacement methods work during construction

14:37 Super class constructor invocation needs to be the first thing which happens, but the proxy override methods are closures, so they are themselves per-proxy-class-instance function-instances which need to somehow be passed in

14:38 So I think it's just un-/not-explicitly-documented behavior, but is surprising enough to warrant e.g. a mention in the doc string

14:39 mi6x3m-alt: llasram: indeed, I stumbled upon a similar issue yesterday where I needed to delay the initialization

14:39 just because of this super class constructor call issues

14:57 aphyr: Raynes: Hey, outta curiosity, does the github plugin for lazybot work still?

14:59 justin_smith: aphyr: yeah, I have seen it work on #leiningen since the big update

15:00 Raynes: I was just suggesting he use a friend's bot (designed for the purpose) instead.

15:00 There's a website ye can go to and just set up a hook

15:02 TEttinger: and github provides an IRC hook

15:02 borkdude: I'm looking for something to allow users embed links in their text, without allowing the use all of html. Maybe markdown is an option, or just html with restrictions. Any libs I could use for this?

15:02 TEttinger: sounds like markdown

15:02 Raynes: TEttinger: Github's sucks though

15:02 IIRC, rcmp joins and stays there for a long while

15:02 Rather than join -> yell -> part every time

15:03 borkdude: ok markdown it is

15:03 TEttinger: Raynes, because github's joins, sends a message, and immediately quits? yeah I can see that being annoying

15:04 Raynes: borkdude: Yeah, markdown or if it's literally just links you could just parse out []() yourself.

15:04 borkdude: ok sounds good

15:11 aphyr: Raynes: hmm, rcmp just throws 500 internal server error

15:12 Raynes: aphyr: Yeah, I noticed. Consulting the author. I think he took it down because he and nobody else was using it.

15:12 There's always lazybot :P

15:18 aphyr: Raynes: oh it looks like you can use mlock and the github bot won't part/join

15:19 Frozenlock: Is there a way to get a hold of a previous value in the repl? (further than *4)

15:20 Raynes: Oh you can do that

15:20 Awesome

15:21 aphyr: Dope!

15:21 aphyr: I'd suggest using that as it's a github supported thing, but let me know if you ever want lazybot reporting

15:21 aphyr: Thanks :)

15:22 TimMc: ,(for [i (rest (range)), :let [sym (symbol "clojure.core" (str "*" i)) v (resolve sym)] :while v] sym)

15:22 clojurebot: (clojure.core/*1 clojure.core/*2 clojure.core/*3)

15:22 TimMc: Frozenlock: I don't think *4 is a thing.

15:22 Frozenlock: eh... you are right, it goes to *3

15:23 TimMc: ,(def recursive [*0])

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

15:23 TimMc: aw

15:24 amalloy: TimMc: (defn f [] (*1)), (f) ; implicit y combinator????

15:25 TimMc: &(defn f [] (#'*1))

15:25 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

15:25 TimMc: ,(defn f [] (#'*1))

15:25 clojurebot: #'sandbox/f

15:25 TimMc: ,(f)

15:25 clojurebot: #<IllegalStateException java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/*1>

15:27 TimMc: Oh, no need to #' because it's in head position.

15:28 And yeah, totally works... once. :-)

15:28 (def fact (fn [n] (if (zero? n) 1 (* n (*1 (dec n)))))), (fact 5)

15:30 andyf: Sounds like Swearjure has another idiom

15:32 gfredericks: *1 isn't legal swearjure

15:33 andyf: (inc Swearjure)

15:33 lazybot: ⇒ 2

15:33 gfredericks: $karma Swearjure

15:33 lazybot: Swearjure has karma 2.

15:33 gfredericks: $karma swearjure

15:33 lazybot: swearjure has karma 2.

15:33 gfredericks: $karma GFredERicks

15:33 lazybot: GFredERicks has karma 112.

15:33 gfredericks: (inc lazybot)

15:33 lazybot: ⇒ 37

15:33 andyf: I didn't mean to inc Swearjure, I meant to propose that as the name of the extended version of Swearjure :)

15:34 (dec Swearjure)

15:34 lazybot: You want me to leave karma the same? Fine, I will.

15:34 gfredericks: I hate that lazybot response because it's not clear what s/he did exactly

15:34 $karma swearjure

15:34 lazybot: swearjure has karma 2.

15:37 amalloy: gfredericks: that response is supposed to be impossible, but it crops up all the time. some lazybot bug i think

15:39 gfredericks: clojurebot: that response is supposed to be impossible

15:39 clojurebot: c'est bon!

15:39 justin_smith: ~that response

15:39 clojurebot: that response is supposed to be impossible

15:40 gfredericks: I wish I could search for all the times that clojurebot pops out of nowhere and says a random fact.

15:40 andyf: If the bots logged bot messages, you could.

15:41 gfredericks: the what did who

15:41 andyf: The chat logs don't include things the bots say, do they?

15:41 AimHere: Lazybot logs clojurebot

15:41 Even when clojurebot is just replying to people demanding clojure of it

15:41 gfredericks: andyf: even so there's a lot of noise

15:41 andyf: So it does: http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-12-31.txt

15:43 I may have just bred another hairy yak there

15:45 TimMc: It doesn't always log clojurebot. It didn't the last time I set 5 equal to 2. (I was grabbing those logs to show someone.)

15:46 andyf: You may have crashed one of them :)

15:47 TimMc: oooh, right

15:48 No, that doesn't make sense -- it was logging what other people said.

15:48 gfredericks: ~andyf is a hairy yak breeder

15:48 clojurebot: You don't have to tell me twice.

15:48 andyf: That was a perfect response

16:05 amalloy: weird, i thought lazybot ignores clojurebot completely, to prevent all manner of bot quining. i wonder how things actually go

16:23 justin_smith: I think it may be just clojurebot doing the ignoring

16:26 AimHere: &(,(println "Hello World"))

16:26 lazybot: java.lang.NullPointerException

16:26 AimHere: &",(+ 3 4)"

16:26 lazybot: ⇒ ",(+ 3 4)"

16:26 AimHere: ,"&(+ 3 4)"

16:27 clojurebot: "&(+ 3 4)"

16:27 AimHere: ,(println "&(+ 3 4)")

16:27 clojurebot: &(+ 3 4)\n

16:27 lazybot: ⇒ 7

16:27 amalloy: justin_smith: no, clojurebot doesn't ignore lazybot. lazybot prefaces his output with ⇒ so it can't look like a clojurebot command

16:28 justin_smith: oh, interesting

16:28 Raynes: lazybot ignores clojurebot, I'm fairly certain

16:28 amalloy: Raynes: i thought so too, and yet... ^

16:28 AimHere: It certainly doesn't, I just proved the opposite

16:28 justin_smith: Raynes: a couple lines up...

16:28 Raynes: I think you broke it then.

16:29 AimHere: I think it's always been like that

16:29 amalloy: he certainly *used* to. it was a little annoying, because his logs didn't include the stuff clojurebot said at all

16:29 Raynes: user-blacklist

16:29 justin_smith: oh shit did that break?

16:29 Raynes: It's configured, but now broken, I assume as a result of justin_smith's changes

16:29 justin_smith: Not a big deal or anything

16:29 No worries

16:29 A little bot dialog never hurt nobody

16:29 amalloy: justin_smith: you're fired. retroactively rescinding all of your paychecks

16:29 justin_smith: haha

16:32 kenrestivo: botloop

16:46 TimMc: amalloy: Yeah, having clojurebot be missing from the logs was pretty annoying to me.

16:49 [blake|: If I've got a WAR, and some HTML in that WAR for uploading a file, I see that my upload code gets an actual file (in the TMP directory). I'm looking at using AWS and wondering if that's going to cause a problem.

16:49 (Versus, say, receiving the stream in my code and doing something with that.)

17:12 justin_smith: /tmp on aws is no problem

17:13 [blake|: justin_smith: So, it's not like you can't write a file, it's just that you can't expect it to persist?

17:14 justin_smith: [blake|: that, and the default working directory for the war file is not writable

17:14 so make sure you write to something like /tmp that will be, if you are creating files manually

17:15 [blake|: justin_smith: Well, my app originally copied the file passed to a storage directory but I decided to put it into a database instead.

17:15 Which eliminates the need for the storage directory (and has other value).

17:17 So, kind of oddly, the web server will write the stream from the user to TMP, I'll load it from TMP and put it out to the DB.

17:18 justin_smith: is it the server copying the file to tmp, or something in your middleware? because clearly best would be to directly work with that data stream and skip the disk usage

17:18 kenrestivo: eastwood has given me a bizarre error in the ns declaration: https://www.refheap.com/95632

17:18 munderwo: Hi all. So I have a clojurescript question (the cljs channel is rather quiet right now) Does anybody know how to split lines on a new line char and preserve the line?

17:19 *preserve the new line?

17:19 [blake|: Well, I don't have any special code to do the writing...Wait, I do have multipart-params.

17:19 Though I didn't think I was using it...

17:19 justin_smith: it could be your server is doing it, but if it's a middleware you can disable, all the better, no?

17:19 andyf: kenrestivo: That is most likely a case where the line and column number are not trustable

17:19 What Eastwood version?

17:20 kenrestivo: 0.2.1

17:20 andyf: Is it an open source project, or one you are willing to share?

17:21 kenrestivo: can't unfortunately

17:21 andyf: understood. If Eastwood has some kind of bug or limitation where it doesn't get the correct line and column number, it reports 1:1 by default

17:21 [blake|: justin_smith: Yeah. But this is a straight compojure app.

17:22 justin_smith: [blake|: you say that as if that meant there wouldn't be middleware working some magic

17:22 kenrestivo: andyf: gotcha, thanks. but indeed, there is no > anywhere in the file

17:22 and you'll notice the requires are quite benign

17:22 andyf: It could be inside of a macro expansion, which would not be immediately obvious from your source code.

17:22 It almost certainly is not because of the ns form

17:22 kenrestivo: yeah that's what i figured. is there a macroexpand-all for a whole ns?

17:22 andyf: but some macro invocation later in the file.

17:23 [blake|: justin_smith: Well, I tried to use multipart-param. Now all I've got is a post with a "multipart/form-data" part, and when I get that post, I pull out the :tempfile param, which appears to be a /TMP file.

17:23 I mean, I could see there being some middleware magic, but I think I would've had to put it there.

17:24 kenrestivo: i'm thinking in c, there's a feature to dump the source after all the macros have been expanded and includes have been included

17:24 andyf: If you add :debug-warning true to your options map, you will get some additional info about some warnings, including :suspicious-expression warnings, but it might be confusing.

17:24 Try it and see if any of the expressions printed out look like they are macros invoked in your code.

17:24 e.g. lein eastwood '{:debug-warning true}'

17:24 kenrestivo: well it also could be a function call i'm making which calls a function which calls a macro, which causes trouble

17:25 andyf: I don't think that is possible, the way Eastwood works.

17:25 It is not executing your functions, unless you call those functions inside of a macro expansions.

17:27 kenrestivo: :debug-warning outputs the same stuf

17:27 andyf: No extra output?

17:28 ah, I see. There are different kinds of suspicious-expression warnings detected in different ways in Eastwood, and I only added the extra debug output for 1 of them. Sorry about that.

17:29 [blake|: Which raises the question: What IS handling that?

17:29 kenrestivo: all good. it's a great tool.

17:29 justin_smith: [blake|: either ring or the server I guess?

17:30 andyf: It does narrow it down a bit. Let me look at the Eastwood code for the other cases of that warning and see if it jogs my memory.

17:30 kenrestivo: cool, thanks. if there's some patch you'd like me to try to eastwood, i'm game.

17:32 justin_smith: [blake|: so you are sure that multipart-params isn't being used?

17:32 andyf: No occurrences of the character > in that file, you said?

17:32 kenrestivo: indeed, plenty of ->, but no >

17:32 [blake|: justin_smith: Took it out.

17:32 justin_smith: [blake|: never mind, now I see it is something jetty does

17:33 [blake|: if the request has a file input, jetty creates a file

17:33 [blake|: justin_smith: Oh! OK...this raises some other questions.

17:33 kenrestivo: there's some->, ->, and async/>!!. but no (> anywhere

17:33 justin_smith: [blake|: http://docs.codehaus.org/display/JETTY/File+Upload+in+jetty6 explained pretty clearly here

17:33 andyf: Is it test code, e.g. any uses of 'is' ?

17:34 [blake|: justin_smith: I've got ring-mock, ring-jetty-adapter and javax.servlet/servlet-api in my dev dependencies.

17:34 justin_smith: I got bupkis anywhere else. Which would seem to be a barrier to deployment.

17:34 justin_smith: [blake|: yeah, by default ring uses an embedded jetty server in dev

17:35 and then you would deploy by creating an uberwar, which is put inside some container

17:35 kenrestivo: oh, there's also map->Foo

17:35 justin_smith: [blake|: another option is using http-kit or aleph at runtime and deploying a standalone uberjar that hosts itself

17:36 [blake|: justin_smith: That might be interesting, especially if -- Well, I've been deploying to WildFly. It might make my life simpler if I didn't.

17:36 So, if I wanted to capture the stream, could I do that? And is it worth it? I like the neatness of it. But.

17:37 andyf: You can try '{:debug [:all]}' as comand line options, but the output is really long, and you'll want to redirect it to a file. Among many, many other things, it will show you the macro expanded forms, but the other stuff might drown that out.

17:38 Looks like I may want to add a debug option that only shows the macro-expanded forms, and not everything else.

17:39 Oh, it would be a bit shorter if you used '{:debug [:compare-forms]}' and then look in the file forms-emitted.txt

17:40 Search in forms-emitted.txt for occurrences of > (that are not part of -> or other longer names)

17:41 Likely what is happening is some macro you are using is transformed into code that contains an expression of the form (> expr). If so, that isn't necessarily a bug in your code or the macro -- perhaps just a degenerate case in the macro that made it straightforward to write.

17:51 kenrestivo: emitted-forms.txt is pretty cool. doing the needle/haystack thing now

17:52 hahaha

17:52 andyf: got it.

17:52 )))>)))

17:53 thanks

17:53 andyf: able to trace it back to something you wrote? Cool.

17:53 kenrestivo: yeah, stupid typo. not easy to find due to a > being buried in a forest of closing parens

17:54 but... lein check didn't catch it, eastwood did. so, yay eastwood

17:54 andyf: I'm surprised that turned into a call to > with 1 arg

17:55 kenrestivo: git commit -a -m "derp"

17:55 andyf: but if the warning goes away after fixing that, then I don't have any other explanation :)

17:56 kenrestivo: no that was totally it.

17:56 andyf: Was it in a macro definition in another file?

17:56 kenrestivo: no it was literally )))>)))

17:56 can you spot the problem with that?

17:56 andyf: In the file with the warning?

17:56 kenrestivo: i didn't :-P

17:56 yep

17:57 andyf: Is the function something you can share, e.g. short and nothing terribly proprietary?

17:57 If not, I can try to reproduce my own example. It would be better if the line/col number info was more accurate there.

17:58 kenrestivo: sure. it was (some-> state-thread (async/>!! :stop)>)

17:58 andyf: thx

17:58 justin_smith: [blake|: backing up for a moment, if /tmp is at least a ramfs and not a disk fs you at least aren't paying for disk latency you don't need

17:58 kenrestivo: feel free to include in tests. compiler is fine with that, for some reason. but eastwood flagged it.

17:59 andyf: There is nothing illegal about a call to > with 1 arg, just not usually what you want

17:59 [blake|: justin_smith: Yeah, I don't know. Maybe worrying about it is a form of premature optimization. It's not like there's going to be any volume anyway.

18:00 kenrestivo: andyf: the full version of the function is here: https://www.refheap.com/95634

18:01 looking at it, i'm kind of surprised the compiler didn't puke blood when confronted with that

18:02 andyf: kenrestivo: Consider this form: (-> 5 (+ 1) >)

18:02 expands to (> (+ 5 1))

18:02 nothing illegal

18:02 some-> is similar

18:20 gizmo385: What are the performance impacts of using multimethods vs using protocols?

18:21 gfredericks: the multimethods are slower.

18:39 kenrestivo: hmm, i guess so. and since the function is just doing side-effecty things, the fact that it returns garbage isn't relevant

18:58 Dynasty: Can a macro call a function which makes use of the macro itself?

19:07 gfredericks: are you talking about the macro itself calling a function or the macro emitting code that calls the function?

19:07 the latter should be okay I think, especially if they're in the same namespace

19:12 Dynasty: the macro makes use of a function while generating its output

19:12 but the function makes use of the macro itself

19:12 does that make sense?

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

19:13 gfredericks: does the macro only conditionally call the function, or always? if always that sounds like a guaranteed stack overflow during macroexpansion

19:15 Dynasty: conditionally I guess

19:21 EvanR-work: ok im going insane

19:21 trying to assert that x is less than 2, i.e. no bigger than 1

19:21 (assert (< 2 x) ...)

19:22 (< x 2)

19:22 amalloy: EvanR-work: "less than 2" is quite different from "no bigger than 1" unless you're guaranteed an integer

19:23 EvanR-work: yes its integers

19:23 amalloy: but the former is (< x 2); you can imagine moving the < into the middle, or of < as meaning "increasing", as in (< 1 2 3 4)

19:23 EvanR-work: i need to put (< x 2) here, but how do i write it so its easy to actually read and understand?

19:23 ok..

19:23 amalloy: if you want to get cutesy you can write stuff like (-> x (< 2))

19:24 EvanR-work: i dont even want to use 2

19:24 "no more than 1"

19:24 amalloy: okay, so <=

19:24 (<= x 1)

19:24 EvanR-work: x <= 1

19:25 looks like a freakin arrow

19:25 (not (> x 1)) ?

19:25 amalloy: that wouldn't include 1

19:25 oh

19:25 TMA: ,(macroexpand '(-> x (-> (-> 1 1+) (<))))

19:26 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 1+>

19:26 amalloy: i mean, sure, you can write that if that more clearly expresses what you intend

19:27 EvanR-work: (at-most-one x)

19:28 guess i need macroz

19:29 TMA: ,(*)

19:29 clojurebot: 1

19:32 TMA: ,(macroexpand '(-> x (< (-> (*) (+ (*))))))

19:32 clojurebot: (< x (-> (*) (+ (*))))

19:34 TMA: ,(macroexpand '(-> x +))

19:34 clojurebot: (+ x)

19:35 TMA: ,(macroexpand '(-> * ()))

19:35 clojurebot: (nil *)

19:36 amalloy: why would you need a macro, EvanR-work?

19:37 TMA: ,(macroexpand '(-> (*) (-> (*) +)))

19:37 clojurebot: (+ (* (*)))

19:38 EvanR-work: you wouldnt. it wouldnt need to be a function either

20:12 kenrestivo: crossclj appears to have stopped working. page loads, but the javascript in it seems to just lock up.

20:14 actually it doesn't lock up, it just doesn't render anything.

20:18 amalloy: kenrestivo: did you maybe search for "rhymes with orange"? maybe it's just having trouble finding the answer you want

20:18 or like "functions better than juxt"?

20:18 kenrestivo: no search, just loading home apage

20:19 it's just a big white nothing. something's gone awry.

Logging service provided by n01se.net