#clojure logs

2014-12-15

00:00Bruce_WayneI need this to be deployed on heroku
00:15Bruce_Wayneanyone know a good way to make a calendar on a web app?
00:22sdegutisWhy did Clojure choose to be dynamically typed?
00:22sdegutisI find that especially odd because most people who like Clojure seem to prefer static typing.
00:27rritochsdeguutis: You would need to ask the original developers to get an answer to that question but the following issues probably played a role http://stackoverflow.com/questions/3323549/is-a-statically-typed-full-lisp-variant-possible
00:33puredangerI don't think that had anything to do with it
00:34puredangerhaving heard Rich talk about it a few times
00:34sdegutispuredanger: what do you think?
00:34puredangerI think Rich doesn't have a problem with types, but he prefers (given the benefits and consequences) not to be required to use them
00:35rritochpuredanger: So the original developers had nothing to do with the decision? It seems you were just looking for an excuse to counterdict me.
00:35puredangerRich is the original developer
00:36puredangerhttps://github.com/clojure/clojure/graphs/contributors (richhickey)
00:37rritochI'm aware of that, I have a signed CA
00:37puredangerwell then, I don't understand the question re original developers
00:38rritochIt was a rhetorical question.
00:39puredangermy point was that Clojure is not dynamic because statically typed lisps are hard/impossible, but because that's what Rich preferred
00:40puredangerShen is a pretty interesting statically typed Lisp for example http://www.shenlanguage.org/
00:41rritochEither way, clojure is a bit of a hybrid now. There are often situations where type matters. Sometimes, but not always, clojure will resolve type issues with reflection, but when Java interop is involved, such as return types needing to match that of an interface, sometimes it's required to specifically cast to a required type.
00:43puredangerI prefer to think of Clojure as a language that gives me choices about how much checking I want to do in different parts of my code
00:43sdegutisIntersecting.
00:43puredangerin some places I may use a bunch of libraries (prismatic etc) and rigorously check data against a schema either at compile-time or runtime
00:44puredangerwhile in others, I may not care (or it may not make sense)
00:47sdegutisI like having compile time static type checking just as a way of having free extra tests.
00:48puredangerthat is a popular view :)
00:48sdegutisPlus it helps me to design my system more thoughtfully, instead of changing some code 5 times before it's what I meant for it to be in the first place.
00:49sdegutisThat said, it's not the popular view when writing web apps.
00:49puredangerI don't feel like static typing has any impact on that for me personally
00:49puredangerin that I always do it wrong 5 times regardless of types :)
00:49sdegutisHonestly my only real complaint about Clojure is how long it takes to start up. I know there are tricks to compensate for it, but it's just not the same as having a clean, fresh start.
00:50sdegutishaha!
00:50sdegutis@ puredanger
00:50puredangerwell, there's ongoing work in that. we'll get there eventually, maybe next yera.
00:52puredangerit's really the cost of eager var loading that's expensive
00:52sdegutisForgive me if I'm erring on the side of caution i.e. pessimism.a
00:54puredangerregarding startup time?
00:54puredangerplenty of room for improvement
00:55puredangerthere are limits of course
00:56puredangerClojure never really targeted optimizing startup time given the jvm (which actually starts pretty quickly now)
00:58sdegutisI suppose that's reasonable.
00:58sdegutisI don't know what it is. Something just bothers me about Clojure these days.
01:00rs0sdegutis: if you work with the JVM a *lot* you get more used to it
01:00puredangeryou just need more paren hugs ( ( ( ( ( ) ) ) ) ) )
01:00arrdempuredanger: I was gonna say have some faith but the parens hug is better :P
01:00puredangerI've got more if you need 'em
01:01sdegutis:)
01:01arrdemup to my eyeballs in 'em over here :c
01:01sdegutisMaybe it's actually just web dev that I'm getting tired of.
01:01puredanger,(repeat "()")
01:01clojurebot("()" "()" "()" "()" "()" ...)
01:01sdegutisAll the static asset pipeline caching, all the hacks, all the nonsense.
01:01rs0after studying Clojure, i have a hard time finding programming languages to study that don't look boring. does anyone have suggestions for what i could study to get a similarly mind-blowing experience? Forth, Prolog, Smalltalk, APL?
01:01sdegutisYeah, I'm pretty sure it's actually just web dev that I'm annoyed with.
01:01puredangersdegutis: I'm so tired of that I can't even start
01:02sdegutisAll the CSS preprocessors, the JS concatenation, the transpilers...
01:02puredangerrs0: Factor, Idris, Agda, Shen
01:02arrdemrs0: prolog is good, haskell is worthwhile but hard, haven't played with shen but it's somewhere inbetween the other two and clojure
01:03puredangeryeah, prolog broke my brain when I first encountered it
01:03rs0arrdem: i've already studied haskell on and off. i was most recently looking at lenses and MPTCs (which i now understand in terms of multimethods)
01:03rs0TBoS?
01:03arrdemThe Book of Shen
01:03rs0ah
01:04arrdemDr. Tavor's overpriced, non US printed Shen manual but I'm not bitter or anything :P
01:04puredangerdid I hear they were changing the license?
01:05arrdempuredanger: yeah the BSD changeover is confirmed. Sent in my £20 yesterday
01:05rs0puredanger: why specifically Factor over Forth? any reason?
01:05puredangerrs0: no reason / either
01:06arrdemdamnit... the -1 bug is back
01:06puredangerthis is one of my favorite Strange Loop talks from Chuck Moore http://www.infoq.com/presentations/power-144-chip
01:06rs0puredanger: anyway, thanks; those are good suggestions
01:06puredangera guy on a totally different wavelength
01:06arrdempuredanger: that's an awesome talk.
01:07arrdemevery time I sat down on my LispM article I had that in the back of my mind as an argument to the contrary :P
01:07puredangerI saw him talking to Dan Friedman in the hall and I just thought man, those guys are both awesome and coming from totally opposite ends of the spectrum
01:08rs0puredanger: what dichotomy are you guys referring to? just high level/low level?
01:08rs0arrdem: i'm not sure which LispM article you're referring to
01:08puredangeryeah kind of abstraction vs hardware power optimization or something
01:08arrdemrs0: http://arrdem.com/2014/11/28/the_future_of_the_lispm/
01:08puredangerMoore actually drove to Strange Loop from Nevada
01:09rs0arrdem: "It is expected to piss off loper-os."
01:09rs0arrdem: okay, I immediately see where this is going
01:09arrdem:D
01:09puredangerthat in itself is a lofty goal
01:09rs0arrdem: he's fascinating
01:10arrdemrs0: I go back and forth on that guy. And Rich. And Alex. It's probably a sign that I'm thinking about your work at this point :P
01:10rs0arrdem: but i don't think he's right about everything. i think he's extremely wrong about immutability
01:10arrdemrs0: where'd he go off on immutability? I don't remember that one.
01:12rs0arrdem: well, i can't remember exactly--i think it might have been his article where he eulogized Urbit or something. he said that mutability is useful and important because the hardware is inherently a mutable substrate, and because the mapping from immutable data structures to the underlying state of the machine is much more complex
01:12rs0http://www.loper-os.org/?p=1390
01:12arrdemyeah I remember reading that one.
01:13arrdemUrbit... is its own kind of crazy.
01:13arrdemI actually agree with loper-os there. The Urbut VM is crap, but for different reasons.
01:13rs0arrdem: i took one look at that and kept right on driving, so to speak. the aggressively unfamiliar and arbitrary lingo didn't help
01:13rs0which is of course superficial, but there was *so much stuff*
01:14arrdemyeah. I'm usually willing to read through the vitriol because there is technical merit there, but it takes effort and can't be done in bulk.
01:14arrdemnot someone I'd want to actually debate.
01:15rs0arrdem: i think he's most correct when he talks about how computers should actually work, and we don't really expect them to--but he's not exactly going out on a limb there, either. it's not a brave statement
01:15arrdemoshit. all my tests just passed. brb committing everything.
01:15rs0arrdem: i remember one of his articles about video codecs that seemed really out-of-touch with reality, despite the fact that the writing was amazing and hilarious. here, let me find it
01:15rs0arrdem: http://www.loper-os.org/?p=309
01:16rs0arrdem: the Kay stuff he's quoting there strikes me as the worst kind of quasi-object-oriented snake oil
01:18fairuzHow do people usually deploy their clojure app in the test environement? uberjar / uberwar? Or still with lein
01:18arrdemfairuz: running lein in production is discouraged, so if you really want "test" you should be running from uberjar/uberwar.
01:19arrdemrs0: idk. I like his vision of the loper-os itself and the note taking prosthetic, I just think that he's setting out to do more than needs to be done which is the thesis of my LispM post.
01:20arrdemrs0: he's reinventing a past that never existed and ignoring perfectly good hardware/software to do so.
01:20arrdemwhy invent a "better" lisp when you could "fix" Clojure or r7rs neither of which is half bad.
01:20rs0arrdem: oh believe me, i can't wait to read this article
01:20rs0arrdem: whether he's right or wrong, he's making very important claims
01:21arrdemI'm just offended by his pervasive application of the No True Scottsman argument to define Clojure and any other lisp dialect he doesn't like as Not Lisp. It's kinda funny.
01:22arrdempuredanger: so while I'm playing with reader madness... is #+foo #+bar qux defined?
01:22rs0arrdem: yeah. he's positioning it like Clojure is the sellout pop group and Common Lisp is the ballsy underground band
01:23puredangerarrdem: meaning what?
01:23puredangernested feature expressions?
01:24arrdempuredanger: are we/will we be allowed to nest host exprs to get logical conjunction?
01:24arrdemyeah.
01:24puredangerthe current impl has conjunctions built in
01:24arrdemkk.
01:24puredanger#+(and foo bar)
01:24arrdemOh. Or that.
01:25puredangerI don't actually know what your example would do on the current patches but that's one of a few things I'm hoping to get back to soon
01:25arrdemI'll be watching with interest.
01:25fairuzarrdem: ty. Let say I'm using uberjar. When I did java -jar xxxx-SNAPSHOT-standalone.jar port 3000. I got an error with something like Exception in thread "main" java.lang.AssertionError: Assert failed: Something is wrong with the port argument: port. Is there other way to specify the port?
01:26arrdemafter Tuesday lemme know if I can help :P
01:26rs0whatever happened to clojure-py2 and clojure-scheme? dead projects?
01:26arrdemfairuz: just from that I can't help a ton. Can you paste your -main somewher? refheap preferred.
01:27arrdemrs0: well we have pixie now..
01:27arrdemI think that clojure-scheme and clojure-racket are both kinda dead.
01:27fairuzarrdem: here you go https://www.refheap.com/94912
01:27arrdemKiss/Oxlang has some life in it but they're more dialects/experiments than imp'ls
01:27rs0oh wow, pixie targets RPython. i wasn't familiar with this project
01:28devll``
01:28arrdemfairuz: what's (first ["port" "3000"]) gonna be?
01:28devll`is Incanter dead too ?
01:28arrdemdevll`: why would Incanter be dead?
01:28arrdemmore feature complete if anything..
01:29fairuzarrdem: yeah just realized that dumb mistake.
01:29fairuzI got another error: Wrong number of args (0) passed to: core/production-config but let me investigate first :)
01:30arrdemfairuz: hey at least I'm gonna be nice about it :P
01:30fairuzarrdem: :)
01:30puredangerisn't someone working on an update of incanter?
01:30arrdemno idea. Incanter is something I haven't touched yet.
01:30devll`I don't see many updates recently .
01:31puredangerit has not been very actively developed for quite a while but I still use it occasionally
01:32puredangerLooks like mikera is still tending it, probably useful as a front-end for core.matrix stuff
01:33TEttingermikera's pretty awesome, I've seen some of his projects relating to core.matrix. it's a shame he doesn't come here often
01:33devll`Coming for Java background, I really like REPL while writing analytical stuff. I hope Incanter long live and prosper.
01:33TEttingerdevll`, oh man absolutely
01:34kenrestivo(inc anter)
01:34puredangerheh
01:34arrdemis there a way to "clear" a multimethod? I'm not seeing one.
01:34TEttingerI think helping coders make sense of complex data is one of the biggest strengths of clojure
01:34puredanger arrdem as in removing existing methods?
01:34rs0arrdem: well, there's remove-method
01:34rs0arrdem: but i don't think you can list or clear methods
01:34arrdempuredanger: removing all methods.
01:35mattreplanyone here use incanter?
01:35puredangerwell MultiFn has reset() :)
01:35arrdemwell damn.
01:35arrdemI can't read.
01:35arrdemlazybot is still AFK or I'd inc.
01:36puredanger(remove-all-methods)
01:36puredangercalls that
01:36arrdemseeing exactly zero mentions of that googling around.
01:36puredangerI'm just looking at the source
01:37arrdemtotally on ClojureDocs/Grimoire
01:37puredangerhttps://clojuredocs.org/clojure.core/remove-all-methods
01:37rs0that reminds me--it's pretty difficult to add multimethods from Java using only Clojure's Java API
01:37arrdempuredanger: got a minute to talk about docs stuff before I crash for the night?
01:37rs0i ended up using a StringBuilder to construct and eval Clojure code
01:37puredangersure
01:37puredangerrs0: ew
01:38arrdemrs0: why we have perfectly good list construction via `
01:38arrdem(dec eval-string)
01:38rs0puredanger: https://github.com/rschmitt/dynamic-object/blob/master/src/main/java/com/github/rschmitt/dynamicobject/DynamicObjects.java#L119
01:38puredangerrs0: you could just call .addMethod() on the MultiFn
01:39arrdempuredanger: have you seen lib-grimoire?
01:39rs0puredanger: i realize that, but i was being a reeeeeal choir boy about the whole "don't take dependencies on Clojure's internal Java classes" thing
01:39puredangerrs0: <shrug>?
01:39puredangerwith great power, yada yada
01:40rs0puredanger: which is technically everything other than Clojure#var and Clojure#read I think
01:40puredangerarrdem: no, although I've seen enough updates from you here or elsewhere that I inferred what it must be :)
01:40puredangerrs0: pretty much. IFn is kind of unavoidably public
01:40kenrestivo"remove all methods" sounds like it should be said in a dalek voice
01:40puredangerkenrestivo: agreed
01:40rs0puredanger: yeah it gets weird
01:41arrdempuredanger: lol. I basically exported the Grimoire datastore as a library and threw an abstraction layer around it so that you can have multiple backends besides the raw filesystem I use.
01:41kenrestivospeaking of which, i hope those fixes to multimethods make it into a release soon
01:41rs0kenrestivo: which ones?
01:41puredangerkenrestivo: the ones in my blog were in 1.7.0-alpha1
01:42kenrestivothis one? http://dev.clojure.org/jira/browse/CLJ-979
01:42puredangerI have that in my mental AOT bucket, not multimethods
01:42puredangerbut yes, I'm hoping to build a case for putting that in 1.7 this week
01:43kenrestivothanks for all the work you're doing to move releases along.
01:43arrdempuredanger: so what I can do now is source in multiple repos/dir trees of docs and notes. My question to you is "officially" how should I handle Core|Contrib docs? Obviously I don't expect an authoritative answer now, but I'm cool to just run my own docs repo licensed appropriately or if you guys want to have an official docs package.
01:43arrdemthere's a proof of concept repo breaking out the 1.4-1.6 docs and notes somewhere, but I need to partition those.
01:44puredangerarrdem: well, I wouldn't gate on anything "official" :)
01:45arrdempuredanger: lol I vote on Jira I'm aware what I'd be waiting for ;)
01:51rs0arrdem: you mentioned that you go back and forth on Rich (among others). i was wondering what you think he might have gotten wrong
01:52arrdemrs0: lol you expect me to answer that in public?
01:52arrdem /s
01:53tickingtransducers
01:53tickingthey are not worth the introduction of local mutable state
01:54arrdemSo... I think it's an interesting design decision to base transducers on function composition. I'm not sure it's a decision I agree with, but I haven't thought about it yet.
01:55tickingthey could also take an additional state argument which would be fine as well
01:55rs0ticking: you mean the stateful transducers like unique and take and so on?
01:55tickingrs0: yes
01:55rs0i think it's okay to have mutable state, and it's okay to have shared state, but it's not okay to have shared mutable state
01:56rs0and by "shared" i mean something more general than "across threads"
01:56puredangerinc that
01:56tickingrs0: any lazyly transduced function or channel will be shared
01:56puredangertransducer state is encapsulated inside the process and not shared
01:56puredangertransducer functions are never lazy
01:56tickingthe sequence produced by them is
01:56tickingpotentially
01:57puredangeryou mean via "sequence" ?
01:57puredangertransduce doesn't produce a sequence
01:58tickingpuredanger: via sequence or via a channel that has an associated transducer
01:58tickingonce you do something that is not completely eager
01:58puredangerI don't know what a sequence with an associated transducer is
01:59puredangera channel encapsulates its transducing function (and any state) inside the channel
01:59ticking(sequence xf (range 1000))
01:59nxqdhi guys
02:00puredangerticking: if you're saying that the sequence produced by that is stateful, I don't agree with that
02:00nxqdWhat is the meaning of this function in clojure : (defn ^String as-str . Is it used to define a function of an object ?
02:00rs0nxqd: i think you're referring to the type hint
02:00puredangernxqd: ^String is a type hint on the return value
02:01puredangerticking: I don't think it's any different than a lazy seq with a pending tail
02:01nxqdrs0 and puredanger. Thanks for the keyword. I would read more about type hints :)
02:01puredangerticking: (conceptually, obviously impl is different)
02:01tickingpuredanger: yeah because lazy seqs are statefull as well, but at least they use atoms
02:02puredangerticking: the state is encapsulated via synchronization in LazyTransfomer, so it's not any different in safety than lazyseq
02:03tickingpuredanger: people are going to use that new datatype in places where it should not be used
02:03puredangerI'm saying you can't use it in that way
02:04tickingpuredanger: I'm not saying that the transducers themselves are the problem, but the introduction of volatile
02:04puredangerunless you create your own transducible process that did evil things
02:04puredangerticking: oh, just volatile itself?
02:04tickingyeah
02:04puredangerit's a tool
02:04tickingbut volatile was introduced for making transducers faster
02:04puredangerbad programmers do bad things
02:04tickingyeah but people will abuse it
02:04tickingno
02:04puredangerso don't do that
02:05tickingbad languages encourage mediocre programmers to do bad things
02:05tickingthe way it will be used is the way the language encourages usage
02:05tickingalso partition-bu
02:05tickingpartition-by
02:05tickingnothing to do with the above
02:05tickingbut its completely useless compared to a binary arggument version that splits on returning true
02:06rs0i gotta say, i think ticking is right regarding the larger point
02:06puredangerwell, I disagree.
02:06rs0i'm less and less sympathetic to the arguments about how great multiple inheritance is if people would just use it correctly
02:06rs0but i don't think that transducers or volatile are an example of that
02:07puredangerClojure has always aimed to give developers powerful tools
02:07EmpperiI haven't really decided if I like volatiles in Clojure or not
02:07Empperithey are a tool like puredanger said
02:07Empperibut then again, a dangerous tool in wrong hands
02:08Empperimost of the tools in Clojure are pretty safe for idiot use
02:08rs0powerful tools aren't necessarily dangerous. immutable persistent collections are a good example. how do you misuse them?
02:08rs0the worst-case scenario is pretty much poor performance
02:08rs0or sticking java.util.Date instances in them
02:08Empperiwhat I said :)
02:08arrdem^ lol
02:08puredangerexactly
02:09puredangerthere are a million ways to subvert the paths that exist in Clojure to do things that are a bad idea
02:09Empperianyway, volatiles are great to have when you need to get that very last performance improvement
02:09puredangerI would much rather have the tool for that then have to drop into java
02:10puredangerif you want to see some abuse, go look at the alioth programs I worked on :)
02:10Empperior some java programs I've written :P
02:10Empperior some co-workers of mine
02:10arrdempuredanger: come now that doesn't even count as Clojure. That's C written in Java written in Clojure.
02:10rs0if i had to maintain an incompetent developer's code, i would prefer that that code was being written in Clojure. i guess it's possible to basically write PHP in Clojure but all the idioms and documentation and creature comforts of the language are working against it
02:11Empperione of the things I love in Clojure is the fact that it makes it really hard for you to write bad code
02:11rs0obligatory: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition
02:11arrdemrs0: right because immutable datastructures force decoupling so unless there are atoms literally everywhere it can't be bad.
02:11Empperione sees that "this cannot be the way it should be" when writing clojure improperly
02:21tickingpuredanger: sorry disconnect
02:45TEttingerEmpperi, I recognize that it isn't easy to write bad clojure, but I do it anyway https://www.refheap.com/94916
02:45TEttingerthat got reformatted by refheap, the original message is
02:46TEttinger(clojure.string/join" "(repeatedly 200(fn[](apply str(concat[(rand-nth["s""z""t""k""ch""n""th""sh""y""p""k""l""g""ny"""""])](take(+ 3(* 3(rand-int 2)))(interleave(repeatedly #(rand-nth["a""i""o""e""ia""u""ai"]))(repeatedly #(rand-nth["""""""-""'"]))(repeatedly #(rand-nth ["s""pr""t""rl""n""k""gl""g""ts""lt""gr""rk""kh""x""sh""ng"]))))[(rand-nth["urr""icth""ato""omkur""iashi""oroth""okh""yng""otep"""""])])))))
02:48EmpperiTEttinger: :)
02:48TEttingeralthough to be fair there's no way that would fit in one IRC message in any curly-brace language
02:49tickingTEttinger: needs more space
02:49TEttingerhits the limit in about 5 more chars, ticking
02:49tickingah
02:50TEttinger414 chars with the prepend to evaluate, and the limit on some servers is around 418-420-something
02:55tickingTEttinger: what is this for :)?
02:55aaelonyhi, I'm doing some Java interop with a library that has little documentation. I am able to get a method call to return an object that appears to have the information I need (a country lookup) among the 12 fields in that object, however I'm not sure how to extract one particular field. Is there a way to learn the names of the fields the object contains, and extract one of them?
02:55TEttingeraaelony, yeah you can use reflection, I wouldn't recommend overusing it though
02:56TEttingerticking, in another channel we got trying to come up with ancient greek sounding random words
02:56aaelonyTEttinger: How would I do that? Once I know the correct name, I'll use that name in the code
02:57tickingTEttinger: is there a reason for multiple empty strings in the syllable lists?
02:57aaelonyfor example, I can see: #<TheObjectNameHere> blah 123 456 foo bar
02:57aaelonysuppose I want the "foo" part
02:58TEttinger,(clojure.reflect/type-reflect String)
02:59clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.reflect>
02:59TEttinger,(require 'clojure.reflect)
02:59clojurebotnil
02:59TEttinger,(clojure.reflect/type-reflect String)
02:59clojurebot{:bases #{java.lang.Object java.lang.Comparable java.lang.CharSequence java.io.Serializable}, :flags #{:public :final}, :members #{#clojure.reflect.Method{:name replaceAll, :return-type java.lang.String, :declaring-class java.lang.String, :parameter-types [java.lang.String java.lang.String], :exception-types [], ...} #clojure.reflect.Field{:name CASE_INSENSITIVE_ORDER, :type java.util.Comparator, ...
02:59TEttinger,(:fields (clojure.reflect/type-reflect String))
02:59clojurebotnil
02:59aaelonythat is very, very cool
03:00aaelonythank you TEttinger
03:00TEttingerno prob, I just learned about it too!
03:00TEttinger,(:members (clojure.reflect/type-reflect String))
03:00clojurebot#{#clojure.reflect.Method{:name replaceAll, :return-type java.lang.String, :declaring-class java.lang.String, :parameter-types [java.lang.String java.lang.String], :exception-types [], ...} #clojure.reflect.Field{:name CASE_INSENSITIVE_ORDER, :type java.util.Comparator, :declaring-class java.lang.String, :flags #{:public :static :final}} #clojure.reflect.Method{:name indexOf, :return-type int, :de...
03:00aaelonywow
03:00TEttingerI knew it was possible, just not the details
03:01aaelony:)
03:01TEttinger,(:members (clojure.reflect/type-reflect Math))
03:01clojurebot#{#clojure.reflect.Method{:name atan, :return-type double, :declaring-class java.lang.Math, :parameter-types [double], :exception-types [], ...} #clojure.reflect.Method{:name getExponent, :return-type int, :declaring-class java.lang.Math, :parameter-types [float], :exception-types [], ...} #clojure.reflect.Method{:name max, :return-type long, :declaring-class java.lang.Math, :parameter-types [long...
03:01TEttingerneat stuff
03:02tickingindeed
03:04aaelonyhmmmm, uh oh..
03:04aaelonyIllegalArgumentException No implementation of method: :typename of protocol: #'clojure.reflect/TypeReference found for class
03:06TEttingerhow'd that happen...
03:07aaelonyit's weird..
03:07aaelonybut this works: (reflect obj-name)
03:07aaelonyI have a long method call to generate the object
03:08aaelonyif I assign that long method call to a (def x ...) and then reflect the x, it works
03:08aaelonyotherwise, it got confused
03:08TEttingeroh, yeah type-reflect takes a type, not an object of that type, that might be it
03:08aaelonyahh
03:09aaelonywell, it's working now :)))
03:09TEttingersweet!
03:09aaelonyreally sweet!!
03:09aaelonybig thanks for showing me reflection
03:13TEttingerno problem, it's something I haven't needed yet but know I will someday
03:16arrdemI take it there is no good way to do string unescaping from Java or Clojure without a library?
03:18ticking(+ 3 (* 3 (rand-int 2))) is a bit weird :D
03:18tickingTEttinger: why?
03:19TEttingeroh heh
03:20TEttingerticking, we were fiddling with procedural name generation and some of the greek gen was handy.
03:21TEttingergreek generator: https://www.refheap.com/94919
03:22TEttingerticking, that's used to get a random number of vowel-option-consonant triples, either 3 or 6 items in total, where option is either an empty string or sometimes a fantasy standby character like ' or -
03:23ticking(rand-nth [3 6])?
03:24TEttingerit was a modified version of some more numbers that were allowed
03:24tickingah
03:25TEttingerneat though, it saves 7 chars :P
03:25TEttingerthanks ticking
03:25tickingyeah
03:56rritochHi, is anyone here familiar with classfiles? I'm trying to make a persistent classfile reader but I keep running into cp_info.tag = 0 cases which I can't find any documentation on. As a test I wrapped the inputstream as a pushbackinputstream and did a pushback on the zero, and now it seems to be working, but this doesn't seem right to me.
03:57rritochWIth some class files this never hits the cp_info.tag = 0, but many do.
04:00rritochYou can see the pushback here > https://github.com/rritoch/clj-bytecode/blob/master/src/java/com/vnetpublishing/java/asm/bytecode/T_CPInfo.java#L80-L82
04:32tickingTEttinger: https://gist.github.com/ticking/f25dbc47d084cbfed89b
04:32ticking306 chars
04:34zotgood (or morning afternoon evening)!
04:34TEttingernice, ticking. the extra empty quotes were to change the behavior so ' and - are not in 2/3 of syllables
04:34zotwhen using clojure.async, with code that's running in another thread, what's the idiomatic way to handle exceptions? i already have a control channel and could do try/catch and pass it through the channel, but was curious if there are other ways (that might not rely on a control channel)
04:35tickingTEttinger: yeah, I figured it was to skew the probability distribution, so I just went with a slighlty altered one
04:36tickingTEttinger: adding them back won't increase the code size significantly though
04:36TEttingeroh yep.
04:36TEttingerit's good.
05:04dagda1_I've just been using transducers with native javascript arrays in clojurescript and I had to wrap the reducing function in completing (completing-me (fn [arr x] (.push arr x) arr))
05:04dagda1_I mean (completing (fn [arr x] (.push arr x) arr))
05:04dagda1_what does the tranducer function expect that made this necessary and why is this not necessary with something like conj
05:05dagda1_(transduce (filter #(not (.hasOwnProperty prevChildMapping %))) (completing (fn [arr x] (.push arr x) arr)) #js [] nextKeys) is the whole expression
05:06Bronsadagda1_: conj already has 0 and 1 arities
05:06Bronsa,(conj)
05:06clojurebot[]
05:06Bronsa,(conj [1])
05:06clojurebot[1]
05:06dagda1_Bronsa: which one does the reducing function expect, 0 or 1?
05:07Bronsadagda1_: a reducing function to transduce has to have 0 1 and 2 arities
05:08Bronsadagda1_: read http://clojure.org/transducers#toc8
05:08dagda1_Bronsa: perfect, I missed this point. Thanks
05:09Bronsadagda1_: note that completing still expects your function to have the 0 arity, it will only add the 1 arity
05:10dagda1_Bronsal: I need to add the 0 arity to my function?
05:12Bronsadagda1_: no, sorry. I was wrong, the reducing function only needs 1 and 2 arities.
05:13dagda1_Bronsa: k, thanks
05:15TEttingerI bet Raynes is wondering what's going on with refheap
05:16TEttingerhttps://www.refheap.com/94935
05:16TEttingerticking, with those shortenings you did, I was able to add punctuation to make fake sentences
05:16tickingTEttinger: nice :D
05:31tickingTEttinger: without the re-find right? otherwise only single words are output for me
05:32TEttingeruhhh
05:33TEttingerI made a bunch of changes, the re-find is so it doesn't have punctuation at the start and starts with a capital letter
05:36rritochI found the problem and the classreader is now working. Aparently there's an undocumented flaw where longs and doubles count as two entries in the constant pool table. So this library is now functional, but has a ways to go.
05:37tickingTEttinger: well the version you posted only produces single words :\
05:37TEttingerthis one? https://www.refheap.com/94935
05:38hydoI have a namespace clash with clojure.core/update in module X, despite it being :required with :as something, and (refer-clojure :exclude [update]). Could someone tell me what I'm missing?
05:38Bronsarritoch: I don't have contex but the fact that longs and double take 2 slots is not an undocumented flaw, it's definitely documented in the jvm spec
05:39rritochBronsa: Ok, well I'm looking at the specs and I didn't notice anything about it.
05:39ticking(if (seq b) s (.toLowerCase(a s))) ?
05:40tickingTEttinger: b is always either an empty string or not, but (.toLowerCase (apply str(flatten ""))) is also ""
05:40tickingTEttinger: so the check is not needed
05:40TEttinger,(seq "")
05:40clojurebotnil
05:40Bronsarritoch: in fact there are bytecodes that come in `x` and `x`2 variant, where the `x`2 variant works for double/longs by acting on two slots rather than one e.g. pop vs pop2
05:40rritochBronsa: Ok, I found it. They should really highlight that fact
05:41ticking,(.toLowerCase (apply str(flatten "")))
05:41clojurebot""
05:41TEttingerand that's a used value, it needs to apply str so it doesn't have lazyseq@126t263 as a word
05:41ticking,(str)
05:41clojurebot""
05:41rritochBronsa: The only way I was able to solve the problem was looking at other (non persistent) classreaders
05:41TEttingerwait, I used flatten "" ?
05:42tickingTEttinger: maybe you test the wrong variable? because b is (n"!""..."".""""""""")
05:42TEttingerah, you're confusing b (just the beginning) with the s I use (the single word string)
05:42tickingTEttinger: yeah youre right sorry haven't slept much
05:42TEttingerit's fine, you've already shaved like 100 chars off :P
05:43tickingI thought you did (if (seq b) b (something b))
05:43TEttingerno, it checks b to see if there's punctuation, if not it lowercases the word
05:43tickingyeah
05:43tickingI misread that as the above though :D
05:43rritochBronsa: I haven't actually made it that far with this system, but its good to know. Im trying to make persistent class manipulation systems, it should make inspecting and manipulating code at a low-level easier, and possibly thread-safe.
05:44Bronsarritoch: nice, have you had a look at the syntax I've used for bytecode emission in t.e.jvm? might be relevant
05:45rritochBronsa: I'm not familiar with t.e.jvm , is that short for something?
05:46Bronsarritoch: tools.emitter.jvm
05:46Bronsarritoch: https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm/emit.clj#L1402-L1442 this is how I'm representing bytecode/class info as a persistent data structure
05:46rritochBronsa: Oh, I haven't heard of it. But I'll take a look.
05:46tickingTEttinger: and yeah the last one only produces single words
05:47TEttingersolved it
05:47TEttingerticking: if you copy from refheap, it turns one " " into "\n"
05:47TEttingerby line breaking inside a string
05:47TEttinger(let[a #(apply str(flatten %))r repeatedly n #(rand-nth %&)w(fn[](let[b(n"!""..."".""""""""")s[(n"S""Z""T""K""N""Th""Sh""Y""P""K""L""G""Ny""Ft""Cth")(r(n 1 2)#(vector(n"a""i""o""e""ia""u""ai")(n"""""""-""'")(n"l""h""s""pr""t""rl""n""k""gl""g""gh""ts""lt""gr""rk""kh""x""sh""ng")))(n"urr""ato""omkur""iashi""oroth""okh""yng""otep""ilal""ugu""""")]][b" "(if(seq b)s(.toLowerCase(a s)))]))](re-find #"[A-Z].+"(a(r 200 w))))
05:48tickingTEttinger: ah yes I see :D
05:48TEttingerthat in turn breaks the regex, which only goes to end of line
05:53tickingTEttinger: btw you can shave of one char by changing #(vector to (fn[][]
05:55rritochBronsa: I see. What I'm doing is mostly in java, Developing persistent types for low-level class manipulation. Currently I only have one clojure function, read-class, which reads the source classfile for a provided class so it can eventually be manipulated.
05:56rritochBronsa: Though your project looks like it is very close to something I've been asked for. Someone wanted me to write code which would compile clojure forms into opencl or cuda.
05:57Bronsarritoch: ah gotcha, I assumed you were doing this in clojure :)
05:57rritochBronsa: No, just for clojure
06:00rritochBronsa: https://github.com/rritoch/clj-bytecode
06:01rritochBronsa: The types are all persistent, and being designed to interact with clojure to make it easy to inspect classes. Though I'm not sure this would apply well to generated code unless I knew the classname and classloader it was generated with/into.
06:51tickingdn
06:51tickingsorry, does anybody know if there is a reason that core.match is not able to match lists and sets?
06:52tickingIt seems weird that the patterns only encompass a small subset of the clojure datastructures syntactically expressable
06:59yogsotothHi does someone knows how I could write a test.check generator to generate maps with fixed keys?
07:00yogsotothI would like to generate {:keyword (gen/string)}
07:02CookedGryphonjust use fmap
07:05CookedGryphona pattern I sometimes use if I want a fixed structure with multiple generated components is to gen a tuple of all the values i want, then fmap a function which just slots each of the generated values into my structure
07:20noidiyogsototh, there's gen/hash-map
08:00yogsotothnoidi: thanks, I don't know why I didn't saw it!
08:54hydoWho was it that was working on the context class loader? I asked a question a few days back about how I had to disable it to get my plugin to work, and someone else said that there was work being done to make it semi-optional or somesuch. I'd really like to use things like embedded nrepl in my project :)
08:55hydoI just can't remember who it was.
09:19m1dnight_guys, I'm trying to manipulate some code with a macro but i'm not getting what i want
09:20m1dnight_I have a function replace-recur which should replace (recur ..) with (do (foo) (recur ...))
09:20m1dnight_I'm not sure what to pass to the function that does this for me though..
09:20m1dnight_At the moment I call it like this: (replace-recur % `end-receive), where % is my form
09:20m1dnight_and in the form I traverse and return this: (= (first body) 'recur)
09:20m1dnight_ `(do (fnname) body)
09:20m1dnight_oh, sorry for multiline paste
09:21m1dnight_but this gives me, instead of "meta-clojure.stm.actor-friendly/end-receive", "meta-clojure.stm.actor-friendly/fnname"
09:26stuartsierram1dnight_: If "fnname" and "body" are arguments to the macro, you probably need to unquote it like `(do (~fnname) ~@body)
09:30m1dnight_hrm, okay
09:30m1dnight_i'm testing it atm hold on. Some issues atm with emacs :p
09:32m1dnight_is it nrmal that lein run does not print my expanded macro, and emacs does?
09:32m1dnight_it just gives me back my input, i dont get it :p
09:34m1dnight_oh wait, for '(and 1 2) it does give me back my desired output
09:34stuartsierram1dnight_: It's hard to diagnose editor / environment issues over chat. :) The standard way to test a macro from the REPL is (macroexpand-1 '(my-macro …))
09:34m1dnight_yeah, that is what I'm trying
09:34m1dnight_in my core.clj I have (println (clj/macroexpand '(and 1 2)))
09:35m1dnight_that works fine in emacs and in lein repl console
09:42m1dnight_ugh, what is this sorcery :p
09:43m1dnight_https://github.com/m1dnight/meta-clojure/blob/master_slave_transactions/src/meta_clojure/core.clj
09:43m1dnight_this is the core.clj file
09:43m1dnight_https://github.com/m1dnight/meta-clojure/blob/master_slave_transactions/src/meta_clojure/stm/actor_friendly.clj#L658
09:43m1dnight_this is the code it is calling
09:44m1dnight_is there something about namespaces and macros that differs between lein run and emacs?
09:44m1dnight_oh wait, I restarted cider and now I have the same problem again
09:44m1dnight_so now it matches the lein run output
09:50stuartsierraWow, there's a lot going on in there. :) Don't think I'll be able to help much.
09:50stuartsierraRemember that Clojure's macroexpand keeps expanding the source form until the first element is no longer a macro. macroexpand-1 is usually easier to use if you just want to see what your macro is doing.
09:55m1dnight_well, that's what I'm trynig
09:55m1dnight_it seems to work fine in cider, but lein run just gives me unchanged input
09:55m1dnight_not the kind of issues one likes to handle on mondays :(
10:01silasdaviswhere can I find an authoritative latest version for org.clojure/foo libraries?
10:01silasdavisfor use in project.clj
10:01justin_smithsilasdavis: lein search for finding, lein ancient for getting info of newer versions
10:02justin_smithclojars has search too
10:02silasdavisyeah I usually use clojars
10:02stuartsierrasilasdavis: http://search.maven.org/
10:02m1dnight_so it appears that I have to fully qualify my macro, even though I expand in the namespace it is defined in
10:02silasdavisbut for example data.avl is not on there
10:02justin_smithhttps://github.com/xsc/lein-ancient
10:02stuartsierraAll org.clojure libs are released to the Maven Central Repository, not necessarily Clojars.
10:02silasdavisah
10:02silasdaviscool thanks
10:05engblomsilasdavis: I am using 'lein ancient' for upgrading all dependencies to the latest. https://github.com/xsc/lein-ancient
10:05engblomsilasdavis: It is a lein plugin that is nice to have
10:31nXqdhi guys, what is the trick behind showing clojure doc of the function under the cursor in this video : http://youtu.be/HXfDK1OYpco?t=8m14s
10:31nXqd* in emacs editor
10:52itruslovenXqd: it's cider's eldoc integration. You will need to add a tiny bot of configuration to your init.el to turn it on. See the first item in https://github.com/clojure-emacs/cider#basic-configuration
11:01ordnungswidrigIs there a simple way to graph the dependencies in a lein project? (Including different revisions required by transient dependencies)?
11:01munderwo lein deps :tree
11:02munderwothat gives you wants currently depended on by your leiningen project
11:04lgrapenthinIs it true that I still have to run an extra JVM to "lein cljx auto"?
11:05lgrapenthin(I'd prefer cljsbuild would do this already)
11:07ordnungswidrigmunderwo: i'd like to have a graph: blobs, connected by lines
11:30birdspiderhello, in java "0xFF000000 is -16777216" in clojure "0xFF000000 is 4278190080" why ? I assumed that the literal syntax for hex is the same ? I suppose it gets auropromoted but is there a way to keep it java-style at least in local scope ?
11:30justin_smithbirdspider: fixed point literals are longs in clojure, ints in java
11:30birdspiderjustin_smith, aaaah
11:31justin_smith&(unchecked-int 0xFF000000)
11:31justin_smith,(unchecked-int 0xFF000000)
11:31clojurebot-16777216
11:31birdspidervery nice, thank you
11:31Bronsabirdspider: clojure numeric literals are always autopromoted anyway
11:32Bronsa,Long/MAX_VALUE
11:32clojurebot9223372036854775807
11:32Bronsa,9223372036854775808
11:32clojurebot9223372036854775808N
11:32Bronsa^ it's autopromoted to a bigint
11:33birdspiderBronsa, yes I knew that, I just wanted to be unchecked in this particular case since im in java-interop-land - but could formulate what I needed for google :)
11:37justin_smithso unchecked-int should do what you need then
11:46jeffterrellTo nobody in particular: in case you're ever helping anybody with a 4Clojure problem and they're getting time outs, the problem might be that they're using `for`. https://github.com/4clojure/4clojure/issues/211
11:46jeffterrellI spent days wrestling with time outs until I found that.
11:48jeffterrellAlso apparently `case` doesn't reliably work either.
12:58aaelonyhi, I'm using a static class method via java interop and not understanding the behavior I'm seeing. I can call (.methodname (. (. com.blah.blah.blah.blah.util.theLibrary _aMapField) findResult x y ) ) and get the output of the function I am looking for, e.g. the "foo" part of #<TheObjectNameHere> blah 123 456 foo bar. But.. if I wrap the methodname call above in a function, I get a "No matching method found" error. I also need to avoid using
12:58aaelonyreflection as this method call will happen a lot. any ideas on how to resolve this?
13:00nooniani'd recommend using the threading macro or .. to make that a little more readable. if it isn
13:00aaelonynoonian: yeah, I've been trying that, but the java call is somewhat fragile
13:01noonianare you trying to dynamically build the method call in your function? thats something you will probably need to use a macro for if so
13:01mnngfltgstatic class methods you can also call like this: (java.lang.Math/abs -3)
13:01aaelonyI just need to pass the method call 2 arguments and capture the result
13:02aaelonymnngfltg: I'm trying to convert my call to (java.lang.Math/abs -3) syntax.. haven't been successful with that yet
13:04nooniansomething like this? https://www.refheap.com/94947
13:04aaelonylet me try...
13:06aaelonynoonian: that gives me "No matching method found"
13:07aaelony... at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)
13:07ben8hello clojure. I have question: if someone running clojure web in production - do you use Nginx as proxy and are there alternatives?
13:07justin_smithben8: nginx is the best option I know of
13:08ben8ah ok. Netty maybe?
13:09mnngfltgben8, Apache is fine too for my needs
13:09justin_smithben8: none of the java http servers I know of have the security features of nginx.
13:10ben8I see. jetty is not that great...
13:11ben8there is for example https://github.com/ztellman/aleph
13:11justin_smithsure, but you still should put nginx in front of that
13:14TimMcheck, put 3 in front in serial
13:14TimMcjust to be sure
13:14ben8juston_smith: thanks for the info. I'm trying to figure out why this is standard, and if there is not a more light weight way of load-balancing (?)
13:15justin_smithben8: it's not about load balancing, it's about not getting your shit hacked
13:15andyfBronsa: If I have a :map ast, is there already a util fn to get the :vals ast for a particular key? Easy for me to write, but wondering if it exists.
13:15justin_smithben8: load balance however you like, but you are better off with nginx in front regardless
13:17justin_smithben8: last I checked, nothing java native did what it does, sadly.
13:17ben8I see. on what attack vectors? DDOS?
13:17ben8trying to wrap my head around this. I wonder what Java-enterprise solutions look like
13:17ben8Tomcat is not very fancy
13:17justin_smithben8: there are a lot of gotchas in http. nginx covers them.
13:18justin_smithben8: right, you put an nginx reverse proxy in front of tomcat
13:22ppppaulcan someone point me to a url that can help me learn about the datomic aggregate functions
13:23justin_smithben8: there is a nice rundown on setting nginx up securely, if you want to use something else instead, there should be equivalent options for each of the settings http://www.cyberciti.biz/tips/linux-unix-bsd-nginx-webserver-security.html (you need to scroll down a bit until you get to nginx specific stuff)
13:24ben8ok, cool. there is this specific module: https://github.com/nginx-clojure/nginx-clojure
13:24justin_smithben8: that is one option, but it is more often to just set up nginx as a reverse-proxy
13:24justin_smiththough I hear the plugin module method does have excellent performance
13:24justin_smiths/more often/more common/
13:37TimMcjustin_smith: Looks like just headers and timeouts, basically.
13:38justin_smithand blacklists based on referrer
13:38TimMcFrom the article: "Referer spam is dengerouns."
13:38justin_smithyeah, not a top notch article
13:38TimMccyberciti.biz
13:39TimMc.exe
13:41justin_smithTimMc: I don't pretend to be an expert on all the particulars, but I have been told that nginx will protect from a bunch of stuff that the java based servers don't really address (or don't address properly). But I would be pleased to see a more reputable source. I just went on word of mouth from a trusted colleague to be honest.
13:41engblomThere seem to be plenty of web frame-works for clojure. Which one do you recommend at this moment?
13:41TimMcI would say "eh, adding nginx can't hurt" but it does increase the attack surface a little.
13:45technomancyit reduces the attack surface since nginx should run as a separate user and has a much stricter HTTP parser.
13:45elarsonTimMc: I could see it reducing the attack surface by only exposing nginx vs. a cluster of java based servers.
13:48TimMctechnomancy: *Should* run as a separate user, but it's still a C program exposed to internet traffic.
13:48TimMcA buffer overflow + privilege escalation could still lead to funtimes.
13:48TimMcnginx is pretty mature so that's less likely than a vuln in your own program, but that does still contribute to an increased attack surface.
13:49technomancyif you're terminating in Java then you don't need a privilege escalation
13:50TimMcOK, so the filtering it does probably decreases the overall attack surface, but I think it bears mentioning.
13:50hiredmantechnomancy: you are refering to port 80 being a privileged port?
13:51hiredman(because that is easily fixed)
13:51technomancyhiredman: no, just that the jvm is likely to run as the same user as your application code
13:51technomancyso a compromise will likely expose your DB, etc
13:51hiredmanah
13:52justin_smithand local priv escalations are available on every system out there, even openbsd, and clojure has a bytecode compiler and shell access for arbitrary strings available at runtime
13:57TimMchiredman: Huh, I never thought about that port 80 issue.
13:58TimMcI guess I've always either run on a different port or had something else fronting my app.
14:13justin_smith(inc eastwood)
14:14justin_smithamalloy_: you around for a lazybot restart?
14:14justin_smith"lein do clean, check, eastwood, run"
14:15andyfjustin_smith: Find something non-obvious?
14:15justin_smithyeah, yet again :) thanks
14:16Bronsaandyf: if you missed it, ccw now has eastwood integration
14:17andyfI did notice that.
14:18andyfBronsa: The quickref docs for ASTs say that :tag is "The tag this expression is required to have", whereas :o-tag is "The tag of this expression, based on the node's children". If that is correct, what criteria is used to determine :tag ? Something about how the value is used?
14:19andyfI don't need to know in great detail, just curious about the basic idea.
14:19Bronsaandyf: yeah. differences between :o-tag and :tag imply casts/boxings
14:20Bronsaandyf: re your earlier question -- no, you have to search in :keys and use the index.
14:21andyfIn my particular case right now, I'm looking at a call to clojure.core/str in a place where it is the value of a literal map key. Its :tag is java.lang.String, but its :o-tag is java.lang.Object. Since clojure.core/str has a :tag of String in its defn, this seems backwards to me.
14:22andyfI wrote a function to do it in the mean time. Thanks for the info, though.
14:22trisshey all. I recently rebooted and my clojure/cljs/lein/chestnut project has gone to pot.
14:22aaelonynoonian: Thanks for your help earlier, it turns out the answer was that I needed to cast my function arguments to the types that java expected. That solved everything.
14:22amalloyjustin_smith: aww, i thought we'd fixed the problem of needing restarts
14:22Bronsaandyf the return type of an .invoke call is Object, thus the :o-tag is Object. str has a type hint of String the :tag will be String
14:22noonianaaelony: nice!
14:22trissi'm getting this error:
14:22trissjava.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found
14:22triss for class: nil
14:23aaelonywhat a relief... ;)
14:23trisswhen it comes to compiling my cljs
14:23trisseverything was fine prior to restating the repl
14:24andyfBronsa: OK, so :o-tag is indeed an inferred type, but it is a generic Object because :invoke's all return that type. :tag is what the value is required to be, because that is what the type tag on the defn says it should be?
14:24trissI see: Uncaught ReferenceError: goog is not defined(index):9 (anonymous function)
14:24trissin the browser
14:24trissI've tried lein clean, lein cljsbuild clean and restarting and the issue remains
14:24stephenmac7Is (last (take n l)) or (nth l (inc n)) preferred?
14:25Bronsaandyf: yeah
14:25stephenmac7(dec n) I mean
14:26stephenmac7,(last (take 3 '(1 2 3)))
14:26clojurebot3
14:26amalloyjustin_smith: interesting. the last thing lazybot remembers saying or hearing was a NOTICE he sent to someone about an unread $mail message
14:26trissis my app now not able to find the google closure stuff? (wherever that comes from... this stuff is a bt of a mystery to me)
14:26stephenmac7,(nth '(1 2 3) (dec 3))
14:26clojurebot3
14:26amalloyafter that there have been lots of server messages (eg, QUIT/PART), but no messages to or from users
14:27amalloyno, i guess that's not true
14:36justin_smithamalloy: which part? I am fully ready to blame mongo, of course
14:37justin_smith(inc eastwood)
14:37lazybot⇒ 4
14:37amalloyjustin_smith: nah, i was wrong
14:38justin_smithamalloy: it would be nice to track down the rest of the instability issues, I'll be happy to accept any logs that help track the issue down
15:03nicferrierif I want to map over a ref, can I just go (map #(...) (dosync @ref))
15:04technomancynicferrier: the dosync there is a no-op
15:05technomancyit works but it probably doesn't do what you think it does
15:05justin_smithyeah, if you wanted to ensure refs are in sync while mapping, you could do (dosync (map ...))
15:05nicferrierI just want to get at the value
15:05technomancyjustin_smith: that would also be a no-op =)
15:05justin_smithno need for dosync if you are not updating anything
15:05amalloyjustin_smith: that's lazy :P
15:05technomancyjustin_smith: multiple consistent reads also need a dosync
15:05justin_smithtechnomancy: I mean if the fn inside the #() did any ref alterations
15:06nicferrieroh I thought I wasn't even allowed to deref outside of a tx?
15:06justin_smithfair points
15:06amalloynicferrier: observation is always free
15:06technomancyas long as you don't need to guarantee consistency with other reads you should be good without it
15:07nicferrierok then.
15:07nicferrierhum.
15:13amalloyhaha. just found a lazybot bug
15:13amalloy(incrementing users works even with synonyms)
15:13lazybot⇒ 1
15:14AimHere(incredibly interesting)
15:14lazybot⇒ 1
15:15dweaveif you were making a real time chat app in clojure how would you go about it.
15:18TimMcamalloy: Nice.
15:18TimMc$karma interesting
15:18lazybotinteresting has karma 0.
15:18TimMc$karma redibly interesting
15:18lazybotredibly interesting has karma 1.
15:18justin_smithhaha
15:18dweavehow does aleph differ from an event loop
15:19justin_smiththat's a weird question
15:19dweavemine?
15:19justin_smithit's like asking "how does a rabbit differ from biology"
15:19dweavehow does aleph differ from node’s event loop
15:19dweavei guess
15:19dweaveconceptually
15:20amalloywell more than one thing can happen at a time
15:20amalloythat's a big plus
15:20justin_smithfor one thing, aleph has actual threads
15:20dweavei’m just trying to discover some different paradigms for making real time apps
15:20amalloyalso, aleph is a websever built on top of lamina; lamina has all the primitives you're thinking of
15:21noonianwith a real time chat app your server is pretty much just a message broker; you might use something like sente (websockets) to get you easy push to clients
15:22justin_smithdweave: the major division in the clojure world is between the servers that give each request a thread from a pool (ie. jetty) vs. those that use a thread pool plus async so that the request doesn't own its own thread (ie. aleph, httpkit)
15:22trissarghhhhh. I keep being told: Uncaught SyntaxError: Unexpected token .
15:22amalloy(decrement redibly interesting)
15:22amalloyfixed it
15:22trissby my browser.
15:23dweavei see justin_smith
15:23trissbut when I navigate to the source my browser sees... or the copy of it in my project there's not a . to be found
15:23trissany one experienced this?
15:24TimMcUh... should I assume this is a CLJS project?
15:24trissoh yes... sorry TimMc
15:24dweaveis httpkit similar to like netty?
15:25amalloydweave: lamina is built on top of netty. dunno about httpkit
15:25dweaveah ok cool thanks
15:25llasramOMG -- I just figured this out: clojure.lang.Namespace isn't final, which lets you implement namespaces which do dynamic code generation on Var lookup
15:25dweavethese questions probably sound stupid but the answers help
15:26amalloytriss: http://stackoverflow.com/a/24164554/625403 is an interesting-looking possibility
15:26nooniandweave: http-kit is all implemented in clojure instead of using netty
15:27dweavegotcha
15:27amalloythat's...interesting, llasram
15:27trissthanks amalloy... I'll take a look
15:28amalloynoonian: that's kinda an absurd claim. it has to be based on something in java. and if you read the project.clj, it depends on netty
15:28dweaveso one more: in node you would use something like redis for shared memory between processes. Is this a problem that doesn’t exist in clojure world? Couldn’t you just use STM
15:28Raynesllasram: whoa r u srs
15:28noonianamalloy: my bad then, that was my understanding based on their docs
15:29llasramamalloy: This actually came up at the atl-clj meetup, and there was some confusion. I actually believe http-kit only has it in the *dev* profile
15:29llasramProbably for benchmarking comparison or such
15:29amalloyoh, you're right
15:29amalloyit has to be based on java still. nio sockets, i guess?
15:30llasramRaynes: the constructor is package-private, so you need to put something in the `clojure.lang.` package to get access, but a narrow path remains open
15:30Raynesllasram: You should make a branch of conch that uses this to do something fantastic.
15:31amalloyyeah. nio socket channels. so of course it's not "all clojure", but it's implemented on top of a low-level-enough primitive that it's reasonable to call it all clojure. sorry for claiming it was absurd
15:31noonianit looks like http-kit has a decent amount of java code in its implementation also, it just doesn
15:31llasramRaynes: Oh, like the Python sh package? That could be fun
15:31nooniandoesn't wrap netty is what i meant
15:32Raynesllasram: The saddest thing I had to give up with conch was the Python version's lovely import magic that allows you to just magically pull import shell programs
15:32RaynesI'd be very grateful to gaze upon a crazy hack that allows something similaer
15:32amalloylol. opened up the first interesting-looking source file in http-kit, and here is the first line of code i see: https://github.com/http-kit/http-kit/blob/master/src/java/org/httpkit/server/AsyncChannel.java#L25
15:32Raynessimilar*
15:37justin_smithdweave: in one clojure process you can use STM between threads, yeah. Eventually you may want multiple machines (there is little point to having multiple jvms running a clojure server on one box since it will likely be using pthreads), then you would look for some shared state solution, either Redis, or Kafka, or ZeroMQ or RabbitMQ or whatever...
15:37justin_smithand it would have to be a networked sharing of state, of course
15:37justin_smithsometimes even a db suffices, depending on what you are trying to do
15:39justin_smithdweave: usually you don't even need STM, and an atom coordinating values between threads suffices
15:40justin_smith~refs
15:40clojurebotExcuse me?
15:40justin_smith~stm
15:40clojurebotHuh?
15:40justin_smithI keep forgetting where the factoids are at
15:42llasramNot a "good" use, but: https://github.com/llasram/method-fn/blob/master/src/clojure/method/fn.clj#L99-L107
15:50llasramThe obvious thing to do now is factor that out into a tiny little library, allowing the meme to more easily infect new victims
15:52amalloyllasram: what happens if you :refer :all?
15:53llasramamalloy: If humor: ha! If actual question: I believe it'll pull in everything which has already been dynamically created, in this case under un`read`able names
15:54llasramIt's probably be pretty easy to further refine so that the mechanism used to discover the namespace contents turns up empty
15:55llasramOh, interesting -- actually the NS was never `require`d so it errors on failing to find matching source
15:55llasramAlso would be easy to fix for e.g. Raynes proposed use
15:58llasramThere we go -- yep, works like hypothesized
15:59reborgcljHello, quick sanity check:
15:59reborgclj,(unchecked-subtract Integer/MIN_VALUE 1)
15:59clojurebot-2147483649
16:00reborgcljshouldn't that be 2147483647?
16:01amalloyreborgclj: 1 is a long
16:01reborgclj,(unchecked-subtract Integer/MIN_VALUE (int 1))
16:01clojurebot-2147483649
16:01godd2https://clojuredocs.org/clojure.core/unchecked-subtract
16:01godd2in the docs, the example shows it should be 2147483647
16:02amalloygodd2: clojuredocs isn't "the docs", it's a community-maintained (and mostly unmaintained) collection of examples
16:02amalloyit probably was 2147483647 back in 1.2
16:02reborgclj@amalloy so possibly clojuredocs not correct? Ah.
16:03godd2reborgclj any doc is possibly incorrect ;)
16:04amalloyreborgclj: oh, right. clojure only does primitive math on longs and doubles
16:05mikerodWhat would be a good reason why leiningen can always download dependencies from "https://clojars.org/repo/&quot;, but always fails to from "https://repo1.maven.org/maven2/&quot; ?
16:05mikerodI am fairly sure this has something to do with a proxy
16:05reborgcljSo no way I can reproduce in clj what I can do in Java with (-2147483648 - 1)?
16:06mikerodI get "If you are behind a proxy, try setting the 'http_proxy' environment variable." as my message, but I'm not sure how accurately that describes what could be going on.
16:06puredangerreborgclj: what result are you looking for?
16:06mikerodIf there is something to do with a proxy though, why is clojars ok, but not the maven repo?
16:06amalloyreborgclj: probably not without modding the result
16:06reborgclj@puredanger 2147483647
16:07puredangerso underflow
16:07amalloyoh, of course. you can use unchecked-int
16:08amalloy,(unchecked-int (- Integer/MIN_VALUE 1))
16:08clojurebot2147483647
16:08puredangerreborgclj: yeah, the -int functions give you integer over/underflow characteristics
16:08reborgclj@amalloy that's it! :)
16:08amalloyoh, there's unchecked-subtract-int, too
16:08puredangeruseful for hash calculation sometimes
16:08amalloythat's much more sensible, puredanger
16:09noonianis anyone using the chestnut template with prismatic's schema? i'm not sure where the conflict is but schema.macros won't compile because it cant find potemkin
16:10reborgcljamalloy: puredanger thx
16:10mikerodnever mind, I just realized why I have problems.
16:11amalloyi just realized clojure.lang.RT.intCast(int) : int exists. that's a funny little method
16:11amalloysure hope it gets inlined by the jit
16:12hiredmanor has a compiler intrinsic
16:12amalloyhiredman: it doesn't
16:12hiredmanoh, just the unchecked-int cast does
16:13amalloyi noticed it because it was showing up in the disassembly; checked, and there's no intrinsic (of course, otherwise it wouldn't have been in the disassembly)
16:14hiredmanI guess the checked cast actually does something
16:14hiredmanthe unchecked cast has an intrinsic as a nop
16:14hiredmanhttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Intrinsics.java#L103
16:15amalloyhiredman: the checked cast doesn't actually do anything; the intrinsic was just omitted
16:15amalloyand the intrinsic for unchecked-subtract-int is broken
16:16hiredman:/
16:16Bronsaamalloy: how so?
16:16amalloyi'm not sure how it's broken, since it seems fine to me. but when i disassemble (unchecked-subtract-int (unchecked-int Integer/MIN_VALUE) (unchecked-int 1)), it emits a call to clojure.lang.Numbers.unchecked_int_subtract(int, int)
16:16amalloyrather than just an isub
16:19amalloyhmmmm, interesting. maybe the intrinsic isn't broken, but gets bypassed somehow if it's the final return value?
16:20amalloyif i change it to like (unchecked-inc-int (unchecked-add-int 1 (unchecked-subtract-int (unchecked-int Integer/MIN_VALUE) (unchecked-int 1)))), then all the operations get intrinsified except the outermost one, which uses a static method
16:21tickinghey I was wondering, is it expected behaviour that :or default values in map destructuring get evaluated eagerly wether they are used or not?
16:21Bronsaamalloy: ah I think I see why it's so. probably the intrinsic ops are emitted only when the value can be a primitive, since an IFn invoke can't return an int, that never gets through
16:21Bronsajust a guess though
16:21amalloyBronsa: well the value *can* be a primitive here. the function looks like https://www.refheap.com/aa32fa60ce419f4f599b11491 - ends with a static method returning an int, and then an Integer/valueOf
16:22amalloythat static method call could be intrinsified at no cost
16:22Bronsaamalloy: not saying it can't be done, just that because of how it's implemented the optimization is probably skipped
16:23amalloyagreed
16:24nicferrierthis is frustatring. I've got a go-loop with a bunch of channels that I'm mapping from a map along with a timeout channel and I'm alt!-ing them and I seem to be getting the timeout only once.
16:24nicferrierit's frustrating as well as frustatring
16:25noonianare you making the timeout channel anew each loop?
16:25pandeironicferrier: are you let binding the timeout ?
16:25nicferrieryes
16:25nicferrier(let [[[message id arguments] ch] (alts! (conj channels (timeout 100)))]
16:26Bronsaamalloy: yeah looking at the source, intrinsics for static methods are used only on emitUnboxed
16:27amalloynicferrier: what message does a timeout channel produce? if you try to destructure that into [message id arguments], does that break?
16:28nicferrieramalloy: good question, but I seem to get nil
16:28nicferrierI want proper matching.
16:30nicferrierreally the problem is my messaging is broken. it was working. and then I changed stuff around. and now it's not! hurrah!
16:31noonian,(let [[a b c] nil] [a b c])
16:31clojurebot[nil nil nil]
16:32nicferrier:-)
16:37nicferrierwhy would the channel I'm trying to use be different in the function I made it from the function I'm trying to read off it from?
16:37nicferrierthe jvm object is different.
16:40nicferrierhmmm. no I can probably explain that.
16:40nooniannicferrier: could you post the code? you said you are doing it in a loop, somehow you must be getting your references mixed up
16:43tuftcolleague just came up with a great class name: AbstractUntestableStateMachineMixin
16:45nicferrierrecommended pastebin?
16:45nicferrierturns out my personal one is broken for clojure
16:45nooniannicferrier: refheap
16:45nicferrierrequires login
16:46technomancyI don't think it does?
16:46nooniannot for public pastes at least
16:46nicferrieraha. if you go to the right url it's ok
16:47nicferrierhttps://www.refheap.com/94954
16:49amalloyRaynes: feature request: make refheap work even if you go to the wrong url
16:49nicferrieramalloy: the top urls on p1 of google all imply login.
16:49nooniannicferrier: style nitpick: (map #(% :from) @started) can just be (map :from @started)
16:49nicferrierprobably because no one needs to link to the paste post page
16:49nicferriernoonian: cool.
16:50amalloynicferrier: what? you searched for "refheap" and got links that suggest you log in? i can't find a single link that does that
16:50nicferrieramalloy: no I searched for clojure pastebin and didn't get the front page of refheap
16:51nooniannicferrier: i think your go-loop is throwing an error because you have no default case in the 'case' (since the timeout will return nil on close) and go blocks at least used to swallow errors and fail silently
16:51amalloyiiinteresting. refheap's about page does look a little unfriendly
16:52amalloyRaynes: feature request: make a google search for "clojure pastebin" take you to the right place
16:52nicferriernoonian: I've tried filtering that out
16:52nicferriernoonian: putting a (when message ...) around it for example. makes no difference.
16:53dbasch$google clojure pastebin
16:53lazybot[Refheap - The pastebin for your, you know, pastes] https://www.refheap.com/about
16:53nicferrierthe about page just needs a link to the front page.
16:53nicferriertitled something like "paste something now"
16:53amalloynicferrier: well, of course it does have a link to the front page, the Refheap logo. but it does need a more obvious "paste" link
16:55nicferriernoonian: the process actually starts in startProcess, but I never get the messages either.
16:55nicferrierpretty sure the alts! is hanging.
16:55nicferrierprintlns show the loop going rounf again
16:56noonianand you get more than one println?
16:57nicferrieryes. but I did something different now. adding the when and the printlns I got 2 sets of output.
16:57Raynesamalloy: You can be my SEO go. Have at it.
16:57noonianbecause the second go-loop will definitely throw an exception as soon as you get a message that isnt :line or :exit
16:57nicferrieryeah, I put a when around it.
16:57nicferrierbut it's still not working in some scenario.
16:58amalloyRaynes: seriously though i do like nicferrier's suggestion: the About page could use a link labeled "Paste now" or somethign
16:58amalloyas it is, the About page looks like all you can do is sign in
16:58RaynesYou can click on the header image
16:58Raynes'image'
16:58nicferrierhttps://www.refheap.com/94956
16:58amalloyRaynes: i know you can, and i said the same
16:59amalloyit just *looks* like there's nothing you can do but sign in
16:59noonianafk a min
16:59mikerodis https://github.com/thickey/lein-nevam abandoned ?
17:02nicferrierdo refs and go blocks work ok together?
17:07nicferrieroh well. I'm sure I can make it work in the morning. it's holding up pretty well against the scala version right now. which is good.
17:07chousernicferrier: excellent question! If I had to bet, I would say reading and writing on channels is a side effect, and thus not safe in a dosync.
17:08nicferrierchouser: my code isn't reading or writing channels in a dosync.
17:08nicferrierso that should be ok.
17:08chouseroh. Just reading from refs in a go block?
17:09nicferrierit's alt!ing on a bunch of channels derived from an @ref
17:09nicferrieralts!ing rather
17:13noonianchouser: here is the code in question: https://www.refheap.com/94956
17:13nicferrierok. I think it's falling over on channels being nil.
17:14nicferrierso what gets passed to alts! is [(timeout 100) nil]
17:14nicferrierwhich it barfs on
17:14nicferrierI think.
17:15nicferrierthe empty vector is true. :-(
17:16noonianyup, everything except nil and false
17:16nicferrierright.
17:17justin_smith&(map not-empty ["" "hi" [] [1]])
17:17lazybot⇒ (nil "hi" nil [1])
17:18justin_smithfor when you want empty to be falsey, but also to preserve the type
17:19nicferrieris really odd. it never times out when the channels are more than just the timeout channel.
17:19puredangerare you ever closing the timeout channel?
17:19puredangerif so, don't do that
17:20nicferrierpuredanger: no. I'm making a new one in the loop.
17:21nicferriergrrr. still have an nil channel. raarr.
17:22nicferrierok. that's got it.
17:22nicferriernow I'm not alts!ing from nil it's working.
17:22nicferrierit's not working. but it's working. if you see what I mean. :-)
17:23puredangerI haven't thought about it much, but if that's always a bug, we could presumably throw an error in that case.
17:23nicferrierso my problem is... apparently I never get the actual channels from the ref.
17:31nicferrierworking now! https://www.refheap.com/94961 - thanks everyone
17:33nicferrierthis makes quite a good exercise I think.
17:33nicferrierI might take it to the clojure dojo and see what people think.
17:38nicferrierless than 70 lines of code is pretty good.
17:49ikitommi_yogsototh: not very simple to add a new custom serialization format for compojure-api. Should be fixed, wrote an issue of it (https://github.com/metosin/compojure-api/issues/61).
17:50ikitommi_would love to push the needed changed to ring-middleware-format but it doesn't seem to be taking PRs in.
18:15trisshey all. I'm rather pleased to be finding myself saying stuff like (partial apply blah blah blah)
18:15trissi do it rather a lot... i wonder if there's a short hand?
18:16justin_smithdo you ever provide more than one arg?
18:17justin_smithif not, #(apply blah blah blah %)
18:17trissi have done.
18:17justin_smithOK
18:17trissof yeah!
18:17trissthanks man.
18:20amalloyyou can also (def ap (partial partial apply)), and then (ap blah blah blah)
18:21amalloythat's in useful somewhere
18:21trisshah splendid.
18:21trisswhat's useful?
18:21amalloyhttp://flatland.org/useful/
18:22amalloymostly i use useful.utils, useful.seq, useful.fn, and useful.map
18:23trisssome of this looks really useful...
18:23amalloythat's the idea
18:27trisshmmm. applied! if I was clever that's what Id have called this function too..
18:28trissmakes the ap abbreviation a little clearer I think.
18:41keedsquit
18:44TimMckeeds: No, I refuse!
18:50keedsTimMc: Sorry, please don't!
18:56TimMc:-)
19:17turbofailwe'll beat #haskell's offer by 10%
19:34trisshey all. if I've got a function name as a symbol how do i apply it
19:34triss?
19:34tickingtriss: you mean you want to get the function associated with a symbol?
19:35trissyep and feed it some values....
19:35amalloytriss: usually the answer is to hop in a time machine and get the function as something better than a symbol
19:35trissi was just thinking that.
19:35noonianthats the correct answer
19:35noonianthe one you shouldn't do in actual code is use eval
19:35justin_smiththere is resolve though, usually useful for ugly hacks
19:35justin_smith(doc resolve)
19:35clojurebot"([sym] [env sym]); same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)"
19:36noonianah thats better too
19:36justin_smith,((resolve 'clojure.core/+) 1 1)
19:36clojurebot2
19:36justin_smithbetter than eval at least
19:36tickingalso find-var
19:37ticking,((find-var 'clojure.core/+) 1 1)
19:37clojurebot2
20:49akkadyour Uber door is a jar
21:42seangroveThe flexibility of the ns form seems to cause endless debate/trouble
21:48andyfwhat kind of trouble?
21:50andyfIn particular, if you?ve ever been bitten by a problem that Clojure itself didn?t tell you about, I?m interested to add a warning to it for Eastwood, if I can figure out how. I think I?ve got most of the common problems covered in the next version.
21:51seangroveandyf: I think they're probably all covered by eastwood at this point
21:52seangroveandyf: Just saw some comment about it on an internal GH project
21:53andyfabout Eastwood, or about trouble debugging something with an ns form?
21:53seangroveDebugging ns form style
22:02yguan,(take-while even? [-2 -1 0 -1 -2 3])
22:02clojurebot(-2)
22:02yguanwhy only -2 is returned?
22:03seangrove,(filter even? [-2 -1 0 -1 -2 3])
22:03clojurebot(-2 0 -2)
22:03eyelidlessness1is there a particular approach to printing clojure values that will show a visual distinction between `false` and `(Boolean. false)`?
22:04yguanseangrove: :), right so take-while stops when it hit something?
22:04seangroveYup, it takes until the predicate is false
22:05yguanseangrove: my bad... need some tea...
22:05seangroveyguan: No worries!
22:08andyfeyelidlessness1: I hope you are not using (Boolean. false) in your own code on purpose? Read this if so: http://clojuredocs.org/clojure.core/if
22:08andyfIf you are trying to debug occurrences of (Boolean. false) that may be injected by other code you didn't write, then I'm not sure if there is an easy way to display it differently.
22:09eyelidlessness1andyf: nope, not using it directly. got bitten in a return value from… something
22:09TEttinger,(= (Boolean. false) false)
22:09clojurebottrue
22:10eyelidlessness1,(when (Boolean. false) true)
22:10clojurebottrue
22:10TEttinger,(= (Boolean/false) false)
22:10clojurebot#<CompilerException java.lang.NoSuchFieldException: false, compiling:(NO_SOURCE_PATH:0:0)>
22:10andyf(if (Boolean. false) "logical true" "logical false")
22:10andyf,(if (Boolean. false) "logical true" "logical false")
22:10clojurebot"logical true"
22:10TEttinger,(= Boolean/FALSE false)
22:10clojurebottrue
22:10TEttingerah, that is confusing
22:10andyfJava docs warn about this, and recommend against ever using it.
22:11andyfThat's why I wrote that page in ClojureDocs, so I could link to it when it comes up :)
22:11TEttingerah, that is confusing
22:11eyelidlessness1had to special case a particular (when) form into (= false), but without better visibility into where that value became (Boolean. false), no confidence in my fix
22:12andyfeyelidlessness1: Is it reasonable to walk traverse whatever data structure you have that might contain those, and conver all (Boolean. false) values to false? That might not be easy, I realize.
22:13andyfCould it be coming from one of several different libraries?
22:13TEttinger,(defn bad-boolean? [huh] (and (= huh false) (when huh)))
22:13clojurebot#'sandbox/bad-boolean?
22:13eyelidlessness1it is tough to automatically sanitize, i have several uses of defrecord which does not support (empty)
22:13TEttinger,(bad-boolean? (Boolean. false))
22:13clojurebotnil
22:14eyelidlessness1and yes, there are several libraries that may have interfered
22:14eyelidlessness1the data source was JSON, so it certainly wasn't in the original data
22:14TEttinger,(when (Boolean. false))
22:14clojurebotnil
22:14TEttinger,(when (Boolean. false) true)
22:14clojurebottrue
22:14TEttinger,(defn bad-boolean? [huh] (and (= huh false) (when huh true)))
22:14clojurebot#'sandbox/bad-boolean?
22:14TEttinger,(bad-boolean? (Boolean. false))
22:14clojurebottrue
22:15TEttinger,(bad-boolean? (Boolean/FALSE))
22:15clojurebotnil
22:15andyfeyelidlessness1: You know that your JSON reader lib doesn't produce (Boolean. false) values?
22:15TEttinger,(bad-boolean? Boolean/FALSE)
22:15clojurebotnil
22:15eyelidlessness1andyf: it never had before.
22:15TEttingerwill that check fail for anything big?
22:16TEttinger,(bad-boolean? false)
22:16clojurebotnil
22:16andyfI suppose there are conditions all over your code that might be affected, not just a handful?
22:16eyelidlessness1andyf: using clojure/data.json
22:16eyelidlessness1yes, potentially
22:16eyelidlessness1it would take a while of close analysis to have any confidence
22:17TEttingerandyf, eyelidlessness1: would (defn bad-boolean? [huh] (and (= huh false) (when huh true))) be suitable for checking?
22:18eyelidlessness1the function seems suitable enough, but it doesn't solve the immediate issue, that i now cannot be sure whether any (if) form in my codebase(s) does what i expect (nor any macros around it, like when-*)
22:20eyelidlessness1perhaps a lesson not to trust "truthyness" at all
22:20eyelidlessness1and to be more specific in expected values
22:20eyelidlessness1that tends to be harder in lower-level code though
22:22andyfeyelidlessness1: This (Boolean. false) thing does affect your code at a fairly low and pervasive leve, which is very annoying.
22:22andyfI spot-checked data.json, and don't see any obvious way it could be producing these bad falses.
22:22eyelidlessness1so.
22:22andyfAre you getting booleans from a database?
22:22eyelidlessness1no
22:23eyelidlessness1my strong suspicion
22:24eyelidlessness1we are also using storm. my strong suspicion is that it is an artifact of deserialization of custom types by storm
22:24eyelidlessness1but i have not proven that yet
22:24andyfIn a situation like this, it would be nice if you could set a flag before starting Clojure that would cause it to throw an exception if it ever did a condition test on (Boolean. false).
22:24eyelidlessness1YES.
22:24andyfBut I'm not aware of anyone who has implemented something like that.
22:25eyelidlessness1it would require forking clojure, as far as i can tell.
22:25andyfIt might be not very difficult to do by creating a modified version of Clojure.
22:25eyelidlessness1(if) is in Compiler.java
22:25TEttingercan you do a multimethod on Boolean?
22:25eyelidlessness1it may well be worth it
22:25andyfYeah, if making a locally modified version like that doesn't scare you, I'd say go for it.
22:26eyelidlessness1the relevant compiler code is pretty clear
22:26andyfI'm not saying you should be scared -- just some might avoid it.
22:26eyelidlessness1i'm mostly concerned about selling that to my team :)
22:27TEttingermaybe just use a fork for testing, not in production?
22:27eyelidlessness1but… we are using storm. thus stuck on clj 1.5.1. so not a huge maintenance risk.
22:27andyfHave you built and installed modified versions of Clojure before? git clone on the source code, git checkout to get to the version you want to modify (after 'git tag -l' to list the tags available), edit source code, then 'mvn install' to install it in your local mvn repo after compile and test.
22:27eyelidlessness1haven't before but the process seems straightforward enough.
22:28andyfIf you can localize your testing to a single machine, that would be easiest.
22:28TEttingermight want to change the pom to be a snapshot if it isn't
22:28puredangerandyf: also, don't forget running antsetup.sh
22:28andyfYeah, if you can easily change "1.5.1" to "1.5.2-SNAPSHOT", that would help keep it isolated to your local version.
22:28andyfpuredanger: Even if you do 'mvn install'?
22:29puredangerI think so
22:29puredangerbeen a while
22:29puredangereyelidlessness1: one way you can get new Booleans is via deserialization
22:29andyfI'll check, but I thought that was only if you ran 'ant', and I don't know how to use 'ant' to install in the local maven repo
22:31eyelidlessness1puredanger: interesting. that does seem like the likely culprit.
22:31andyfOut of curiosity, that would be deserialization performed from what source, for what reason?
22:32eyelidlessness1storm spout or bolt to bolt
22:33Bruce_WayneDoes anyone know how to produce a calendar
22:33andyfeyelidlessness1: If you do track down where these values are coming from, I hope you file reports about the issues, in hopes of eliminating them.
22:33eyelidlessness1absolutely
22:33Bruce_WayneI want to make a clickable html calendar with data structures behind each day that lead to a display of that data structure
22:34puredangereyelidlessness1: this might be too crazy for you, but you might consider hacking the jdk to debug this
22:34Bruce_WayneI already have code to display the data structure, just need to know a quick way to produce an html calendar with linkgs
22:34Bruce_Waynelinks
22:35puredangereyelidlessness1: grab the source for Boolean, modify it to dump stack when a new instance is created, compile, prepend to your bootclasspath
22:36eyelidlessness1puredanger: i feel far more comfortable modifying clojure, and at a glance it seems like a straightforward change.
22:36puredangerandyf: you're right btw, mvn works w/o antsetup
22:36puredangereyelidlessness1: fair enough - maybe it's a next step to find the source of the bad values
22:37eyelidlessness1is it crazy to suggest that clojure ought to just treat (Boolean. false) as (Boolean/False)?
22:38eyelidlessness1it could be a surprise for java interop
22:39andyfeyelidlessness1: It may be a performance degrader, since conditional tests are so pervasive.
22:39andyfAnd Java itself has the same issues, hence the documentation against using these Booleans.
22:39puredangereyelidlessness1: that stuff pre-dates my deep involvement but I know it's just a huge pain in the ass
22:41eyelidlessness1andyf, puredanger: this has been really helpful. thanks for taking the time to point me in a good direction (and understanding my frustration!)
22:42puredangersure, ping me at alex.miller@cognitect.com if you run into anything in clojure itself
22:42eyelidlessness1cheers!
22:49munderwoHi all. Is there anyway to have a look at the contents of a core.async channel in a javscript debugger?
22:54steveanyone have any good tips on web validation
23:00kenrestivoi find that most of the web is invalid. c.f. http://research.microsoft.com/en-us/people/mickens/ToWashItAllAway.pdf
23:02kenrestivojoking aside, there's https://github.com/weavejester/valip, https://github.com/joodie/pretzel , http://github.com/leonardoborges/bouncer, https://github.com/michaelklishin/validateur
23:02kenrestivoprobably lots others, but that's what i have in my notes
23:10stevethanks ken. yeah, so many choices makes it hard on the new guy :)
23:13steveseems people were using Schema for it, but I guess I'll stick with noir since I at least have a pretty good example
23:14kenrestivoschema has a lot of other advantages too.
23:15kenrestivoi'm using it for validating a conf file. haven't used it for form validation, but it seems like it'd do that well, also api input, lots of things.
23:19steveyeah, i guess i didn't get how to make the connection between the error map it throws and an actual error message i'd want to show the user.
23:20stevealso so new, not ever sure how error handling in clojure really works yet. Thanks for the thoughts, i'm sure it'll start to click as i go
23:57gfredericksis #"((x)|(y))\2\3" unmatchable? it seems to be