#clojure logs

2015-04-06

01:30guthurcan i use ClojureScript with Clojure to dynamically generate JS?
01:30guthursome examples on the web would be helpful
01:32TEttingerguthur, depends how dynamic you mean. clojurescript is typically compiled to save on the amount of space the standard lib takes up
02:01TEttingerjustin_smith, amalloy, gfredericks, other helpful people who may be awake now: I could use some advice on how to structure something kinda complex. I don't normally ping gfredericks except for silly things, because his skill level is way higher than mine, but this could involve some internals-of-clojure stuff.
02:01TEttingerI'm rewriting a C# game that was getting to use too much immutable stuff to be succinct in C# or any other OOP/imperative-ish lang
02:02TEttingerobviously, clojure is great with immutable stuff
02:03TEttingerbut every time I've tried to write a clojure game before, I end up using clojure for things that should not be immutable, basically graphics stuff and things that are very close to the display code
02:03guthurTEttinger: yeah, i'm not sure if clojurescript is really the solution i want
02:03TEttingerguthur, take a look at Mori, Ki, and the other family of clojurescript-derived stuff to use from JS maybe
02:04guthurI more want a transpiler, something a little like parenscript for CL
02:04TEttingerhttps://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS#clojure-like
02:05guthurTEttinger: cheers
02:05TEttingerhttps://github.com/arohner/scriptjure maybe guthur?
02:05TEttingeryeah that list is amazing
02:07guthuryeah, unfortunately the vast majority seem to not get very frequent updates
02:07guthurmakes me cautious, possible abandonware
02:11arrdemguthur: with respect to what?
03:37TEttingerwell that was fun
03:37TEttingerhttps://www.refheap.com/99272
03:37TEttingerthe 9999th fibonacci number
04:11TEttingerI guess I should ask again in full this time
04:12TEttingerI'm rewriting a C# game that was getting to use too much immutable stuff to be succinct in C# or any other OOP/imperative-ish lang
04:12TEttingerobviously, clojure is great with immutable stuff, but every time I've tried to write a clojure game before, I end up using clojure for things that should not be immutable, basically graphics stuff and things that are very close to the display code
04:13TEttingerI have kinda an odd use case, I think, but it could really be broadly applicable to other problems (not games)
04:16TEttingerI'd like to be able to have an explicitly tracked and versioned chunk of state. I would need to be able to store versions (preferably just as an incremental number) and jump back to earlier ones if the user undoes an action. I also want to be able to create new states without switching the version to the newly created one, that is, a tentative or planning state
04:16TEttingerthe problems are with parts of clojure I really don't understand
04:17TEttingerI would need to create some sort of macro to replace def when defining something as part of that chunk of state
04:18TEttingerI would need the state to somehow understand namespaces, and if something was declared in one it can be treated as part of that namespace but still tied to the version (if the user rolls back to an earlier revision, all namespaces need to roll back)
04:19TEttingerclojure's immutable persistent data structures make this concise, but if a non-persistent data structure somehow gets in there, copying it would be horrendous
04:23amalloyTEttinger: if you want time-travel for the stuff in your namespaces, use maps instead of namespaces
04:23TEttingerone of the "catch" parts of this is that I really still need java interop, and none of the java classes should ever be in the versioned state
04:24TEttingerI'm not sure I understand, amalloy
04:24amalloylike instead of (def a 1) (def b 2) (def a 3) (rollback a version-1) where rollback is some magic we don't totally have
04:25TEttingerlike defining defstate so it modified a global atom to a map?
04:25amalloyyou (def versions (atom {})) (swap! versions assoc 1 {:a 1, :b 2})
04:25amalloyyes
04:25amalloythen you can (swap! versions rollback-to 1)
04:25amalloymanage the states you care about yourself
04:26amalloyit means that instead of just writing a to get the current value of a, you have to manually get a snapshot of the current environment, and then look up its :a key
04:27amalloybut you're looking for fine-grained environment contorl, so you're gonna have to control your environment
04:27TEttingeroh I think there's a slight confusion
04:28TEttinger(rollback a version-1) isn't what I'm after
04:28TEttinger(rollback 1) is pretty much it
04:28TEttingerresetting everything to what it was in version 1
04:28TEttingerI don't need to track every var separately
04:28TEttingerI want to track them all in a blob
04:29amalloyokay, you still need the same structure
04:29amalloya map from version to maps of values
04:29TEttingergotcha
04:31TEttingerso this has some big advantages, like everything being clojure data structures
04:34TEttinger(inc amalloy)
04:34lazybot⇒ 254
04:37oddcullyTEttinger: what library are you using for the graphics, sound, ...? libgdx?
04:38TEttingeroddcully, I've used play-clj before but this time I'm doing a text based game, so squidlib
04:39TEttingerI'm a contributor to squidlib, so it helps that I can use a large codebase made by someone else but also fix things and commit directly if need be :)
04:39oddcullyrogue with undo? that would be great ;)
04:39TEttingerhttps://github.com/SquidPony/SquidLib
04:39TEttingerhehe
05:23guthuris there a way for me to easily convert a Cons to persistentList
05:24guthurI am using backquote to construct a form to pass to clojurescript compiler
05:24guthurbut it complains that it can not compile a Cons
05:25justin_smithguthur: apply list?
05:25justin_smith,((juxt type identity) (apply list `(a b c)))
05:25clojurebot[clojure.lang.PersistentList (sandbox/a sandbox/b sandbox/c)]
05:40guthurok i solved it by doing (apply list `(1 2))
05:40guthurbut i would be interested in any other approach
06:00mnngfltguser=> (apropos "get")
06:00mnngfltg(get-possibly-unbound-var get-pretty-writer get-drunk
06:00TEttingerwhat
06:00mnngfltg... wait. Where did `get-drunk` come from?
06:00TEttingerit's a sign
06:01TEttingeryou need to reach the ballmer peak
06:01TEttinger(actually the basketball team that steve ballmer bought is doing pretty well, I wonder how drunk they are)
06:02mnngfltgheh
06:03TEttinger"take your vitamins, big guy." "this tastes like vodka!" "Oh, uh, no, it's..." "I didn't say I didn't want it."
06:34carkHello, i'm giving a try to datascript and have a question, is this the right place to ask it ?
06:38carkmore specifically : i'm having a :db.cardinality/many relationship for my :card/children attribute, and i wonder if a query fro a child to find its parents would benefit from soe kind of index lookup, or is it only from parent to child ?
06:39carkor more succintly : are many-to-many lookups bi-directionally index based, or should i add a "many" relation fro children to parents as well ?
06:40TEttingerI've never heard of datascript tbh, is it something related to datomic?
06:41carkit's kind of like a datomic lite for the browser
06:41TEttingerthen yeah, stick around, datomic experts may be waking up soon
06:41carki think an answer for datoic would help e as uch
06:41carklooks like my M key is acting up =(
06:42carkthanks, i'll wait up .... this isn't easy software where you can look the source code and quickly understand it
07:04not-much-ioIs there an idiomatic way to mark a function as only being used in one other function as to avoid creating confusion?
07:05not-much-ioBesides letfn which limits testing somewhat
07:06not-much-ioAlso letfn makes the main logic of the function seem much bigger than it really is. IMO
07:07not-much-ioI have not seen it used but I would think that metadata would be good for this, though I don't think it is clojre idiomatic.
07:08raspasovnot-much-io: you can just (let [f (fn [x] x)]) inside that function... if you have to test that local function... well it probably shouldn't be local
07:09TEttinger(inc amalloy) ; it turned out to be really easy to implement what you described, thanks again!
07:09lazybot⇒ 255
07:09raspasovnot-much-io: what I personally like to do to avoid confusion is to put that function right above the one that's using it
07:11not-much-ioraspasov: I want to abstract away the nitty gritty details of the implementation of a function. let and letfn unfortunately clutter up the function IF the functions being used are not trivially small.
07:11not-much-ioraspasov: I do that too. Just wondering if there is anything else I could do. :)
07:12raspasovnot-much-io: yea I'm not aware of anything else :) end the function name with -helper? lol
07:13raspasovnot-much-io: and using IntelliJ + Cursive allows me very nicely to always do "Find usages" on a function to see who's using that function, that helps a lot in many cases to browse foreign code or your own that you've forgotten lol
07:16not-much-ioraspasov: build-connection-structure-which-is-get-connections-helper :D I have also found find-usage very useful.
07:17raspasovnot-much-io: haha
07:19not-much-ioraspasov: Is documenting something like this in the docstring a way to do this. Again I've never seen it done, but I can't really think of a reason not to.
07:20raspasovnot-much-io: I'd assume saying something like "used only in x function" is OK if that's important for your or the project
07:20raspasovfor you*
07:23not-much-ioraspasov: I'll try "Helper function for X". So if future me looks at a file, he can see not to focus on these at first. :) Thanks for discussing.
07:43donbonifacioif I have 2 namspaces with the same function, for examle a/run and b/run, is there an easy way to dynamically call them? Like (let [n dynamic] (n/run)) ?
07:48not-much-iodonbonifacio: I'm not sure if I understand correctly, but you can just reference the other ns and call from there. For example while in a ns: local run -> (run), b ns run -> (b/run)
07:49donbonifacioI want the namespace as an argument
07:49donbonifacio(defn run [namespace] (namespace/run))
07:54not-much-iodonbonifacio: You could give the namespace as a string and add the "/run" to the end and eval that. (defn run [namespace] (eval (str namespace "/run")). Where namespace is either "a" or "b"
07:55not-much-ioso in the end (eval "a/run") or (eval "b/run")
07:55not-much-iodonbonifacio: Although it seems hacky to me, but I could be wrong.
07:57oddcullywhat about resolve?
08:00donbonifacionice, didn't know about resolve
09:01lumrandirHello, is there some templating language like Yesod's Hamlet or Ruby's HAML?
09:03oddcullyyou mean beside that one, that comes first on a websearch?
09:05lumrandirNope, the one where I will not have to type class's and id's over and over again.
09:06lumrandirI would prefer something where I can type .class and #id
09:06arrdemlumrandir: what problem are you trying to solve?
09:06arrdemlumrandir: HTML templating?
09:06lumrandirYep
09:06arrdemhiccup is Clojure's canonical answer to that.
09:07arrdemI highly recommend it.
09:07Empperithat or enlive
09:07Empperidepending on how you want to do your HTML templating
09:07lumrandirThanks, I'll try Hiccup then.
09:08Empperiif you don't mind (or want to) write your HTML as clojure code, then hiccup definetly
09:08Empperiif you want your HTML as HTML then enlive
09:08Empperiout of these two hiccup is more powerful since it's clojure code
09:08Empperibut you might end up in trouble with designers etc
09:09lumrandirWell, I'm lacking a designer anyway. Thanks.
10:11badfish129Is there a way to create a record programmatically, say I have a set (def fields (sorted-set :name :address)), a way to do (defrecord Person fields) ?
10:15sobelyes, but i'm not very good at metaprogramming yet.
10:16sobelbet someone else can answer that easily
10:44wirrbelany advice on using SQL with Clojure?
10:44wirrbelI experimented with Yesql and Postgre, porting some python code to clojure
10:45wirrbelI would like to use a more Java-ish DB now (for easier testing, like H2)
10:45wirrbeland I am a bit reluctant to build upon Yesql
10:45sobelPostgrey is a whitelisting filter for Postfix. Presumably you intended Postgres or PostgreSQL
10:45wirrbelI like the approach to keep SQL queries in SQL
10:45wirrbelPostgreSQL
10:46sobeli think it makes sense to keep the SQL queries in SQL, too.
10:46sobeli use the basic clojure jdbc interface
10:46wirrbelWhat I do not like about Yesql is that the argument sequence is dependent on the usage in the sql query
10:46sobelthat is not good
10:46wirrbelI would like to script the Table creation, etc also in clojure
10:47wirrbelin my python solution I just sourced a .sql file with pg sql
10:47sobelunless you are generating a lot of tables to a pattern, i'd recommend keeping schema scripts in plain SQL you can run without clojure
10:47wirrbelwhich seems a bit harder with clojure jdbc
10:49sobelyou can still use Runtime.exec in clojure, it's not harder than calling out with python
10:49justin_smithalso we have yesql, which turns sql files into functions (with optional parameters if you want them)
10:50sobelgetting sql interfaced to clojure apps is not very hard, but sql and relational databases are non-trivial, and many people make their interaction with them harder by involving tools they thought would protect them from complexity
10:51sobelkeep it simple. write the hard sql when you have to. don't let that pain poke its way into the rest of the app.
10:51ShayanjmDoes using emacs inside iterm2 defeat the purpose of using emacs in general?
10:51wirrbelI really like the idea of yesql, however, it seems sub-standard in the sense that a queries' argument list is dependent of the sequence of placeholders in the .sql file
10:52Shayanjmi.e - do i miss out on anything by using my terminal as the interface rather than X?
10:52the-kennyShayanjm: No, definitely not. But you'll miss some features.
10:52Shayanjmthe-kenny: anything big?
10:52sobelwirrbel: totally agreed. sequence position is a horribly way to match parameters in sql.
10:52justin_smithwirrbel: it supports named args
10:52the-kennyClipboard integration, mouse scrolling, colors might be broken
10:52the-kennysuch stuff, nothing really heavy
10:52Shayanjmgotcha
10:52the-kennyand iterm2 might eat some kind of keyboard shortcuts
10:53the-kennyShayanjm: but if you're on OSX: There's a non-X version of emacs using native Cocoa
10:53ShayanjmOh really?
10:53the-kennyof course
10:53the-kennyare you using homebrew?
10:53Shayanjmyup
10:53Shayanjmbrew install emacs?
10:53the-kennyyeah, plus some flag to enable cocoa
10:54the-kennybrew install --with-cocoa emacs I think was it
10:54Shayanjmsweet
10:54Shayanjmyeah I'm making the jump from sublime to emacs
10:54the-kennyor just emacsformacosx.com
10:54Shayanjmsublimerepl just wasn't cutting it for me
10:55the-kennywhen using the latter you might want to add some symlinks to the binaries inside the appbundle so it works correctly from the terminal. Iirc homebrew does that automatically
10:55the-kenny(for emacsclient, mostly)
10:55sobelSublimeREPL isn't very good. I really wish it were better for both Clojure and psql (PostgreSQL client)
10:55Shayanjmsobel: I know. I had it set up to where i could hotload stuff into the repl via keybindings
10:55Shayanjmbut if i loaded things that were a bit 'big'
10:56Shayanjmthe sublime would get SO slow
10:56sobelI ended up going with LightTable
10:56ShayanjmI tried lighttable before sublime
10:56ShayanjmI just couldn't get into it
10:56Shayanjmfelt too rigid for me
10:56sobelmay still jump one more time to Cursive but i can't afford more tool pain for a week or more
10:57ShayanjmI'm still using sublime for my daily stuff until I feel comfortable enough to switch to emacs completely
10:57sobelit is more rigid than sublime, but its integrated REPL access works *great* and it colors clojure better than Sublime
10:57ShayanjmI work with Python @ day job, but haven't done any research into emacs py support
10:57Shayanjmyeah true that
10:57Shayanjmi did miss lighttable colors
10:57enn`Shayanjm: fwiw I use Emacs inside iterm2 (so that I can pair and/or connect remotely using tmux) and clipboard integration and mouse scrolling are both totally achievable, though neither works out of the box
10:57sobeli don't expect to ditch Sublime for other purposes. it's still a killer editor.
10:58sobelbut it's not a great IDE.
10:58Shayanjmenn` do you feel like you miss out?
10:58justin_smithenn`: you can connect to GUI emacs from a terminal (emacsclient -nw)
10:58Shayanjmso actually that brings up a good question
10:58Shayanjmi've been running emacs via 'emacs' and that's that. I see some people using emacsclient but that connects to an already-running instance of emacs
10:59Shayanjmso how do most people handle their workflows? Do they run emacs on startup and connect to it throughout the day?
10:59Shayanjmor load emacs every time they want to use it?
10:59enn`justin_smith: yeah, I use emacsclient locally, but have never gotten it to work (nor really tried) remotely -- plus it's nice to be able to share shell sessions, etc. too in tmux
11:00sobelwho closes their editor at the end of a day?
11:00Shayanjmsobel: I mean, I close sublime all the time
11:00kryftI use emacs, but I haven't really bothered with cider-repl even though I have it set up :P
11:00justin_smithenn: emacsclient works when I log in via ssh, like I mentioned the -nw flag
11:00sobelShayanjm: weird, i only close it when i have to update my OS :)
11:00justin_smithenn: this will also work for the pairing or tmux uses you cite
11:00Shayanjmsobel: I think I just like keeping my windows tidy, though
11:01kryftMaybe I would find it more useful if I configured it for evil
11:01justin_smithenn: just saying, you can have the best of both worlds, if you want it
11:01ennjustin_smith: ah, I see what you're saying. Yeah, maybe I should try that at some point.
11:02justin_smithenn: I use a reverse tunnel from my vps back to my home machine, and via that I can connect to my home emacs instance from anywhere else I like by logging into my vps
11:02ennShayanjm: I leave one regular emacs running all the time. my $EDITOR is emacsclient so that things like git commit messages get edited in a new buffer in Emacs
11:05Shayanjmhmm enn - so how would you start emacs in the background?
11:05Shayanjmdo you do it manually or do you have it set to do so on start up?
11:06justin_smithShayanjm: you can start a server from emacs (either via elisp or with the -server flag) and that makes it accept client connections
11:06the-kennythen you can 'connect' via emacsclient
11:06justin_smithShayanjm: with a terminal, emacsclient opens in your own window
11:07Shayanjminteresting
11:07justin_smithwith the gui, it opens a new frame, or pops up in the app instance (this is configurable)
11:07the-kennyand emacsclient -nw will give you an emacs in the terminal
11:07justin_smithright
11:09sobelShayanjm: i use OSX multiple desktops. it's always tidy. ;)
11:10sobelreally, i just like leaving my station ready for work, because i dislike a setup burden when i'm starting my day
11:17canweriotnowSo is anyone using kibit? It doesn't seem to be very actively maintained.
11:18sobela paradigmatic conception of intelligence?
11:18justin_smithcanweriotnow: frankly, I just think its authors haven't changed their opinion of how to write clojure code, so they haven't needed updates
11:19sobelcanweriotnow: yeah, don't confuse "still working" with "not maintained"
11:20canweriotnowjustin_smith: It's not just that, it's stuff like the 20 open issues for things like ns-aliased keywords (which places it outside the set of "still working") and wishlist things like cljx support don't seem to be moving at all...
11:20sobelwhen i read the source to data.csv (same reason -- i was concerned it had not seen any commits for a long time) i realized it was tiny, correct, and short of a demonstrated bug, had no reason to change
11:20canweriotnowI know, I know, "where's your PR?"
11:21sobelwell, feature incompleteness is a different concern. for smaller libs that's less of an issue.
11:21justin_smithcanweriotnow: my recollection of PRs on kibit is they mostly reflect differences of opinion, on which the maintainer is not going to budge
11:22canweriotnowIn the case of ns-aliased keywords, it's a difference of opinion with Clojure... and it looks like cemerick committed a possible fix that isn't... just wondering about the status.
11:22justin_smithcanweriotnow: fair enough, there are some actual issues there
11:22sobeldamn. i have been reading "kitbit" this whole time.
11:22sobelkitbit looks neat.
11:22canweriotnowsobel: what is?
11:23canweriotnowsobel: googled. whoa.
11:23sobelhttp://kitbit.com/
11:23canweriotnowyeah, looking now.
11:23sobelsorry to squirrel but that is darn nifty.
11:25canweriotnowYeah, nerding out on this. Making me forget all about my static analysis woes, replacing them with AI-lust WHOA's
11:29canweriotnowAs far as kibit goes... I guess it's time to fork and hack if I want to keep using it. Or I can try to not use ns-aliased kw's... I don't even like them personally, but The Creator says they are good (hilarity ensues: http://clojure-log.n01se.net/date/2009-04-30.html#08:11 )
11:38justin_smithsomeone discovered that with-out-str (and by extension pr-str) is succeptible to a race condition. I have read that code and it totally should have occurred to me that it would behave that way too http://stackoverflow.com/questions/29469580/pr-str-also-prints-out-trace-messages/29474418#29474418
11:43gfredericksI've seen that happen I think
11:44gfredericksthat's not a with-out-str problem, right? just a pr-str problem?
11:46justin_smithgfredericks: pr-str is just a with-out-str call
11:46justin_smithso it's definitely a with-out-str problem
11:47justin_smithAHA
11:47justin_smithno
11:47justin_smithI was wrong - the problem could only happen if they were generating the log output inside the with-out-str block
11:47justin_smithso there is no race there
11:49noncomdid anyone receive a timeout on mvn deploy to clojars?
11:49noncomit times out on uploading the pom (the jar is uploaded fine)
11:50gfredericksjustin_smith: and if the printing code were rejiggered so as to accept a printwriter directly, rather than using with-out-str, everything would be great
11:50justin_smithfair enough!
11:50tcrawleynoncom: multiple times, or just once?
11:50noncomi tried several times
11:50noncomi had increased the timeout in settings.xml
11:50noncombut to no avail
11:51tcrawleywhat is the artifact?
11:51justin_smithnoncom: well, clojars also won't accept duplicate uploads
11:51tcrawleyunless it is a snapshot, and the rejection for a duplicate shouldn't be a timeout
11:51noncomartifact ddf.minim:minim:jar:2.2.1-b8afdc1
11:52noncomi guess that i better say SNAPSHOT while i'm still learning maven
11:56danlentzClojars down?
11:56tcrawleynoncom: looks like it uploaded a SNAPSHOT successfully?
11:56tcrawleydanlentz: it's up for me
11:57noncomtcrawley: strange, but: https://www.refheap.com/99279
11:57danlentzMaybe it's a network issue then
11:58noncomdanlentz: you ohave the 8001 port specified in your http adress?
11:58noncomtcrawley: the artifact is there, but maven said "failure"
11:58danlentzNo, I can't even get to clojars.org
11:59danlentzTraceroute
11:59danlentzOr website
12:00noncomtcrawley: also, on the page: Oops. We hit an error opening the metadata POM file for this project so some details are not available.
12:01danlentzOk, I just checked and I can't reach either one over LTE or hard wired cable internet
12:09danlentzSo, can others also confirm they are able to reach http://clojars.org
12:11oddcullydanlentz: curl gets a 301; looks okish
12:11danlentzYes, it's back.
12:11danlentzI guess that was just some network glitch upstream from me?
12:12tcrawleynoncom: are you going through a proxy that may be blocking? In the clojars access log, I can see the PUTs for some of the artifacts, but no attempt to upload the maven-metadata.xml for the SNAPSHOT itself
12:12tcrawleydanlentz: maybe so, it's been available to me this entire time
12:29pandeirohas clojure.java.jdbc never been able to infer java.util.Date ?
12:32gfredericksyou mean convert it to java.sql.Timestamp or something?
12:32gfrederickswhen writing?
12:32gfredericksI don't think it ever has, but there are protocols you can extend if you want it to do that
12:55sm0kei dont think that is true
12:55sm0kejdbc spec maps DATE to java.sql.Date
12:56sm0keand TIME to java.sql.Time
13:11pandeirogfredericks: sm0ke: thanks yeah i understand why it couldn't just do that conversion for me; doing it explicitly works fine
13:11pandeironow i need to do org.joda.money.Money -> postgres money type
13:14reiddraperdnolen: now we just need to convince you to help us port this to cljs: https://github.com/clojure/test.check/commit/83f65420f192c23cf3b757a4aa422063b0f43863
13:15reiddrapergfredericks: can correct, but i think the biggest outstanding question is how to deal with numerics in cljs
13:16justin_smithreiddraper: I feel like there's a super unhelpful snarky answer to that question
13:16dnolenreiddraper: haha, doesn't look so hard, it just requires longs right?
13:17reiddraperdnolen: yeah, and some bit manipulation
13:17dnolenreiddraper: goog.math.Long delivers
13:17dnolenit works great and it reasonably performant
13:17dnolens/it/is
13:17reiddraperdnolen: excellent!
13:52noncomtcrawley: nope, no proxy.. but maybe i will try at home once again
13:57noncom$seen tcrawley
13:57lazybottcrawley was last seen talking on #clojure 1 hour and 45 minutes ago.
14:04csd_I have a high-level core.async question. I'm working with the following function https://www.refheap.com/99283, which accepts a single socket connection and which I want to expand to support multiple connections. I'm wondering how I should handle having a connection limit. I'm guessing I'd use a loop + parking, but I'm not sure what it should look like exactly
14:13justin_smithcsd_: for a limited number of connections, why not N go loops all reading on the same "make a connection" channel?
14:13justin_smithyou can use a dotimes to launch all the connection-making go blocks
14:14csd_justin_smith: but what about after one of the N connections disconnect? would that way allow the loop to resume accepting connections?
14:15justin_smithcsd_: the way I imagined the loop was to accept a connection, do its thing, and then loop back to accept a new connection - thus you have exactly as many connections potentially active as you start go blocks accepting the connections
14:16justin_smiththis is in the super abstract of course, not knowing all the details of what you are doing
14:17csd_so something like if current-connections < max-connections then recur? with no else clause
14:17justin_smithcsd_: not really - each go-loop is one potential connection
14:17justin_smithso you have a channel with connections coming in, and then N potential blocks handling the connection
14:17justin_smithif they are all busy, the ones in line wait or fail
14:18the-kennyyou span N go loops. Each waits for a client, then starts an inner loop handling the connection. if the client disconnects, it goes into the outer loop and waits for another client
14:18justin_smithexactly
14:18the-kennyNew clients can be distributed from one single channel that will block (or drop?) if no go loop is free
14:18justin_smithand it's all coming in on one channel, that is read by all of those loops
14:18justin_smithright
14:19csd_so would the channel buffer then represent the limit N?
14:19the-kenny(go-loop [] (<! (handle-client! (<! new-client-ch))) (recur)) basically :)
14:19the-kennycsd_: no, the count of go-loops is N.
14:20csd_i don't understand where the code is limiting the number of connections
14:21justin_smithcsd_: the-kenny's go-loop call above would be inside a dotimes
14:21justin_smithyou only have so many blocks accepting a connection
14:21justin_smithotherwise you block or drop
14:21justin_smithdepending on how you defined your channel
14:21csd_but the dotimes won't reflect after a connection drops
14:21the-kennyjustin_smith: sorry, haven't looked at the code yet
14:22justin_smithcsd_: no, the dotimes decides how many listeners you have
14:22justin_smithit exits, and after that you have N go-loops running
14:22justin_smithif there is no listener ready, you don't get served
14:22csd_oh
14:22csd_so have a queue of listeners
14:22justin_smithkind of
14:23justin_smithN listeners all accepting tasks on the same queue, each task guaranteed to be read by at most one listener
14:24jcromartieIs core.cache appropriate for caching Ring responses?
14:25jcromartieI am having a hard time figuring out how to do it without possibl race conditions
14:25csd_justin_smith: this sounds like a good use for alt?
14:25justin_smithcsd_: why alt?
14:25csd_alt would dispatch to the first available listiner
14:25justin_smitheach loop has exactly one input: the channel that gives you tasks
14:25justin_smithno
14:25justin_smithyour inverting it
14:25mgaareother way around, alt reads from the first channel that has something on it
14:26justin_smithcsd_: if you have 20 go-loops, all reading the same channel, exactly one of them gets each message
14:26justin_smithcsd_: this does exactly what you want, and is super simple
14:26justin_smithno need for alt or anything else, just let them all read
14:27justin_smithcsd_: because if the message sender is deciding who to send the message to, suddenly you need to keep track of who is busy
14:27justin_smithand who is ready
14:27justin_smithetc.
14:27justin_smithmuch easier to have the task doers listen if available
14:27justin_smithand send to a single channel they all read
14:27csd_so how does the connection handler hand the new connect off to a listener? how does it select an arbitrary go loop?
14:28justin_smithcsd_: it doesn't select, core.async selects, because that is what core.async is designed to do when multiple reads are going on for one channel
14:28justin_smithif more than one reader is ready, core.async picks one
14:29csd_i see
14:29csd_this is confusing
14:29justin_smithcsd_: core.async is simple but only if you learn "its way"
14:30csd_how would i put that relationship into a hashmap?
14:30justin_smithI don't understand that question
14:30csd_say i have a map reflecting the attributes of a given connection. obviously one would need to be the means of communicating with the go-loop
14:30csd_for message passing purposes
14:31justin_smithcsd_: so you're saying you have a central coordinator that needs a handle to the specific go loop handling that request? why? that violates some abstractions I think.
14:32csd_basically, i want N client threads and 1 or some fixed number of server threads which processes the actions of the client threads
14:32justin_smithsure
14:33csd_does that violate abstractions?
14:33justin_smiththe individual server go block should be able to do its thing just based on the handle you pass to it
14:33justin_smithcsd_: central coordination of that would, but if you let each loop take care of itself, then no, and you don't need a hash map for that
14:33justin_smithcore.async already handles per loop state as needed
14:34csd_by handle are you referring to socket handle or the go-loop
14:34justin_smithcsd_: it sounds like your mental model has tasks in it which core.async does implicitly, but you want to describe explicitly
14:34csd_you are probably right
14:34csd_this is my first time working with it in a larger project
14:35justin_smithif you are passing tasks (including the resource (eg. client socket handle)) to a go loop, you should not need to control that go loop from the outside any more, it should be autonomous, except for the dispatch that core.async does for you implicitly
14:36csd_right
14:36justin_smithany control you want to exert should be flipped and be expressed as a read or alt of some sort inside that loop (where it checks for an override / reconfig / etc.)
14:36csd_im not sure where i suggested i want to control it from the inside
14:36justin_smithoutside
14:36csd_right
14:36justin_smithwhen you said you wanted to put the handlers in a hash map
14:36csd_i'm more wondering, how do i get a handle such that i can pass messages to it from outside
14:37justin_smithyou can pass that handle into each loop as it is created
14:37csd_oh
14:37csd_that would just be a new (chan)?
14:37justin_smithsuch that they all share a single "get a request" chan, and then each has its own chan
14:37justin_smithyeah
14:37csd_i see
14:37csd_what did you think i was trying to do?
14:38justin_smithsome sort of central logic to control the go loops
14:38csd_ohh
14:38csd_no i realize that they're supposed to be autonomous
14:38justin_smithcool, glad we sorted that out
14:38csd_yes thank you
14:38csd_so after i spin up the app, i'd basically have N listeners going automatically
14:39justin_smithright
14:39csd_and then each listener thinks ok if im not processing a connection, im reading from this one channel everyone else is reading from for a new connect
14:39justin_smithright
14:39csd_ok awesome this makes so much more sense now
14:40csd_one other thing tangentially related
14:40justin_smithit's kind of like delivery drivers at dominos, they wait in line until a pizza is ready to go out, rather than the boss assigning a driver to each pizza
14:40csd_can i actually use go-loops if i'm working with sockets? i thought those required unique threads per connection
14:40justin_smithcsd_: nothing about a socket requires a thread per connection actually
14:41csd_i thought socket listening was blocking?
14:41justin_smithcsd_: see aleph and http-kit
14:41justin_smithsure, you need to use the right async-friendly lib
14:41csd_oh
14:41csd_im using the java io right now
14:41jlongsterhow do you all install something like core.async in your lein projects? do you literally go to https://github.com/clojure/core.async/ and copy the lein dep info (w/version)?
14:41justin_smithyeah, regular sockets will stay on one thread, but aleph matches your design very nicely
14:42csd_cool i'll check it out
14:42justin_smithjlongster: you use its dep vector in your project.clj
14:42csd_do you know why i might have been told that sockets can't support go-loops?
14:42csd_the person who told me is pretty knowledgable about clojure
14:42justin_smithjlongster: it's less about "installing the dep" and more about "setting up your classpath to see that dep"; lein will make sure anything you are using is downloaded if it hasn't been already
14:43justin_smithcsd_: they probably meant vanilla java sockets, like I said see aleph
14:43csd_ok
14:43csd_thanks again
14:43jlongsterjustin_smith: is there a quicker way to do it via CLI though? the search command didn't seem to make it clear which version to use
14:43jlongsterI'm coming from npm where you can just do `npm install core.async`
14:43justin_smithjlongster: I use clojars or the github page
14:43justin_smithjlongster: yeah, we always have explicit versions - I know it seems weird but it saves huge amounts of hassle
14:44jlongsterjustin_smith: ok, thanks
14:44justin_smithit turns out to be much saner, I think anyone here will agree
14:44justin_smithjlongster: there is a plugin "lein ancient" you can use if you want to check for newer versions of your deps
14:44jlongsterI mean, I like explicit versions (I use --save-exact which pins down the version) but it would be nice if it just automatically figured out the latest stable version when I want to install it
14:45jlongsterjustin_smith: thanks
14:45justin_smithjlongster: lein-ancient has an option to upgrade your versions automaticly or interactively https://github.com/xsc/lein-ancient#upgrade-artifacts
14:46jlongsterjustin_smith: cool, thanks
14:48tcrawleyjlongster: you can do [org.clojure/core.async "LATEST"] to get the latest release
14:48tcrawleyI don't recommend that though
14:48justin_smithtcrawley: I'm both surprised to see that option and unsurprised it isn't more widely talked of
14:48justin_smithhaha
14:49jlongstertcrawley: yeah, thanks but I was hoping just for "lein install core.async" and `[org.clojure/core.async "0.1.346.0-17112a-alpha"]` would appear in my project file
14:49justin_smithfyi "lein install" is for putting your project in the deps cache
14:49tcrawleyjustin_smith: it's an easter egg, but one that you find 6 months after easter
14:49justin_smithhaha
14:49justin_smithall rotten
14:53jlongsterjustin_smith: I think I'd be happy if `lein search` sorted by version descending
14:54justin_smithjlongster: definitely a fair request. Another nice possibility would be optional args to lein new specifying libs that should each pull in the newest non-snapshot release.
14:55jlongsteryeah
14:55justin_smitheg. lein new compojure org.mine/blog-app org.clojure/core.async prismatic/schema org.clojure/java.jdbc
14:55justin_smithand that would insert deps for all those requested libs
14:55amalloyjustin_smith: LATEST is discouraged because it will update to snapshots too, iirc, or at least alphas, when you least expect it
14:55justin_smiththat would be cool
14:56amalloyso a built that used to work stops working, without any change from you
14:56justin_smithamalloy: yeah, I wouldn't have used it anyway, but good to know :)
14:56justin_smiththanks for making the reason explicit
15:17amalloyabout once a year i look back at https://github.com/amalloy/enum/blob/master/src/enum/core.clj and ask myself just what kind of monster i really was five years ago
15:20amalloyhuh, accidentally discovered a github feature while linking that. there's a link you can only discover by tabbing (it doesn't normally render) on every code-listing page. like if you visit that link and hit tab+enter, it skips over the navbar/header to the main content
15:25justin_smithinteresting
15:45jlongsterdnolen: is this section still right? https://github.com/clojure/clojurescript/wiki/Quick-Start#less-boilerplate
15:45jlongsterI use lein-cljsbuild with just `:output-to` and it seems to generate a single runnable .js file without needing to add ":main"
15:46dnolenjlongster: cljsbuild sadly supplies many outdated defaults
15:46dnolenjlongster: it's really a mess now
15:46jlongsteroh boy
15:46jlongsterwhere are the defaults it supplies?
15:46jlongsterat least it works by default
15:46dnolenjlongster: it defaults to :simple :optimizations which negates most of the benefits of incremental compilation
15:47dnolenjlongster: in general the Quick Start is the source of truth, any other information you will encounter is inferior
15:48jlongsterdnolen: sure, I read through that but I also want to use lein. quick start doesn't go into optimizations either, why does that kill incr compiling?
15:48jlongsterI would think :advanced would do that more
15:49dnolenjlongster: incremental compilation mean recompilation in tens or hundreds of milliseconds
15:49dnolenjlongster: :simple applies several non-trivial passes
15:49dnolenacross everything in your build
15:50jlongsterdnolen: got it. like pretty-printing?
15:50dnolenjlongster: no :simple is pretty fancy, lambda lifting, constant folding, var renaming all happen under simple
15:51dnoleneven basic inlining
15:51jlongsterdnolen: so what should I use? those don't happen under :advanced?
15:51dnolenjlongster: advanced does even more stuff, and dead code elimination is very intensive
15:51jlongsteryeah, that's quite awesome
15:51jlongsterso :none ?
15:52dnolenyes development is nearly always done with :none, it also provides the most accurate source map
15:52dnolen:simple & :advanced require source map merging, it works but is lossy
15:52jlongsterthat makes perfect sense
15:52jlongsterthanks
15:52jlongsterstill, about boilerplate, cljsbuild must pass :main or something?
15:53jlongsterit works now, I can look into details later
15:53dnolenjlongster: cljsbuild simply forwards :compiler, where it goes wrong is in supplying defaults as these do not align with ClojureScript's default anymore
15:53dnolendefaults
15:54jlongsterright, I'm wondering why I can just include the .js without needing to specify :main. according to quick start I need to include goog.base.js etc
15:54jlongsterbut it works without it
15:55jlongsterdnolen: ooh with :optimizations :none I do see the `goog is not defined` error
15:55jlongster:advanced probably inlined all that, etc
15:55jlongsterthanks
15:55dnolenjlongster: and :simple inlines it too
15:56dnolenjlongster: there's an outstanding ticket to always support :main, but haven't gotten around to it yet
15:56jlongstergotcha
15:56dnolenyou definitely need it under :none to avoid writing extra markup
15:56dnolenit doesn't mean anything to :advanced or :simple so you can still supply it if you like
15:57jlongsterright
15:58dnolenjlongster: also there's a #clojurescript channel ;), pretty active these days and good place for ClojureScript specific questions :)
15:58jlongsterdnolen: oh, didn't know that, thanks!
16:27chouserDo I guess Clojure 1.7-alpha6 isn't doing .cljc files yet?
16:27chousers/Do/So/
16:33tbaldridgechouser: it's part of the changelog
16:35chouserFileNotFoundException Could not locate foo/bar__init.class or foo/bar.clj on classpath.
16:35chouserdoesn't look like 'require' is attempting to load from anything other than *.clj
16:36chouserI guess I should read the code. Perhaps it's just the error message that's out of date.
16:41Shayanjmspent the better half of today getting familiarized with emacs
16:42Shayanjmit's pretty sweet
16:43chouseroh, I'm an idiot. Wrong namespace name. Thanks for the reality-check, tbaldridge.
16:45bridgethillyerI’ll vouch for you, chouser. You’re not an idiot.
16:50chouseraw, thanks. Maybe we can compromise on "I make stupid mistakes"?
16:51sobelShayanjm: it's aged well
16:52Shayanjmsobel: key bind all the things
16:54bridgethillyerchouser: Me too!
17:00ShayanjmIf I have a vector of things, and I'd like to analyze that entire vector in 'chunks' (i.e: subvectors of n elements), what's the best way of expressing that?
17:01Shayanjmi.e: I'd like to be able to take 15 elements at a time from a vector and do things with it until every element in the parent vector has been used
17:01xemdetiaShayanjm, I am not really sure but take and drop might be what you need
17:01amalloypartition
17:02Shayanjmooh looked up partition, thanks amalloy
17:10danlentzI don't know if anyone uses google+, but I put together a "Lisp Jobs" community and all are welcome -- the content seems to be almost entirely clojure/clojurescript (surprse)
17:10danlentzhttps://plus.google.com/communities/114701006686888945987
17:11mavbozodanlentz, awesome
17:13danlentzI will be trying to make an effort to update it more frequently -- there was a bit of a lull in postings while I was finding a new gig myself :)
17:14sobelnice, i hope to remember to join that when i get home
17:14bjaeek, yesql apparently doesn't understand variables in plpgsql that need to be DECLAREd with :=
17:15sobelwhy would yesql need to know about vars in pl/pgsql?
17:15bjabecause it thinks := is a named param
17:15sobelwhy is yesql looking inside a pl/pgsql proc, and how?!
17:15justin_smithoh yeah it would do that, that's too bad :(
17:16justin_smithsobel: yesql loads sql files and makes them into functions
17:16justin_smithsobel: but it interprets keywords to be named params
17:16sobeloh right, now i remember which one yesql is
17:16sobelthat made me cringe earlier, and it makes me cringe now
17:16sobeli knew that wouldn't work
17:16justin_smithsobel: sql is a good dsl for sql
17:16sobeland how
17:17sobeleventually, i'll just assign yesql the value of DUDE
17:17justin_smithbja: try using a unicode escape for : maybe?
17:17sobeland when i read yesql, i'll remember not to respond :)
17:17sobelkeep your sql in a file psql can read
17:17sobeldon't plan for anything except postgresql to parse it
17:18sobelsrsly. it's a complex syntax. you'll poke your eye out.
17:18bjajustin_smith, I think I'm just going to put DDL into a separate .psql file that I can slurp up
17:18justin_smithyeah, that sounds sane
17:18sobelyou could slurp it, but psql adds value
17:18bjaI was being lazy when I was keeping my ddl creation and querying in the same place
17:18justin_smithif you don't need to paramaterize on the clojure side especially
17:19mavbozosobel, so, where do you put your sqls in clojure projects?
17:19sobelmavbozo: db/
17:19mavbozosobel, in .clj files or .sql files?
17:19sobelit's sql. i put it in sql files.
17:19sobelas we've been discussing here, clojure is a poor representation for sql
17:20sobelor maybe it's that translating between is error-prone
17:20sobelanywho, i strongly recommend keeping DDL in plain text so it can be "executed" with psql
17:21sobelelse you end up with a predictable hassle of leaky abstractions between DSLs
17:21bjayesql also cannot handle using CTE to create a query-specific tmp table (an alternative to ```WHERE (foo = "a" AND bar = "b") OR (foo = "c" AND bar = "b") OR ....````)
17:22mavbozosobel, you put 1 sql statement per 1 .sql file? or you put many sql statements in 1 .sql file?
17:22bjai.e. WITH tmp(a,b) AS VALUES (1,2) (3, 4) SELECT ....
17:24bjaunless I missed a solution other than altering how jdbc deals with PersistentVectors (which is a no-go due to me overriding that differently for other reasons)
17:24bjaalthough I can build that use case up with honeysql easy enough
17:26ShayanjmWhat's the best way to 'wait' before executing the next iteration of a loop?
17:27justin_smithShayanjm: (Thread/sleep N)
17:27Shayanjmpreferably for long periods of time - in this case I have to wait ~15 minutes before each execution
17:27justin_smithwhere N is in ms
17:27Shayanjmjustin_smith: is that reliable?
17:27ShayanjmI read somewhere that JVM timeouts/sleeps are unreliable but the post didn't explain that further
17:27justin_smithShayanjm: depends how precise you need it to be, you can bind a timestamp and check elapsed time when it resumes
17:27ShayanjmAnything over 15 minutes is great
17:27justin_smithand sleep again if you need to wait longer etc.
17:28Shayanjmyeah
17:28Shayanjmi'll try it out thanks
17:28sobelmavbozo: it varies. rarely 1 statement in a file by itself, though. i tend to make rational separations between create-all-the-objects scripts, data dumps, and "patches" that generally assume and build on the main (large) schema create script
17:29sobelmavbozo: but after a project launches and you have data in play, you don't ever get to run that all-create script except in dev, so modifications have to be written as changes against it
17:29Shayanjmjustin_smith: follow up - if I'm using something like pmap in the function body that I would like to sleep
17:29Shayanjmhow do I wait for pmap to finish before executing the sleep?
17:29bjaShayanjm: I liked using core.async to do that. (let [t (async/timeout timeout-ms)] (do-stuff) (<!! t))
17:29sobeldoes sleep park?
17:30Shayanjmbja: I saw async but I didn't want to introduce another component just to do something relatively small to the bigger implementation
17:30justin_smithsobel: in the core.async sense? no, you would wait for a timeout chan in that context
17:31sobeljustin_smith: aho k
17:31justin_smithShayanjm: in order to wait for pmap to complete, do something that requires realizing the full results
17:31justin_smithShayanjm: it's "semi-lazy" as the docs describe
17:31Shayanjmjustin_smith: something like wrapping the pmap in a doall?
17:32justin_smithShayanjm: I think that should suffice, yeah. Or any other operation that would require every element to be realized.
17:32Shayanjmk sweet
17:32Shayanjmthanks
17:36chouserok, so what about clojurescript support for .cljc files?
17:39mavbozosobel, so you put statements that routinely executed like "SELECT * FROM `member` WHERE..." in a file. How do you organize that many statements in a file? I mean, to execute a certain query, you must retrieve it a from the file or some cache.
17:42sobelmavbozo: oh, if it's a SQL query needed at run-time, i put that directly in the code as a string
17:43sobelat that point the query is a parameter the application needs to get data at run-time. it's not generally something i intend to modify except during development.
17:43sobeli hard code those
17:45mavbozosobel, for a while there i thought you went extreme and put all those sql statements in a file
17:45mavbozosobel, :)
17:45sobelmavbozo: that's crazy talk
17:45oddcullycrazy talk would be: put them in a db table
17:45sobeloddcully: you say that, but...
17:46sobelthat's every ERP
17:47sobel(it would still need a 'core' with a decent DAO/DAL that has some a-priori knowledge of the schema
17:47sobel)
17:47mavbozosobel, i stil think it might be easier to scan what runtime sqls needs to change if schema changes
17:47oddcullybut where do you put the query to load your queries... /me listens now to the sound of trees
17:47sobeloddcully: some a-priori knowledge of the schema is required
17:48sobelmavbozo: i'm not sure what you mean by scan
17:49sobeli don't know why you'd separate sql from code that depends on it. i haven't seen a useful case of it.
17:50mavbozosobel, so far, when schema changes, for example, i use text editor's search to see what column to add or delete
17:50mavbozoeasier to do when all those statements are in .sql files and under a parent directory such as '/db'
17:55sobelthat is not enough information. as i mentioned, your freedom changes after live data goes into the schema. you can't re-roll it from scratch, you have to patch against it.
17:55sobelif you add or drop a column, it's a subsequent script to make that change against the 1st schema script
17:56sobelthis is generally the issue addressed by "migration" systems
17:56sobel(and poorly at that)
17:59mavbozoi haven't found any sql "migration" systems that handles migration for sqls that are needed at runtime.
18:00sobelyeah, that's because modifying your queries is not defined by migrations. that's part of your application interface, not the database.
18:02sobelusually the reason to upgrade a schema is because the application needs to grow, too. i think it sounds like you're a little concerned about changes to the database coming out of left-field, and you're left trying to figure out how to adjust queries in the code?
18:02arrdemso is someone crawling Grimoire with wget?
18:04arrdembecause I got pinged by wget 4.5k times in the last 12hrs, never seen a wget view before.
18:05mavbozosobel, yeah, i am forced to use search or grep because those sql statements are everywhere
18:06sobelmavbozo: sql should be isolated to a library
18:06sobelmavbozo: you should not have to crawl your whole source tree to find affected queries. that sounds like a poor source code decision.
18:07sobelarrdem: that sounds amateurish. it's a pretty brutal site mirror tool.
18:08justin_smitharrdem: sounds like time for some nginx rules
18:08arrdemjustin_smith: quite possibly
18:09sobelraise the bar. require use of that user-agent flag.
18:09sobel(sorry, not helping...)
18:09arrdemhehe
18:09justin_smitharrdem: by default if you have rel="nofollow" on an href, wget won't traverse it
18:09justin_smitharrdem: if it's just someone being naive, that will at least limit the damage
18:09justin_smithit's an easy change if you are generating the links
18:10sobelwow, i did not know wget honored any link attrs
18:10arrdemsobel: it will by default but you can turn all that off
18:10justin_smithright, it only helps if the guy is naive, not if they are a jerk :)
18:12arrdemyeah looks like at 3:30pm someone pegged the server
18:13mavbozosobel, most of legacy code bases that i work on are like that. And also usage of both ORM and plain sql statements.
18:14sobelmavbozo: that is unsurprising.
18:16sobelg'night, gents. see you tomorrow.
18:16mavbozosobel, thanks for the discussion
18:21mavbozoarrdem justin_smith i remember the old days in campus when i schedule a cron job to wget sites i like because outside campus, internet is expensive
18:21arrdemyou poor devil
18:22justin_smithhaha
18:22mavbozoarrdem, it's possible there's someone from a 3rd world country who wants to learn clojure
18:24mavbozoarrdem, can you trace the country where those wget comes from?
18:24arrdemmavbozo: no I don't log source IPs
18:24arrdemone of the many reasons I need to build a Ring logging middleware lib
18:27arrdemother open avenues of work are non-en_US localization and a caching API layer because yes the intertubez go out
18:47lewixHi guys
18:57arrdemon examining the logs looks like I owe our wget friend some beer, he found a bunch of bad links :P
19:01hyPiRionarrdem: why do you wonder why I write Swearjure on contract btw? Need something?
19:02arrdemhyPiRion: I just did new business card designs this afternoon and was toying with the idea of having a highlighted swearjure program as the logical back of the card.
19:02arrdemhyPiRion: opted instead for the SR-71 pictures I used for Oxcart/Ox-lang
19:02hyPiRionarrdem: Oh. Well, there are some over at https://github.com/hyPiRion/swearjure/tree/master/examples
19:03hyPiRionNot sure if they are too short or too long
21:38deadghostwhat's the simplest solution to not blocking on sending email?
21:38justin_smithdeadghost: put it in a future
21:38deadghostcore.async? queues?
21:39TEttingeryah, futures are great
21:39TEttinger(inc justin_smith)
21:39lazybot⇒ 233
21:39deadghostI shall take a look
21:39justin_smithhow many emails, and how often? if you want to put out a steady stream, maybe a queue, if it's just a few, or only occasionally, just use a future
21:39deadghostit's not a feature I've really used
21:39deadghostyeah just a few
21:40justin_smithyeah, no need to set up a big async machine for that, that's a natural fit for a future
21:43vas(hello)
21:44irctcclojure
22:01Niacuser=> (BatchJob/main (char-array [])) ClassCastException [C cannot be cast to [Ljava.lang.String -init6948500342059468836.clj:1) user=> (BatchJob/runBatchJob 123)
22:02Niacpublic static void main (String[] args) {.....}
22:03Niacit seems the params are wrong.
22:06Niacem,is it defferent from char and string???
22:06lazybotNiac: Yes, 100% for sure.
22:07Niaclazybot: is it defferent between char and string?
22:26nuwanda_Niac: ??
22:26lazybotnuwanda_: Uh, no. Why would you even ask?
22:26nuwanda_??
22:26lazybotnuwanda_: What are you, crazy? Of course not!
22:26clojurebot? is !
22:37lewix(> Clojure (rest Languages)) what does it return?
22:38lewix(> Clojure (rest 'Languages))
22:38lewixany guess?
22:38lewixjustin_smith: * :)
22:45gfredericksNiac: you want #(into-array String ["foo" "bar"])
22:45gfredericks&(into-array String ["foo" "bar"])
22:45lazybot⇒ #<String[] [Ljava.lang.String;@2f94db83>
22:45gfrederickssorry that's it
22:45Niacyes ,it work
22:47Niaci used to write php ,there is no defference between char and string.text use string as always.
22:47gfrederickschars are what strings are made of
22:48gfredericks,[(type "foo") (type (first "foo"))]
22:48clojurebot[java.lang.String java.lang.Character]
22:48lewixis there a better way to do this:
22:48lewix(> 22 (apply + (remove #(= % 3) '(3 2 8))))
22:49lewix, (> 22 (apply + (remove #(= % 3) '(3 2 8))))
22:49clojurebottrue
22:49Frozenlock,(remove #{3} '(3 2 8))
22:49clojurebot(2 8)
22:53lewixFrozenlock: is it syntactig sugar?
22:53Frozenlock#{} is a set
22:54Frozenlock,(#{3} 3)
22:54clojurebot3
22:54lewixoh
22:54lewixa set is also a function?
22:54lewixdaymn
22:54FrozenlockJust like the map {} :-)
22:55Frozenlock,({:a 1} :a)
22:55clojurebot1
22:55lewixi knew about map
22:55lewixomg thats amazing
22:55lewixDo you guys use lowercase , snakecase or camel
22:59Frozenlockeh... I guess it's lisp-case
23:00Frozenlockwhatever-the-name-is-for-this
23:11lewixFrozenlock: thank
23:11lewixis it a better way to do this (let [ All-languages {:Clojure 0 :C++ 3 :java 5}](> (:Clojure All-languages) (apply + (vals (dissoc All-languages :Clojure)))))
23:11lewix(I'm practicing )
23:12Frozenlocklewix: first lesson: use refheap.com for multi-line functions :-p
23:13FrozenlockThere's even refheap.el if you are using emacs. Quite handy.
23:14Frozenlocklewix: What are you trying to do with the function?
23:17lewixFrozenlock: is there refheap for vim
23:17lewixFrozenlock: basically trying to add up all the values and compare it to the value of clojure
23:17FrozenlockI don't know the vim ecosystem, sorry.
23:18lewixFrozenlock: https://www.refheap.com/99305
23:18ncthom91hi all! I'm doing a small project to learn about clojure's concurrency, but I also want to use nashorn for some javascript execution. If I'm using the Executors framework for concurrency, but have only defined one Nashorn engine in the relevant scope, will each thread try to share that one nashorn engine?
23:21lewixFrozenlock: did i make any mistake? seems fine right?
23:22FrozenlockIt does. I might add a threading macro somewhere to make it a little clear, but that's just me splitting hair :-p
23:23ncthom91Here's an example: http://pastebin.com/0jQ6rZy5
23:23Frozenlocklewix: https://www.refheap.com/99306
23:24lewixFrozenlock: can you explain the macro >>
23:24lewixdoes it make it readable from left to right instead of right to left?
23:25Frozenlockhttps://clojuredocs.org/clojure.core/-%3E
23:25Frozenlock(+ (+ (+))) becomes (-> (+)(+)(+))
23:26FrozenlockIn some places it can be easier to read and reason about.
23:26lewixFrozenlock: not in this situation
23:28lewixFrozenlock: thanks though.
23:28oskarkvnote that you don't need parens have just one element, (-> + +) = (-> (+) (+))
23:29oskarkvand ->> puts things at the end, while -> put things second (as first argument)
23:31Frozenlockhow dare you remove parens?
23:33lewixoskarkv: Frozenlock awesome
23:33lewixwhats the norm - do clojurian use ->> all over the places ?
23:34oskarkvNo, just when it looks nicer :p
23:34ncthom91anybody? :) is there a way to define a new nashorn engine for each thread to reference so that there is no competition?
23:35Frozenlockncthom91: you might have a better chance in the US day hours. #clojure is slow at night.
23:35ncthom91Frozenlock ah, bummer, thanks
23:36ncthom91http://cemerick.com/2009/11/03/be-mindful-of-clojures-binding/ makes me think I could use thread-local bindings
23:39oskarkvlewix https://www.refheap.com/
23:39oskarkvjust two examples in my code :p
23:39lewixoskarkv: its the main page ^^
23:39Frozenlockthat empty paste tho...
23:39oskarkvoh
23:39lewixoskarkv: beautiful code
23:39oskarkvlewix https://www.refheap.com/fdbfd7e5dbae5125d4c6fe0dd
23:39lewixits very succinct
23:40oskarkv:p
23:41lewixoskarkv: it requires a lot of cognitive power sheesh
23:41lewixwhats partition again?
23:41oskarkv,(partition 2 1 [1 2 3 4])
23:41clojurebot((1 2) (2 3) (3 4))
23:41oskarkvlewix i guess i just do what I feel like. Sometimes I use -> just to get shorter lines