2016-02-22
| 03:50 | CStorm | how do i set a environment variable on unbuntu which environ can get? ive tried putting it in /etc/environment but no luck. |
| 04:49 | hyPiRion | CStorm: You probably need to restart/logout then login again for it to be reflected |
| 05:53 | Kah0ona | solatis: I'm currently working on a nice green-field freelance solo project for a company in Tilburg until like May-June, but when it's done, we probably need to talk ;-) (I'm Dutch, freelancer, Den Haag based.) |
| 05:54 | Kah0ona | (if i read correctly that you are hiring that is) |
| 05:54 | Kah0ona | kinda skimmed over the cats discussion |
| 05:55 | Kah0ona | I have two cats too ;-) |
| 05:56 | Kah0ona | Anyway; in summer I have another fairly large clj project added to my portfolio. working on it now |
| 06:06 | TEttinger | haha |
| 06:06 | TEttinger | cats |
| 07:13 | aurelian | hi there... what's the idea with lein creating an empty folder called dev-resources ? |
| 07:13 | aurelian | how do I get rid of it? |
| 07:16 | ridcully | {:profiles {:dev {:resource-paths set? |
| 07:17 | aurelian | doesn't look like |
| 07:17 | aurelian | :profiles {:uberjar {:aot :all}}) |
| 07:17 | aurelian | it's a standard lein new project |
| 07:17 | aurelian | using app template or wtv the default is |
| 07:18 | aurelian | oh. upgraded lein and now is gone. |
| 07:18 | aurelian | mind me |
| 07:19 | aurelian | I was on 2.5.something |
| 07:37 | hyPiRion | aurelian: yeah, sorry about the empty folders. They should be gone with 2.6.x |
| 07:37 | aurelian | it's ok, thanks! |
| 07:37 | aurelian | confirmed they're gone |
| 07:58 | timvisher | i'm logging from a background thread that updates an atom that i dereference. everytime i dereference the atom a log message comes out but if i don't dereference the atom no message comes out. is there any way i can force those exceptions to be logged without having to dereference the atom? |
| 08:21 | TimMc | timvisher: Dereferencing an atom should not cause side effects. Do you have lazy seqs or something in there? |
| 08:26 | timvisher | laziness… |
| 08:26 | TimMc | ~laziness |
| 08:26 | clojurebot | laziness means not traversing anything twice |
| 08:26 | TimMc | ~laziness |
| 08:26 | clojurebot | laziness means not traversing anything twice |
| 08:26 | TimMc | oh well |
| 08:27 | TimMc | timvisher: So yeah, sounds like you need a dorun or doall in there somewhere. :-) |
| 08:27 | timvisher | anyway yeah. one `map → mapv` transformation later and boom |
| 08:39 | TimMc | Could I get some advice/rubber ducks on a concurrency mechanism for serializing writes to a cache? |
| 08:40 | TimMc | The code is currently sending ~50 writes per second (luxuriously few, given that writes are 1-2 ms) and I was thinking of just dumping them into a dropping or sliding queue and spinning a thread to pick them up at the other end and put them in the cache. |
| 08:42 | TimMc | I'm thinking simple 'n' robust is better, because we rely on the cache being up, and if we stop updating it, there's going to be trouble. |
| 08:42 | TimMc | Any constructs I should be looking at in particular? |
| 08:47 | TimMc | Agents are out, as usual. I've never ended up finding a good use for them. |
| 08:50 | jamesturnbull | hi all - I have a collection [var1 var2] that I am trying to join. var2 may sometimes be nil. I want to ensure a separater is present if there are two elements but not if there is one. (clojure/string.join "." [var1 var2]) becomes var1. if var2 is nil. |
| 08:50 | hyPiRion | TimMc: I think just a Thread and a BlockingQueue would work fine. Then you can use .offer to insert values which may be dropped. |
| 08:50 | hyPiRion | I am no guru on concurrency mechanisms though |
| 08:50 | TimMc | And just a try/catch in the thread is probably sufficient to make sure it never dies? |
| 08:51 | TimMc | I'll monitor the length of the queue, of course. |
| 08:51 | hyPiRion | Yeah. |
| 08:51 | TimMc | hmm, also need shutdown mechanism |
| 08:51 | TimMc | Channels feel like maybe they're relevant here, although I hesitate to introduce *yet another* concurrency mechanism or structuring principle to this codebase... |
| 08:54 | hyPiRion | TimMc: It depends on how you'd like to shut down. I like to just use .interrupt and catch InterruptExceptions |
| 08:59 | TimMc | hiredman: That... sounds perfectly reasonable, actually. |
| 08:59 | TimMc | oops |
| 08:59 | TimMc | hyPiRion, rather |
| 09:01 | TimMc | jamesturnbull: They're both strings already? |
| 09:03 | TimMc | I'd probably go with something simple like (cond-> (str v1) v2 (str "." v2)) |
| 09:03 | jamesturnbull | TimMc: yeah both strings. thanks will try that! |
| 09:04 | TimMc | (that handles them not being strings, but not if v2 can legitimately be the boolean false) |
| 09:04 | dysfun | what's the function called that turns '_BANG_' etc. into '!' in a name? |
| 09:04 | TimMc | demunge? |
| 09:04 | dysfun | that's the one, ta |
| 09:04 | TimMc | but I think it's only in clojure.repl |
| 09:05 | TimMc | and has a bug, IIRC |
| 09:05 | dysfun | that's acceptable for this, this module is meant for during development |
| 09:05 | dysfun | oh :/ |
| 09:05 | TimMc | something about double underscores |
| 09:06 | dysfun | haha, and the literal word 'BANG' probably |
| 09:07 | TimMc | hmm, I think I'm thinking of a bug in pst around extracting munged fn names |
| 09:13 | jamesturnbull | TimMc: thanks - works perfectly - didn't know about cond-> - neat. |
| 09:15 | dysfun | TimMc: so demunge is fine? |
| 09:15 | dysfun | (to the best of your knowledge) |
| 09:16 | TimMc | dysfun: Yeah, and I found the original (fixed) bug: http://dev.clojure.org/jira/browse/CLJ-1083 |
| 09:17 | dysfun | aha |
| 09:18 | dysfun | of course if you're a java programmer and you're writing _BANG_, you need your head looking at |
| 09:20 | ridcully | static final String LOL_BANG_LOL seems not so far out that head inspection is needed? ;P |
| 09:20 | TimMc | Probably true, but that kind of argument never sits well with me. |
| 09:22 | TimMc | This is why we have problems like not having any way to escape characters in a <script> block in HTML. "Just don't write </script> in your script, ever, OK?" Fast forward a decade and we've got user data being plunked down in JSON into script blocks and no end of trouble. |
| 09:22 | TimMc | Universality is good for security and correctness. |
| 09:23 | TimMc | (I gave a talk on this at work. I should turn it into a blog post.) |
| 09:24 | dysfun | i'd read it |
| 11:27 | justin_smith | TimMc: agents are when you want a mutable container and retries on update are out of the question |
| 11:28 | justin_smith | (in my experience, they probably also have other uses) |
| 11:28 | justin_smith | TimMc: as such they are the only clojure mutable container that it's safe to put actual mutable objects inside |
| 11:31 | sineer | Hi! if I have a (let [foo "bar"] (if foo (let [foo "baz"]))) is there a nicer way to reassign my foo var without requiring yet another let? |
| 11:31 | justin_smith | ,(let [foo "bar" foo (if foo "baz" foo)] foo) ; sineer |
| 11:32 | clojurebot | "baz" |
| 11:32 | justin_smith | sineer: and it is not "reassigning" anythign, it's shadowing |
| 11:32 | justin_smith | but that's good enough (unless a previous binding used the value, then it's clear it was just shadowing) |
| 11:33 | sineer | right (about shadowing). it feels wierd... I'll try it |
| 11:33 | justin_smith | sineer: it's the same thing the nested let would do |
| 11:33 | Bronsa | justin_smith: care to expand on "agents are the only clojure container that it's safe to put mutable object inside"? |
| 11:34 | justin_smith | Bronsa: no retries |
| 11:34 | justin_smith | retries fuck with mutable things |
| 11:34 | Bronsa | ah, gotcha |
| 11:34 | justin_smith | I mean yeah you could put a mutable thing inside and promise not to mutate it in swap! or alter calls... |
| 11:34 | Bronsa | I'd feel so safe doing that |
| 11:36 | justin_smith | oh, there's vars too of course |
| 11:36 | justin_smith | but that's only for top level things |
| 11:36 | justin_smith | so for example when I use stuartsierra/component I put my system inside a var or an agent (neither retries) instead of an atom or ref |
| 11:57 | TimMc | If the actions on the mutable thing are idempotent it might be OK. |
| 12:01 | justin_smith | TimMc: sure, maybe, but still, if what you have is a thing containing maybe some clojure data and some mutable stuff that isn't concurrency safe that you need to punch in unsafe ways, agents are a decent way to manage that state |
| 12:01 | justin_smith | because the actions sent are guaranteed to be one at a time, no retries, etc. |
| 12:02 | justin_smith | simpler than wrangling locks anyway |
| 12:06 | TimMc | justin_smith: What's an example of something you've used an agent for? |
| 12:07 | justin_smith | TimMc: stuartsierra/component system object (I don't want retries just because something else tried to start it) |
| 12:08 | justin_smith | TimMc: various cases where I was using core.async but realized all I needed was one queue and I could send it functions |
| 12:09 | justin_smith | and I would use it if I needed to use a mutable object unsafe for concurrency that had namespace level scope, but that hasn't come up remarkably |
| 12:10 | TimMc | hmm |
| 12:13 | justin_smith | TimMc: if you have a simpler solution for those cases feel free to offer, of course |
| 12:17 | justin_smith | of course the canonical thing with a component is a var, but that doesn't cover overlapping calls as nicely I don't think? |
| 12:20 | justin_smith | actually I can't tell if this retries or not? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Var.java#L302 |
| 12:25 | sineer | clojure.lang.ExceptionInfo: Cannot recur accross try ... I can't try/catch inside a go loop if I must recur ? |
| 12:25 | justin_smith | sineer: you need to move the try/catch to not surround the recur |
| 12:25 | justin_smith | sometimes this requires a promise or delay for the value propagation to work (sadly) |
| 12:26 | sineer | so inside the go block but before the (loop ) ? |
| 12:26 | sineer | otherwise if it's outside the go block then it won't work correct? |
| 12:26 | justin_smith | or inside the loop but not surrounding the recur |
| 12:26 | justin_smith | depends what needs catching |
| 12:27 | justin_smith | sineer: (loop [x 1] (let [res (promise)] (try .... (deliver res v) ... (catch ... (deliver res nil)) (recur @res)) ; if you need to use a value created inside the try in your recur |
| 12:28 | justin_smith | if you don't need to use any value from inside the try in your recur call, that's much simpler of course |
| 12:28 | sineer | k, thanks! |
| 12:31 | justin_smith | sineer: actually there should probably be a deliver in the finally clause in the above, to guarantee you don't do a blocking deref that won't be fulfilled inside the recur call |
| 15:04 | mping | hi guys |
| 15:27 | gfredericks | I need some names for things in test.check |
| 15:27 | TimMc | fred |
| 15:27 | gfredericks | to be more specific |
| 15:27 | AimHere | fred smith |
| 15:28 | TimMc | the third |
| 15:28 | gfredericks | I need to differentiate a test run from a single trial |
| 15:28 | gfredericks | but "test run" sounds too much like running your whole test suite |
| 15:28 | gfredericks | I don't know which of the two "trial" sounds like |
| 15:28 | {blake} | "single trial" seems pretty clear |
| 15:28 | gfredericks | this is for things to go under the :type key in a map passed to a callback function to let you know what's going on |
| 15:29 | gfredericks | so event names I guess |
| 15:29 | gfredericks | maybe :start-test, :trial, :end-test, that sort of thing |
| 15:29 | gfredericks | i.e. I think "test" is a decent name for the larger chunk of work |
| 15:29 | gfredericks | GREAT thanks everybody |
| 15:30 | gfredericks | cfleming: hi |
| 15:50 | TimMc | gfredericks: Yes, trial sounds right. |
| 15:50 | TimMc | or even probe, but trial is better |
| 15:50 | TimMc | chcek :-P |
| 15:50 | TimMc | *check |
| 15:51 | gfredericks | naming is one of the 94 hard problems in computer science, along with cache-invalidation and off-by-91-errors |
| 15:52 | TimMc | *71 |
| 16:10 | andyf | I know a gentleman from India whose last name is "Furniturewala". Yes, the English word "furniture" followed by "wala", with no space. |
| 16:11 | andyf | "wala" means "maker", so he is named for one of his recent ancestors being a furniture maker, after English was reasonably common in India, but before surnames were common, so the surname was created after that. |
| 16:12 | andyf | That was one of my top all time favorite names, until this weekend, when I heard a similar but even more awesome name: "Sodabottleopenerwala" |
| 16:12 | andyf | I am not joking |
| 16:15 | andyf | Sorry, no application to your naming question, gfredericks, although I would suggest putting 'wala' in constructor names whenever you can :-) |
| 16:16 | justin_smith | andyf: beats Factory for sure |
| 16:16 | zipper | Hey guys, I need some clojurescript help. I can get it here, right? |
| 16:17 | andyf | If all planets line up properly, then yes. |
| 16:17 | hiredman | maybe, depending on the nature of the help required, there is a #clojurescript channel I think too |
| 16:18 | gfredericks | ~andyf is a walanamewala |
| 16:18 | clojurebot | Ik begrijp |
| 16:19 | {blake} | A propos of which, I'm having reagent timing issues. |
| 16:19 | {blake} | I have a reagaent component that renders a table full of controls. |
| 16:19 | {blake} | After rendering, I want to attach some Jquery to the controls. |
| 16:20 | {blake} | I dutifully used with-meta and :component-did-mount, which I wrapped my rendering function around. |
| 16:20 | {blake} | The code is called. I know, because it starts a timer. |
| 16:20 | {blake} | But the attempt to collect all the controls of a class fails. (I'm collecting, e.g., currency controls to apply MaskMoney to.) |
| 16:21 | {blake} | If I put the collection code into the timer code, it works, I presume because that stuff fires long enough for everything to have settled. |
| 16:21 | {blake} | er, late enough |
| 16:21 | amalloy | MaskMoney is the account bruce wayne sets aside for batman-related activities |
| 16:22 | {blake} | And I suppose I could create a timer event to fire JUST to set this Jquery code. But that seems cheesy, and wrong. |
| 16:22 | {blake} | He must go through masks like crazy. |
| 16:23 | amalloy | fwiw andyf, we have lots of names like that in english already, we're just used to them because we've had them so long |
| 16:24 | amalloy | plenty of masons, smiths, thatchers, coppersmiths, and so on |
| 16:24 | gfredericks | andyf: the clear conclusion is that you need to come to clojure/west this year |
| 16:24 | hiredman | {blake}: sounds like you need the js equiv of swing's invokeLater, which I guess would be a zero second settimeout |
| 16:25 | {blake} | hiredman: Mebbe. It's gotta exist. No way people =aren't= doing this exact thing. But it can be hard to find info. |
| 16:25 | {blake} | (Or in this case, figure out where I've gone wrong, because if :component-did-mount isn't for this, what IS it for?) |
| 16:27 | hiredman | https://facebook.github.io/react/docs/component-specs.html#mounting-componentdidmount it does sone like that is what it is for |
| 16:27 | hiredman | sound |
| 16:27 | {blake} | Hmmm. Immediately after initial rendering occurs. |
| 16:27 | andyf | gfredericks: The thing I found interesting was the *combination* of words from two languages in a single name. |
| 16:27 | zipper | So since the clojurescript channel isn't full of life. I will ask here too. |
| 16:28 | zipper | So in this code https://www.refheap.com/115084#L-2 The Line 2 fails. I am trying to rewrite whatever is from L12 since that regex fails to work for () and | |
| 16:28 | andyf | gfredericks: Kids still in college, and on top of that there is big hardware/software product release coming up this April, but maybe the hubbub will be over by the Conj. |
| 16:29 | hiredman | zipper: you are qouting the regex and not the list |
| 16:30 | hiredman | zipper: so you are invoking the regex as a 0 arg function, you should be seeing errors in the error console and possibly at compile time |
| 16:30 | hiredman | zipper: if you do quote the list, you local 'regex' in the let is being bound the result of the if, which is a list containing a regex, not a regex |
| 16:31 | hiredman | oh, I guess you only care about the second |
| 16:31 | andyf | amalloy: Sorry, meant to send one of my recent comments to you. Senior moment. |
| 16:32 | hiredman | zipper: what does "fails" mean? a compilation error, a runtime error, or it fails to match what you want? |
| 16:32 | zipper | hiredman: Yes I am seeing an error in the JS console |
| 16:32 | hiredman | for which snippet? |
| 16:33 | zipper | hiredman `Uncaught TypeError: /\/[\-\[\]\\/\{\}\(\)\*\+\?\.\\\^\$\|]\/gi/.call is not a function` |
| 16:33 | zipper | hiredman: I assume it comes from L2 |
| 16:34 | zipper | I can see that because it tries to call that regex.call |
| 16:34 | zipper | plus it ends with /gi |
| 16:34 | hiredman | zipper: right, so A. you don't need to quite the regexes B. don't call them as zero argument functions |
| 16:34 | hiredman | to quote |
| 16:35 | zipper | hiredman: How do I avoid calling it if not using ' |
| 16:35 | zipper | ? |
| 16:35 | hiredman | you have the ' and are still calling |
| 16:35 | hiredman | (foo) is a function call |
| 16:35 | hiredman | you have (some-regex) |
| 16:35 | hiredman | that is trying to invoke the regex as a 0 argument function |
| 16:36 | hiredman | you use of ' does nothing in this case, because regexes are literals that evaluate to themselves |
| 16:37 | zipper | Okay so I get rid of the () and have that read as; `#"/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/gi"` |
| 16:37 | hiredman | '(foo) would mean it is a quoted list, not a function call, but then you would have a list containing a regex, not a regex |
| 16:37 | gfredericks | andyf: is going to conferences more difficult when your kids are in college? |
| 16:37 | zipper | That's a regex now |
| 16:37 | hiredman | zipper: yes, that is |
| 16:38 | zipper | hiredman: Trying it out |
| 16:38 | zipper | My chest hurts, it's so cold :( |
| 16:38 | {blake} | component-did-update does the trick. |
| 16:39 | andyf | gfredericks: Only in that I feel budget tightness more than before then. I should splurge on a Conj before they are done, though. |
| 16:40 | gfredericks | andyf: are you telling me college is going to cost *money*?? |
| 16:40 | hiredman | if there was money in the future, instead of just hugs |
| 16:41 | andyf | gfredericks: I fully believe that it will become common-place for some cheaper alternative to traditional 4-year degree to be acceptable for more jobs than they are now. Not sure when that will happen. Maybe a decade or 2 from now? |
| 16:42 | Somelauw | How to quickly run a clojure.clj file interactively which is not part of a project? |
| 16:43 | Somelauw | Is lein repl, (source filename) the only way? |
| 16:43 | gfredericks | andyf: I need a proposal on my desk by 14 years from now |
| 16:43 | hiredman | http://clojure.org/reference/repl_and_main |
| 16:43 | hiredman | Somelauw: source doesn't run anything |
| 16:48 | amalloy | you know, i read "that's a regex now" as "that's a regret now", and it seemed even more apt, given that the subject is #"/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/gi" |
| 16:48 | gfredericks | a programmer has a regret, and thinks, "I know, I'll use a regular expression!" ... |
| 16:48 | hiredman | amalloy: also, it is being used to edit a string, that is then being turned into a regex |
| 16:49 | hiredman | crazy |
| 16:49 | Somelauw | Running 'java -cp clojure.jar clojure.main' says 'Error: Could not find or load main class clojure.main' I just want to run a single script without turning this script into a project. |
| 16:50 | hiredman | Somelauw: because you picked a random jar instead of the jar that contains clojure |
| 16:50 | hiredman | clojure.jar doesn't, in this context, mean some jar with your clojure code in it, it means the jar containing the clojure runtime |
| 16:52 | Somelauw | so clojure.jar should be the full path to the clojure.jar that lays somewhere deep in ~/.m2 |
| 16:53 | hiredman | or whereever, you can download the jar from the website |
| 16:53 | hiredman | http://clojure.org/community/downloads |
| 16:54 | Somelauw | so that is ~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar |
| 16:56 | Somelauw | I'll just write a wrapper for it |
| 16:57 | Somelauw | I only miss autocompletion in my repl that lein has |
| 16:58 | ridcully | don't forget to put rlwrap -m -M .clj -C clojure around it :) |
| 17:01 | Somelauw | ridcully: ehm, do I replace clojure by 'java -cp clojure.jar clojure.main'? |
| 17:04 | ridcully | Somelauw: no. it's just a name used for the history file |
| 17:04 | ridcully | Somelauw: this will use ~/.clojure_history then |
| 17:05 | andyf | gfredericks: My iPhone calendar actually lets me schedule events 14 years in advance. Huh. Not sure whether the event I just created will get copied to whatever device I am using to remind me of calendar events then. |
| 17:06 | Somelauw | ridcully: I'm not sure at what place of your command to insert the whole 'java -cp clojure.jar clojure.main' |
| 17:09 | ridcully | Somelauw: i use it like this (some var with the version involved): rlwrap -m -M .clj -C clojure java -cp ~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar clojure.main |
| 17:10 | ridcully | Somelauw: the -m gives you multine capabilities - so you can open your $EDITOR with ctrl-^. the -M tells it to put a .clj on that "file" to open so your $EDITOR behaves nicely |
| 17:27 | Somelauw | ridcully: thanks, that works well, although it would be preferable to still use lein somehow |
| 17:30 | ridcully | Somelauw: you can always run a `lein repl` from anywhere |
| 17:30 | spuz | Is there a function that combines filter and first? I.e. it returns the first element of a sequence that matches a predicate? |
| 17:30 | ridcully | Somelauw: add the `try` plugin for it and you can also fetch some deps right into it |
| 17:31 | Somelauw | ridcully: I know I can run lein repl from anywhere, just not how to run it with a script that is not part of a project. |
| 17:31 | amalloy | spuz: incredibly, there is not |
| 17:33 | Somelauw | lein repl filename doesn't work for me |
| 17:33 | andyf | spuz: Some Clojure 'utility libraries' include such a thing, e.g. find-first in Medlay: https://github.com/weavejester/medley/blob/master/src/medley/core.cljc |
| 17:33 | Somelauw | then it says unknown subcommand |
| 17:33 | andyf | spuz: er, Medley, even. |
| 17:34 | spuz | andyf, thanks |
| 17:35 | Somelauw | but filter is lazy, so first-filter should already be fast |
| 17:49 | justin_smith | ridcully: cool rlwrap tricks |
| 17:56 | lerax | Someone knows a good lib for pt-br natural lang processing? |
| 18:03 | ridcully | Somelauw: mhm i might have put you on the wrong track then. i only saw your "have to wrap it" bits and tought you just want to have a faster repl |
| 18:15 | ImBadAtClojure | Is there a way to convert a clojure vector of java objects into a java List<java object's type>? |
| 18:15 | hiredman | that is a generic, those don't actually exist |
| 18:16 | ImBadAtClojure | So it's impossible? |
| 18:16 | hiredman | no, you don't need to |
| 18:16 | rhg135 | generics are only a delusion that javac enforces |
| 18:17 | hiredman | javas generic types exist in the java (the language) compiler, once you have bytecode running on the jvm, they don't exist (this is called erasure and I am sure there are like a billion blog posts about it) |
| 18:17 | hiredman | you just need something that implements List |
| 18:17 | ImBadAtClojure | so when I send this custom data structure back to java how do I get it into java datastructures? |
| 18:17 | hiredman | if you pull up the java docs for List, there are links to few handy implemntations of that interface |
| 18:18 | hiredman | ,(java.util.ArrayList. (vec (range 10))) |
| 18:18 | ImBadAtClojure | I was just trying to map it directly into POJOs somehow |
| 18:18 | clojurebot | [0 1 2 3 4 ...] |
| 18:18 | hiredman | ,(type (java.util.ArrayList. (vec (range 10)))) |
| 18:18 | clojurebot | java.util.ArrayList |
| 18:18 | hiredman | clojure data structures are java data structures |
| 18:19 | hiredman | so depending on what interfaces java requires and what methods it calls, you can just pass in clojure data structures |
| 18:19 | ImBadAtClojure | Fair enough, so just pass it back in a simple array list then map into my pojos on the java side? |
| 18:19 | hiredman | ImBadAtClojure: I am not sure what you mean? |
| 18:19 | hiredman | any java objects you want to construct, you can construct from clojure and pass to java |
| 18:21 | ImBadAtClojure | But to construct one of my java objects in clojure I need to create a list of a previously constructed java object |
| 18:21 | ImBadAtClojure | ClassCastException java.util.ArrayList cannot be cast to [L<myType>; |
| 18:21 | TEttinger | oh |
| 18:21 | TEttinger | that isn't a list |
| 18:21 | TEttinger | that looks like an array |
| 18:22 | TEttinger | ,(class (make-array java.util.String 2)) |
| 18:22 | clojurebot | #error {\n :cause "java.util.String"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: java.util.String, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.ClassNotFoundException\n :message "java.util.String"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :... |
| 18:22 | TEttinger | ,(class (make-array java.lang.String 2)) |
| 18:22 | clojurebot | [Ljava.lang.String; |
| 18:22 | ImBadAtClojure | that would make an array of strings right? |
| 18:22 | ImBadAtClojure | so I can make an array of my java object's type in the same way? |
| 18:23 | TEttinger | yeah, it looks like your exception is caused by passing an ArrayList where it actually wants an array |
| 18:23 | ImBadAtClojure | Yeah I was just trying random things since I didn't know how to create a new array with a non primative type |
| 18:24 | ImBadAtClojure | I'll try it, thanks :D |
| 18:24 | TEttinger | arrays are kinda less supported in clojure than other data structures since they can't be made to have the nice features in clojure's immutable data structures |
| 18:24 | TEttinger | arrays are always mutable, fixed-size |
| 18:24 | hiredman | that is non-sense |
| 18:25 | amalloy | i like the implication that clojure's built-in structures are immutable but change size all the time |
| 18:25 | TEttinger | heh |
| 18:25 | TEttinger | good point |
| 18:26 | TEttinger | I do have the feeling that arrays are not quite first-class in clojure, at least partly because of the separate amap, areduce, etc. fns for them |
| 18:27 | hiredman | TEttinger: infact, map and reduce both work on arrays just fine |
| 18:27 | hiredman | TEttinger: amap and areduce are *extra* support for working on arrays |
| 18:27 | TEttinger | I didn't know that, I guess seq works on arrays |
| 18:27 | ImBadAtClojure | so can I do (make-array <custom java type class> ..)? |
| 18:27 | TEttinger | yeah, then the dimension or dimensions |
| 18:27 | TEttinger | ,(doc make-array) |
| 18:27 | clojurebot | "([type len] [type dim & more-dims]); Creates and returns an array of instances of the specified class of the specified dimension(s). Note that a class object is required. Class objects can be obtained by using their imported or fully-qualified name. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE." |
| 18:28 | hiredman | ImBadAtClojure: you can, I would recomend looking at the set of clojure functions with 'array' in the name |
| 18:28 | amalloy | you'd almost certainly prefer to call into-array |
| 18:28 | ImBadAtClojure | awesome, thanks guys |
| 18:28 | TEttinger | right |
| 18:28 | hiredman | ,(doc apropos) |
| 18:28 | clojurebot | "([str-or-pattern]); Given a regular expression or stringable thing, return a seq of all public definitions in all currently-loaded namespaces that match the str-or-pattern." |
| 18:28 | amalloy | although hiredman's advice is probably better |
| 18:28 | rhg135 | what is the best way to shutdown an agent? |
| 18:29 | rhg135 | just stop banging on it? |
| 18:31 | hiredman | I have some projects where object arrays were used more less like a C struct, in clojure, works fine. kind of a pain, if I did it regularlly I would have a nice set of macros that generate setter and getter functions |
| 18:58 | TEttinger | yeah, actually I might need some advice on how to best interop with array-heavy java code. I still need to get some stuff (I think it's setup related) fixed in my installation of cursive, deps still aren't visible in the editor but they are in lein repl |
| 18:59 | TEttinger | but once I can pull in the java deps, I need to wrap them |
| 18:59 | TEttinger | I don't know if it's an appropriate case for an issue on cursive somewhere |
| 19:13 | rhg135 | try telling that to oracle |
| 21:51 | sineer | I'm inside a (go (loop (try .... (catch Exception e e)))) and I try/catch the block that run this go block yet my exception isn't caught by that try/catch block? Clojure 1.8.. |
| 21:52 | justin_smith | sineer: I assume you mean (go (loop [] (try ...))) |
| 21:52 | justin_smith | sineer: is the thing thrown a subclass of Exception? |
| 21:53 | sineer | justin_smith: yeah, it was throwing allright, let me push code on github it'll make our life easier |
| 21:53 | justin_smith | sineer: what I am asking is what the class thrown was |
| 21:53 | justin_smith | is it an Exception or maybe an Error or some other class that catching Exception would not match |
| 21:54 | sineer | NullPtrException |
| 21:54 | justin_smith | yeah, share a paste / github |
| 21:56 | sineer | https://github.com/sineer/sort-challenge |
| 21:56 | sineer | line 46 of boot.clj will throw NullPtrException |
| 21:57 | sineer | I believe it catch it and keep running the go blocks until cnt is 0 but the try/catch in -main never catch anything |
| 21:58 | justin_smith | well, of course, if the try/catch in init-products-from-chan! catches the error, why would -main ever see it? |
| 21:59 | justin_smith | sineer: also you don't need a new let block at line 51, those bindings can be part of the let block right before |
| 21:59 | justin_smith | ,(let [a 0 b (inc a) c (inc b)] c) |
| 21:59 | clojurebot | 2 |
| 22:00 | sineer | I need to run the (if family (assoc info :family family)) before I do the other (let .. |
| 22:00 | justin_smith | why? |
| 22:00 | clojurebot | http://clojure.org/rationale |
| 22:00 | justin_smith | why would that matter at all? |
| 22:00 | sineer | I suppose I can do it after.. |
| 22:01 | justin_smith | sineer: (if family (assoc family x y)) does not have any side effects |
| 22:01 | justin_smith | you need to bind the return value, or it is a noop |
| 22:01 | justin_smith | family is immutable, assoc does not change it |
| 22:01 | justin_smith | the correct version of that line is to have, inside your let binding block 'family (if family (assoc family ...)) |
| 22:01 | justin_smith | it needs to be a binding or it might as well not exist |
| 22:02 | justin_smith | so you only need one let block |
| 22:02 | justin_smith | that binding is just the next binding in the block |
| 22:02 | justin_smith | compare: |
| 22:02 | justin_smith | ,(let [a {}] (assoc a :b 1) a) |
| 22:02 | clojurebot | {} |
| 22:03 | justin_smith | ,(let [a {} a (assoc a :b 1)] a) |
| 22:03 | clojurebot | {:b 1} |
| 22:03 | justin_smith | sineer: do you see the difference? |
| 22:03 | sineer | I'm just confused now :( |
| 22:04 | justin_smith | sineer: assoc does not mutate its arg, it creates a brand new data structure |
| 22:04 | sineer | oh shit yeah I get it now :( |
| 22:04 | justin_smith | sineer: you don't need two let blocks |
| 22:04 | sineer | sorry |
| 22:04 | justin_smith | sineer: don't be sad, I'm trying to help |
| 22:04 | justin_smith | I'm not trying to be mean |
| 22:04 | sineer | I know, I'm sad because I feel stupid having such a hard time with this |
| 22:05 | justin_smith | everything is hard if you haven't learned it yet |
| 22:05 | sineer | yeah but it shouldn't be that hard else I'm either stupid or it's too damn hard I havne't fully decided which one it is yet |
| 22:06 | TimMc | justin_smith: throw in some commas |
| 22:07 | justin_smith | TimMc: in the let blocks? |
| 22:07 | TimMc | yeah |
| 22:07 | justin_smith | ahh, yeah |
| 22:07 | sineer | I just realized the version I pushed print the exception on line 59, I use to just return it that's why I expected -main to catch it.. |
| 22:07 | justin_smith | ,(let [a {}] (assoc a :b 1) a) |
| 22:07 | clojurebot | {} |
| 22:07 | justin_smith | ,(let [a {}, a (assoc a :b 1)] a) |
| 22:07 | clojurebot | {:b 1} |
| 22:07 | justin_smith | sineer: returning an exception is not the same as throwing it |
| 22:08 | justin_smith | it might look the same with some printing rules, but it's different |
| 22:08 | sineer | ok so I need to rethrow inside go block for -main to catch it? |
| 22:08 | justin_smith | yes |
| 22:09 | justin_smith | otherwise you just return an exception, which is a value like any other |
| 22:09 | justin_smith | sineer: in fact you never even consume the channel returned from that go block |
| 22:09 | sineer | no I just assign it so that main don't exit right away |
| 22:10 | justin_smith | right, just saying by returning it from the go block, it might get read if someone consumed the chan |
| 22:10 | justin_smith | but nobody even does that |
| 22:11 | sineer | now I tried replacing that print on line 56 by throw and I see the exception trace but then my program just hang, it doesn't look like -main is caching the exception |
| 22:11 | sineer | line 59 I mean |
| 22:11 | justin_smith | go can be kind of weird about exceptions, it's best to catch them before you exit the scope of a go block and handle them best you can |
| 22:12 | justin_smith | basically what happens is your code is running in one of the threads of the go thread pool, and your exception bubbles up to that thread, not to the -main that launched the go block, so you are at the mercy of the default go block error handler, which is pretty much useless |
| 22:13 | justin_smith | since it's in a different thread, the exception can't go back up to -main |
| 22:13 | sineer | I thought I read somewhere it did so since clojure 1.6? |
| 22:13 | sineer | I probably missinterpreted something |
| 22:13 | justin_smith | probably - how would an exception in one thread interrupt another thread? |
| 22:14 | sineer | yeah that doesn't make sense but I thought there was some magic I didn't know about... |
| 23:02 | solatis | what do people recommend for mocking stuff in tests? |
| 23:02 | solatis | specifically, things like message queues |
| 23:03 | solatis | i am in doubt whether to make my tests just /depend/ upon the availability of those, and create ad-hoc queues |
| 23:03 | solatis | but on the other hand, i could just as well mock the interface to the queue |
| 23:04 | sineer | re |
| 23:04 | hiredman | solatis: are you using clojure.test? |
| 23:04 | solatis | yep |
| 23:05 | hiredman | clojure.test has once (per namespace) and each (per deftest) fixtures |
| 23:05 | solatis | yes |
| 23:05 | solatis | so i'm already doing that for my database |
| 23:05 | solatis | but now i'm depending upon a lot more things (specifically, Amazon AWS services) |
| 23:05 | solatis | and wonder what the best strategy for this is |
| 23:06 | solatis | either using the actual service (albeit self-contained), or mocking the interface |
| 23:06 | sineer | er sorry. I have a question about how to build a regex.. I want to (let [regex #"foo[-][_]"]) something like that. but using a var instead of "foo". Basically I need a regex that will match myvar with optional - or _ at the end |
| 23:06 | hiredman | it can get kind of complicated |
| 23:06 | solatis | yes i know, i don't think there is a "magic bullet" for this and it depends on a case-by-case scenario |
| 23:06 | hiredman | you can make all your interfaces to aws services pluggable and use some local plugin when testing |
| 23:07 | solatis | i was thinking about this: https://clojuredocs.org/clojure.core/with-redefs-fn |
| 23:07 | solatis | and put that in a fixture |
| 23:07 | solatis | or something |
| 23:09 | hiredman | you can do that, but in my experience you end up with a sprawl of things you need to redef, and it is hard to track what a test is actually doing |
| 23:09 | solatis | right |
| 23:09 | solatis | so the answer is, pluggable service |
| 23:10 | solatis | but then that doesn't test the actual integration with the message queue |
| 23:10 | solatis | *argh* |
| 23:10 | hiredman | at my previous job we ended up with a macro we called with-var-roots which was written before with-redefs was added to clojure, and when we had the opportunity to green field another project we tried to avoid that again |
| 23:11 | solatis | i can assume so |
| 23:12 | solatis | ok, then i think what i want to do |
| 23:12 | solatis | *i think i know what i want to do |
| 23:12 | solatis | just use the damned message queue |
| 23:12 | solatis | unless it's really impractical not to do so |
| 23:12 | hiredman | mocking is really painful, but sometimes you have to, because you can't test against the actual service for whatever reason |
| 23:13 | solatis | yes that is true, *however* when you use something like amazon AWS, you have a complete API to create nearly all services ad-hoc and on-demand |
| 23:13 | solatis | so that's just what i'm going to do |
| 23:15 | solatis | ok, so, semi-related question |
| 23:15 | clojurebot | I don't understand. |
| 23:15 | solatis | https://clojuredocs.org/clojure.test/deftest |
| 23:16 | solatis | i am using tests, with fixture |
| 23:16 | solatis | the fixture generates something i want to pass around to all tests |
| 23:16 | solatis | in this case, a random id for a message queue |
| 23:16 | solatis | how can i pass this argument to all the tests? |
| 23:17 | solatis | the test function passed to the fixture appears to be a function that does not accept arguments |
| 23:18 | sineer | how do I create a regular expression and assign it to a var by concatenating strings? something like #(str var "[-_]") but that's not what I expected.. |
| 23:19 | hiredman | ,(doc re-pattern) |
| 23:19 | clojurebot | "([s]); Returns an instance of java.util.regex.Pattern, for use, e.g. in re-matcher." |
| 23:20 | sineer | thanks! |
| 23:29 | sineer | any clue how to build a regex with a wildcard - or _ anywhere within a string? I need to match "string" "s-tring" "st-ring" ... |
| 23:48 | solatis | ohhhh i understand what i need to do with fixtures now to pass around arguments! |
| 23:48 | solatis | and the solution is _not_ pretty |