#clojure log - Apr 06 2015

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

1:30 guthur: can i use ClojureScript with Clojure to dynamically generate JS?

1:30 some examples on the web would be helpful

1:32 TEttinger: guthur, depends how dynamic you mean. clojurescript is typically compiled to save on the amount of space the standard lib takes up

2:01 justin_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.

2:01 I'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

2:02 obviously, clojure is great with immutable stuff

2:03 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

2:03 guthur: TEttinger: yeah, i'm not sure if clojurescript is really the solution i want

2:03 TEttinger: guthur, take a look at Mori, Ki, and the other family of clojurescript-derived stuff to use from JS maybe

2:04 guthur: I more want a transpiler, something a little like parenscript for CL

2:04 TEttinger: https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS#clojure-like

2:05 guthur: TEttinger: cheers

2:05 TEttinger: https://github.com/arohner/scriptjure maybe guthur?

2:05 yeah that list is amazing

2:07 guthur: yeah, unfortunately the vast majority seem to not get very frequent updates

2:07 makes me cautious, possible abandonware

2:11 arrdem: guthur: with respect to what?

3:37 TEttinger: well that was fun

3:37 https://www.refheap.com/99272

3:37 the 9999th fibonacci number

4:11 I guess I should ask again in full this time

4:12 I'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

4:12 obviously, 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

4:13 I have kinda an odd use case, I think, but it could really be broadly applicable to other problems (not games)

4:16 I'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

4:16 the problems are with parts of clojure I really don't understand

4:17 I would need to create some sort of macro to replace def when defining something as part of that chunk of state

4:18 I 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)

4:19 clojure's immutable persistent data structures make this concise, but if a non-persistent data structure somehow gets in there, copying it would be horrendous

4:23 amalloy: TEttinger: if you want time-travel for the stuff in your namespaces, use maps instead of namespaces

4:23 TEttinger: one 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

4:24 I'm not sure I understand, amalloy

4:24 amalloy: like 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

4:25 TEttinger: like defining defstate so it modified a global atom to a map?

4:25 amalloy: you (def versions (atom {})) (swap! versions assoc 1 {:a 1, :b 2})

4:25 yes

4:25 then you can (swap! versions rollback-to 1)

4:25 manage the states you care about yourself

4:26 it 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

4:27 but you're looking for fine-grained environment contorl, so you're gonna have to control your environment

4:27 TEttinger: oh I think there's a slight confusion

4:28 (rollback a version-1) isn't what I'm after

4:28 (rollback 1) is pretty much it

4:28 resetting everything to what it was in version 1

4:28 I don't need to track every var separately

4:28 I want to track them all in a blob

4:29 amalloy: okay, you still need the same structure

4:29 a map from version to maps of values

4:29 TEttinger: gotcha

4:31 so this has some big advantages, like everything being clojure data structures

4:34 (inc amalloy)

4:34 lazybot: ⇒ 254

4:37 oddcully: TEttinger: what library are you using for the graphics, sound, ...? libgdx?

4:38 TEttinger: oddcully, I've used play-clj before but this time I'm doing a text based game, so squidlib

4:39 I'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 :)

4:39 oddcully: rogue with undo? that would be great ;)

4:39 TEttinger: https://github.com/SquidPony/SquidLib

4:39 hehe

5:23 guthur: is there a way for me to easily convert a Cons to persistentList

5:24 I am using backquote to construct a form to pass to clojurescript compiler

5:24 but it complains that it can not compile a Cons

5:25 justin_smith: guthur: apply list?

5:25 ,((juxt type identity) (apply list `(a b c)))

5:25 clojurebot: [clojure.lang.PersistentList (sandbox/a sandbox/b sandbox/c)]

5:40 guthur: ok i solved it by doing (apply list `(1 2))

5:40 but i would be interested in any other approach

6:00 mnngfltg: user=> (apropos "get")

6:00 (get-possibly-unbound-var get-pretty-writer get-drunk

6:00 TEttinger: what

6:00 mnngfltg: ... wait. Where did `get-drunk` come from?

6:00 TEttinger: it's a sign

6:01 you need to reach the ballmer peak

6:01 (actually the basketball team that steve ballmer bought is doing pretty well, I wonder how drunk they are)

6:02 mnngfltg: heh

6:03 TEttinger: "take your vitamins, big guy." "this tastes like vodka!" "Oh, uh, no, it's..." "I didn't say I didn't want it."

6:34 cark: Hello, i'm giving a try to datascript and have a question, is this the right place to ask it ?

6:38 more 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 ?

6:39 or more succintly : are many-to-many lookups bi-directionally index based, or should i add a "many" relation fro children to parents as well ?

6:40 TEttinger: I've never heard of datascript tbh, is it something related to datomic?

6:41 cark: it's kind of like a datomic lite for the browser

6:41 TEttinger: then yeah, stick around, datomic experts may be waking up soon

6:41 cark: i think an answer for datoic would help e as uch

6:41 looks like my M key is acting up =(

6:42 thanks, i'll wait up .... this isn't easy software where you can look the source code and quickly understand it

7:04 not-much-io: Is there an idiomatic way to mark a function as only being used in one other function as to avoid creating confusion?

7:05 Besides letfn which limits testing somewhat

7:06 Also letfn makes the main logic of the function seem much bigger than it really is. IMO

7:07 I 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.

7:08 raspasov: not-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

7:09 TEttinger: (inc amalloy) ; it turned out to be really easy to implement what you described, thanks again!

7:09 lazybot: ⇒ 255

7:09 raspasov: not-much-io: what I personally like to do to avoid confusion is to put that function right above the one that's using it

7:11 not-much-io: raspasov: 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.

7:11 raspasov: I do that too. Just wondering if there is anything else I could do. :)

7:12 raspasov: not-much-io: yea I'm not aware of anything else :) end the function name with -helper? lol

7:13 not-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

7:16 not-much-io: raspasov: build-connection-structure-which-is-get-connections-helper :D I have also found find-usage very useful.

7:17 raspasov: not-much-io: haha

7:19 not-much-io: raspasov: 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.

7:20 raspasov: not-much-io: I'd assume saying something like "used only in x function" is OK if that's important for your or the project

7:20 for you*

7:23 not-much-io: raspasov: 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.

7:43 donbonifacio: if 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)) ?

7:48 not-much-io: donbonifacio: 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)

7:49 donbonifacio: I want the namespace as an argument

7:49 (defn run [namespace] (namespace/run))

7:54 not-much-io: donbonifacio: 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"

7:55 so in the end (eval "a/run") or (eval "b/run")

7:55 donbonifacio: Although it seems hacky to me, but I could be wrong.

7:57 oddcully: what about resolve?

8:00 donbonifacio: nice, didn't know about resolve

9:01 lumrandir: Hello, is there some templating language like Yesod's Hamlet or Ruby's HAML?

9:03 oddcully: you mean beside that one, that comes first on a websearch?

9:05 lumrandir: Nope, the one where I will not have to type class's and id's over and over again.

9:06 I would prefer something where I can type .class and #id

9:06 arrdem: lumrandir: what problem are you trying to solve?

9:06 lumrandir: HTML templating?

9:06 lumrandir: Yep

9:06 arrdem: hiccup is Clojure's canonical answer to that.

9:07 I highly recommend it.

9:07 Empperi: that or enlive

9:07 depending on how you want to do your HTML templating

9:07 lumrandir: Thanks, I'll try Hiccup then.

9:08 Empperi: if you don't mind (or want to) write your HTML as clojure code, then hiccup definetly

9:08 if you want your HTML as HTML then enlive

9:08 out of these two hiccup is more powerful since it's clojure code

9:08 but you might end up in trouble with designers etc

9:09 lumrandir: Well, I'm lacking a designer anyway. Thanks.

10:11 badfish129: Is 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:15 sobel: yes, but i'm not very good at metaprogramming yet.

10:16 bet someone else can answer that easily

10:44 wirrbel: any advice on using SQL with Clojure?

10:44 I experimented with Yesql and Postgre, porting some python code to clojure

10:45 I would like to use a more Java-ish DB now (for easier testing, like H2)

10:45 and I am a bit reluctant to build upon Yesql

10:45 sobel: Postgrey is a whitelisting filter for Postfix. Presumably you intended Postgres or PostgreSQL

10:45 wirrbel: I like the approach to keep SQL queries in SQL

10:45 PostgreSQL

10:46 sobel: i think it makes sense to keep the SQL queries in SQL, too.

10:46 i use the basic clojure jdbc interface

10:46 wirrbel: What I do not like about Yesql is that the argument sequence is dependent on the usage in the sql query

10:46 sobel: that is not good

10:46 wirrbel: I would like to script the Table creation, etc also in clojure

10:47 in my python solution I just sourced a .sql file with pg sql

10:47 sobel: unless 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:47 wirrbel: which seems a bit harder with clojure jdbc

10:49 sobel: you can still use Runtime.exec in clojure, it's not harder than calling out with python

10:49 justin_smith: also we have yesql, which turns sql files into functions (with optional parameters if you want them)

10:50 sobel: getting 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:51 keep 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:51 Shayanjm: Does using emacs inside iterm2 defeat the purpose of using emacs in general?

10:51 wirrbel: I 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:52 Shayanjm: i.e - do i miss out on anything by using my terminal as the interface rather than X?

10:52 the-kenny: Shayanjm: No, definitely not. But you'll miss some features.

10:52 Shayanjm: the-kenny: anything big?

10:52 sobel: wirrbel: totally agreed. sequence position is a horribly way to match parameters in sql.

10:52 justin_smith: wirrbel: it supports named args

10:52 the-kenny: Clipboard integration, mouse scrolling, colors might be broken

10:52 such stuff, nothing really heavy

10:52 Shayanjm: gotcha

10:52 the-kenny: and iterm2 might eat some kind of keyboard shortcuts

10:53 Shayanjm: but if you're on OSX: There's a non-X version of emacs using native Cocoa

10:53 Shayanjm: Oh really?

10:53 the-kenny: of course

10:53 are you using homebrew?

10:53 Shayanjm: yup

10:53 brew install emacs?

10:53 the-kenny: yeah, plus some flag to enable cocoa

10:54 brew install --with-cocoa emacs I think was it

10:54 Shayanjm: sweet

10:54 yeah I'm making the jump from sublime to emacs

10:54 the-kenny: or just emacsformacosx.com

10:54 Shayanjm: sublimerepl just wasn't cutting it for me

10:55 the-kenny: when 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:55 (for emacsclient, mostly)

10:55 sobel: SublimeREPL isn't very good. I really wish it were better for both Clojure and psql (PostgreSQL client)

10:55 Shayanjm: sobel: I know. I had it set up to where i could hotload stuff into the repl via keybindings

10:55 but if i loaded things that were a bit 'big'

10:56 the sublime would get SO slow

10:56 sobel: I ended up going with LightTable

10:56 Shayanjm: I tried lighttable before sublime

10:56 I just couldn't get into it

10:56 felt too rigid for me

10:56 sobel: may still jump one more time to Cursive but i can't afford more tool pain for a week or more

10:57 Shayanjm: I'm still using sublime for my daily stuff until I feel comfortable enough to switch to emacs completely

10:57 sobel: it is more rigid than sublime, but its integrated REPL access works *great* and it colors clojure better than Sublime

10:57 Shayanjm: I work with Python @ day job, but haven't done any research into emacs py support

10:57 yeah true that

10:57 i did miss lighttable colors

10:57 enn`: 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:57 sobel: i don't expect to ditch Sublime for other purposes. it's still a killer editor.

10:58 but it's not a great IDE.

10:58 Shayanjm: enn` do you feel like you miss out?

10:58 justin_smith: enn`: you can connect to GUI emacs from a terminal (emacsclient -nw)

10:58 Shayanjm: so actually that brings up a good question

10:58 i'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:59 so how do most people handle their workflows? Do they run emacs on startup and connect to it throughout the day?

10:59 or load emacs every time they want to use it?

10:59 enn`: 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:00 sobel: who closes their editor at the end of a day?

11:00 Shayanjm: sobel: I mean, I close sublime all the time

11:00 kryft: I use emacs, but I haven't really bothered with cider-repl even though I have it set up :P

11:00 justin_smith: enn: emacsclient works when I log in via ssh, like I mentioned the -nw flag

11:00 sobel: Shayanjm: weird, i only close it when i have to update my OS :)

11:00 justin_smith: enn: this will also work for the pairing or tmux uses you cite

11:00 Shayanjm: sobel: I think I just like keeping my windows tidy, though

11:01 kryft: Maybe I would find it more useful if I configured it for evil

11:01 justin_smith: enn: just saying, you can have the best of both worlds, if you want it

11:01 enn: justin_smith: ah, I see what you're saying. Yeah, maybe I should try that at some point.

11:02 justin_smith: enn: 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:02 enn: Shayanjm: 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:05 Shayanjm: hmm enn - so how would you start emacs in the background?

11:05 do you do it manually or do you have it set to do so on start up?

11:06 justin_smith: Shayanjm: you can start a server from emacs (either via elisp or with the -server flag) and that makes it accept client connections

11:06 the-kenny: then you can 'connect' via emacsclient

11:06 justin_smith: Shayanjm: with a terminal, emacsclient opens in your own window

11:07 Shayanjm: interesting

11:07 justin_smith: with the gui, it opens a new frame, or pops up in the app instance (this is configurable)

11:07 the-kenny: and emacsclient -nw will give you an emacs in the terminal

11:07 justin_smith: right

11:09 sobel: Shayanjm: i use OSX multiple desktops. it's always tidy. ;)

11:10 really, i just like leaving my station ready for work, because i dislike a setup burden when i'm starting my day

11:17 canweriotnow: So is anyone using kibit? It doesn't seem to be very actively maintained.

11:18 sobel: a paradigmatic conception of intelligence?

11:18 justin_smith: canweriotnow: frankly, I just think its authors haven't changed their opinion of how to write clojure code, so they haven't needed updates

11:19 sobel: canweriotnow: yeah, don't confuse "still working" with "not maintained"

11:20 canweriotnow: justin_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:20 sobel: when 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:20 canweriotnow: I know, I know, "where's your PR?"

11:21 sobel: well, feature incompleteness is a different concern. for smaller libs that's less of an issue.

11:21 justin_smith: canweriotnow: my recollection of PRs on kibit is they mostly reflect differences of opinion, on which the maintainer is not going to budge

11:22 canweriotnow: In 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:22 justin_smith: canweriotnow: fair enough, there are some actual issues there

11:22 sobel: damn. i have been reading "kitbit" this whole time.

11:22 kitbit looks neat.

11:22 canweriotnow: sobel: what is?

11:23 sobel: googled. whoa.

11:23 sobel: http://kitbit.com/

11:23 canweriotnow: yeah, looking now.

11:23 sobel: sorry to squirrel but that is darn nifty.

11:25 canweriotnow: Yeah, nerding out on this. Making me forget all about my static analysis woes, replacing them with AI-lust WHOA's

11:29 As 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:38 justin_smith: someone 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:43 gfredericks: I've seen that happen I think

11:44 that's not a with-out-str problem, right? just a pr-str problem?

11:46 justin_smith: gfredericks: pr-str is just a with-out-str call

11:46 so it's definitely a with-out-str problem

11:47 AHA

11:47 no

11:47 I was wrong - the problem could only happen if they were generating the log output inside the with-out-str block

11:47 so there is no race there

11:49 noncom: did anyone receive a timeout on mvn deploy to clojars?

11:49 it times out on uploading the pom (the jar is uploaded fine)

11:50 gfredericks: justin_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:50 justin_smith: fair enough!

11:50 tcrawley: noncom: multiple times, or just once?

11:50 noncom: i tried several times

11:50 i had increased the timeout in settings.xml

11:50 but to no avail

11:51 tcrawley: what is the artifact?

11:51 justin_smith: noncom: well, clojars also won't accept duplicate uploads

11:51 tcrawley: unless it is a snapshot, and the rejection for a duplicate shouldn't be a timeout

11:51 noncom: artifact ddf.minim:minim:jar:2.2.1-b8afdc1

11:52 i guess that i better say SNAPSHOT while i'm still learning maven

11:56 danlentz: Clojars down?

11:56 tcrawley: noncom: looks like it uploaded a SNAPSHOT successfully?

11:56 danlentz: it's up for me

11:57 noncom: tcrawley: strange, but: https://www.refheap.com/99279

11:57 danlentz: Maybe it's a network issue then

11:58 noncom: danlentz: you ohave the 8001 port specified in your http adress?

11:58 tcrawley: the artifact is there, but maven said "failure"

11:58 danlentz: No, I can't even get to clojars.org

11:59 Traceroute

11:59 Or website

12:00 noncom: tcrawley: also, on the page: Oops. We hit an error opening the metadata POM file for this project so some details are not available.

12:01 danlentz: Ok, I just checked and I can't reach either one over LTE or hard wired cable internet

12:09 So, can others also confirm they are able to reach http://clojars.org

12:11 oddcully: danlentz: curl gets a 301; looks okish

12:11 danlentz: Yes, it's back.

12:11 I guess that was just some network glitch upstream from me?

12:12 tcrawley: noncom: 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:12 danlentz: maybe so, it's been available to me this entire time

12:29 pandeiro: has clojure.java.jdbc never been able to infer java.util.Date ?

12:32 gfredericks: you mean convert it to java.sql.Timestamp or something?

12:32 when writing?

12:32 I don't think it ever has, but there are protocols you can extend if you want it to do that

12:55 sm0ke: i dont think that is true

12:55 jdbc spec maps DATE to java.sql.Date

12:56 and TIME to java.sql.Time

13:11 pandeiro: gfredericks: sm0ke: thanks yeah i understand why it couldn't just do that conversion for me; doing it explicitly works fine

13:11 now i need to do org.joda.money.Money -> postgres money type

13:14 reiddraper: dnolen: now we just need to convince you to help us port this to cljs: https://github.com/clojure/test.check/commit/83f65420f192c23cf3b757a4aa422063b0f43863

13:15 gfredericks: can correct, but i think the biggest outstanding question is how to deal with numerics in cljs

13:16 justin_smith: reiddraper: I feel like there's a super unhelpful snarky answer to that question

13:16 dnolen: reiddraper: haha, doesn't look so hard, it just requires longs right?

13:17 reiddraper: dnolen: yeah, and some bit manipulation

13:17 dnolen: reiddraper: goog.math.Long delivers

13:17 it works great and it reasonably performant

13:17 s/it/is

13:17 reiddraper: dnolen: excellent!

13:52 noncom: tcrawley: nope, no proxy.. but maybe i will try at home once again

13:57 $seen tcrawley

13:57 lazybot: tcrawley was last seen talking on #clojure 1 hour and 45 minutes ago.

14:04 csd_: 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:13 justin_smith: csd_: for a limited number of connections, why not N go loops all reading on the same "make a connection" channel?

14:13 you can use a dotimes to launch all the connection-making go blocks

14:14 csd_: justin_smith: but what about after one of the N connections disconnect? would that way allow the loop to resume accepting connections?

14:15 justin_smith: csd_: 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:16 this is in the super abstract of course, not knowing all the details of what you are doing

14:17 csd_: so something like if current-connections < max-connections then recur? with no else clause

14:17 justin_smith: csd_: not really - each go-loop is one potential connection

14:17 so you have a channel with connections coming in, and then N potential blocks handling the connection

14:17 if they are all busy, the ones in line wait or fail

14:18 the-kenny: you 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:18 justin_smith: exactly

14:18 the-kenny: New clients can be distributed from one single channel that will block (or drop?) if no go loop is free

14:18 justin_smith: and it's all coming in on one channel, that is read by all of those loops

14:18 right

14:19 csd_: so would the channel buffer then represent the limit N?

14:19 the-kenny: (go-loop [] (<! (handle-client! (<! new-client-ch))) (recur)) basically :)

14:19 csd_: no, the count of go-loops is N.

14:20 csd_: i don't understand where the code is limiting the number of connections

14:21 justin_smith: csd_: the-kenny's go-loop call above would be inside a dotimes

14:21 you only have so many blocks accepting a connection

14:21 otherwise you block or drop

14:21 depending on how you defined your channel

14:21 csd_: but the dotimes won't reflect after a connection drops

14:21 the-kenny: justin_smith: sorry, haven't looked at the code yet

14:22 justin_smith: csd_: no, the dotimes decides how many listeners you have

14:22 it exits, and after that you have N go-loops running

14:22 if there is no listener ready, you don't get served

14:22 csd_: oh

14:22 so have a queue of listeners

14:22 justin_smith: kind of

14:23 N listeners all accepting tasks on the same queue, each task guaranteed to be read by at most one listener

14:24 jcromartie: Is core.cache appropriate for caching Ring responses?

14:25 I am having a hard time figuring out how to do it without possibl race conditions

14:25 csd_: justin_smith: this sounds like a good use for alt?

14:25 justin_smith: csd_: why alt?

14:25 csd_: alt would dispatch to the first available listiner

14:25 justin_smith: each loop has exactly one input: the channel that gives you tasks

14:25 no

14:25 your inverting it

14:25 mgaare: other way around, alt reads from the first channel that has something on it

14:26 justin_smith: csd_: if you have 20 go-loops, all reading the same channel, exactly one of them gets each message

14:26 csd_: this does exactly what you want, and is super simple

14:26 no need for alt or anything else, just let them all read

14:27 csd_: because if the message sender is deciding who to send the message to, suddenly you need to keep track of who is busy

14:27 and who is ready

14:27 etc.

14:27 much easier to have the task doers listen if available

14:27 and send to a single channel they all read

14:27 csd_: so how does the connection handler hand the new connect off to a listener? how does it select an arbitrary go loop?

14:28 justin_smith: csd_: 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:28 if more than one reader is ready, core.async picks one

14:29 csd_: i see

14:29 this is confusing

14:29 justin_smith: csd_: core.async is simple but only if you learn "its way"

14:30 csd_: how would i put that relationship into a hashmap?

14:30 justin_smith: I don't understand that question

14:30 csd_: 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:30 for message passing purposes

14:31 justin_smith: csd_: 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:32 csd_: basically, i want N client threads and 1 or some fixed number of server threads which processes the actions of the client threads

14:32 justin_smith: sure

14:33 csd_: does that violate abstractions?

14:33 justin_smith: the individual server go block should be able to do its thing just based on the handle you pass to it

14:33 csd_: 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:33 core.async already handles per loop state as needed

14:34 csd_: by handle are you referring to socket handle or the go-loop

14:34 justin_smith: csd_: it sounds like your mental model has tasks in it which core.async does implicitly, but you want to describe explicitly

14:34 csd_: you are probably right

14:34 this is my first time working with it in a larger project

14:35 justin_smith: if 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:36 csd_: right

14:36 justin_smith: any 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:36 csd_: im not sure where i suggested i want to control it from the inside

14:36 justin_smith: outside

14:36 csd_: right

14:36 justin_smith: when you said you wanted to put the handlers in a hash map

14:36 csd_: i'm more wondering, how do i get a handle such that i can pass messages to it from outside

14:37 justin_smith: you can pass that handle into each loop as it is created

14:37 csd_: oh

14:37 that would just be a new (chan)?

14:37 justin_smith: such that they all share a single "get a request" chan, and then each has its own chan

14:37 yeah

14:37 csd_: i see

14:37 what did you think i was trying to do?

14:38 justin_smith: some sort of central logic to control the go loops

14:38 csd_: ohh

14:38 no i realize that they're supposed to be autonomous

14:38 justin_smith: cool, glad we sorted that out

14:38 csd_: yes thank you

14:38 so after i spin up the app, i'd basically have N listeners going automatically

14:39 justin_smith: right

14:39 csd_: 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:39 justin_smith: right

14:39 csd_: ok awesome this makes so much more sense now

14:40 one other thing tangentially related

14:40 justin_smith: it'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:40 csd_: can i actually use go-loops if i'm working with sockets? i thought those required unique threads per connection

14:40 justin_smith: csd_: nothing about a socket requires a thread per connection actually

14:41 csd_: i thought socket listening was blocking?

14:41 justin_smith: csd_: see aleph and http-kit

14:41 sure, you need to use the right async-friendly lib

14:41 csd_: oh

14:41 im using the java io right now

14:41 jlongster: how 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:41 justin_smith: yeah, regular sockets will stay on one thread, but aleph matches your design very nicely

14:42 csd_: cool i'll check it out

14:42 justin_smith: jlongster: you use its dep vector in your project.clj

14:42 csd_: do you know why i might have been told that sockets can't support go-loops?

14:42 the person who told me is pretty knowledgable about clojure

14:42 justin_smith: jlongster: 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:43 csd_: they probably meant vanilla java sockets, like I said see aleph

14:43 csd_: ok

14:43 thanks again

14:43 jlongster: justin_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:43 I'm coming from npm where you can just do `npm install core.async`

14:43 justin_smith: jlongster: I use clojars or the github page

14:43 jlongster: yeah, we always have explicit versions - I know it seems weird but it saves huge amounts of hassle

14:44 jlongster: justin_smith: ok, thanks

14:44 justin_smith: it turns out to be much saner, I think anyone here will agree

14:44 jlongster: there is a plugin "lein ancient" you can use if you want to check for newer versions of your deps

14:44 jlongster: I 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:45 justin_smith: thanks

14:45 justin_smith: jlongster: lein-ancient has an option to upgrade your versions automaticly or interactively https://github.com/xsc/lein-ancient#upgrade-artifacts

14:46 jlongster: justin_smith: cool, thanks

14:48 tcrawley: jlongster: you can do [org.clojure/core.async "LATEST"] to get the latest release

14:48 I don't recommend that though

14:48 justin_smith: tcrawley: I'm both surprised to see that option and unsurprised it isn't more widely talked of

14:48 haha

14:49 jlongster: tcrawley: 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:49 justin_smith: fyi "lein install" is for putting your project in the deps cache

14:49 tcrawley: justin_smith: it's an easter egg, but one that you find 6 months after easter

14:49 justin_smith: haha

14:49 all rotten

14:53 jlongster: justin_smith: I think I'd be happy if `lein search` sorted by version descending

14:54 justin_smith: jlongster: 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:55 jlongster: yeah

14:55 justin_smith: eg. lein new compojure org.mine/blog-app org.clojure/core.async prismatic/schema org.clojure/java.jdbc

14:55 and that would insert deps for all those requested libs

14:55 amalloy: justin_smith: LATEST is discouraged because it will update to snapshots too, iirc, or at least alphas, when you least expect it

14:55 justin_smith: that would be cool

14:56 amalloy: so a built that used to work stops working, without any change from you

14:56 justin_smith: amalloy: yeah, I wouldn't have used it anyway, but good to know :)

14:56 thanks for making the reason explicit

15:17 amalloy: about 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:20 huh, 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:25 justin_smith: interesting

15:45 jlongster: dnolen: is this section still right? https://github.com/clojure/clojurescript/wiki/Quick-Start#less-boilerplate

15:45 I use lein-cljsbuild with just `:output-to` and it seems to generate a single runnable .js file without needing to add ":main"

15:46 dnolen: jlongster: cljsbuild sadly supplies many outdated defaults

15:46 jlongster: it's really a mess now

15:46 jlongster: oh boy

15:46 where are the defaults it supplies?

15:46 at least it works by default

15:46 dnolen: jlongster: it defaults to :simple :optimizations which negates most of the benefits of incremental compilation

15:47 jlongster: in general the Quick Start is the source of truth, any other information you will encounter is inferior

15:48 jlongster: dnolen: 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:48 I would think :advanced would do that more

15:49 dnolen: jlongster: incremental compilation mean recompilation in tens or hundreds of milliseconds

15:49 jlongster: :simple applies several non-trivial passes

15:49 across everything in your build

15:50 jlongster: dnolen: got it. like pretty-printing?

15:50 dnolen: jlongster: no :simple is pretty fancy, lambda lifting, constant folding, var renaming all happen under simple

15:51 even basic inlining

15:51 jlongster: dnolen: so what should I use? those don't happen under :advanced?

15:51 dnolen: jlongster: advanced does even more stuff, and dead code elimination is very intensive

15:51 jlongster: yeah, that's quite awesome

15:51 so :none ?

15:52 dnolen: yes development is nearly always done with :none, it also provides the most accurate source map

15:52 :simple & :advanced require source map merging, it works but is lossy

15:52 jlongster: that makes perfect sense

15:52 thanks

15:52 still, about boilerplate, cljsbuild must pass :main or something?

15:53 it works now, I can look into details later

15:53 dnolen: jlongster: cljsbuild simply forwards :compiler, where it goes wrong is in supplying defaults as these do not align with ClojureScript's default anymore

15:53 defaults

15:54 jlongster: right, 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:54 but it works without it

15:55 dnolen: ooh with :optimizations :none I do see the `goog is not defined` error

15:55 :advanced probably inlined all that, etc

15:55 thanks

15:55 dnolen: jlongster: and :simple inlines it too

15:56 jlongster: there's an outstanding ticket to always support :main, but haven't gotten around to it yet

15:56 jlongster: gotcha

15:56 dnolen: you definitely need it under :none to avoid writing extra markup

15:56 it doesn't mean anything to :advanced or :simple so you can still supply it if you like

15:57 jlongster: right

15:58 dnolen: jlongster: also there's a #clojurescript channel ;), pretty active these days and good place for ClojureScript specific questions :)

15:58 jlongster: dnolen: oh, didn't know that, thanks!

16:27 chouser: Do I guess Clojure 1.7-alpha6 isn't doing .cljc files yet?

16:27 s/Do/So/

16:33 tbaldridge: chouser: it's part of the changelog

16:35 chouser: FileNotFoundException Could not locate foo/bar__init.class or foo/bar.clj on classpath.

16:35 doesn't look like 'require' is attempting to load from anything other than *.clj

16:36 I guess I should read the code. Perhaps it's just the error message that's out of date.

16:41 Shayanjm: spent the better half of today getting familiarized with emacs

16:42 it's pretty sweet

16:43 chouser: oh, I'm an idiot. Wrong namespace name. Thanks for the reality-check, tbaldridge.

16:45 bridgethillyer: I’ll vouch for you, chouser. You’re not an idiot.

16:50 chouser: aw, thanks. Maybe we can compromise on "I make stupid mistakes"?

16:51 sobel: Shayanjm: it's aged well

16:52 Shayanjm: sobel: key bind all the things

16:54 bridgethillyer: chouser: Me too!

17:00 Shayanjm: If 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:01 i.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:01 xemdetia: Shayanjm, I am not really sure but take and drop might be what you need

17:01 amalloy: partition

17:02 Shayanjm: ooh looked up partition, thanks amalloy

17:10 danlentz: I 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:10 https://plus.google.com/communities/114701006686888945987

17:11 mavbozo: danlentz, awesome

17:13 danlentz: I 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:14 sobel: nice, i hope to remember to join that when i get home

17:14 bja: eek, yesql apparently doesn't understand variables in plpgsql that need to be DECLAREd with :=

17:15 sobel: why would yesql need to know about vars in pl/pgsql?

17:15 bja: because it thinks := is a named param

17:15 sobel: why is yesql looking inside a pl/pgsql proc, and how?!

17:15 justin_smith: oh yeah it would do that, that's too bad :(

17:16 sobel: yesql loads sql files and makes them into functions

17:16 sobel: but it interprets keywords to be named params

17:16 sobel: oh right, now i remember which one yesql is

17:16 that made me cringe earlier, and it makes me cringe now

17:16 i knew that wouldn't work

17:16 justin_smith: sobel: sql is a good dsl for sql

17:16 sobel: and how

17:17 eventually, i'll just assign yesql the value of DUDE

17:17 justin_smith: bja: try using a unicode escape for : maybe?

17:17 sobel: and when i read yesql, i'll remember not to respond :)

17:17 keep your sql in a file psql can read

17:17 don't plan for anything except postgresql to parse it

17:18 srsly. it's a complex syntax. you'll poke your eye out.

17:18 bja: justin_smith, I think I'm just going to put DDL into a separate .psql file that I can slurp up

17:18 justin_smith: yeah, that sounds sane

17:18 sobel: you could slurp it, but psql adds value

17:18 bja: I was being lazy when I was keeping my ddl creation and querying in the same place

17:18 justin_smith: if you don't need to paramaterize on the clojure side especially

17:19 mavbozo: sobel, so, where do you put your sqls in clojure projects?

17:19 sobel: mavbozo: db/

17:19 mavbozo: sobel, in .clj files or .sql files?

17:19 sobel: it's sql. i put it in sql files.

17:19 as we've been discussing here, clojure is a poor representation for sql

17:20 or maybe it's that translating between is error-prone

17:20 anywho, i strongly recommend keeping DDL in plain text so it can be "executed" with psql

17:21 else you end up with a predictable hassle of leaky abstractions between DSLs

17:21 bja: yesql 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:22 mavbozo: sobel, you put 1 sql statement per 1 .sql file? or you put many sql statements in 1 .sql file?

17:22 bja: i.e. WITH tmp(a,b) AS VALUES (1,2) (3, 4) SELECT ....

17:24 unless 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:24 although I can build that use case up with honeysql easy enough

17:26 Shayanjm: What's the best way to 'wait' before executing the next iteration of a loop?

17:27 justin_smith: Shayanjm: (Thread/sleep N)

17:27 Shayanjm: preferably for long periods of time - in this case I have to wait ~15 minutes before each execution

17:27 justin_smith: where N is in ms

17:27 Shayanjm: justin_smith: is that reliable?

17:27 I read somewhere that JVM timeouts/sleeps are unreliable but the post didn't explain that further

17:27 justin_smith: Shayanjm: depends how precise you need it to be, you can bind a timestamp and check elapsed time when it resumes

17:27 Shayanjm: Anything over 15 minutes is great

17:27 justin_smith: and sleep again if you need to wait longer etc.

17:28 Shayanjm: yeah

17:28 i'll try it out thanks

17:28 sobel: mavbozo: 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:29 mavbozo: 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:29 Shayanjm: justin_smith: follow up - if I'm using something like pmap in the function body that I would like to sleep

17:29 how do I wait for pmap to finish before executing the sleep?

17:29 bja: Shayanjm: I liked using core.async to do that. (let [t (async/timeout timeout-ms)] (do-stuff) (<!! t))

17:29 sobel: does sleep park?

17:30 Shayanjm: bja: I saw async but I didn't want to introduce another component just to do something relatively small to the bigger implementation

17:30 justin_smith: sobel: in the core.async sense? no, you would wait for a timeout chan in that context

17:31 sobel: justin_smith: aho k

17:31 justin_smith: Shayanjm: in order to wait for pmap to complete, do something that requires realizing the full results

17:31 Shayanjm: it's "semi-lazy" as the docs describe

17:31 Shayanjm: justin_smith: something like wrapping the pmap in a doall?

17:32 justin_smith: Shayanjm: I think that should suffice, yeah. Or any other operation that would require every element to be realized.

17:32 Shayanjm: k sweet

17:32 thanks

17:36 chouser: ok, so what about clojurescript support for .cljc files?

17:39 mavbozo: sobel, 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:42 sobel: mavbozo: oh, if it's a SQL query needed at run-time, i put that directly in the code as a string

17:43 at 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:43 i hard code those

17:45 mavbozo: sobel, for a while there i thought you went extreme and put all those sql statements in a file

17:45 sobel, :)

17:45 sobel: mavbozo: that's crazy talk

17:45 oddcully: crazy talk would be: put them in a db table

17:45 sobel: oddcully: you say that, but...

17:46 that's every ERP

17:47 (it would still need a 'core' with a decent DAO/DAL that has some a-priori knowledge of the schema

17:47 )

17:47 mavbozo: sobel, i stil think it might be easier to scan what runtime sqls needs to change if schema changes

17:47 oddcully: but where do you put the query to load your queries... /me listens now to the sound of trees

17:47 sobel: oddcully: some a-priori knowledge of the schema is required

17:48 mavbozo: i'm not sure what you mean by scan

17:49 i don't know why you'd separate sql from code that depends on it. i haven't seen a useful case of it.

17:50 mavbozo: sobel, so far, when schema changes, for example, i use text editor's search to see what column to add or delete

17:50 easier to do when all those statements are in .sql files and under a parent directory such as '/db'

17:55 sobel: that 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:55 if you add or drop a column, it's a subsequent script to make that change against the 1st schema script

17:56 this is generally the issue addressed by "migration" systems

17:56 (and poorly at that)

17:59 mavbozo: i haven't found any sql "migration" systems that handles migration for sqls that are needed at runtime.

18:00 sobel: yeah, that's because modifying your queries is not defined by migrations. that's part of your application interface, not the database.

18:02 usually 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:02 arrdem: so is someone crawling Grimoire with wget?

18:04 because I got pinged by wget 4.5k times in the last 12hrs, never seen a wget view before.

18:05 mavbozo: sobel, yeah, i am forced to use search or grep because those sql statements are everywhere

18:06 sobel: mavbozo: sql should be isolated to a library

18:06 mavbozo: you should not have to crawl your whole source tree to find affected queries. that sounds like a poor source code decision.

18:07 arrdem: that sounds amateurish. it's a pretty brutal site mirror tool.

18:08 justin_smith: arrdem: sounds like time for some nginx rules

18:08 arrdem: justin_smith: quite possibly

18:09 sobel: raise the bar. require use of that user-agent flag.

18:09 (sorry, not helping...)

18:09 arrdem: hehe

18:09 justin_smith: arrdem: by default if you have rel="nofollow" on an href, wget won't traverse it

18:09 arrdem: if it's just someone being naive, that will at least limit the damage

18:09 it's an easy change if you are generating the links

18:10 sobel: wow, i did not know wget honored any link attrs

18:10 arrdem: sobel: it will by default but you can turn all that off

18:10 justin_smith: right, it only helps if the guy is naive, not if they are a jerk :)

18:12 arrdem: yeah looks like at 3:30pm someone pegged the server

18:13 mavbozo: sobel, most of legacy code bases that i work on are like that. And also usage of both ORM and plain sql statements.

18:14 sobel: mavbozo: that is unsurprising.

18:16 g'night, gents. see you tomorrow.

18:16 mavbozo: sobel, thanks for the discussion

18:21 arrdem 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:21 arrdem: you poor devil

18:22 justin_smith: haha

18:22 mavbozo: arrdem, it's possible there's someone from a 3rd world country who wants to learn clojure

18:24 arrdem, can you trace the country where those wget comes from?

18:24 arrdem: mavbozo: no I don't log source IPs

18:24 one of the many reasons I need to build a Ring logging middleware lib

18:27 other open avenues of work are non-en_US localization and a caching API layer because yes the intertubez go out

18:47 lewix: Hi guys

18:57 arrdem: on examining the logs looks like I owe our wget friend some beer, he found a bunch of bad links :P

19:01 hyPiRion: arrdem: why do you wonder why I write Swearjure on contract btw? Need something?

19:02 arrdem: hyPiRion: 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:02 hyPiRion: opted instead for the SR-71 pictures I used for Oxcart/Ox-lang

19:02 hyPiRion: arrdem: Oh. Well, there are some over at https://github.com/hyPiRion/swearjure/tree/master/examples

19:03 Not sure if they are too short or too long

21:38 deadghost: what's the simplest solution to not blocking on sending email?

21:38 justin_smith: deadghost: put it in a future

21:38 deadghost: core.async? queues?

21:39 TEttinger: yah, futures are great

21:39 (inc justin_smith)

21:39 lazybot: ⇒ 233

21:39 deadghost: I shall take a look

21:39 justin_smith: how 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:39 deadghost: it's not a feature I've really used

21:39 yeah just a few

21:40 justin_smith: yeah, no need to set up a big async machine for that, that's a natural fit for a future

21:43 vas: (hello)

21:44 irctc: clojure

22:01 Niac: user=> (BatchJob/main (char-array [])) ClassCastException [C cannot be cast to [Ljava.lang.String -init6948500342059468836.clj:1) user=> (BatchJob/runBatchJob 123)

22:02 public static void main (String[] args) {.....}

22:03 it seems the params are wrong.

22:06 em,is it defferent from char and string???

22:06 lazybot: Niac: Yes, 100% for sure.

22:07 Niac: lazybot: is it defferent between char and string?

22:26 nuwanda_: Niac: ??

22:26 lazybot: nuwanda_: Uh, no. Why would you even ask?

22:26 nuwanda_: ??

22:26 lazybot: nuwanda_: What are you, crazy? Of course not!

22:26 clojurebot: ? is !

22:37 lewix: (> Clojure (rest Languages)) what does it return?

22:38 (> Clojure (rest 'Languages))

22:38 any guess?

22:38 justin_smith: * :)

22:45 gfredericks: Niac: you want #(into-array String ["foo" "bar"])

22:45 &(into-array String ["foo" "bar"])

22:45 lazybot: ⇒ #<String[] [Ljava.lang.String;@2f94db83>

22:45 gfredericks: sorry that's it

22:45 Niac: yes ,it work

22:47 i used to write php ,there is no defference between char and string.text use string as always.

22:47 gfredericks: chars are what strings are made of

22:48 ,[(type "foo") (type (first "foo"))]

22:48 clojurebot: [java.lang.String java.lang.Character]

22:48 lewix: is there a better way to do this:

22:48 (> 22 (apply + (remove #(= % 3) '(3 2 8))))

22:49 , (> 22 (apply + (remove #(= % 3) '(3 2 8))))

22:49 clojurebot: true

22:49 Frozenlock: ,(remove #{3} '(3 2 8))

22:49 clojurebot: (2 8)

22:53 lewix: Frozenlock: is it syntactig sugar?

22:53 Frozenlock: #{} is a set

22:54 ,(#{3} 3)

22:54 clojurebot: 3

22:54 lewix: oh

22:54 a set is also a function?

22:54 daymn

22:54 Frozenlock: Just like the map {} :-)

22:55 ,({:a 1} :a)

22:55 clojurebot: 1

22:55 lewix: i knew about map

22:55 omg thats amazing

22:55 Do you guys use lowercase , snakecase or camel

22:59 Frozenlock: eh... I guess it's lisp-case

23:00 whatever-the-name-is-for-this

23:11 lewix: Frozenlock: thank

23:11 is 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:11 (I'm practicing )

23:12 Frozenlock: lewix: first lesson: use refheap.com for multi-line functions :-p

23:13 There's even refheap.el if you are using emacs. Quite handy.

23:14 lewix: What are you trying to do with the function?

23:17 lewix: Frozenlock: is there refheap for vim

23:17 Frozenlock: basically trying to add up all the values and compare it to the value of clojure

23:17 Frozenlock: I don't know the vim ecosystem, sorry.

23:18 lewix: Frozenlock: https://www.refheap.com/99305

23:18 ncthom91: hi 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:21 lewix: Frozenlock: did i make any mistake? seems fine right?

23:22 Frozenlock: It does. I might add a threading macro somewhere to make it a little clear, but that's just me splitting hair :-p

23:23 ncthom91: Here's an example: http://pastebin.com/0jQ6rZy5

23:23 Frozenlock: lewix: https://www.refheap.com/99306

23:24 lewix: Frozenlock: can you explain the macro >>

23:24 does it make it readable from left to right instead of right to left?

23:25 Frozenlock: https://clojuredocs.org/clojure.core/-%3E

23:25 (+ (+ (+))) becomes (-> (+)(+)(+))

23:26 In some places it can be easier to read and reason about.

23:26 lewix: Frozenlock: not in this situation

23:28 Frozenlock: thanks though.

23:28 oskarkv: note that you don't need parens have just one element, (-> + +) = (-> (+) (+))

23:29 and ->> puts things at the end, while -> put things second (as first argument)

23:31 Frozenlock: how dare you remove parens?

23:33 lewix: oskarkv: Frozenlock awesome

23:33 whats the norm - do clojurian use ->> all over the places ?

23:34 oskarkv: No, just when it looks nicer :p

23:34 ncthom91: anybody? :) is there a way to define a new nashorn engine for each thread to reference so that there is no competition?

23:35 Frozenlock: ncthom91: you might have a better chance in the US day hours. #clojure is slow at night.

23:35 ncthom91: Frozenlock ah, bummer, thanks

23:36 http://cemerick.com/2009/11/03/be-mindful-of-clojures-binding/ makes me think I could use thread-local bindings

23:39 oskarkv: lewix https://www.refheap.com/

23:39 just two examples in my code :p

23:39 lewix: oskarkv: its the main page ^^

23:39 Frozenlock: that empty paste tho...

23:39 oskarkv: oh

23:39 lewix: oskarkv: beautiful code

23:39 oskarkv: lewix https://www.refheap.com/fdbfd7e5dbae5125d4c6fe0dd

23:39 lewix: its very succinct

23:40 oskarkv: :p

23:41 lewix: oskarkv: it requires a lot of cognitive power sheesh

23:41 whats partition again?

23:41 oskarkv: ,(partition 2 1 [1 2 3 4])

23:41 clojurebot: ((1 2) (2 3) (3 4))

23:41 oskarkv: lewix i guess i just do what I feel like. Sometimes I use -> just to get shorter lines

Logging service provided by n01se.net