#clojure logs

2015-04-08

00:44netrobyWhere is clojure Sepecification document?
00:44netrobyI can not find it anywhere
00:54justin_smithit doesn't exist
01:55netrobyOh. no . every language had a specification paper. why clojure does not have one?
01:56mavbozopython, ruby also do not have one
01:56TEttingermany successful languages do not have specs for important reasons.
01:56TEttingerone is that if there's a mistake in the spec, implementations need to implement that mistake
01:57netrobyhttps://docs.python.org/3/reference/
01:57TEttingerthat is a reference manual not a spec
01:57justin_smithnetroby: we have docs at clojure.org
01:57netrobyhttp://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579
01:57netrobyI am not interesting document, i am asking for specification document.
01:58justin_smithnetroby: that python link is not a specification
01:58netrobyLike java specification https://docs.oracle.com/javase/specs/
01:58justin_smithnetroby: clojure does not have one, and never will
01:58netrobyEven scala have it's specification http://www.scala-lang.org/files/archive/spec/2.11/
01:59justin_smithnetroby: I am not arguing that some languages have specifications
01:59TEttingerif you require a spec, may I suggest looking at scheme, which has things like s6rs, and all implementations of scheme that people use have, of course, non-specified extensions
01:59justin_smithnetroby: what I am saying is that the authors of clojure have said explicitly that they will never make a spec
01:59justin_smithit's not up to any of us here
02:00TEttingerthe java specification is kinda a joke, I'd be interested if any alternative implementations of java actually follow it
02:01netrobyIf you would like to implement a language . you need to read specification or something like that.
02:01TEttingergwt doesn't I am fairly sure, dalvik, if it did, that was probably used against google in oracle's spec
02:01TEttingerno.
02:01justin_smithnetroby: that's not true
02:02TEttinger*in oracle
02:02netrobyIt just like a blue print
02:02TEttinger*in oracle's lawsuit against google
02:02justin_smithnetroby: I know what a spec is, and I know clojure will never have one.
02:02mavbozoother python implementation is based on cpython implementation not specs, ruby also
02:03netrobymavbozo: Python have spec document (relate to specification paper)
02:03netrobymavbozo: Ruby have a ISO paper
02:03netrobymavbozo: ISO/IEC 30170:2012
02:03justin_smithnetroby: that is not true, python has no spec
02:04netrobyEven c language have it's spec, ISO/IEC 9899:2011
02:04mavbozonetroby, but other python and ruby implementations does not strictly follow the specs
02:04TEttingerin most languages without explicit specs, if you implement a different version of the non-specified language, you copy as much of the functionality of the existing language as the new version can given platform differences. clojurescript obviously has differences from JVM clojure, stemming from JS' lack of threads that work everywhere, and several other key limitations of JS
02:04mavbozonetroby, the canonical references for both languages are its original implementation in C
02:04justin_smithnetroby: I don't know what you are trying to prove - even if you convinced everyone in this room that clojure needed a spec, none of us are the implementor of clojure, that's not our decision to make.
02:06netrobyjustin_smith: I just searching for clojure language specification document. It's absolutely none
02:06justin_smithnetroby: that's true
02:06TEttingercorrect
02:06justin_smithther is none
02:06TEttingerlike python
02:06mavbozoagree
02:08netrobyAfter coding for a while, I am interesting how Clojure implements and how about the language, so read a specification paper should be useful.
02:08justin_smithnetroby: I think it would be awesome to have a pet unicorn.
02:10Jaoodjustin_smith: to big for a pet
02:11justin_smithJaood: I would also like a 100 acre field for my unicorn
02:11mavbozonetroby, great but unfortunately clojure does not have a formal spec
02:11netrobyHum, i thought i should have to read the source code of clojure instead.
02:12JaoodI would like a lein like tool written in Java :P
02:12netrobylaood: you have ant, maven.
02:12justin_smithJaood: that's definitely the most achievable one so far
02:12justin_smithant is nothing at all like lein, maven would need quite a bit of work
02:13justin_smiththough maven's support for multiple config file formats now is a step in the right direction
02:17mavbozoJaood, don't we have in our eclipse, intellij? (I assume those IDEs hide all that ant, maven complexities)
02:17netrobyGradle is useful and better choice for java developers
02:17justin_smithmavbozo: the problem with that is that now everyone on your team needs to use the same ide
02:18justin_smithmavbozo: it's actually strongly recommended against for that reason
02:21mavbozojustin_smith, recommended against even java development projects?
02:21mavbozo*even for*
02:22Jaoodmavbozo: I was complaining more about start-up time and memory consumption
02:22justin_smithmavbozo: yeah
02:22justin_smithmavbozo: that's the party line on ##java
02:23justin_smithmavbozo: also, this makes it harder to have nice things like CI tools
02:23justin_smithunless you expect travis or jenkins to be running your IDE...
02:23mavbozojustin_smith, interesting. so you don't want to use eclipse, intellij, or others for maintaining legacy java codebase?
02:24Jaoodmaven is very project centric
02:24justin_smithmavbozo: you can use them to maintain a codebase, that's fine. Don't let them control dependency management. Use a proper IDE-agnostic tool (like maven)
02:24justin_smithI'm not saying no IDE, I'm saying no IDE automagic dep controls
02:25justin_smitha build system that requires starting up a specific app that isn't a build tool is bad
02:27Jaooddoes Hickey uses lein? I would guess he's more of a maven peson
02:27Jaoods/peson/person
02:27justin_smithclojure.core is still maven
02:27justin_smithI wonder if it will ever have a project.clj
02:28Jaoodhmm yeah, it looks like it supports both ant and maven
02:29mavbozojustin_smith, thanks for the advice. might come in handy if someday i have to maintain a legacy java codebase
02:29JaoodHickey would probably respond, "get off my lawn"
02:37netrobyIn 1994, Steele joined Sun Microsystems and was invited by Bill Joy to become a member of the Java team after the language had been designed, since he had a track record of writing good specifications for existing languages.He was named a Sun Fellow in 2003.
02:38justin_smithI know arrdem would be very happy if there was a spec. Probably Bronsa too.
02:40mavbozois there any good story of language spec written after the language implemented?
02:40justin_smithmavbozo: common lisp kind of counts - the hyperspec defined a common spec to bring together a bunch of lisp implementations
02:40netrobyOn 16 March 1984, Steele published Common Lisp the Language (Digital Press; ISBN 0-932376-41-X; 465 pages). This first edition was the original specification of Common Lisp
02:40netrobyThe same guy.
02:40justin_smithyup
02:41justin_smithhe also worked on the scheme srfis
02:41mavbozojustin_smith, people complained that the spec is bloated
02:41netrobyWritten Java specification and Lisp specification
02:41justin_smithwhich form the scheme spec
02:41justin_smithso clearly the answer is to elect guy steele to replace rich hickey
02:41netrobyDo you have vote?
02:41mavbozojustin_smith, and make it really hard to fully implement that spec
02:42justin_smithnetroby: no, that was a joke, rich hickey doesn't run clojure as a democracy
02:42mavbozoi vote younger ones such as ambrosebs
02:42mavbozoensuring clojure longevity
02:43netrobyGuy Lewis Steele Jr. 61 years old
02:43mavbozohe also has proven track records in making typed.clojure
02:44netrobyI am using Emacs, seems he also the coauthor of Emacs
02:44netrobyThis guy really stronger and powerful
02:44mavbozoambrosebs is about 20s
02:44justin_smithdefinitely a smart guy
02:45netrobyThe newer programmer will not to invent a new language or new tools.
02:46mavbozojustin_smith, agree ambrosebs is definitely a smart guy
02:46netrobyIf the old guys dead. we have nothing left
02:46justin_smithnetroby: there's a good video of a talk by guy steele jr. - "growing a language" https://www.youtube.com/watch?v=_ahvzDzKdB0
02:47netrobyjustin_smith: thanks
02:49tahmidHello guys
02:49mavbozohello
02:49benzs129Hello, I'm new here and have some question regard ISP. I am planing to change my ISP service from Verizon Fiios to Time warnner cable. My current plan with verizon is 75/75 down and up load speed for $140/m. The new plan that I'm currenlty consider is Time wanner 200/20 $100/m. Should I change the plan?
02:49tahmidIn cljs how to add multiple classes using the #js
02:49tahmidI can add one class like this #js {:className “myclass”}
02:50tahmidBut how can I add multiple classes
02:50tahmidbtw I am talking about om
08:07J_ArcaneSeesaw seems really nice.
08:17timvisherjustin_smith, tbaldridge, Jaood: thanks for the input. the other thing that's killing http-kit at this point as far as my org is concerned is lack of in-band https support
08:18timvisheri keep talking about VPN with SSL termination on the outside via nginx etc. but our tech lead really wants SSL on all end points, which means that I can't use http-kit unless I also embed an SSL terminator
08:19Glenjaminwould sit any http-kit-based server behind a load balancer, i'd have thought
08:19Glenjaminso i'd usually terminate SSL there
08:20timvisherGlenjamin: yeah. the concern seems to be sniffing on the internal network
08:20Glenjaminyou have an insecure internal network?
08:20timvisheralso the goal is to have each of our services eventually be public facing, so then they'll all need SSL anyway
08:21timvisherGlenjamin: not in any known way, but paranoia :)
08:24mpenetyou could just use jetty9, it is fairly solid in my experience, not to mention "modern" if you need such things as async, spdy, soon http2 etc
08:25mpenetwebsockets as well
08:27mpenetwe switched from http-kit a while ago, we hit some of the issues you can see in its issue tracker
08:30pcnI'd much rather have a proxy on localhost with ssl managed there than have to deal with java's keystore and truststore annoyances.
08:30timvishermpenet: yes. that's another scary thing. maintenance seems to be tough for the http-kit devs.
08:30timvishermpenet: did you go with ring-jetty9-adapter?
08:30timvisheror did you rolly our own jetty 9 dep?
08:31timvishers/rolly/roll/
08:31timvisherpcn: i would too
08:31timvisheryou have any good docs to link to as far as why ssl in java isn't the best idea?
08:33mpenettimvisher: no we rolled our own: https://github.com/mpenet/jet
08:33mpenetit started as a fork and ended up rewriting pretty much everything
08:33timvishermpenet: nice. thanks for the link
08:34pcntimvisher: it doubles operational cost of e.g. maintaining CA certs. Adding and removing them are a specialized set of commands.
08:34timvishermpenet: have a write up as to why?
08:35timvisherpcn: oh man i totally forgot about that :)
08:35mpenettimvisher: why the switch or why the lib?
08:35pcnAnd then you have to start putting logic surrounding what is secure vs not in your code
08:35Lutin`anyone have tips on profiling a clojure program?
08:36timvishermpenet: why you rewrote the jetty9-adapter
08:36timvisherLutin`: start with visualvm and see how far that gets you
08:37Lutin`Alright, thanks. Will take a look
08:37mpenetwe wanted tighter core.async integration, and some of the internals of rint-jetty9-adapter where not of our liking (missing options here and there, proxy vs reify etc)
08:37timvishermpenet: thanks!
08:37danlentzLutin`: probably doesn't qualify as a "tip" but I recently used YourKit and criterium
08:37mpenet+ I ended up doing client side stuff wrappers too (websocket & http clients)
08:38Lutin`danlentz: Counts for me! I guess I meant more like suggestions than "tips". I don't know haha
08:38danlentzYourKit for a statistical (?) profile and criterium to optimize hot spots
08:38timvisherdanlentz: did you pay for it?
08:38timvisheror was it for an opensource thing?
08:39timvisherYourKit is definitely best of breed afaik, but it costs money for proprietary profiling
08:39danlentzNo, it was open source but even do I just downloaded the beta version
08:39danlentzBut I think you can apply for a license
08:39tbaldridgeyeah YK is pretty nice about handing out free copies to OSS projects
08:40danlentzI should do that actually. It's a very useful package.
08:41danlentzBut, my scenario was that I needed to get a high level picture of where cost was incurred during computation of UUID's
08:41timvisherdanlentz: ah. is that feature-restricted or time restricted?
08:41danlentzSo once I had that I focused in using criterium
08:42danlentztimvisher: the beta is time restricted
08:42timvisherLutin`: for wider application profiling and visibility you could also consider something like NewRelic
08:42timvisherdoes NewRelic have first class clojure support at this point?
08:42timvishers/application/system
08:43Lutin`Right now I'm just profiling an IRC bot
08:43Lutin`trying to figure where all this memory usage is coming from for something I thought would be fairly small
08:43danlentzI think YourKit retails for something like $600 which is well worth it
08:44timvisherLutin`: yeah. push visualvm to its limit and then see whether YK does what you need. :)
08:46Lutin`huh, so GC increases the PermGen size
08:46Lutin`didn't know that
08:47Lutin`maybe it's just due to the way VisualVM does it
08:48timvisherpcn: could you elaborate a bit more on putting code around what's secure and what's not in your code?
09:00Lutin`hmm so it looks like at this point most of my memory savings are going to be from removing libraries?
09:00Lutin`Only need about 10MB on the heap, but the total resident memory is around 80MB
09:02Lutin`Trying to slim this down to run on a VM with only 128MB available ram and 256MB swap, which might be a bit crazy
09:08sveriHi, I want to generate some clojure code and put it into a file with a namespace and require expressions so it's working later OOTB. What would be the most idiomatic way to do this? spit clojure data structures into a file?
09:54csd_How can I play with async code without having to kill the repl session each time I want to stop the code? e.g. https://www.refheap.com/99362
09:54justin_smithLutin`: clojure uses a lot more permgen than a normal java program would
09:54justin_smithLutin`: but in 1.8 this is not as much of a concern
09:55justin_smithLutin`: the issue is that every function made via fn is a new class
09:55justin_smith(or, that's part of the issue)
10:01sobelheh, looks i have design approval to avoid interfacing clojure to java
10:02sobel...this time
10:02justin_smithcongrats
10:03justin_smithsobel: if you do have to make your clojure accessible from java, a good option is to make a small wrapper in java code, that does the interop calls via RT to your real code
10:03justin_smiththat way you can provide whatever sort of interface java coworkers expect without having to do anything weird on the clojure side
10:03sobelyeah, i'm going to treat it like a sql dao
10:04justin_smithmakes sense
10:04justin_smithin-process or ipc?
10:04sobelit's pretty basic OO, there
10:04sobelin-process, when i do have to go there
10:04justin_smithhaha, so a dao model for code within the same vm
10:05sobelsure, clojure is foreign enough to need that much fanfare around the interface
10:05sobelit keeps the abstraction tight :)
10:05justin_smithbut with a very thin wrapper, it need not be at all
10:05justin_smithbut if dao works, it works
10:05sobelin this case, 100% of the domain is implemented in clojure
10:06sobelmapping the useful bits 1:1 to java methods makes sense
10:07mnngfltg2,(let [v (with-meta [1 2] {:foo :bar})] (map #(meta %) [v (conj v 3) (map identity v) (subvec v 1)]))
10:07sobeli got this one hammer, you see... :)
10:07clojurebot({:foo :bar} {:foo :bar} nil nil)
10:07mnngfltg2I'm a bit confused about meta-data. When a PersistentVector has meta-data, it is preserved when modifying it, though not always.
10:08justin_smithmnngfltg2: yes, map and subvec are not going to preserve metadata
10:08justin_smithand yeah, vectors or maps only sometimes
10:08justin_smithand it's not good to rely on it
10:08mnngfltg2justin_smith, huh
10:08mnngfltg2is there a way to *prevent* the proliferation of metadata?
10:09justin_smithmnngfltg2: you could use into
10:09mnngfltg2My use case is that I want to know if v has changed
10:09justin_smithmnngfltg2: v never changes
10:09justin_smithit's immutible
10:09mnngfltg2yes I know
10:10justin_smiththen you want to know if you are accessing v, or something else derived from v? = should suffice for that
10:10mnngfltg2true
10:10mnngfltg2my use case is that I keep track of an immutable collection
10:11mnngfltg2something outside my control makes a change and returns me a new-val
10:11mnngfltg2now I want to know if I've already seen new-val
10:11justin_smithI would keep a binding to the coll, and compare new values to it
10:12mnngfltg2so I could keep track of what I've seen in a lookup table?
10:13justin_smithsure, a stack or hash-map would make sense, depending on how your access pattern works
10:13mnngfltg2hm ok
10:14mnngfltg2if I do (assoc {} big-object :seen)...
10:14mnngfltg2does it store big-object once more, or just a reference to it?
10:14mnngfltg2i.e. a pointer
10:14mnngfltg2seems silly to ask that, but I'm not sure now
10:14justin_smithmnngfltg2: it's effectively a pointer
10:14justin_smiththe only drawback is that it would prevent gc of the value
10:15mnngfltg2preventing gc is fine by me, for now
10:15justin_smithbut thanks to structural sharing, this will be done fairly efficiently where it matters
10:15mnngfltg2alright I'll try that then
10:15justin_smitheg. if you have it and a modification, they can share their internals past a certain size of common elements
10:15mnngfltg2yes, that feature of persistent data structures I know
10:15justin_smithhyPiRion has a good series of articles on how that works with vectors
10:16mnngfltg2I've read them
10:16justin_smithoh, cool :)
10:16mnngfltg2it'a pity my meta-data approach doesn't work though
10:16justin_smithI would think that in that case one would know that the assoc didn't do a full copy :)
10:17mnngfltg2justin_smith, I suspected it
10:18mnngfltg2it would have been cool to just tag the vector itself so I can check if I've already written it to disk
10:18justin_smithmnngfltg2: yeah, metadata doesn't work that way though (as you've seen)
10:19justin_smithif you are tracking items and whether you have seen them, a set seems a natural fit for that
10:19mnngfltg2I wonder what's the rationale behind the "transitivity" of metadata
10:19justin_smithmnngfltg2: it's a weird abstraction leak to be sure
10:19justin_smith(exposing when the collection gets promoted up to a bigger vector)
10:19mnngfltg2rich must have had some use case in mind when he added that feature
10:20sobelok, i started a simple lein app project and now i want to change its namespace to match with some java code. do i need to modify my src tree same as java package spaces?
10:20sobelor should i just make a new project and drop my ONE source file into it
10:21justin_smithsobel: yeah, I would think so. There is a project for automating this sort of namespace refactor, but I forget the name.
10:21justin_smithfrom technomancy iirc
10:21sobelwas it vinyasa?
10:22sobelguess i'll try it by hand once just to see it break
10:22justin_smithno, that isn't for refactoring at all is it?
10:23mdrogalisjustin_smith: Slamhound
10:23justin_smithsobel: for emacs, there is clj-refactor
10:23justin_smithmdrogalis: AHA!
10:23justin_smith(inc mdrogalis)
10:23lazybot⇒ 8
10:23justin_smiththat's the one
10:24mdrogalisThat's the first thing I've said on here in ages!
10:24mnngfltg2sobel, yes the directory layout needs to match the one.two.three class hierarchy in clojure (as in java)
10:24justin_smithsobel: https://github.com/technomancy/slamhound makes this stuff easy
10:30yellow13hi there! https://www.refheap.com/99364
10:30yellow13i was wondering which of these is more idiomatic
10:30justin_smithso you want to return nil if url is nil?
10:31justin_smithit would be more typical to return page unchanged if url is nil, or page with a new url assoc'd on if it isn't
10:34yellow13some function will upload a file and produce a url if it suceeds
10:34yellow13then im gonna put that new url on the page
10:34yellow13im not sure how to remember the pages where the upload failed
10:35yellow13thats why change-page-url accepts nil
10:35justin_smithOK
10:36justin_smithyellow13: if you either return a modified page, or nil, then the surrounding code needs a conditional to replace something it has, or do nothing
10:36justin_smithif you either replace page unmodified, or update its :url key, then the caller can unconditionally use the result
10:37justin_smiththat's the kind of pattern I would see in my own code, at least
10:45yellow13justin_smith: the original idea was this (map pages #(some->> % upload-page (change-page-url %)))
10:45yellow13resulting in [nil {:url "a"} nil] then ill save on mongo the updated pages
10:46yellow13im trying to wrap my head around the functional way, ima mainly a php dev
10:55sobelhope slamhound works...bout to attempt it through the LT plugin
10:57justin_smithyellow13: oh, you have the args to map reversed, but that could make sense
10:58justin_smithyellow13: just, in my experience, having the default be the unmodified thing rather than nil tends to usually simplify my code
11:00sobeli must say, i love RainbowParens
11:00sobelsliced bread, etc
11:01timvishersobel: i should really turn that on at some point
11:01timvisherparedit makes much more of a difference for me though :)
11:01sobelyeah, i use that too.
11:01sobelbut even with paredit, it's still easy enough to get lost in nests
11:01the_frey_paredit > rainbow parens
11:01sobelparedit + rainbowparens
11:05zerokarmaleftparedit + show-paren-mode is a bit more subtle...I find the additional color distracting
11:06sobelmaybe i'll get tired of it later. surely helping me for now, though.
11:10timvisherhas anyone written a ring adapter using netty?
11:10timvishersorry... should have googled https://github.com/RallySoftware/netty-ring-adapter
11:10sobelhm, still not clear how i would use slamhound to refactor my src. just want to change the package space and get the dirs/files handled by it
11:11mpenettimvisher: aleph is likely more stable/advanced
11:13timvishermpenet: good point
11:14justin_smithsobel: move the namespaces to where they should be in the directory structure, and use slamhand to fix the ns forms
11:16sobelnoice
11:19sobelhm, it didn't seem to pick up the file/pkg changes
11:38danlentzAnyone yet had a look at "Clojure Applied"?
11:38danlentzhttps://pragprog.com/book/vmclojeco/clojure-applied
11:39justin_smithdanlentz: I'd give it a positive just because puredanger is one of the authors
11:39justin_smiththough I don't have the book
11:39danlentzHe should just write under the name puredanger
11:39arrdemjust going from the clj-public post it looks interesting
11:40justin_smithhehe
11:40arrdemI'd read it expecting to learn something
11:40justin_smitharrdem: and write everything in the form of superhero comics
11:40arrdemhahah
11:41justin_smithI mean, if we're talking about uncreative handle choice...
11:42arrdemoh you win at that hands down
11:42arrdemfor some definition of win
11:42danlentzHalf of developers use their real name but a fake avatar, the other half use their real profile picture with a fictitious name.
11:43sobeli stole mine from something i heard a grunt say in warcraft3
11:43arrdemmy initials are "R D M" and if you slur that a bit...
11:43szatzjust discovered transients. the post on them says not to bash in place, but the example calls conj! over a range. is this not bashing?
11:44justin_smithszatz: bashing is using conj! but not using the return value
11:44arrdemszatz: link? it's only bashing if you don't use the return value
11:44justin_smithtl;dr: use the return value
11:44arrdemI should just give up and let justin_smith have all the low hanging karma
11:44szatzhttp://clojure.org/transients
11:44justin_smithhahaah
11:45justin_smitharrdem: your turn, I'll peace out for a bit
11:45arrdemgod save us
11:46justin_smithszatz: in the example on that page, it's not bashing it because (conj! v i) is an arg to recur
11:46justin_smithwhich means the return value is captured and used
11:46szatzsorry if this sounds silly, but in what situation would one not use the return value?
11:46justin_smithszatz: if you were coding as if it were java
11:47danlentzCould someone give me the address of the website where I can cash in irc karma for cool gifts and prizes? I seem to have misplaced it.
11:47arrdemwhen you are abusing update in place
11:47arrdemdanlentz: I have a bridge I'd like to interest you in
11:47justin_smith$karma justin_smith
11:47lazybotjustin_smith has karma 235.
11:47szatzthanks to all you guys for jumping all over this, btw.
11:48justin_smithnice, almost enough to get the collectable beer-koozy
11:48sobelwhy does using the retval make it not bashing?
11:48arrdemsobel: first, convention, second the transient contract does not guarantee that updates will always occur in place
11:49szatzhmm, OK re: "like java." maybe me not getting it is a good thing.
11:49justin_smithsobel: ##(let [h (java.util.HashMap.)] (.put h :a 0) h)
11:49lazybot⇒ {:a 0}
11:49justin_smithsobel: it's not bashing because the args to recur are the new bindings for the next iteration
11:50justin_smithszatz: sorry, I miss-directed this before ##(let [h (java.util.HashMap.)] (.put h :a 0) h)
11:50lazybot⇒ {:a 0}
11:50justin_smiththat's java style - notice I modify h but don't use the return value of the .put method
11:50sobelso it's not bashing because the retval is used inside the loop scope
11:50justin_smithsobel: right
11:50sobelthink i got it
11:51justin_smithsobel: bashing is if you ignore the return value, and then just use the thing it implicitly (probably) modified
11:51justin_smiththat is error-prone with transients - it works until it doesn't
11:51justin_smithwith no warning
11:51sobelthere was a related discussion in the cljs minecraft demo, about giving in to bashing a JS array on the inner loop because it was sooooo performant
11:52justin_smithsobel: yes, if something is performance critical, bashing an array in place is almost always the best option
11:52justin_smithbut it also leads to less than sane code
11:52justin_smithif used without discretion
11:53justin_smithless so in js where "arrays" aren't
11:53justin_smithbut the general principle still holds
11:54arrdemjustin_smith: worth mentioning doto
11:54justin_smithyup
11:55sobelyes, all was caveated appropriately, then they bashed that array for a pretty sweet 3d render loop in cljs
11:56justin_smithcool - yeah trying to do that with persistent data structures would likely be bad for your frame rate, on today's hardware at least
11:56szatzjustin_smith: so the mutating call should always be inside another call? is that the gist?
11:57justin_smithszatz: yeah - the return value of the conj! or whatever should be replacing your binding
11:57justin_smithwhether that's because it becomes an arg to recur, or the return value of your reducing function, whatever
12:00szatzOK, I got it. I think I got tripped up because there are two returns going on when transients are used correctly, it seems.
12:00szatzone from the mutation, and one to move that value to whatever's next.
12:02justin_smithszatz: it's the same way it would look if you were using conj in a loop
12:02justin_smiththe only reason it is tricky is because conj! will sometimes work as if it updated in place - it's just that this is not guaranteed to work and should not be relied on
12:04szatzjustin_smith: yeah, i got it. thanks a lot.
12:05oddcullyis map killing a binding? as in (binding [*a* b] (map ...))?
12:06arrdemoddcully: map is lazy, binding is eager. If you are relying on dynamic bindings to pass values into your mapped function, you're gonna have a bad time.
12:07justin_smith(inc arrdem)
12:07lazybot⇒ 43
12:07timvisherthis is probably not sensical, but `lein deploy` doesn't appear to be able to deploy war files, only jars.
12:07arrdemoddcully: prefer partial application of the mapped function if possible.
12:07timvisherthat's accurate right?
12:08justin_smithtimvisher: I use lein beanstalk to deploy wars
12:08justin_smitherr... to beanstalk at least :)
12:08timvisherjustin_smith: do you use lein release?
12:08justin_smithnever tried it
12:08oddcullyarrdem: thanks. this right now is just some test code and it tripped me over. so i am not sure right now, if binding is the best thing in my case anyway
12:09arrdemoddcully: binding is generally discouraged for playing really badly with lazy sequences and implicit lazy behavior
12:09justin_smithoddcully: general rule with binding and with-* macros -- force any laziness before it leaves scope, and if that isn't a good idea, that macro isn't a good idea
12:10arrdemshout out to Chas.. http://cemerick.com/2009/11/03/be-mindful-of-clojures-binding/
12:10arrdemjustin_smith: does lazybot have factoids on?
12:11arrdemsince I can't use clojurebots
12:11mpenetjustin_smith: transients are not always faster than normal maps btw, depends on the usage pattern really (calling persitent!/transient has a cost)
12:12mpenet*persistent!
12:12justin_smithmpenet: very true
12:12oddcullythanks, guys. i guess i will look for something other than bindings
12:12oddcully(inc arrdem)
12:12lazybot⇒ 44
12:12arrdemsure thing. good luck!
12:12justin_smitharrdem: I forget the name of the plugin, but I think so
12:13arrdemjustin_smith: https://github.com/Raynes/lazybot/blob/master/src/lazybot/plugins/knowledge.clj ?
12:14justin_smith$addtopic help lazybot can organize help in topics
12:14lazybotjustin_smith: It is not the case that you don't not unhave insufficient privileges to do this.
12:14justin_smitharrdem: it's in help.clj, but you need perms to add topics :(
12:14arrdemlaem
12:14justin_smitharrdem: knowledge is for some natural language query system api iirc?
12:14arrdemclearly the only choices I have are to roll yet another bot or write a bunch of elisp macros for frequently linked articles
12:16sobeldo you have a db behind clojurebot?
12:16arrdemmy elisp foo is amazingly weak. I have bbatsov and john2x for that
12:18hiredmanclojurebot currently is storing factoid data in postgres
12:27sobelhmm.. i renamed everything but somehow lein is still trying to find old names. i hit my src directory structure, ns declaration, and related names in project.clj
12:39sobelgah, i just found a file out in /tmp with info i am trying to refactor.. how do i make lein clear its cache?
12:39justin_smithsobel: have you been doing all this without restarting lein?
12:42sobelno
12:42sobeli am not using lein except to build uberjar for the most part
12:44justin_smithin that case you may need lein clean
12:44sobeloh, maybe LT is making that cache
12:44sobeli did lein clean
12:45sobelwhy would it be looking for foo/bar_baz.clj after i changed its filename and project.clj reference to foo/bar-baz.clj
12:48nuwanda__sobel: pretty sure every - turns into _ when dealing with file names
12:48oddcullysobel: it is _ for dirs. so for sure also for file names then too
12:50sobeloh. yuk.
12:50sobeli wasn't aware of that mangling.
12:52oddcullyi bet it's for this popular non-unix-os
12:53justin_smithit has to do with what java accepts as a package name
12:58yellow13can a function like this #(foo %1) receive args and disacrd them?
12:59arrdem##(println (quote #(foo %1)))
12:59lazybot⇒ (fn* [p1__46534#] (foo p1__46534#)) nil
13:00arrdemyellow13: you would have to use the term %& and ignore its value IIRC
13:00arrdem##(println (quote #(let [_ %&] (foo %1))))
13:00lazybot⇒ (fn* [p1__46545# & rest__46544#] (let [_ rest__46544#] (foo p1__46545#))) nil
13:18TimMcyellow13: Sure, but it would be clearer to say (fn [_] foo) rather than using #() and adding hacks to get around that.
13:18TimMcor (fn [x & _] (foo x))
13:19TimMc_ is a convention for "unused value"
13:20sobelthx all, that fixed me up
13:21sobeloh i just realized i'm jerk for making a class with _ in it
13:22yellow13TimMc: youre right
13:22yellow13i was just thinking about the possibilities
14:50pbxapparently i unknowingly broke something in my lein/clojure setup in the past hour. lein now dies with a core dump: http://dpaste.com/06KSQQP#wrap
14:52sobelpbx: commit early, commit often?
14:54pbxsobel, to clarify i didn't knowingly change anything between when it worked a couple hours ago and this. i have no project, this happens with a bare invocation of lein
14:54pbxthe offending line fwiw: http://dpaste.com/01XQ5CR
14:59andyfsobel: Eastwood linter can help quickly find file name / namespace mismatches. Plus done other things
14:59andyfS/done/some/
15:01andyf~Eastwood
15:01clojurebotPardon?
15:01andyfCan someone in the know make that link to github URL for Eastwood?
15:01rrraaafffhttps://github.com/jonase/eastwood
15:02Bronsa~eastwood
15:02clojureboteastwood is https://github.com/jonase/eastwood
15:03dnolenBronsa: looks like Alex Miller wrapped up the conditional reader patch, let me know when you can get that applied + released. Would like to push a new ClojureScript release by Friday so people can actually use and test this stuff.
15:03Bronsadnolen: I'm already looking at it :)
15:03dnolenBronsa: k cool, thanks! :)
15:03justin_smithpbx: are you using a super old version of lein?
15:04pbxjustin_smith, not to my knowledge no
15:04pbxjustin_smith, again, it worked two hours ago
15:04pbxso it's clearly my fault but how i do not know
15:04pbxlein 1.7.1
15:04Kowryhwhat development environment do you guys use?
15:05KowryhI'm on this course that uses lighttable, I've found it pretty good (on Linux)
15:05justin_smithpbx yeah, that is ancient
15:06justin_smithpbx: at least try lein 2.x
15:06pbxjustin_smith, interesting. orthogonal to my problem but probably worth fixing anyway. i installed from the ubuntu software center
15:06andyfIt would be funny if running 'Lein ancient' with old versions of Lein replied with 'yes, I am.'
15:06justin_smithpbx: it's a very old version of lein, I would not be surprised if things in newer libs break it
15:07justin_smithandyf: haha
15:07justin_smithpbx: don't use a package manager for lein, lein is better at managing deps (including its own) than your package manager is
15:07justin_smithI also use ubuntu
15:08pbxjustin_smith, yeah, i wanted it to be available to all users and the leiningen.org method was one-user, but i'll work around
15:08puredangerBronsa: would be interested in any review on latest reader conditionals patch for tools.reader http://dev.clojure.org/jira/browse/TRDR-14
15:08pbxthanks for the help
15:09justin_smithpbx: it's a single shell script, you can put it in a place that is on everyone's PATH
15:09oddcullyKowryh: vim-fireplace and cursive
15:15Bronsapuredanger: I'll let you know, might take me a couple of hours -- not the most lightweight of patches
15:18puredangeryeah, it was a pain. no urgent rush. David is still working on the cljs side of it.
15:41katratxohi all, i'm trying to use s3-wagon-private to deploy some library code and i'm getting an Access Denied error (the .jar and some other files end up in the bucket) ... i've tried the technomancy and circle fork ... any hint on what can be wrong?
15:41katratxoi'm using an `iam` user that has full access to that bucket
15:51ncthom91hey all. I'm working on a small project involving creating a simple tree. This alone is a pretty simple task, but I'd also like to keep an index into the tree for quick access to each node. The way I've been building this involves side effects which update an (atom {}) representing my index, which causes some headache errors when lazy evaluation yields before hitting the side effect I was expecting. Surely this isn't the clojure
15:51ncthom91 way... how would you approach maintaining an index like this while assembling a tree or graph structure?
15:53cflemingSo I'd like some suggestions for how to show seqs in the debugger
15:53cflemingI'm planning to have custom renderers for LazySeq, Cons and IChunkedSeq
15:54cflemingFor LazySeq I'll display all the realised elements up to a limit, and for Cons I'll show all elements also up to a limit
15:55cflemingFor IChunkedSeq it looks like I can call chunkedFirst, and display that whole chunk, but I'm not sure how/if I should handle chunkedNext and chunkedMore
15:56cflemingFor other ISeq implementations I'm not sure what to do
15:57amalloycfleming: it's more complicated than that, right? like a sequence isn't any one of those things, necessarily, but an amalgam
15:57cflemingamalloy: Yeah, I'll actually probably have a single Seq renderer, and handle those three cases
15:57amalloyeg, (iterate inc 1) is a Cons, followed by a LazySeq
15:58puredangernot anymore it's not...
15:58amalloywell
15:58amalloycfleming's going to want his renderer to work on 1.6 anyway, i'm sure. and this was just an example
15:58cflemingAnd... right, I don't know how, or if, all this ties in with transducers
15:58puredangerfor sure
15:58puredangerit doesn't
15:59cflemingRight, they're just consumption rather than production, right?
15:59puredangeryou might want to make sure eduction does something useful though
15:59puredangerEduction that is
15:59cflemingOk, I don't really understand how that works, I'll read up on it.
16:00puredangerCalling eduction returns an Eduction instance, which is an implementation detail, but it will implement Iterable and IReduceInit, but not sequence
16:01cflemingBut amalloy is right, I definitely need a combined renderer. Is there an example anywhere of how to iterate the realised values of a chunked seq?
16:01puredangerfirst and next work pretty well :)
16:02cflemingSo in the case of a chunked seq, it doesn't have the concept of realisation in the same way? I wanted to iterate the realised elements, but I may be misunderstanding how that works.
16:02puredangerthey're all seqs, so you can always walk them as such
16:03cflemingRight, but for LazySeq at least, I only want to walk the realised elements, and not provoke realisation if the user hasn't asked for that
16:03cflemingIs LazySeq really the only special case, then?
16:04cflemingAll other ISeqs I just walk them until either I'm done or I hit my limit?
16:04puredangersure
16:04puredangerchunked seqs (ChunkedCons) will realize 32 at a time - I'm not sure if you care though
16:05cflemingOk. Eduction might be tricky, I'll have to check what the debugger does currently with Iterables
16:05puredangerIterable produces an Iterator, which is stateful
16:05cflemingAnd I'll never encounter an Eduction instance walking a seq, since they're not really seqs, right?
16:06cflemingRight, so I'm not sure I actually want to do anything with that.
16:06puredangerright
16:06cflemingSo Eductions might be tricky to display
16:06puredangeryou could wrap an iterator-seq around it of course
16:07puredangerand treat it as a seq - as of 1.7 iterator-seq will also be a chunked sequence
16:07cflemingHmm - I think I'll get seqs to do something useful first, and then worry about eduction
16:07puredangersure
16:08cflemingActually, while I have you, I have another related question. When I'm reading the indices in IntelliJ, they use a process() model, where I pass it essentially a function which is invoked for the elements of the index
16:09puredangerlike nth?
16:09cflemingWhat's the best way to use a push model like that with transducers/seqs, which are a pull model.
16:09Bronsapuredanger: any reason I'm missing why return-on-value is a parameter rather than just being READ_FINISHED hardcoded?
16:09puredangerBronsa: hang on :)
16:09cflemingpuredanger: No, this is more when I'm handling, say, all the values I have indexed for a particular ns
16:10puredangercfleming: not really getting what you're asking
16:10cflemingI give intelliJ what is essentially a function, and it calls that function for each matching element. What I currently do is use an atom, and put the elements into a vector, which I then return when process() is done.
16:10puredangerBronsa: good question - this might be an artifact of how the Clojure patch evolved, let me double-check
16:12puredangercfleming: so it controls the iteration and processing model
16:12cflemingRight
16:13cflemingpuredanger: So now I'd like to actually do my processing as I'm called back, so I'm not buffering a bunch of values - this places an unnecessary delay on autocompletion
16:14puredangersomething like core.async channels and go blocks right?
16:14cflemingpuredanger: It seems like a transducer might work well here, since I could create my processing logic and then either create a process() which calls the transducer or just run the transducer over a collection for the cases when I actually have a collection.
16:15cflemingHmm, maybe - I was hoping there was a simpler solution
16:15puredangeryou could use the same transducer with either transduce or with an async channel
16:15jcromartiewhat's the *right* way to implement the associative interfaces
16:16cflemingpuredanger: Right. I'll play around with that idea and see what I come up with.
16:16cflemingpuredanger: Thanks.
16:16puredangercfleming: the hard part is really the inversion of control
16:17cflemingpuredanger: Yeah, that's what's difficult, since sometimes it controls the processing model, and sometimes I do.
16:18cflemingpuredanger: But I'd like to be able to use the same logic. I haven't played around with transducers enough to know how I'd make that work, but from what I understand it seems like a good fit.
16:18puredangerchannels are reducible too
16:21puredangerBronsa: I think you're probably right.
16:21ircxyShouldn't (read-string nil) return nil instead of throwing a NPE?
16:23ircxyGiven the NPE behavior I have to wrap with an if. (if x (read-string x) nil)
16:27puredangerwhy are you trying to read a nil string? this seems like correct behavior - trying to read a string, but found nil.
16:28kungiOMG! Cider has a debugger now. This is so awsome!
16:29danlentzpuredanger: purchased my beta copy of Practical Clojure. That's you?
16:29puredangeryep! thanks!
16:30ircxypuredanger: I'm validating required and optional parameters on a rest call. When the optional params are not given they're nil. When they're both nil it's valid, both provided also valid.
16:31puredangerdanlentz: oops, I assume you meant Clojure Applied :) Practical Clojure is Luke VanderHart and Stuart Sierra
16:32danlentzRight, sorry
16:32puredangerdanlentz: (also a good book!)
16:33puredangerircxy: it may not match up for your particular use case, but current behavior is consistent with many other parts of Clojure
16:33danlentzYou should just author under the name puredanger so people would just know to buy the book.
16:33ircxypuredanger: min and max are optional rest params, but they must either both be there of not. (xor min-param max-param) So if they're both given validate them, like min < max, etc.
16:33justin_smithircxy: (some-> x read-string)
16:34justin_smith,(some-> "hello" read-string)
16:34clojurebothello
16:34justin_smith,(some-> nil read-string)
16:34clojurebotnil
16:34ircxyjustin_smith: cool, didn't know about some->. thanks.
16:34justin_smithircxy: it also does chaining like -> does
16:34justin_smithbut stops at the first nil, and I think in this case it is clearer than an if
16:35ircxyjustin_smith: learned something. tx
16:39danlentzPragmatic seems to turn out quality texts more consistently than packt, in what limited experience I've had. Although I've also been learning a lot from Leonard Borges Reactive Clojure
16:40danlentzQuite a month in clojure publications
16:47puredangerdanlentz: pragmatic has a much stronger and more rigorously enforced house "style than any publisher I know
16:49danlentzComing over from common-lisp, this sensation of having new texts published all the time for clojure is quite a nice thing
17:04szatzhello, again. after seeing how transducers can get rid of computation in a scenario like (into [] (comp (take 2) (map some-fn)) big-collection) vs. older style, it seemed like just further laziness. Something similar can be done by default in Haskell: take 2 $ map someFn bigCollection. i feel like there's more to transducers that i'm missing. can anyone offer guidance?
17:06mikerodszatz: I guess I don't know if Haskell allocates intermediate sequences there.
17:06raspasovszatz: they can be applied to core async channels, and potentially other things in the future
17:06mikerodI also do not know if there is a sort of "thunking" setup laziness overhead in Haskell
17:06hiredmanmikerod: it does, without adding stream fusion or whatever
17:06szatzmikerod: given that you can take 2 $ map someFunction [1..] means it doesn't.
17:06szatzmikerod: or listen to hiredman, but you get a result with an infinite list.
17:07mikerodszatz: transducers will run the composed function in one pass over the input data producing the output structure - no further allocations and no necessary lazy-thunking overhead
17:07hiredmanszatz: that doesn't mean anything about if intermediate results are generated, it just means they are lazy
17:07hiredman(the [1..] bit)
17:07mikerodhiredman: yeah, I thought it would
17:07mikerodI don't know at all about the stream fusion stuff - I've just heard the name
17:08szatzhiredman: so the thunking (which seems inexpensive, but perhaps i'm wrong) is the only overhead from the Haskell one?
17:08hiredmanszatz: I dunno
17:08mikerodszatz: and intermediate seq allocation potentially
17:09mikerodperhaps :)
17:09hiredmanszatz: it can seem inexpensive, but igven the effort people have gone through to make stream fusion work, obviously it can be expensive enough
17:10mikerodI can't imagine how that would work - sounds magical
17:10mikerodI guess when the compiler can't figure it out, it just falls back to the normal style
17:10szatzhiredman: ok, that's fair.
17:11mikerodHowever, isn't there a concept with transducers that the tranducer "process" itself can be sort of optimized for specific usages. So like `into` is "aware" that laziness is not needed. The composed functions are just applied as a single fn per item that passes through the process.
17:12mikerodSo you can write transducer processes for different types of scenarios. `transduce` vs `sequence` vs `educe` vs etc
17:13justin_smithmikerod: right, but the main advantage of that is bypassing the thunking
17:13mikerodjustin_smith: yeah, I'd figure so
17:13mikerodWell there is the difference of caching vs non-caching
17:14mikerodin other scenarios
17:14mikerodDoes Haskell cache realized lazy elements?
17:14mikerodtime to know more about Haskell I guess :(
17:17amalloymikerod: haskell caches all computed values that you save a reference to
17:17amalloy"caches", of course, since like...what else would it do
17:18justin_smithI wonder what a language that doesn't do that would look like
17:18mikerodI mean caching in the sense of computing the value once
17:18mikerodnot in the sense of throwing away referenced objects or something
17:18amalloymikerod: in java, when you write: int x = 2 + 2; is the compiler caching x?
17:18mikerodeduce vs sequence
17:20mikerodso in Clojure if I have a lazyseq it is a bunch of thunks that delay teh computation. when the element is needed it is realized and cached - thunk isn't called anymore.
17:21mikerodthat's what I mean by caching.
17:21mikerodSo if Haskell returns an infinite lazy collection and one caller wants 5 elements. the next caller wants
17:21mikerod6
17:21mikerodis only 1 new computation done
17:22amalloymikerod: all values in haskell start as thunks, which are cached if you save a reference to them
17:22mikerod(assuming the first caller is done with those 5 references)
17:22mikerodamalloy: if all references disappear, does it start from scratch again?
17:22amalloythat's impossible
17:23amalloyhow could you reuse an object with 0 references to it?
17:23mikerodscope?
17:23clojurebotscope is at http://paste.lisp.org/display/73838
17:23mikerodcaller needs a few values of an infinite seq to figure something out then doesn't need them anymore
17:23mikerodI'm not seeing how that is an impossible scenario
17:24amalloymikerod: it's not impossible, but it's not having 0 references to the object
17:24mikerodoh, ok
17:24amalloybecause you're assuming the second caller somehow gets a reference to the same seq
17:24amalloywhich means that the original seq still had a reference to it somewhere
17:24mikerodI see what you mean. So they are cached indefinitely.
17:24amalloyuhhhh
17:24amalloythey are cached for as long as you have a reference to them
17:24mikerodyes
17:24mikerodI get it, sorry
17:34szatzsorry if i'm being hard-headed, but i'm still not clear on if there is more to transducers than avoiding the thunking?
17:34szatzperhaps it's because the concept ports "easier" to other languages that don't support laziness as strongly as Haskell?
17:35mikerodMy point on caching was that with educe you can have a lazy computation that you don't retain the results if they are not held specifically. So the computation will happen again. But I give up on that topic I guess. I've alos noticed it is really hard to search for `educe` on the internet.
17:35mikerodit just gets fixed and assumed to be `reduce` :P
18:10pandeirois there any hope for clj-webdriver or is the compatability battle a lost cause?
18:24ambrosebshow can I throw an exception from nREPL middleware without stopping the entire REPL?
18:25ambrosebsdo I manually set e* and prn the exception?
18:25ambrosebsthat sounds sane enough
18:25justin_smithas a user, I would find the fact that I couldn't catch and handle it confusing
18:26ambrosebsI don't want the user to catch it, I'm piping code through core.typed for checking
18:27justin_smithmy usual assumption would be that if I saw an exception printed (or what looked like an exception being caught and printed) I could catch it myself nad handle it some other way. But if this is totally not interactive I guess that's another thing.
18:28ambrosebsmakes sense
18:28ambrosebsit would be like catching a type error in Haskell. not advised.
18:28ambrosebsso perhaps setting e* doesn't make sense either
18:29justin_smithI guess this is a strange beast - it deserves printing and handling but shouldn't be caught or handled - maybe you don't want an exception, you just want sternly worded logging?
18:29justin_smith*shouldn't be caught or handled outside of your middleware, of course
18:30ambrosebsyes this is what I want
18:30justin_smithyeah, I would say logging with level of WARNIGN or SEVERE ?
18:31ambrosebs,(throw 1)
18:31clojurebot#error{:cause "java.lang.Long cannot be cast to java.lang.Throwable", :via [{:type java.lang.ClassCastException, :message "java.lang.Long cannot be cast to java.lang.Throwable", :at [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval25 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval ...
18:31ambrosebsright, I want something special like that
18:31ambrosebsbut no return value
18:31ambrosebsbut it's not an "exception" either
18:31justin_smithright, so just a WARNING log or a SEVERE log I'd say
18:32justin_smithit will get attention, but it doesn't affect control flow
18:32ambrosebswell I'm going to throw away the REPL interaction if we get a type error
18:32hiredmanwhy don't you want users to be able to catch it
18:33ambrosebshiredman: this is a simple typed repl: code goes in, return or type error comes out
18:33ambrosebsI'm not sure what catching a static type error would mean
18:34ambrosebscore.typed already exposes primitives for type checking arbitrary code, which you can call if you need to "catch" type errors
18:34hiredmanambrosebs: sure, but like, we can't think of a reason to allow that now, is it a good idea to rule it out?
18:35hiredmanwhat is the harm of allowing users to catch it if for some crazy idea they want to?
18:35ambrosebshiredman: I don't even know what this would look like.
18:35hiredmanso throw an exception and whatever
18:35ambrosebshiredman: you can't catch a static type error in any typed langauge I know
18:36hiredman*shrug*
18:36hiredmanthe compiler throws exceptions
18:36ambrosebsdo you mean I should populate e* ?
18:37hiredmanI dunno, just throw an exception
18:37hiredman*e is a property of the repl implementation you use
18:37ncthom91http://stackoverflow.com/questions/840190/changing-the-current-working-directory-in-java is there really no way to change the cwd in clojrue?
18:37ambrosebsright. I'm implementing nREPL middleware and I don't know how to simply throw an exception. It seems to just kill the entire repl.
18:38ambrosebsmust be some special handler to do so.
18:38hiredmanambrosebs: oh, right, the thing to do there is send a response message explaining the error
18:38hiredmanambrosebs: when dealing with nrepl, you are doing rpc
18:39justin_smithncthom91: it's a portability problem
18:39hiredmanambrosebs: you are not in a single jvm, throwing exceptions doesn't exist
18:39justin_smithncthom91: there's an answer that works for like everything but windows
18:39ambrosebshiredman: aha
18:39hiredmansetting *e doesn't exist
18:40hiredmanhttps://github.com/clojure/tools.nrepl#handlers has a section that mentions error keys in nrepl messages
18:40ncthom91justin_smith hm... that's a bummer. I'm working on a tool that will look for a config file in the cwd... would like to set up a "mock" directory structure within my project to test within
18:41justin_smithncthom91: if you don't need windows support, it can be done
18:42ambrosebshiredman: seems like I want a {:status :error} entry, where do I put the error message?
18:42ncthom91justin_smith sure. how can I do that?
18:43justin_smithncthom91: it requires using jna to change the PWD environment variable
18:44justin_smithturns out "current directory" is just that one var in your env
18:44justin_smithncthom91: https://github.com/arohner/lein-daemon/blob/master/daemon-runtime/src/leiningen/daemon/runtime.clj
18:44hiredmanambrosebs: checkout some other middlewares I guess, https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/middleware/interruptible_eval.clj#L55
18:45hiredmanmaybe you just put the message in :out or something
18:46justin_smithncthom91: but even that is not portable to Linux - he uses user.dir instead of PWD (I guess osx must use user.dir?)
18:47justin_smithoh, getProperty not getenv
18:47justin_smithI've got that confused
18:48justin_smithncthom91: this may be more helpful http://stackoverflow.com/questions/840190/changing-the-current-working-directory-in-java/8204584#8204584
18:49justin_smithncthom91: the magic lines in that gist are line 45 and line 45
18:49justin_smitherr, 35 and 45
18:56ambrosebshiredman: struggling to find where :status is actually checked
19:00ncthom91justin_smith cool, thanks
19:03hiredmanambrosebs: a client would use it
19:04ambrosebslike leiningen?
19:04hiredmanambrosebs: tools.nrepl has a simple client, but tools.nrepl is mostly just the server
19:04hiredmanambrosebs: reply is the client leiningen uses
19:04hiredmancider contains a client written in elisp
19:04hiredmanetc
19:05ambrosebsok
19:30daviidhow do i write (let ((i 0)) ... (when something (set! i (+ i 1)))) in clojure ?
19:31amalloydaviid: first, embed a common lisp interpreter
19:32amalloy(you can't mutate locals)
19:32daviidamalloy: i know, what would you write to get the same result ?
19:33amalloysomething else. (let [i (if something 1 0)] ...), for example. the stucture will depend on why you think you need to mutate it
19:41daviidamalloy: here is a code extract: http://paste.lisp.org/+35CI where i have an ep variable init to 0 and i need, somehow, to increment it [last line, scheme code on purpose] and use it in the write-pp-h call, how woulkd you write that in proper clojure ?
19:41tolstoydaviid: Maybe (loop [i 0] do-something (recur (inc i))) if do-something has side effects, or reduce if not?
19:43amalloyyeah, the answer is to not use dotimes probably
19:44amalloyalthough honestly even in CL this structure wouldn't work, because you're initializing a brand-new `ep` in every iteration of the loop anyway
19:44daviidamalloy: yes i did paste too quickly :) the ep is out the dotimes ...
19:45daviidbut still, i just don't know
19:45daviidhow do we write proper clojure for this trivial example?
19:45amalloy(loop [i 0, ep 0] (let [...] (when (< i obj-num) (let [...] (if ... (do (write-whatever) (recur (inc i) ep)) (recur (inc i) (inc ep)))))))?
19:46amalloyit's hard to say exactly, because this paste is kinda vague in what you expect to happen inside of the if/dotimes
19:46amalloyoh, and i wrote too many lets. doesn't matter really
19:47daviidbut you got the quizz right? i have an external let holding ep, a loop of what ever construct, and i want to increment ep when an object is smaller then ..
19:47tolstoyThe idea is to use recursion (or reduce) to produce a value and return it.
19:47amalloydaviid: yeah the idea is to not do that
19:48daviidtolstoy: reduce won't work, or show me
19:48daviidas i said, i'm learning, please tell me
19:48daviidan example
19:48amalloyi did show an example
19:48amalloyi don't understand your followup "you got the quizz right"
19:53tolstoy(loop [i obj-nb ep 0] (if (zero? i) ep (do (whatever) (recur (dec i) (if (min-max-thing) (inc ep) ep))
19:54tolstoySomething like that.
19:54tolstoy?
19:54justin_smithdaviid: you can't change ep if something else holds it - you need to return it from your loop
19:55justin_smithtolstoy yeah, that looks about right
19:55tolstoyYou could use reduce, but that "write" thing suggests a side-effect.
19:55daviidok, recursive function i can write, i'll try that because these loop construct i am not so familiar with, but thanks all of you!
19:56justin_smithdaviid: loop is like a recursive function
19:56daviidtolstoy: the 'write' is a funct5ion which writes the file which is a crop of the original image
19:56justin_smithdaviid: be careful, in clojure recursion is not optimized (except via recur)
19:56daviidoh! id that true?
19:57justin_smithdaviid: if you call recur it's fine
19:57justin_smithjust don't expect normal recursion to be optimized as a tail call
19:57daviidoh too bad
19:57daviidi love tail call recursive 'style'
19:58daviidbut let me try one of yur examples
19:58justin_smiththe only difference is calling recur
19:58justin_smithinstead of your own function
20:06Bronsadnolen: fixed a couple of bugs in the reader conditionals patch, can't see any other issue right now. I'm going to wait until tomorrow anyway and if nothing else comes up will release 0.9.0
20:06dnolenBronsa: cool, on the CLJS side of things, I'm ready for tools.reader, anywhere a user can supply .cljs, .cljc is now permitted and checked first
20:07Bronsadnolen: if you want to try it out it's in the reader-conditionals branch
20:07dnolenso the only thing I need to do at this point is turn on conditional reading for .cljc files
20:07dnolenBronsa: yeah I saw that, done for the day, will check it out tomorrow, thanks!
20:11daviidi wrote this: http://paste.lisp.org/+35CI/1 it complains you can only recur from tail position
20:12daviidoh tipo
20:14justin_smithdaviid: while inside loop is almost never the right thing
20:14daviidhttp://paste.lisp.org/+35CI/2 but it still complains
20:14daviidjustin_smith: fine, what do you suggest ?
20:14justin_smithdaviid: the while is infinite, because i cannot cahnge in the scope of i
20:14justin_smithdaviid: remove the while
20:15justin_smithinstead, only recur if i is less than obj-nb
20:15justin_smithotherwise don't recur
20:15daviidah ok let me try
20:15justin_smithfrom a quick read this looks very close to being what you want though
20:16daviidjustin but if obj-nb is zero it will crash if a execute the let and only check at recur time
20:16daviidthat why i wrote while ...
20:16justin_smiththen you need the if before the let block
20:17justin_smithmaybe you want when instead of while
20:17daviidwhen will work?
20:17justin_smiththe thing about using when is that it means you return nil
20:17daviidbecasause if outside the loop sounds redondant
20:18justin_smithit's not outside the loop
20:18justin_smithit would be inside the loop
20:18justin_smithbut before the let
20:18justin_smithif you want to return nil, use when
20:18justin_smith(exactly in the way you had used while)
20:18daviidi thing when is fine
20:18justin_smithif you want to return ep, then make an if that either returns ep, or enters the let block
20:19daviidok
20:22daviidhttp://paste.lisp.org/+35CI/3 this works, is this good coding standard for clojure ?
20:23justin_smithdaviid: it would be much simpler if you can get a seq over obj-nb and use some sort of filter / map / reduce
20:23justin_smithbut getting a working loop is a good start :)
20:23justin_smitherr, a seq over results I mean
20:24daviidi don't know how to write that [ a seq over results ]
20:25daviidi'd love too, this code is very verbose to my scheme taste :)
20:25justin_smithdaviid: if it was a Collection or an Enumeration we have seq or enumeration-seq built in
20:28daviidjustin_smith: i've no idea how to write this shorter than i did
20:29justin_smithdaviid: what is the class or type of result ?
20:29justin_smithbecause if it were a sequential thing, it could be converted to a reduce that would be less verbose
20:30daviidi'm not sure what it is, it is a java beast [imagej] i thought it ws an array
20:30justin_smithoh, you can reduce on an array
20:32justin_smithit would be something like (reduce (fn [ep item] (let [x (something item "BX") ...]) 0 results)
20:32justin_smiththe next question being what the right call is when you have a single element of results, and not the whole collection
20:32justin_smith(to fill in for that "something", of course)
20:34daviidjustin_smith: here is a def http://rsbweb.nih.gov/ij/developer/api/ij/measure/ResultsTable.html
20:36justin_smithyeah, you're stuck with the ugly way, unless you want to write a bunch of clumsy interop to try to treat that as a normal collection
20:37justin_smithwhich would be uglier, unlessy you plan on operating on many of these, then it might be worth just doing it once and getting it out of the way
20:37justin_smith*unless
20:38daviidjustin_smith: ok, that's fine this results beast is a given inagej object, not much i can do i guess
20:40justin_smithdaviid: it's kind of sad, because we have all these wonderful tools for collections of things, and then an API like that doesn't contain any data that couldn't be represented that way, but just has to be a special snowflake and not cooperate with any of our nice otherwise-reusable abstractions
20:40daviidi could apply map list maybe ?
20:40justin_smithbut it isn't a list
20:40justin_smithit's not exposing itself as anything sequential
20:41daviidi could grab 4 list of values
20:41daviidbx by width and height
20:41justin_smithinstead, you have to ask for an X and Y (row and column) to get a value
20:41daviidthen reduce
20:41justin_smithyes, that's the "clumsy" way I was mentioning above :)
20:43daviidok, have to run, thanks a lot! i'm not regular at #clojure but will be back sometine, maybe soon :)
20:43daviidtx all!
20:44justin_smithrx np
21:00ncthom91Hi all. Suppose I define an instance of nashorn at the top of my file... (def nashorn (.getEngineByName (ScriptEngineManager.) "nashorn")), but then I spin off some threads that each evaluate various expressions and function calls in that nashorn engine... Nashorn doesn't guarantee thread safety, so how can I make sure that each thread gets its own instance of the nashorn engine?
21:00ncthom91(I'm using the executors framework with newFixedThreadPool)
21:00ncthom91so theoretically each thread could bind its own reference and then just hang onto it for its lifetime
21:01amalloythat's pretty much the only way to do it, ncthom91; solutions will just be more or less fancy ways of doing it
21:01justin_smithncthom91: if each thread should have its own instance, don't bind it at the top level
21:01ncthom91justin_smith where bind it then?
21:02amalloyyou could eg use https://github.com/flatland/useful/blob/develop/src/flatland/useful/utils.clj#L201, and (def nashorn (thread-local (.getEngineByName (ScriptEngineManager.) "nashorn")))
21:02amalloythen each thread can just refer to @nashorn to get its private version
21:03ncthom91amalloy that sounds pretty nice
21:04amalloythis presupposes that giving each thread its own copy is the right thing to do, which only you know for sure
21:05ncthom91well that seems to be the only way to safely evaluate js in an MT environment given that nashorn doesn't support it itself, right?
21:05ubuntuboyhello all
21:06amalloywell, you could ensure that there's only one engine, and that only one thread accesses it at a time
21:06amalloyor you could create engines in some other context, such as a "job" or something at a different granularity level than a thread
21:07ncthom91amalloy true. I expect the js execution will be the bottleneck, so I don't want the threads blockign each other for access to the engine
21:07ubuntuboyI have a question, does anyone know why I can not stream Time Warner live tv in Ubuntu 14.10?
21:08amalloyubuntuboy: this is the wrong channel for that question
21:09ubuntuboysorry cant you point me in the right channel?
21:09amalloytry #ubuntu, i dunno
21:09ubuntuboyokay thanks.
21:14ncthom91amalloy can you explain thsi syntax to me? https://github.com/flatland/useful/blob/develop/src/flatland/useful/utils.clj#L195-L196
21:14amalloy,(doc proxy)
21:14clojurebot"([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, mus...
21:16ncthom91heh, thanks :)
23:11danielglauserWhy do defmulti and defmethod have defonce semantics?
23:15justin_smithdanielglauser: if you redefine the defmethod, it destroys all your multis
23:15justin_smithso the default is to make it defonce so just reloading your ns does not break other namespaces
23:16tomjackjust defmulti, not defmethod, though, yes?
23:16amalloyi think you had method/multi backwards there justin_smith
23:16tomjack(or did I get them backwards yet again?)
23:16justin_smithamalloy: oh, yeah, I did flip those
23:17tomjackI guess my mnemonic will be that it's in order: multi. method. :)
23:17danielglauserjustin_smith: That makes sense. I don't often have the defmethods in other namespaces but yeah, that's a thing.
23:55IgorWhen I want swap! atom with value, must I do it in sync block, if value depends on given atom?
23:55justin_smithIgor: you swap! an atom with a function
23:56justin_smithand no, using atoms does not require sync blocks or transactions
23:57Igorno swap! , reset! , sorry
23:57justin_smithno, reset! does not require a sync block, if you are only changing one atom
23:57justin_smithif you have two changes that have to go together, something like that may be called for (and you may be better off using a ref)