#clojure log - May 21 2014

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

0:00 blr: quizdr: when you have some time, you could get austin setup https://github.com/cemerick/austin

0:00 I've been meaning to check it out myself

0:08 Frozenlock: If only emacs was written in clojure, I wouldn't have to leave it. Ever.

0:11 quizdr: Frozenlock, well they say Light Table is the new emacs, and it is written in clojure(script)

0:11 light table is so pretty and has many nice things, but it seems that as soon as i try something non-trivial in my workflow, things break

0:12 and i've become perhaps overdependent on other emacs features, like shell and irc integration, directory browsing, etc. so not sure light table will replace those

0:12 Frozenlock: I don't really believe it. It if far as customizable as emacs.

0:12 *from being

0:13 gtrak: technomancy: seems like the meetup liked hacking on syme, we're going to keep pushing it forward: https://github.com/baltimore-clojure/syme/wiki/TODO

0:13 quizdr: Just doing something as simple as increasing or decreasing the font size of the code screen you are looking at is not simple in light table. Emacs, just as keystroke.

0:13 *a

0:16 justin_smith: quizdr: oh, control+scroll doesn't do it? I thought they piggybacked on webkit

0:17 quizdr: justin_smith by "scroll" you mean... scroll lock button? I'm on Mac, and I tried the standard zoom in/out keys (mapped to the + and -) buttons but they don't do anything in light table

0:17 justin_smith: quizdr: as in mouse scroll wheel

0:17 Frozenlock: scroll... mouse scroll

0:17 justin_smith: or two finger drag or whatever you know

0:17 quizdr: ouch! did you say "mouse" ?!! perhaps another reason i prefer emacs :)

0:17 justin_smith: lol

0:17 Frozenlock: :-p

0:18 He might also be using an old 1 button mac mouse

0:18 quizdr: if light table depends on a mouse or touch pad, scroll wheel, scroll bar or anything else for basic navigation then I will not look at that app ever again

0:18 Frozenlock: Because why would you need to use more than one finger on your hand? -Mac

0:18 justin_smith: Frozenlock: for multi-touch, of course

0:19 Frozenlock: quizdr: One of the deal-breaker for me is the lack of buffers

0:19 quizdr: actually i take that back: two-finger scrolling on a touchpad is quite easy. but i'd had to use scrolling for anything else, especially in combination with a keystroke

0:19 Frozenlock: I tried to implement one, but the documentation is too spares.

0:19 justin_smith: Frozenlock: so it is "document" based?

0:19 quizdr: Frozenlock switching buffers in emacs is really nice too, and fast (without a mouse, of course). i would think light table should eventually support file view switching easily and quickly

0:20 justin_smith: I wish I had iswitchb for my web browser

0:20 Frozenlock: justin_smith: Yes, what you see is your document; you can't see it in another tab.

0:20 quizdr: I would actually think that the future of code editing is in fact a web page interface. you could have tabs or buffers for your different views, etc.

0:21 to edit code on a server, it's just a browser page on that server, etc...

0:21 amalloy: justin_smith: switch to konkeror? it probably has that

0:21 Frozenlock: Well, perhaps you can. Like I said, I tried to implement it using the CodeMirror functions, but that opened a whole can of Worms, bugs appeared everywhere. The current LT isn't supporting multiple view of the same document.

0:21 amalloy: but seriously, there are extensions for the major browsers with features like that, i think

0:23 justin_smith: amalloy maybe you mean conkeror? konkeror mostly finds me konqueror results (kde's ur-webkit thing) http://conkeror.org/

0:23 amalloy: oh, i probably do

0:23 Frozenlock: If anyone wants to try to solve it: https://github.com/Frozenlock/Bufferize/blob/master/src/lt/plugins/bufferize.cljs

0:23 amalloy: i forget how to spell it. the one that's got like the emacs keybinds

0:23 yeah, conkeror

0:24 beamso: quizdr: i've done that type of editing (online editing/remote compilation) through using salesforce. it's actually really annoying.

0:24 quizdr: beamso probably because salesforce messes it up

0:24 no reason why a nice GUI editor couldn

0:24 beamso: no, the latency is too huge.

0:24 justin_smith: amalloy: yeah, I see people talking about doing iswitchb in conkeror, doesn't look like it exists as a finished thing yet though

0:24 quizdr: oh i see, latency

0:25 but latency would be an issue with any remote code editor, even emacs, no?

0:25 justin_smith: quizdr: I like how emacs handles it actually, via tramp

0:25 bodie_: uh, why would a web interface necessarily be laggy?

0:25 justin_smith: it replaces file load / write with remote access, everything else is local

0:26 I bet if your site uses standard rest put / get tramp can already be used to edit the content

0:26 bodie_: just because someone's done it wrong doesn't mean it can't be done right ;)

0:26 beamso: bodie_: the latency was terrible and it really showed how good/bad your internet connection actually was.

0:26 quizdr: bodie_ i agree. i have no doubt salesforce is not doing it the best way (having used other SF services)

0:27 bodie_: latency of what specifically?

0:27 justin_smith: beamso: no reason you can't do it emacs style in javascript (everything is just local editing, only file load and file save use the network)

0:27 beamso: saving and compilation

0:28 if it was inside my local network i wouldn't have an issue

0:28 quizdr: beamso but compilation doesn't depend on an internet connection. and saving should be just sending a file over the connection, which would be the same regardless of editor

0:28 justin_smith: another option is sending diffs to the server instead of a full file upload (depending on file size and change size of course)

0:29 beamso: quizdr: for salesforce it does. there is no compiler in their eclipse plugin, just a crappy parser.

0:29 bodie_: saving should really just be a matter of flushing the cached entry to a persistent location -- if it's not already doing so. think google doc

0:29 s

0:29 there's not even a save button

0:29 justin_smith: ie. look at how the sam editor manages to edit files that are larger than the computer's working memory, things are lazily loaded and lazily updated as regards disk

0:30 bodie_: well with google docs they are definitely doing it diff / delta based rather than naive re-upload

0:30 bodie_: right

0:30 i mean the remote cached version

0:31 it seems reasonable to use an in-memory db for syncing a document between users, for example

0:33 beamso: i feel kinda unclean for dropping salesforce references in the room.

0:33 clojurebot: Pardon?

0:33 beamso: you heard me, clojurebot.

0:34 bodie_: justin_smith, do you know of any alternatives to datomic?

0:34 Frozenlock: Now I'll have to goolge salesforce. Thanks beamso.

0:35 What a lousy landing page. I don't know what it's doing.

0:35 quizdr: beamso a lot of people swear by the power of salesforce -- and they do own Heroku after all -- but getting their stuff to work always seems like a bigger job than necessary (Heroku excluded, but they didn't create that service themselves)

0:37 * technomancy hides

0:37 beamso: it is a bigger job then necessary because you need to identify how you can or can't bend salesforce to your will.

0:37 quizdr: ha ha technomancy you are proving the exception to the rule, no need to hide :)

0:38 beamso: they are moving to a situation where you develop your front ends on heroku and keep your internal users on salesforce

0:39 quizdr: we actually have a large system build on salesforce for many years, but now we are going to deploy a clojure app on Heroku and are trying to figure out if it makes sense to link the two systems or just let the new app be totally independent and self-contained

0:39 beamso: depends on the data and usecases

0:40 justin_smith: bodie_: no, I really don't. I haven't even gotten a chance to play with datomic even... but I may just find the free time soon between some contract work now that I am laid off

0:40 quizdr: i'm leaning to keeping the existing salesforce integration out of the new project for the sake of elegance because i know just what a hack job it may turn out to be

0:40 (to integrate them)

0:40 beamso: also on how much you want/don't want to pay for licencing

0:40 technomancy: quizdr: have you seen the postgres bridge?

0:41 quizdr: postgres on heroku offers a native bridge to existing salesforce data?

0:41 beamso: technomancy is referencing https://devcenter.heroku.com/articles/herokuconnect

0:41 quizdr: Ahh, looks like that service is not yet widely available

0:42 technomancy: I don't know a lot about it, but from what I can gather not wanting to use salesforce apis is a pretty common thing

0:42 huh; I thought it was supposed to be open for everyone now

0:43 quizdr: it looks like a "we'll let you use it if we liked your project" kind of thing.

0:44 i wonder how expensive it is.

0:44 beamso: i expressed interest through a webform when it was announced. i got an email 8 days ago referencing that document.

0:45 Frozenlock: Wait, am I really the only one who didn't know about salesforce?

0:45 quizdr: Frozenlock they are huge, they are everywhere.

0:45 technomancy: Frozenlock: I don't know about salesforce

0:45 and I work there

0:46 Frozenlock: quizdr: Pepsi kind of everywhere?

0:46 quizdr: They offer a lot of conveniences and tools for cloud stuff, but frankly it all feels a bit old-school to me.

0:46 It could be in the quality of the code that our SF consultants have written that is giving me a bad impression

0:46 beamso: looks like heroku app admins have to manage the fact that the databases go out of sync

0:46 quizdr: I don't work with SF directly (thank goodness) but it just seems like everything is handing together by threads.

0:47 *hanging

0:47 Frozenlock: quizdr: that's the whole Internet...

0:47 I'm amazed to see it still works every day :-p

0:47 quizdr: well SF is *not* the whole internet.. it's an expensive system that is suppose to make things easier, and it doesn't seem to live up to that

0:47 beamso: quizdr: from what i've seen salesforce haven't upgraded from jsfv1 to a later version so the platform for devs is kinda stale

0:48 quizdr: whenever i login to the user admin system in our SF backend i am plagued by a variety of error pop-ups that have never gone away despite years of SF consultants doing work for us

0:49 beamso: the only popups i used to get were about applying updates, but that was for the standard ui.

0:49 quizdr: but when you are tying in a marketing platform, a Windows app licensing service, a payment processing system and more all in a single SF account, things are bound to get complex. but SF should make it easier than it is.

0:52 Apparently the impetus for the Salesforce system and services was the result of a conversation its founder had with Steve Jobs, who offered like a single sentence of advice that led to this huge corporation

0:53 * bodie_ tweaks state

0:53 beamso: never knew that one. i just knew that the founder was a former oracle sales exec

0:54 bodie_: justin_smith, after watching the Rich Hickey vid on Datomic I got really excited, until I checked out the "pricing" page.

0:55 thus, my desire to find something a little less soul-shattering ($10,000 is way outta my price range. I think twice before dropping $10 on a cloud service. ha!)

0:55 maybe one day if something i'm working on takes off.

0:56 but, planning for success right now means launching with a low cost solution

0:57 Cr8: there's pro starter

0:59 dissipate: bodie_, why u so cheap?

0:59 bodie_: I'm saving up for a new piggy bank

0:59 gotta count my pennies

0:59 Frozenlock: Because when you spend all you money, you end up poor?

0:59 bodie_: lol

1:00 Cr8 -- I think I somehow got it into my head that pro starter wasn't free :) thanks for the pointer

1:00 Frozenlock: "Frozenlock, how could you afford this $2k accordion while being in school?" "By not spending it all in drinks, child."

1:10 nkozo: I want to define a macro mymacro that gets an expression and returns the same expressions with his symbols fully qualified, ej (mymacro [list vec]) => [clojure.core/list clojure.core/vec] . There is a short way to do this?

1:11 justin_smith: ,list

1:11 clojurebot: #<clojure.lang.PersistentList$1@a60d19>

1:12 nkozo: ,`list

1:12 clojurebot: clojure.core/list

1:12 justin_smith: right, that's the one you want

1:12 (resolve 'list) another option

1:13 ,(resolve 'list)

1:13 nkozo: but I want to fully-qualify an arbitrary expression containing symbols

1:13 clojurebot: #'clojure.core/list

1:13 nkozo: basically what syntax-quote does, but you cannot use syntax-quote directly to do this

1:13 justin_smith: nkozo: then you need to iterate across the whole expression, or use syntax-quote (`) which acts on a whole expression

1:14 nkozo: cannot use syntax quote, (defmacro mymacro [expr] `expr) will not work

1:14 justin_smith: what about `'expr

1:14 `'(list + vec)

1:15 amalloy: why do you want it to be a macro instead of just using `?

1:15 justin_smith: ,`'(list + vec)

1:15 clojurebot: (quote (clojure.core/list clojure.core/+ clojure.core/vec))

1:15 amalloy: justin_smith: that doesn't work if expr is passed in

1:15 justin_smith: amalloy: in a macro it would, that's why I added the '

1:15 amalloy: no it wouldn't

1:16 nkozo: amalloy: long history, this is the distilled problem and I forgot the initial reason :)

1:16 amalloy: try writing a macro foo such that (foo (list + vec)) expands to that, using just ` and '. you can't do it

1:16 nkozo: I think I want a runtime syntax-quote, not a read-time one.

1:17 amalloy: nkozo: i mean, people have written that. ztellman and bbloom each have an interesting take on it

1:17 nkozo: sure, I can walk the expression, but I thought maybe it was simpler

1:17 amalloy: i think it's bbloom, anyway. hiredman has one too

1:17 ztellman: bbloom has backtick

1:17 nkozo: checking it...

1:20 justin_smith: amalloy: right as usual

1:20 (inc amalloy)

1:20 lazybot: ⇒ 110

1:21 amalloy: justin_smith: the thing to remember is that ` only happens at read time, and your macro body is only read once, so it can't know about the contents of expr

1:21 justin_smith: right, I had forgotten that

1:21 * rpaulo wonders how to call syscalls from clojure

1:22 justin_smith: rpaulo: do you mean kernel system calls as in sys.h or like shell calls?

1:23 rpaulo: kernel syscalls

1:23 I found a clojure-jna project online

1:23 TerranceWarrior: how can you do RAII under clojure?

1:23 justin_smith: rpaulo: welcome to the joyful and exciting world of platform dependent java, via clojure interop, you are shure to have a load of fun

1:24 rpaulo: :p

1:24 amalloy: TerranceWarrior: how do you use perl's $_ in c? it's just not a thing you do; it doesn't exist in the language

1:24 justin_smith: rpaulo: there was a jni lib I really wanted to use, and I spent a long time trying to figure out how to integrate it with clojure, to no avail. Maybe someone else can provide more useful suggestions though.

1:24 amalloy: instead of asking how to apply a specific technique/language feature in a new language, ask about how to solve a problem

1:26 bbloom: nkozo: you can use the backtick/syntax-quote-fn function

1:26 or make your own variant of it

1:26 justin_smith: the jvm has a lot of raii just built in to the default classes that come with it, you don't have to do anything special to benefit from it

1:26 it's kind of implicit for making the jvm gc even work properly

1:26 rpaulo: justin_smith: I'm currently trying this https://github.com/Chouser/clojure-jna/

1:26 nkozo: bbloom: thanks, I'm studying your lib

1:28 justin_smith: rpaulo: using syscalls directly you can skip the C compatibility part - if jna lets you put values into registers and then invoke an opcode you just need to make a map of syscall name to integer value based on the C header file - that's how C is doing it anyway

1:29 rpaulo: well, how would I go about creating C structures in clojure?

1:29 justin_smith: syscalls don't use c structures

1:29 you put some numbers in registers, then invoke an interrupt

1:29 that's it

1:30 rpaulo: sure, but that's not what I meant

1:30 justin_smith: oh, ok

1:30 ztellman has a lib for that actually

1:30 rpaulo: for statfs, I need to get a struct statfs

1:30 justin_smith: https://github.com/ztellman/vertigo

1:31 rpaulo: It's still not clear to me, how I could map that to clojure structures

1:31 ah, ok.

1:31 justin_smith: c uses a simple linear format, you tell vertigo how the bytes are laid out, and it should help do the rest

1:31 rpaulo: got it.

1:32 Frozenlock: WOW. That's a special kind of customer service attitude: https://www.refheap.com/85711

1:33 bodie_: lulz

1:33 please don't bug us, kthx dummy.

1:33 justin_smith: whoever writes their copy sounds like a pretty fun dude

1:34 Frozenlock: I think I'll ask them the time estimate just for the lulz.

1:35 bodie_: subject: hi

1:35 body: has it shipped yet? pls to be knowing now.

1:35 amalloy: Frozenlock: send them a postcard asking for a time estimate. they only said not to call

1:35 justin_smith: Frozenlock: "we have superimposed the time estimate over the plates for your print run, HTH"

1:36 Frozenlock: justin_smith: lol!

1:48 jw`: Are a lot of folks using CIDER for development? I'm starting out learning clojure, and I'm a huge emacs junkie, so I'm gravitating towards CIDER, but would it make more sense to not mess around with CIDER yet? I notice there isn't much docs :-).

1:53 justin_smith: jw`: the frequency of "I installed cider and everything is broken" posts on the cider repo bug tracker have slowed down quite a bit :)

1:53 I'm still on nrepl though, some day I will do a purge and upgrade to cider

1:53 Frozenlock: jw`: I still use nrepl.el

1:54 rpaulo: jna-test.core=> (jna/invoke Integer c/printf "My number: %d\n" 5)

1:54 13

1:54 jw`: Ok :). I'm going to give 6.1 a shot

1:54 * rpaulo wonders where the printf went

1:54 rpaulo: 13 is the correct return value, though

1:56 amalloy: rpaulo: probably to stdout, instead of *out*. or it may not have been flushed

1:57 rpaulo: yeah, lein run works fine

1:59 quizdr: jw` i use cide jack in for all my clojure repl work, never had a problem

2:00 jw`: quizdr - I'm going to give it a try now... I'm actually already running prelude, so this might just work out dandy.

2:01 quizdr: emacs-live uses cider too i think

2:01 it's quite popular

2:08 jweaver: Ok, there we go.

2:08 All setup now (cider).

2:10 rpaulo: what's being done to lower the startup time of clojure? I understand the problem because there are several explanations online.

2:10 justin_smith: rpaulo: there are at least two GSOC projects for a lean (faster startup) clojure

2:11 rpaulo: also if you have a finished app and just want faster run time, making an uberjar and running with java -jar has much better startup time (lein is a dev tool, not a launcher)

2:12 rpaulo: right.

2:12 justin_smith: *faster load at run time that is

2:13 maybe with a shell script that sets your jvm opts properly if you need it

2:37 TerranceWarrior: 3~3~in '(take 10 (filter odd? (iterate inc 0)))' does filter "yield" to "take"?

2:38 * Frozenlock just learned now of the 'app' lein template that will automatically add a gen-class and a -main function

2:38 Frozenlock: TerranceWarrior: yield?

2:38 amalloy: TerranceWarrior: lazy sequences aren't generators, but they're sorta similar

2:48 quizdr: ,(take 10 (filter odd? (iterate inc 0))

2:48 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

2:49 quizdr: ,(take 10 (filter odd? (iterate inc 0)))

2:49 clojurebot: (1 3 5 7 9 ...)

3:00 TerranceWarrior: amalloy: clojure is strict evaluation.

3:01 quizdr: I seem to remember reading once that using a map as function vs the key is that if the key is not present, you get nil, while with the key as function you get an exception. But I don't actually see that happening. Did this change in recent versions of Clojure?

3:02 amalloy: yes, but lazy sequences convert expressions to thunks, basically. so (map f xs) is a no-arg function which, when called, produces a single value, and a thunk for producing more of the sequence

3:02 i mean, that's not really quite what happens, but it's the basic mechanism allowing the "strict evaluation" objection to not apply to lazy sequences

3:03 quizdr: the difference is just that whichever one you use as a function will break if it's nil. ie, (k m) fails if k is nil, and (m k) fails if m is nil

3:03 see http://stackoverflow.com/questions/7034803/idiomatic-clojure-map-lookup-by-keyword, for example

3:04 actually, that doesn't really address your question

3:04 TerranceWarrior: amalloy: okay so the 'thunking' is part of eval. makes sense.

3:04 amalloy: i guess http://stackoverflow.com/a/14491027/625403 is what i meant

3:04 TerranceWarrior: well, not really

3:04 quizdr: amalloy oh i see what you mean. i was confusing "not present" with "nil"

3:05 amalloy: (lazy-seq x) is a macro, which expands to something like (fn [] x)

3:05 dbasch: not to mention things like

3:05 ,(let [m 1] ({} m))

3:05 clojurebot: nil

3:05 quizdr: amalloy in your answer to that question you mention "hotspot" what is that?

3:05 dbasch: ,(let [m 1] (m {}))

3:05 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

3:06 amalloy: $google jvm hotspot

3:06 lazybot: [HotSpot - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/HotSpot

3:07 quizdr: i see thanks

3:08 amalloy: tldr, it's the JIT that optimizes your code while it's running

3:09 TerranceWarrior: it's easier to just think of the eval process as always yielding to the enclosing function.

3:14 ,(gensym "hi")

3:14 clojurebot: hi75

3:14 TerranceWarrior: ,(gensym "hi")

3:14 clojurebot: hi100

3:14 TerranceWarrior: ,(gensym "hi")

3:14 clojurebot: hi125

3:16 quizdr: do all defmethods take a single parameter, which is always the result of the dispatch function (which also returns just one value, of course) ?

3:21 AimHere: ,(doc defmethod)

3:21 clojurebot: "([multifn dispatch-val & fn-tail]); Creates and installs a new method of multimethod associated with dispatch-value. "

3:21 quizdr: ah nevermind i see the entire original form is passed on to the mulimethod

3:31 TerranceWarrior: ,(gensym "hi")

3:31 clojurebot: hi27

3:32 TerranceWarrior: ,(= (str gensym "hi") "hi49")

3:32 clojurebot: false

3:32 TerranceWarrior: ,(gensym "hi")

3:32 clojurebot: hi76

3:32 TerranceWarrior: ,(gensym "hi")

3:32 clojurebot: hi101

3:32 TerranceWarrior: ,(= (str gensym "hi") "hi126")

3:32 clojurebot: false

3:33 * babilen hands TerranceWarrior one REPL

3:33 * quizdr confirms the REPL is in good condition

3:33 Glenjamin: you can clojurebot via /msg too :)

3:33 babilen: (if you can't afford your own REPL)

3:34 Glenjamin: it's that jvm/clojure.core startup time :)

3:40 TerranceWarrior: you hear me talkin hillybilly boy?

3:43 quizdr: ok, look, first of all, how did you know my name is Billy?

3:48 TerranceWarrior: how is inheritence used in lisp, through strict encapsulation?

3:48 lisp=clojure

3:49 beamso: inheritence, as in the object-oriented language concept?

3:50 amalloy: are you sure you wouldn't rather write c++? raii, inheritance, encapsulation - these are all things that clojure doesn't really do

3:50 jkj: well java oo is supported and you can layer functionality on classes

3:50 amalloy: i mean, encapsulation, a little, yes

3:51 jkj: so i quess working with java stuff is quite doable, but with native clojure inheritance is likely not needed

3:55 quizdr: i've seen examples of lexical scoping combined with optional keyword arg maps to provide the basic idea of encapsulated member variables and member functions. don't really see a point to it, but it's certainly possible. inheritance would be a bit more complex than that.

3:56 like (myobject :accelerate 50) and (myobject :stop)

4:01 clgv: quizdr: you are trying to build a FSM?

4:02 quizdr: clgv i don't know what FSM is, but no i was addressing question by TerranceWarrior

4:02 finite state machine?

4:02 clgv: yes

4:03 quizdr: i would think that anyone needing to do that would be better off using another language as amalloy suggests or just using protocols, records, types, etc

4:04 clgv: quizdr: not the FSM part. but as I see in the log he was asking for inheritance specifically

4:04 there are at least two clojure libs to define FSMs

4:06 mr-foobar: in a source code how do you detect the compiler as clojurescript or clojure ?

4:06 quizdr: fine extension clj vs cljs

4:06 *file

4:07 martinklepsch: is using env vars to store database details etc a thing clojure people do?

4:07 mr-foobar: macros are clj in clojurescript

4:07 quizdr: mr-foobar but they are actually clojure not clojurescript

4:07 they are clj but you can use them in cljs

4:07 Pugnax: https://github.com/ptaoussanis/sente/blob/master/src/taoensso/sente.cljx

4:08 There are a few examples

4:08 mr-foobar: quizdr : true. its

4:09 beamso: martinklepsch: env vars? you mean defs?

4:09 clgv: martinklepsch: why not just use a config file in clojure data (or EDN)

4:09 martinklepsch: beamso, no more like $HOME

4:10 clgv would make it harder to supply details at runtime

4:10 quizdr: mr-foobar if you look at the javascript that results from using macros in clojurescript, you'll see that the macro is no a part of the javascript. the macro helps to create the clojurescript and is done on the compiler side. and the compiler is clojure anyway, so the macros fit right in there.

4:10 beamso: i know for heroku the database url is an environment variable

4:10 clgv: martinklepsch: what? please explain.

4:10 mr-foobar: quizdr: just that i am writing a debug macro ... pritnln vs console.log i could write the code in separate namespaces or have a if clojurescrpt

4:10 mange: martinklepsch: I've seen http://yobriefca.se/blog/2014/04/29/managing-environment-variables-in-clojure/ discussing using environment variables for config.

4:11 quizdr: well actually all println statements in clojurescript can be console.log if you use (enable-console-print!) mr-foobar

4:11 so you could use the same macro for both in that case

4:11 martinklepsch: clgv, when I start my jar it's simple to set env vars before doing that. when I'd store that in a file I'd have to change the file and starting the application wouldn't be a 1-liner anymore

4:11 clgv: martinklepsch: I often use the pattern to have a commandline option "--config" which specifies the configuration file to use. the main method loads it and uses the parameters as needed

4:12 mr-foobar: quizdr: ah thanks

4:12 clgv: martinklepsch: but therefore it is pretty easy to see what you started the program with

4:12 TerranceWarrior: quizdr: closure is the ultimate inheritence for clojure.

4:12 clgv: martinklepsch: if thats your reason then its not really worth discussing since the "effort" you mention as marginal

4:13 quizdr: TerranceWarrior that sounds a bit cryptic to me

4:13 TerranceWarrior: the flatness of functionality makes me believe that there are as large a scope of function as there are as many functions to scroll through.

4:14 quizdr: And potted plants shall inherit the Earth.

4:14 TerranceWarrior: it doesn't feel right to me there there are soo many functions t traverse through programmability, but i come from a c++ backgrund.

4:15 programmably

4:15 quizdr: TerranceWarrior i too come from a c++ background, and while at first all those functions seem overwhelming, the end of it is that they each do so much with such short work that they prove worth knowing

4:17 and there is something liberating about having the guts of your app be generic data structures that can be easily manipulated without restructuring large parts of your logic, as is often the casein c++

4:17 clgv: TerranceWarrior: classes in c++ usually also have much more than one emthod

4:18 quizdr: lisps in general tend to have more emphasis on data structure and less on actual app logic, since so much of the logic is built into these heavy functions that bend general data

4:18 in c++ to get the same functionality requires a lot of work just to arrive at where clojure starts

4:18 clgv: TerranceWarrior: so if you take all those together there is maybe small factor between the numbers and thats because elementar widely usefull functionality is implemented as small functions in clojure

4:20 quizdr: Writing c++ feels more to me like engineering, while writing clojure seems more artful and creative

4:20 pyrtsa: quizdr: Knowing enough of clojure.core (or any other similar library) actually helps in using the C++ standard library better. There are a number of very useful algorithms 98% of C++ programmers don't know of but should.

4:21 quizdr: pyrtsa that is true. and Qt's library actually has many C++ tools for doing map, reduce and other similar functional tasks concurrently across many cores

4:21 pyrtsa: Of course, it's still not as nice as Clojure. :)

4:22 quizdr: but using the STL cannot be compared to the ease of using clojure.core

4:22 and rarely will you have a finished C++ app that is not at least 10x lines of code as a clojure app of the same scale. hence the engineering vs artfulness i experience

4:22 clgv: I wouldnt touch C++ at all without the STL or boost ;)

4:22 pyrtsa: quizdr: Clojure.core is actually missing a lot of algorithms that are found in the std.

4:23 clgv: Likewise.

4:23 quizdr: pyrtsa example of one you find useful?

4:24 clgv: quizdr: logarithmic search on a sorted random-access "list" - if I remember correctly that is available in the STL

4:24 pyrtsa: lower_bound

4:26 quizdr: hm, lower_bound looks a bit like "some" if you give it the predicate similar to lower-bound

4:27 pyrtsa: Here's a good list of algorithms, some of which have their counterparts in clojure.core, some of which don't but could, some of which are maybe too specific to immutable data structures (but could be implemented for transients, I concur): http://en.cppreference.com/w/cpp/algorithm

4:27 quizdr: You must take into account that the algorithm always comes with a defined complexity. clojure.core/some has a complexity of O(n).

4:28 quizdr: true

4:28 clgv: quizdr: I meant binar search with "logarithmic search" ;)

4:29 quizdr: it is on the linked page as well ^^

4:30 quizdr: it's interesting to note that Rich Hickey was somewhat of a c++ superstar in the years before his invention of clojure

4:30 pyrtsa: clgv: Off-topic, but lower_bound is usually what you need when looking for binary search.

4:30 clgv: pyrtsa: ah right, I didnt use that since quite some time. ;)

4:32 pyrtsa: quizdr: FWIW, here's a very good talk on the use of algorithms instead of hand-written loops, by another "C++ superstar": http://channel9.msdn.com/Events/GoingNative/2013/Cpp-Seasoning

4:34 quizdr: watching the beginning of it now

4:34 pyrtsa: TerranceWarrior: ^ Might interest you as well.

4:36 TerranceWarrior: i like clojure's multiple dispatch.

4:38 if I had a penny for each time a techie started a sentence with the word 'so'.

4:40 martinklepsch: I'm trying to get environ setup but constantly get this when requiring it: CompilerException java.lang.ClassNotFoundException: environ.core

4:40 quizdr: pyrtsa i like how he says than when writing a general function, he always writes it very concretely at first, then learns later how it can become general.

4:40 martinklepsch: I tried to kill all java processes and ran lein clean

4:41 quizdr: i find it can be intimidating to always write good idiomatic ideal-end-result code in clojure (meaning very general) when i'm implementing an idea for the first time

4:41 martinklepsch: is there some other cleanup stuff I could do? [environ "0.5.0"] is in my :dependencies map

4:46 Glenjamin: martinklepsch: try `lein clean`

4:46 oh

4:46 you did

4:46 that's all i had, sorry :(

4:46 `lein classpath` maybe

4:48 martinklepsch: Glenjamin from the error I'd assume that the dependency hasn't been installed but running lein repl usually does that on it's own

4:49 Glenjamin: try nuking the environ folder in ~/.m2 perhaps

4:56 clgv: martinklepsch: lein deps :tree does not complain?

4:58 martinklepsch: clgv, not more than this: "WARNING!!! possible confusing dependencies found" ... (which doesn't seem related to environ

4:58 clgv: martinklepsch: if it is not listed there, right

4:58 martinklepsch: maybe I'll just ditch environ and go for (or (System/getenv "HOME") "/home/martin")

4:58 clgv: martinklepsch: maybe some typo in the actual code then?

5:04 martinklepsch: clgv, environ is in that list. there is a lot in that list actually

5:05 clgv: martinklepsch: I meant a typo/error in the :require form

5:06 martinklepsch: just wanted to write "nevermind ..." — it was actually a missing quote

5:06 (require [environ.core :refer :all]) vs (require '[environ.core :refer :all])

5:06 * martinklepsch bangs his head against the wall

5:08 phillord: anyone got experience with visualvm? It seems to work and then just hangs whenever I do any work in the clojure vm

5:26 clgv: martinklepsch: you use that on the REPL right? in a file you shoud use a :require form in the namespace definition

5:28 szymanowski: Hello, is there something like clojure.math.combinatorics for clojurescript?

5:53 dbushenko: is there a way to list all functions in the clojure namespace or buffer ?

5:53 (in emacs)

5:59 quizdr: dbushenko yes

6:00 well you can list everything that is def'd

6:01 dbushenko: quizdr, how?

6:04 vijaykiran: dbushenko: which emacs setup do you use ?

6:04 dbushenko: emacs-live .. or something or plain emacs ?

6:05 dbushenko: plain emacs with clojure-mode and cider

6:06 vijaykiran: well - usual grep for defn should work then

6:06 dbushenko: yep, thats the rough way, is there a more smart one?

6:07 vijaykiran: I use emacs-live and it has https://github.com/overtone/emacs-live/blob/master/packs/dev/foundation-pack/config/ido-conf.el#L26

6:07 to jump between functions

6:07 dbushenko: thanks!

6:08 no, thats go to symbol, I can do that with cider

6:08 I mean, list of all definitions

6:08 *I need list of all definitions

6:10 elephantTechno: http://stackoverflow.com/questions/2747294/how-to-list-the-functions-of-a-namespace

6:18 clgv: what elephantTechno said ^^

6:18 dbushenko: just use ns-publics on the repl

6:19 alexyakushev: Hello everyone

6:19 clgv: dbushenko: if you need private variables as well -> ns-interns

6:19 alexyakushev: I'm currently experiencing a terrible wtf syndrome

6:19 clgv: ,(apropos "ns-")

6:19 clojurebot: (ns-unmap ns-publics ns-unalias ns-aliases ns-resolve ...)

6:19 alexyakushev: Can someone take a look at this? https://www.refheap.com/85715#L-20

6:20 This is a java bytecode for AOT-compiled clojure.core/first function

6:20 clgv: alexyakushev: what's you problem with that?

6:20 alexyakushev: Lines 20-22

6:21 First argument is assigned to null before calling RT.first

6:21 clgv: locals clearing. it is not what you interpret it to be ;)

6:22 alexyakushev: OK, so how does exactly it work? Does RT.first receives an actual argument and not null?

6:22 clgv: alexyakushev: jvm bytecode has a stack architecture

6:22 or ebtter the jvm has

6:24 alexyakushev: afaik aload_1 loads the object on the stack, aconst_null creates a null constant above it astore_1 overwrites location (register?) 1 with the constant leaving the initial object on the stack which is used for the static function call

6:25 alexyakushev: Tricky

6:26 dbushenko: clgv: thanks

6:26 clgv: alexyakushev: locals clearing is need for lazy sequences to work. otherwise code that does not need to would keep a reference to the head of a lazyseq and thus it'll be impossible to garbage collect unneeded elements of the sequence

6:27 alexyakushev: clgv: Thank you, it makes sense now

6:27 OK, right, astore_1 doesn't consume the object on the stack

6:27 That was what I misinterpreted

6:27 clgv: alexyakushev: it looks pretty weird in the decompilers especially when they try to reconstruct java code

6:28 alexyakushev: clgv: Hell yeah it does https://www.refheap.com/85716

6:28 clgv: alexyakushev: it's a good heuristic to just filter out those null assignments to function parameters

6:29 alexyakushev: Yeah, got it now

6:29 Thanks a lot for clarification

6:29 clgv: alexyakushev: did you search for performance problems?

6:29 alexyakushev: clgv: No, just experimenting with the compiler

6:30 clgv: ah ok

6:30 alexyakushev: try out effects of type hinting and primitve type hints on function arguments ;)

6:32 alexyakushev: Looks disgusting:)

6:35 clgv: huh? I just wanted to recommend interesting cases to look at ;)

6:52 alexyakushev: clgv: I mean, now I understand why wrongfully placed type hints actually hurt performance

6:57 clgv: alexyakushev: non-primitive type hints shouldnt do that. primitive ones might, if they cause continously boxing and unboxing

7:11 colock: hallo

7:11 agarman: colock: hihi

7:11 colock: laugh or salute? :D

7:12 gently approaching the language… i think a lisp is a good thing to have on one's luggage

7:15 noncom|2: colock: lisp is the end of the journey

7:15 clgv: colock: luggage? use it as train or airplane! ;)

7:15 colock: righto

7:15 clgv: spacecraft even :D

7:15 colock: i put myself in the luggage

7:16 agarman: a couple recent movies may have changed people's connotations of ()

7:16 colock: namely?

7:16 clgv: agarman: explain please

7:16 agarman: http://yaleherald.com/wp-content/uploads/2014/04/shia-labeouf-nymphomaniac-movie-poster-revealed-03.jpg

7:17 colock: oh...

7:17 well, lamba now denotes a fps game…

7:17 clgv: agarman: lol what?

7:17 colock: *lambda

7:17 agarman: I saw that poster and thought maybe it's a movie about lisp

7:17 nope

7:17 colock: agarman: nil

7:18 agarman: poster is just ()

7:18 on a white background

7:18 noncom|2: '()

7:21 ddellacosta: homoiconimaniac

7:21 clgv: agarman: you could photoshop it to be about a clojuremaniac ;)

7:21 ddellacosta: or that :D

7:21 agarman: that'd be awesome

7:21 not sure I could hang that in my cube at work still

7:21 colock: or photoshop the original and change "coming soon" to "coming too soon"

7:21 sorry.

7:22 ddellacosta: that was a terrible joke. You're fired.

7:22 clgv: agarman: we have a door full of funny cartoons at the inner side of our office door ;)

7:23 colock: a classic… http://stevemiles70.files.wordpress.com/2008/11/software_treeswing.jpg

7:28 clgv: colock: yeah. that's on the door ;)

7:29 colock: :>

7:30 agarman: clgv: you have a picture of your door?

7:32 clgv: agarman: no

7:33 agarman: the main sites of the cartoons there are dilbert, xkcd, nichtlustig and various cartoons from different sources

7:34 agarman: clgv: nichtlustig is new to me...gonna check it out

7:34 colock: german i guess

7:34 clgv: yeah it is german.

7:34 agarman: translated it means "no funny"

7:34 "not"

7:35 colock: tought that… the little german i did long ago was not completely useless…

7:36 clgv: :D

7:36 agarman: http://static.nichtlustig.de/toondb/140508.html is funny no matter the caption

7:37 clgv: agarman: "and here is another charge forward package from the company antidot corporation"

7:38 agarman: the voodoo cake is funny as well

7:42 clgv: agarman: right. didnt know that one until now ;)

8:08 TimMc: Huh, the treeswing software metaphor cartoon has been around in various forms for 45 years. http://www.businessballs.com/treeswing.htm

8:24 magnars: Anyone know why empty list are not falsy in Clojure, unlike most lisps? I know it's a futile thing to bring up, but it would be interesting to see the reasoning behind the choice.

8:24 jcromartie: '()

8:24 er

8:24 ,'()

8:24 clojurebot: ()

8:24 jcromartie: ,()

8:24 clojurebot: ()

8:25 jcromartie: I thought that one of those evaluated to nil

8:25 hm

8:25 beamso: ,(if '() true false)

8:25 clojurebot: true

8:25 magnars: the empty list is nil in other lisps, but not Clojure

8:25 jcromartie: yeah

8:25 agarman: magnars: it bugged me at first, but then I forgot about it

8:25 jcromartie: I think I largely ignore it because I use functions that call seq on the arg or destructuring, which does the same

8:26 ,((fn [x & more] (when more x)) 1)

8:26 clojurebot: nil

8:26 jcromartie: ,((fn [x & more] (when more x)) 1 2)

8:26 magnars: agarman: it's been a year of full time work with Clojure for me now, and I have to say that it still bugs me some times.

8:26 clojurebot: 1

8:26 phillord: http://clojure.org/lazy#Making%20Clojure%20Lazier--The%20victim%20-%20nil%20punning

8:27 jcromartie: what if we had a type system instead

8:27 :P

8:27 agarman: yeah, I occasionally forget to (seq (rest xs))

8:27 mostly I've tried to stick to using next

8:31 ,(inc phillord)

8:31 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: phillord in this context, compiling:(NO_SOURCE_PATH:0:0)>

8:31 agarman: (inc phillord)

8:31 lazybot: ⇒ 1

8:32 agarman: phillord: I'd forgotten about that change

8:32 phillord: I am unknown in this context -- what a blow to my ego

8:32 agarman: ,(def phillord)

8:32 clojurebot: #'sandbox/phillord

8:32 agarman: there no you're a different sort of unknown

8:33 phillord: ,(declare agarman)

8:33 clojurebot: #'sandbox/agarman

8:33 crispin: hey. whats the clojure zip. putting a number of sequences together.. eg

8:33 phillord: and you are unbound...

8:33 agarman: ,phillord

8:33 clojurebot: #<Unbound Unbound: #'sandbox/phillord>

8:34 crispin: (zip [0 1 2] [3 4 5]) => ([0 3] [1 4] [2 5])\

8:34 agarman: ,(map + (range 5 15) (range 9 11))

8:34 clojurebot: (14 16)

8:35 agarman: ,(map vector [0 1 2] [3 4 5])

8:35 clojurebot: ([0 3] [1 4] [2 5])

8:35 crispin: haha. map and vector. cool

8:35 didnt know map behaved like that with multiple seqs

8:35 thanks agarman

8:36 noncom|2: is there a clojure version of emacs?

8:36 crispin: I just use emacs :P

8:36 is the answer lighttable?

8:36 thats in clojure and is very emacsey

8:37 a little emacsey

8:37 nothings quite like emacs though

8:37 agarman: I use emacs live

8:37 prelude is nice as well

8:37 noncom|2: hmm.. probably! but somehow i do not feel lighttable to be emacsey enough.. like all stuff in it you know.. :)

8:37 agarman: https://github.com/overtone/emacs-live

8:37 noncom|2: currenly i am using live, and gonna research prelude later.

8:38 mercwithamouth: emacs live felt too heavy for me...though it was cool

8:38 noncom|2: i was just wondering, is there something like emacs but written in clojure with the C core of emacs being replaced iwth JVM

8:39 mercwithamouth: i'm liking the setup from braveclojure along with ac-nrepl, yasnippets and rainbow delimiters at the moment...and of course cider

8:39 noncom|2: taking all the jvm and concurrency wins, it would be a cool thing i think

8:39 agarman: my various emacs configs from the last few months are here: https://gist.github.com/agarman/9728389/revisions

8:40 emacs-live was just simpler to explain to coworkers than my previous user.el file

8:52 crispin: i found emacs24 + elpa + melpa + marmalade has stripped my .emacs way down

8:53 used to be a full repository

8:53 now its about 20 lines

8:54 i find cide-jack-in a little unreliable though

8:54 first time it jacks in fine

8:54 but loose your repl somehow and when you jack-in again I get nrepl

8:54 not cider

8:55 its wierd

8:55 agarman: crispin: you probably have both cider and older version of nrepl installed

8:56 crispin: i do yes

8:56 agarman: crispin: remove nrepl

8:56 crispin: i was using nrepl aswell

8:56 yeah ill try that

8:56 agarman: crispin: cider replaces nrepl

8:57 crispin: yeah. i was just fiddling around. had difficulty getting cider to behave how I wanted

8:57 like want to eval last s-exp is the repl buffer

8:57 not in the minibuffer

8:58 and have stdout of repl in another seperate buffer

8:58 that kind of thing

8:58 but maybe I should just drink the kool aid and go all cider blessed route

9:04 mpenet: cider has come a long way, it's really nice now

9:05 mdrogalis: mpenet: That's good to hear. I'll have to give it a go again.

9:05 clgv: we should add some guiness to cider ;)

9:06 mpenet: I like the new error screen in particular

9:10 phillord: is cider 0.6 on marmalade?

9:11 clgv: cider on marmalade sounds awful ;)

9:11 joegallo: phillord: "P.S. I'm having problems uploading the package to Marmalade for the millionth time. Not sure when (if ever) CIDER 0.6 will land there."

9:11 from the release notes for 0.6

9:11 phillord: bummer

9:11 oh, yes, I totally missed that

9:11 joegallo: me too

9:11 phillord: hmmm, well, that's irritating

9:11 mpenet: marmalade has been kinda unreliable lately...

9:11 joegallo: mpenet: yeah :(

9:11 phillord: I know

9:12 but If I move to melpa, then I get too many bleed edge packages

9:12 mpenet: there's melpa stable

9:12 joegallo: anyway, phillord, you can solve it by adding '("melpa-stable" . "http://hiddencameras.milkbox.net/packages/&quot;) to your 'package-archives

9:12 phillord: oh? there is?

9:12 joegallo: mpenet: you beat me to it :)

9:12 mpenet: :)

9:12 dans: @fortune

9:13 mpenet: but I have been ok with cider master

9:13 phillord: probably it was during the change over from nrepl, but life became unstable

9:13 mpenet: I am on cider-nrepl 0.7.0-SNAPSHOT, seems stable

9:13

9:13 stable'ish

9:15 phillord: -ish isn't good enough for me -- I develop on five or six machines, so if I use unstable, they all end up on slightly different versions

9:16 clgv: ,(def fortune (atom "Help! I'm a slave worker trapped in a Chinese fortune cookie factory."))

9:16 clojurebot: #'sandbox/fortune

9:16 clgv: ,@fortune

9:16 clojurebot: "Help! I'm a slave worker trapped in a Chinese fortune cookie factory."

9:17 colock: ahahah

9:19 mmitchell: I'm using prismatics schema and am wondering if it's possible to specify a schema on a record methods *return value*. Anyone know?

9:20 beamso: no idea about the specific answer to your question but there are pre and post assertions that you can put on a function

9:24 clgv: mmitchell: you can easily check that, since they would need a special defrecord macro to do that

9:24 similar to the special defn they have

9:25 mmitchell: beamso: oh thanks, yeah i want to see if i can get the schemas working as an alternative to :pre/:post

9:25 clgv: I tried schema/defrecord, but it's throwing an exception

9:28 clgv: mmitchell: two possibilities - either you are using it incorrectly or you found a bug. the existing docs (hopefully) should help to find out

9:29 mmitchell: clgv: good points. I'll check the docs

9:47 CookedGryphon: Is there a way with a macro to read the column/line number metadata of the s-expression you're about to expand?

9:49 llasram: ,(defmacro form-meta [& args] (meta &form))

9:49 clojurebot: #'sandbox/form-meta

9:49 llasram: ,(form-meta (whatever))

9:49 clojurebot: nil

9:49 llasram: Well, maybe it works in a file :-)

9:49 CookedGryphon: heh

9:50 llasram: Yeah, it does

9:50 CookedGryphon: ooh

9:50 totally does

9:50 okay, think I know what I'm hacking on tonight...

10:04 llasram: sorry, what does the & do?

10:06 crispin: ,(use '[clojure.string :only (join split)])

10:06 clojurebot: nil

10:06 crispin: ,(def fname "some/path/to/file.txt")

10:06 clojurebot: #'sandbox/fname

10:06 crispin: ,(last (split fname #"\."))

10:06 clojurebot: "txt"

10:07 crispin: whats a better way to get file extension?

10:08 colock: last + split seems quite good way to me…

10:08 could reverse and use first

10:09 crispin: they're be the same speed on vectors?

10:09 first and last?

10:09 pyrtsa: ,(last (split ".lein" #"\.")) ;; not quite right

10:09 clojurebot: "lein"

10:09 colock: well, the reverse is costly.

10:33 CookedGryphon: I have a macro which takes multiple args, if I was using backtick syntax I'd do ~@body to replicate all the inputted body

10:33 does that just wrap the things in a do? Or is there some other trick for outputting multiple forms

10:34 joegallo: CookedGryphon: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2386

10:35 you need the do explicitly, or you need to be inside something that already is an implicit do, like a try/catch or a let or fn or something

10:35 cbp: body is a list of forms. ~@body splices that list, which means it basically concats it with whatever you're putting it into

10:38 CookedGryphon: yeah, seems `~@body doesn't actually work

10:39 you can't do that at a top level and splice in more than one form as a result of a defmacro, which makes sense as a restriction

10:42 llasram: CookedGryphon: Yeah, just wrap it in a `do`. The compiler specially handles top-level `do`s, compiling each sub-form as if it were an independent top-level form

10:43 nkoza: llasram: what's the difference for the compiler between a top-level form and a non top-level one?

10:43 llasram: nkoza: The basic unit of compilation is the top-level form. Each top-level form is compiled independently and serially

10:44 Which is e.g. why you need `declare` for forward references, but also keeps the macro model simple

10:45 nkoza: llasram: did the compiler works in this way? if you have a (def a 1) top-level form, a compile-time var is created with the 1 value, so you can access later from macros, etc, and when al vars are created by interpreting all the top-level forms, the compiler gets their values and "freezes" them?

10:47 arrdem: clojurebot: channels is <REPLY> (#clojure #clojure-offtopic #typed-clojure #leiningen)

10:51 CookedGryphon: is there a way to get a map of everything that's bound locally in a frame

10:51 so (let [x 2, y 7] (desired-function)) => {'x 2, 'y 7, ...}

10:52 gfredericks: ,(defmacro locals [] (zipmap (map #(list 'quote %) (keys &env)) (keys &env)))

10:52 clojurebot: #'sandbox/locals

10:52 gfredericks: ,(locals)

10:52 clojurebot: {}

10:52 gfredericks: ,(let [x 12] (locals))

10:52 clojurebot: {x 12}

10:52 CookedGryphon: perfect!

10:52 thanks!

10:53 * gfredericks sometimes feels like #clojure is just a venue for competitive macro speed-writing

10:53 arrdem: gfredericks: what, you don'

10:53 t write macros for internet points?

10:54 gfredericks: I have whole libraries that are just internet-point-macros

11:01 whomp: how do i add surrounding parentheses to the current outermost set of parentheses that my cursor is within? i often work from the inside out, and i hate type "(", having it create "()", and then deleting the extraneous paren and adding it elsewhere

11:01 *hate to type

11:02 CookedGryphon: depends on your editor, with paredit you'd press M-(

11:02 to wrap the next form

11:02 or do what you were doing and then press C-RightArrow to move the bracket to wrap the next form

11:07 whomp: CookedGryphon, got it, thx :)

11:34 servo: for reseting a value in a ref is it better to use ref-set or use something like (commute my-ref (fn [x] some-constant-value))

11:34 where "constant" is (deref some-other-ref)

11:40 noncom|2: how is lighttable now? is someone using it for a daily job?

11:41 arrdem: I understand from cbp and others that Light Table is pretty much the go to tool for srs clojurescript work, but I haven't tried to use it for "real" clojure hacking due to having doubled down on emacs recently.

11:42 cbp: I replaced it with emacs after i figured out austin and weasel after that

11:46 ddellacosta: arrdem: why is it the go-to tool for serious CLJS work? Emacs serves me well for CLJS

11:46 arrdem: but would be interested in hearing what's better about LT

11:47 arrdem: ddellacosta: my understanding was that it packaged a lot of stuff that's finicky to get set up for emacs but I'm not speaking from experience here.

11:47 ddellacosta: arrdem: ah, okay, that I can understand the appeal of

11:47 nullptr: i think brepls are finnicky across the board, but LT does make it easier to set up

11:48 [emacs/*] + cljsbuild auto + [f5] is a reasonably productive cljs env with fewer oddities to sort through

11:48 ddellacosta: yeah, I've been using a hacked together piggieback installation for some time in my main project and haven't tried setting it up from scratch with austin or anything recently

11:48 nullptr: yeah, that's what I use usually

11:49 nullptr: just make sure source maps are off :)

11:49 visof: ,(reduce conj {} (list {:words "hello"} {:words "world"}))

11:49 clojurebot: {:words "world"}

11:49 ddellacosta: fast, simple, does most of what i need w/repl

11:49 even source maps are not that slow recently

11:49 visof: how can i get somethig like {:words ["hello" "world"]}, if there is the same key

11:51 clgv: visof: merge-with

11:51 arrdem: visof: merge-with conj

11:51 visof: ah

11:51 clgv: nope "conj" wont work

11:51 visof: ,(merge-with conj {} (list {:words "hello"} {:words "world"}))

11:51 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.util.Map$Entry>

11:51 clgv: only if you specify an empty map first

11:51 ,(merge-with conj {} {:words "hello"} {:words "world"})

11:51 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IPersistentCollection>

11:52 clgv: harr not even then ;)

11:52 visof: ,(merge-with conj (list {:words "hello"} {:words "world"}))

11:52 clojurebot: ({:words "hello"} {:words "world"})

11:52 clgv: you need to check wwhether you already have a vector there

11:53 nullptr: ,(map :words '({:words "hello"} {:words "world"}))

11:53 clojurebot: ("hello" "world")

11:53 clgv: ,(merge-with #(if (string? %1) [%1 %2] (conj %1 %2)) {:words "hello"} {:words "world"})

11:53 clojurebot: {:words ["hello" "world"]}

11:53 clgv: visof: ^^

11:54 could be worth it to write a single function similar to merge-with that does that

11:54 arrdem: I'm sure flatland's util library already has one...

11:54 clgv: arrdem: never used that one directly ;)

11:54 arrdem: $google flatland useful

11:54 lazybot: [org.flatland/useful - Clojars] https://clojars.org/org.flatland/useful

11:55 clgv: arrdem: hu right no docs. thats a reason ;)

11:56 arrdem: $google flatland.org

11:56 lazybot: [Flatland.org] http://flatland.org/

11:56 visof: (merge-with #(if (string? %1) [%1 %2] (conj %1 %2)) ({:words "hello"} {:words "world"}))

11:56 arrdem: clgv: do you see my name on that list?

11:56 visof: ,(merge-with #(if (string? %1) [%1 %2] (conj %1 %2)) ({:words "hello"} {:words "world"}))

11:56 clojurebot: nil

11:56 arrdem: :P

11:56 clgv: arrdem: no why?

11:57 visof: ,(merge-with #(if (string? %1) [%1 %2] (conj %1 %2)) {:words "hello"} {:words "world"} {:nothing "nothing"})

11:57 clojurebot: {:nothing "nothing", :words ["hello" "world"]}

11:57 visof: ,(merge-with #(if (string? %1) [%1 %2] (conj %1 %2)) {:words "hello"} {:words "world"} {:nothing "nothing"} {:words "foobar"})

11:57 clojurebot: {:nothing "nothing", :words ["hello" "world" "foobar"]}

11:57 clgv: visof: if you need it to operate on lists use (apply merge-with ...)

11:57 visof: yeah okay

12:01 gfredericks: amalloy_: here's a feature for the def-utils lib -- things for defining functions point-free but still getting useful arglists AND function class-names

12:06 sandbags: anyone run into problems with tagged literals in test code? I'm not sure how to narrow this down but my reader function is coming up as an unbound function in my test where the same code in the REPL is working. I realise it's a bit vague but if this pings for anyone I'd appreciate a nudge in the right direction or useful questions...

12:09 llasram: sandbags: Is your test namespace `require`ing the namespace which provides the tagged literal data reader function?

12:09 sandbags: llasram: yep

12:10 llasram: That's the only issue I can think of off the top of my head... Code/paste?

12:11 gfredericks: sandbags: keep in mind how code is read/evaluated

12:11 you need to make sure the namespace defining the reader function is finished loading before _any_ uses of your reader literal are read from your code

12:12 sandbags: gfredericks: okay, is it not finished after the :require part of the ns?

12:12 gfredericks: it should be, yes

12:12 this isn't normally difficult to get right

12:12 sandbags: because my use is after the :require

12:12 i'm just assembling a paste of the relevant stuff

12:12 hopefully i've just done something daft

12:12 llasram: MADNESS is GLADNESS

12:13 CookedGryphon: does anybody have a clue how I might walk a tree extracting the metadata

12:13 gtrak: llasram: atlanta weather getting you down?

12:13 CookedGryphon: postwalk and anything I roll by hand with recursive maps seems to lose the metadata past the top level

12:14 sandbags: okay hopefully i didn't elide anything important: https://www.refheap.com/85727

12:14 CookedGryphon: I tried redefining clojure.walk/walk to create new structures and reattach the metadata of the parent, but it doesn't seem to work

12:14 llasram: gtrak: Actually, it's *gorgeous*. It's at that perfect point where everything is sunny, but not yet heat-stroke-inducing

12:14 gtrak: is everything covered in a layer of yellow yet?

12:14 llasram: gtrak: Oh, that's passed already

12:14 sandbags: oh, i forgot to add the exception

12:15 llasram: sandbags: Oh, cljx. Hmmmm

12:15 sandbags: okay i've resaved the paste with the exception

12:16 I don't get the impression this is CLJX related

12:16 the CLJX part has to be out of the way in order for the CLJ code to be running

12:16 and the relevant CLJ code is all there in my targets/ folder

12:17 llasram: Check the generated CLJ code, see if anything got weirded?

12:17 sandbags: also, if i require from the REPL and use my tagged literal it does work

12:17 llasram: I just haven't used cljx and don't know how it handles reading tagged literals

12:17 sandbags: CLJX is a pre-processor

12:17 llasram: Right, but it pre-processes Clojure data, right?

12:17 WHich means it needs to `read` the code?

12:18 sandbags: yes

12:18 nothing weird about my data_readers.clj

12:18 other clj files look as expected

12:19 AFAICS the CLJX pre-processor has emitted good code

12:19 llasram: ok

12:21 hmmm

12:21 sandbags: as you can see (https://www.refheap.com/85728) from REPL all appears okay

12:24 llasram: I don't know what's happening here. I've done very similar stuff w/o problem

12:25 sandbags: okay, do appreciate you taking a look for me, thanks

12:26 at least i know it *ought* to work :)

12:26 llasram: Probably unrelated issue -- your `emit-entity` function is returning a form which evaluates to an Entity instead of a Entity value itself. Because the expansion happens at read-time, you can end up with weeeeirdness when then passing that form to e.g. threading macros

12:27 sandbags: i'm afraid that's a little bit monkey-see monkey-do as i cribbed the code from the Clojure source for #uuid

12:27 i did wonder about it returning a form

12:27 but i'm still new enough to clojure that i kind of glossed over it :)

12:28 llasram: It looks to me like `default-uuid-reader` returns a UUID object itself... Where does it return a form?

12:28 sandbags: hrmm... possibly i cribbed that from somewhere else

12:28 i definitely wouldn't have done it myself as i would have naturally returned the Entity

12:28 llasram: kk

12:28 sandbags: i'll change that

12:28 it took me a few goes to figure out how to setup tagged literals

12:29 llasram: Also consider not using tagged literals. They're mostly only useful if you're slinging around EDN data

12:29 Viesti: blah, got hit by this: http://dev.clojure.org/jira/browse/CCACHE-15

12:29 llasram: And they're great then, but not amazingly useful otherwise

12:30 gfredericks: llasram: I had fun using them for chessboards

12:30 sandbags: yes i'm mainly playing with them to see if it's a nicer

12:30 llasram: sandbags: Gotcha

12:30 Viesti: core.cache and core.memoize are really neat with pluggability, but sligthly sad that ttl cache performs poorly :/

12:30 llasram: gfredericks: Oh?

12:30 sandbags: i kind of wanted to avoid needing the user of the library to know about Entity type & id's

12:30 gfredericks: llasram: #chess/fen "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1"

12:31 sandbags: but, at the same time, i want a way to distinguish entity id's from other values

12:31 llasram: sandbags: For users in code, calling a function is pretty much identical

12:31 gfredericks: llasram: makes it sooper easy to copy/paste from other tools

12:31 llasram: gfredericks: Iiinteresting

12:31 sandbags: yes i considered (entity "foo") as an alternative

12:31 but wondered if #entity "foo" was more expressive

12:31 gfredericks: sandbags: I think reader literals setup in libraries might be frowned upon

12:32 but I'm not 145383% sure about that

12:32 sandbags: my presumption was that, namespaced, it should be a non-issue

12:32 certainly if i was claiming #entity i would expect to be slow-roasted :)

12:33 llasram: Just don't use a short generic namespace like `db` and you'll be fine ;-)

12:33 sandbags: :)

12:33 i'm not sold on the reader literal

12:33 but i do kind of like the clarity

12:33 gfredericks: I don't remember what happens if you have multiple data_readers.clj on the classpath

12:33 sandbags: esp. when printing out values

12:34 llasram: gfredericks: It loads them all, and as of 1.5.1 only complains if the same literal is assigned different reader vars

12:34 hiredman: gfredericks: datomic does it, it must be fine...

12:35 llasram: gfredericks: And as of Leiningen 2.3.3, lein will merge data_readers.clj files when building an uberjar. So I don't really see any difference from use of namespaces+bases for normal code

12:35 sandbags: man if something could just be done about clojure startup time....

12:35 gfredericks: hiredman: ooh I forgot about that; I'm convinced now.

12:35 arrdem: sandbags: several things being done about it :P

12:35 sandbags: arrdem: i r pleased to hear so

12:35 gfredericks: for example, lots of people are waiting for the jvm to startup

12:35 sandbags: when you're struggling to get a lein command running and try it over and over ... ;-)

12:38 in the normal course of events is there something that could cause a function to be unbound?

12:38 i mean without calling some hypothetical (unbind-fn 'my-fn)

12:38 i'm calling other functions from this namespace in the same code....

12:39 gfredericks: "calling functions" happens at a different time from reading your code though

12:39 if you minified this into a bare project with just enough to repro, you could share the whole project

12:41 sandbags: okay well i can confirm that changing emit-entity to return an Entity rather than a form that return an Entity does not fix the problem, alas

12:41 gfredericks: your point is too subtle for me ... i mean code on adjacent lines is read at the same time right?

12:41 if this function is unbound, why are the others bound?

12:42 arrdem: sandbags: no. forms are read sequentially.

12:42 sandbags: preceding forms are read and evaled first

12:42 sandbags: arrdem: i mistyped

12:42 gfredericks: sandbags: e.g.

12:42 (my/fn #my/reader "123")

12:42 let's say my/fn is defined in the same namespace as your reader

12:43 the reader function will get called (and will have to have been defined) much earlier than the my/fn

12:43 sandbags: what testing library are you using?

12:44 sandbags: gfredericks: Jay Fields expectations

12:44 gfredericks: if expectations was doing something crazy like trying to read all your tests before doing anything else...

12:44 * gfredericks has never used it

12:44 sandbags: hrmm... interesting point

12:44 i'm still grokking what you wrote above

12:45 llasram: Hmm. Are you using `lein test`, or an expectations-specific plugin?

12:45 sandbags: when you say "much earlier" you mean i.e. it's called during the reading phase, not the eval phase?

12:45 gfredericks: right

12:45 sandbags: okay thanks

12:46 so yes that kind of suggests this may be about expectations trying to read the code up-front

12:46 i wonder if Jay is up, if not i may have to read the code :)

12:46 gfredericks: but under sane conditions this should not be an issue as long as you're requiring at the top of any file that uses the literals

12:46 he was up earlier this morning

12:47 on the tooters

12:47 sandbags: indeed he seems up and about

12:49 arrdem: ,(name :ast/forms)

12:49 clojurebot: "forms"

12:49 arrdem: ,(let [{:keys [ast/forms]} {:ast/forms :foo}] ast/forms)

12:49 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: ast, compiling:(NO_SOURCE_PATH:0:0)>

12:51 llasram: sandbags: Are you using the lein-expectations plugin?

12:52 sandbags: llasram: lein autoexpect

12:54 llasram: sandbags: data reader literals are incompatible with reloading namespaces

12:54 At least, they are incompatible with reloading namespaces by destroying the namespace and re-creating it

12:55 Not 100% certain that's what's going on, but is my guess *digging*

12:55 sandbags: hrmm... i hear but do not understand, is there something i could read about this?

12:56 llasram: sandbags: I guess the data readers source code... I'm not aware of any documentation

12:58 sandbags: hrmm... i just bounced off that code

13:00 but i guess i am only seeing the def code, rather than where it's actually working?

13:00 llasram: Well, the gist is that the data_readers code embeds a reference to the var in the *data-readers* map

13:00 sandbags: (i'm looking at core.clj:6945)

13:00 okay yes i see that

13:01 llasram: And then... still digging in the tools.namespace code...

13:01 sandbags: this is a map inside of clojure.core right?

13:01 llasram: right

13:02 jdludlow: I'm reading http://clojuredocs.org/clojure_core/1.2.0/clojure.core/require -- Why does require use a single quote, but (ns … :require) skips the quote?

13:02 llasram: Ah hah. So tools.namespace reloads namespaces by removing the namespace then re-creating it: https://github.com/clojure/tools.namespace/blob/master/src/main/clojure/clojure/tools/namespace/reload.clj#L21

13:03 Actually, that doesn't explain anything

13:03 bah

13:03 Ok, I'm still not certain exactly what's going on :-)

13:04 But I'm well convinced that the reloading machinery is the source of the problems

13:04 sandbags: heh... you're persistent though, i like that :)

13:05 what was your hypothesis?

13:05 llasram: Ooooh! IT does explain everything!!!!

13:05 sandbags: something about the var referring to a function that is now gone?

13:06 llasram: Ok, so usually namespaces are created on-demand and never removed

13:06 When clojure.core is first loaded and initialized *data-readers*, it creates namespaces and vars for all the referenced reader functions, which will be at that point unbound

13:07 Normally, when you then load a namespace, if the namespace object already exists, it just creates/updates the bindings for vars in the namespace

13:07 sandbags: so it creates a 'fate.core ns and puts a Var in it that will be bound to my emit-entity function?

13:07 llasram: Yes, when the namespace gets loaded

13:08 But the tools.namespace reload code is destroying the namespace itself, and creating a new one to then load code into

13:08 sandbags: ok

13:08 llasram: The *data-readers* map is left holding a var in a namespace object which no-one else can see, and never gets new code loaded into it

13:08 gfredericks: is this all stuartsierra's fault?

13:09 llasram: yes

13:09 sandbags: but wouldn't the NS have been loaded (and the function bound) before the NS got reloaded?

13:09 shouldn't the Var still be holding on to a function

13:09 gfredericks: could tools.namespace have some extra data-reader-refreshment logic built in?

13:09 sandbags: or does a var not preserve what it points at

13:09 * sandbags tries to sound like he understands what he is saying

13:10 llasram: sandbags: Normally yes, but the autoexpect plugin is loading the namespace entirely through the tools.namespace reload plumbing, which destroys the namespace first

13:10 sandbags: what i am blindly reaching towards is shouldn't the Var have been bound once, when the NS was loaded

13:10 Oh!

13:10 the NS is never loaded normally you mean

13:10 llasram: Exactly

13:10 sandbags: so the NS created by the data-readers code gets blasted away

13:10 before the Var is ever bound

13:10 llasram: Exactly again

13:10 sandbags: I'm going to say "I see"

13:10 llasram: gfredericks: I believe so

13:11 sandbags: take that with a pinch of salt

13:11 I see!

13:11 llasram: heh

13:11 sandbags: hrmmm

13:11 well, first, bravo

13:12 i guess this is an issue for autoexpect not expectations itself

13:12 llasram: yep

13:13 Well, really IMHO it's a bug in tools.namespace, but autoexpect is your proximate problem

13:13 sandbags: yeah, i see where he is using the tools.namespace

13:13 so

13:13 hand me my smock, torch, and pitchfork

13:13 llasram: :-)

13:14 Have fun storming the castle!

13:14 With my lunchtime good deed done, I should probably get some actual work accomplished...

13:14 * sandbags puts down pitchfork and picks up AK-47

13:14 sandbags: llasram: many thanks

13:14 sterling detective work

13:14 llasram: np!

13:14 sandbags: and i even learned something!

13:16 gtrak: I learned 'I want feature expressions'

13:17 sandbags: gtrak: is that equiv to the +clj +cljs stuff from CLJX?

13:17 gtrak: yea, but it doesn't exist yet.

13:17 in clojure, anyway

13:17 sandbags: right

13:18 <-- uses CLJX for this reason

13:18 * arrdem can't decide if CLJX is evil or genius

13:19 sandbags: arrdem: don't rule out the possibility that it may be both :)

13:19 it works surprisingly well

13:20 but no doubt i'd rather clojure supported this out of the box

13:20 the major downside i have right now is that there's no easy interaction

13:20 between generating CLJX and running tests

13:31 cbp: (inc llasram)

13:31 lazybot: ⇒ 24

13:47 arrdem: dae consider the absence of `clojure.core/atom?` a defect?

13:49 technomancy: I'd rather have ideref? than atom?

13:49 michaelr525: hi

13:52 llasram: ditto re: ideref?

13:53 michaelr525: after going back using c-x c-spc how can i go forward to the

13:53 location I was at before going back?

13:59 agarman: (defn ideref? [x]

13:59 (or

13:59 (instance? clojure.lang.IRef x)

13:59 (instance? clojure.lang.IPending x)))

13:59 boblarrick: michaelr525: c-u c-space ?

14:00 agarman: or I guess just (instance? clojure.lang.IDeref x)

14:00 michaelr525: boblarrick: this one goes back to previous location, right?

14:01 boblarrick: yep

14:01 michaelr525: boblarrick: well, what I'd like to have is the thing which goes forward (back to the location where I were before I went back using c-u c-spc).

14:02 agarman: ,(def deref? #(instance? clojure.lang.IDeref %))

14:02 clojurebot: #'sandbox/deref?

14:03 llasram: agarman: It's not that it's difficult. It's that it would be useful in core :-)

14:03 agarman: I agree

14:04 but it's like unfold, fix and other functions I miss from Haskell that aren't included because they're easy to implement

14:05 of course I'm not sure how instance? stuff would work with cljs

14:05 Jaood: agarman: are you using clojure instead of haskell because of the jvm?

14:05 agarman: pretty much

14:05 easier to find teams working on JVM than on Haskell

14:06 Jaood: that seems to be a common reason

14:06 agarman: Jaood: I prefer the pragmatism of Clojure. And the lack of an ivory tower as well. :-)

14:08 Jaood: agarman: I though Haskell was already pass that :)

14:08 agarman: Jaood: sadly, it's history causes it problems...at my previous employer, a coworker refused to use MVars because he wanted to do it the "right" way

14:10 Jaood: existential quantifiers & state transformed readers & writers make it easy to find the bugs...but you can write the same thing with MVars much faster

14:14 whodidthis: anyone written anything about tellman/automat yet?

14:15 Jaood: agarman: a victim of its past I guess, don't really know haskell, just have skim a little through it, their type system does look like it empowers greatly the dev as they say

14:16 agarman: was curious about your clojure over haskell choice, since most common reasons seem to be the jvm and learning curve

14:18 amalloy: agarman: wait, fix isn't easy to implement in clojure

14:18 it's like impossible

14:18 cbp: fix?

14:20 arrdem: amalloy: pray tell why? the definition of fix is nigh idiot proof.

14:21 agarman: amalloy: about as simple as my deref? function above

14:21 llasram: This? http://en.wikibooks.org/wiki/Haskell/Fix_and_recursion

14:22 TravisD: Hmm, seems like the definition of fix from haskell relies pretty heavily on lazyness

14:23 agarman: Jaood: Haskell is awesome, but people can get pedantic about purity & the "right" way. Even if it means taking 10x longer to solve something trivial

14:23 TravisD: on the up-side, I'm relieved that I /finally/ understand how fix actually works in haskell, lol

14:23 agarman: lol

14:24 gfredericks: Haskell: write once, get cabal compile errors everywhere

14:25 arrdem: heh

14:25 amalloy: arrdem, agarman: because fix only works if function application is non-strict

14:26 right?

14:26 TravisD: amalloy: You also need sharing, no?

14:26 technomancy: this is different from useful's fix?

14:26 amalloy: technomancy: talking about functions missing from haskell

14:26 Raynes: gfredericks: Hahahaha +111

14:26 arrdem: oh good useful has a fix implementation. I could use a better one...

14:27 amalloy: i'm surprised you remember flatland.useful.fn/fix, technomancy. i didn't think anyone but me liked it

14:27 gfredericks: Raynes: where in tarnation have you been

14:27 technomancy: amalloy: trying to remember what part of lein used that

14:27 adsisco: how do you convert nested list into vectors?

14:27 (partition 2 (vec (distance-list)))

14:27 gfredericks: technomancy: leiningen.haskell

14:27 Raynes: gfredericks: The middle of nowhere in Mexico.

14:27 adsisco: the partition still returns a list

14:28 gfredericks: adsisco: why do you need vectors?

14:28 technomancy: the debianistas asked me to remove it since there were only three useful vars being used and they didn't want to have to package tools.macros or whatever just for that

14:28 Raynes: BUT I HAVE RETURNED!

14:28 adsisco: gfredericks: writing them into csv

14:28 Raynes: Tad ill, but I'm alive.

14:28 amalloy: oh yeah, i remember that

14:28 adsisco: gfredericks: using data.csv lib

14:28 technomancy: I wonder what happened to them anyway

14:28 gfredericks: adsisco: that doesn't sound like something that would require vectors

14:28 arrdem: technomancy: amalloy: oh that's a nice fix!

14:28 technomancy: supposedly they were kinda close to getting it through

14:29 amalloy: technomancy: https://github.com/technomancy/leiningen/commit/0f8d67d2e37

14:29 adsisco: https://www.irccloud.com/pastebin/vlCvE8Jc

14:30 lazyness at work? i have to eval them somehow?

14:30 gfredericks: adsisco: you're trying to embed a vector as a single cell?

14:31 amalloy: looks like you used fix to parse project.clj and homogenize :foo x with :foo [x], technomancy

14:31 hiredman: adsisco: that is what toString returns for lazy sequences, realized or not

14:31 adsisco: you have to use pr-str to get a readable printed representation

14:32 technomancy: map-vals <3

14:32 adsisco: hiredman and gfredericks: i am not sure i get you all ...

14:32 gfredericks: technomancy: I use map-vals all the time no matter what amalloy thinks

14:33 pyrtsa: ,(let [xs (range 3)] [(str xs) (pr-str xs)]) ;; adsisco

14:33 clojurebot: ["clojure.lang.LazySeq@7480" "(0 1 2)"]

14:33 technomancy: gfredericks: keeping the dream alive

14:33 gfredericks: plumbing also has map-from-keys and map-from-vals

14:33 arrdem: gfredericks: nice!

14:34 gfredericks: and just yesterday I found a use for group-by-fn

14:34 which I think I want quite often

14:34 adsisco: https://www.irccloud.com/pastebin/Bqrynch3

14:34 amalloy: gfredericks: map-from-keys is what? something like (zipmap ks (repeat v))?

14:34 adsisco: so i guess i just have to wrap a pr-str?

14:34 technomancy: what's the difference between group-by and group-by-fn?

14:35 pyrtsa: adsisco: Wrapping the result from partition with (vec ...) might work too.

14:35 gfredericks: adsisco: that code will give you a single row, no matter how long distance-list is -- is that what you're going for?

14:35 amalloy: no (zipmap ks (map f ks))

14:35 map-from-vals effectively lets you make a uniq index from a collection

14:36 wei__: looking to do immediate mode graphics in clojurescript. any library recommendations? something like Om but for svg/canvas/webgl would be awesome

14:36 cbp: Om can work with svg

14:36 amalloy: i think useful has that somewhere? ninjudd was doing that all the time

14:37 yeah, flatland.useful.map/map-to

14:38 adsisco: https://www.irccloud.com/pastebin/ktnOZxtN

14:38 amalloy: and index-by was the other direction (i guess map-from-vals)

14:38 pyrtsa: adsisco: (mapv vec (partition ...))

14:38 gfredericks: amalloy: yeah that's what I called it originally too

14:38 adsisco: https://www.irccloud.com/pastebin/lXzh2u4l

14:39 gfredericks: adsisco: call (mapv vec (partition 2 ...))

14:39 adsisco: pyrtsa: mapv works perfectly

14:39 thanks guys!

14:40 i'm learning some new useful function everyday =) yesterday someone introduced me to partial, it was magical

14:40 wei__: cbp: I’ve tried Reagent with SVG and the framerate is too slow with 100+ elements. maybe I’m doing something wrong? I assumed React.js wasn’t built for game graphics

14:42 adsisco: gfredericks: you were right about the single row, what happened?

14:43 cbp: wei__: yeah.. I can't help you there sorry

14:43 gfredericks: adsisco: you have the vector literal there, ensuring that the arg you're passing is a vector with one thing in it

14:43 my guess is you just want to remove those square brackets

14:44 and at that point you might not need (mapv vec ...) anymore

14:44 CookedGryphon: Can anybody give me a pointer how I might do something like a trace macro on some code which contains recurs?

14:45 I want to have a side effect print out the value of each s-expression as it completes by wrapping the s-expression in some code which evaluates, prints and then passes on the new value, but that falls down for recur, where the recur is no longer in the tail position

14:45 adsisco: gfredericks: how do i fix it?

14:45 gfredericks: adsisco: remove your square brackets

14:45 Bosky101: hello world.

14:45 whats the emacs shortcut to compile clojure

14:46 turbofail: CookedGryphon: it doesn't make sense to trace the value of a "recur" form

14:46 adsisco: gfredericks: great!

14:46 Bosky101: C-c C-k ?

14:47 CookedGryphon: turbofail: fair point, I guess I should do some analysis to ignore forms for which this doesn't make sense... are there any others you can think of where a form isn't returning a value?

14:47 llasram: Bosky101: If you hit C-h m, you should get a list of all the bindings provided by all the active modes in a buffer

14:47 turbofail: CookedGryphon: (throw ...)

14:49 amalloy: CookedGryphon: i'll be impressed if you can even detect all s-expressions which have a value

14:50 the only solution i can think of is to use tools.analyzer, which seems a bit overkill but what do i know

14:50 gfredericks: clojurebot: tools.analyzer is a bit overkill but what do i know

14:50 clojurebot: Ack. Ack.

14:51 arrdem: gfredericks: how so? t.a.jvm is potentially the only way to do so depending on the value.

14:51 gfredericks: arrdem: I don't have any opinions of my own I'm just teaching the bot new knowledge

14:52 CookedGryphon: amalloy: yeah, perhaps I sohuld be looking at tools.analyzer

14:52 dbasch: clojurebot: I don’t have any opinions of my own

14:52 clojurebot: Pardon?

14:52 gfredericks: clojurebot: I |don't| have any opinions of my own

14:52 clojurebot: Alles klar

14:52 amalloy: CookedGryphon: i think you should be looking at something more targeted than "log the value of every expression that's evaluated"

14:53 llasram: clojurebot: I?

14:53 clojurebot: I don't have any opinions of my own

14:53 CookedGryphon: amalloy: I disagree, I want to pump that out as data with the location of the forms in the file, and then have an after-the-fact step through debugger

14:53 gfredericks: amalloy: CookedGryphon: sounds like that could get quite noisy if you do it after macroexpansion

14:54 CookedGryphon: amalloy: at which point I can hide all the noise with interface, but have it there if it proves useful

14:54 taking the profiler approach of dumping everything I know to a file then exploring it

14:55 amalloy: well, it's a cool idea. you've surprised me by making me think that logging every sexp's value might be a good approach

14:55 although as gfredericks says, macros make it pretty hard

14:56 what do you do with (for [x (range 10) y (range x)] (+ x y))?

14:56 or, god forbid, just (first (range))?

14:56 CookedGryphon: let's find out...

14:56 (it should be limited by print-length)

14:57 gfredericks: a reader literal for truncated seqs!

14:57 amalloy: print-length is fine, but for a stepping debugger i would find it maddening to be unable to look past the fifth (or whatever) element of a sequence

14:57 * llasram shivers

14:57 gfredericks: #truncated-seq (1 2 3 4) ==> (concat '(1 2 3 4) (lazy-seq (throw ...)))

14:58 CookedGryphon: amalloy: yeah, well you have options then, set print-length to an appropriate length for whatever you're debugging...

14:58 or have it run in the same process as your ongoing program then you can evaluate more as required

14:58 gfredericks: I get a lot of mileage out of having a debug-repl

14:58 CookedGryphon: there's not a lot else you can ask of the program beyond that

14:58 gfredericks: you can't step through things, but you can manually evaluate whatever comes next

14:59 CookedGryphon: but yeah, i'm dumping locals too at each point which is a nice sanity check

14:59 amalloy: i still wish we had a real debugger

14:59 CookedGryphon: sohuld be able to turn this into an edebug like experience (but with a step backwards function)

15:02 amalloy: anyway, it works pretty much as I'd expect for your range example above

15:02 it doesn't try and evaluate the range

15:02 it doesn't do any evaluation which your program doesn't do anyway

15:02 gfredericks: um

15:03 how do you serialize it then?

15:03 CookedGryphon: wait, sorry, I'm talking rubbish

15:05 but yeah, it's fine with print-length set

15:06 and given that this is intended for debugging code paths etc. I think that'd be fine

15:06 you very rarely want to look in detail at all the elements of a 100+ element vector

15:06 and in the case that you do, you should probably explicitly say so

15:09 but yeah, this recur problem is a fairly fatal one, I don't know how I would rewrite for example (defn sample [x] (if (= x 0) :foo (recur (dec x)))

15:10 because I can't then wrap the if form without buggering up the recur, it's not as simple as not wrapping the recur form directly

15:10 pkothbauer: Hi! Regarding core.logic: any tips on tutorials or gist for how to use pldb instead of defrel and facts would be super appreciated. I'm just getting started with core.logic and clojure.

15:11 arrdem: CookedGryphon: is there some reason you're trying to do a trace macro rather than just building a full single step linked environment interpreter for Clojure?

15:11 a full interpreting debugger shouldn't be too hard for single thread programs...

15:12 CookedGryphon: well for a start, I wanted something at macro time so I link into the lexical representation, so I can debug what I see, rather than what it expands to

15:13 my motivation for this was a particularly hairy go-block in core.async

15:13 for which it worked a treat, then I tried using it with a go-loop

15:13 and yeah, my program isn't single threaded...

15:15 amalloy: CookedGryphon: i mean, you can rewrite that. it's not impossible, just ugly

15:15 CookedGryphon: and yeah, I don't always know what I'm looking for when I start looking at code, if I record everything then step through *that*, I can go back and look at things from earlier which i didn't realise were important at the time

15:15 without having to re run the entire thing and work out at what point I need to take note of locals, etc.

15:15 makes more sense to me to record everything then explore it

15:16 arrdem: fair enough. just a thought.

15:16 CookedGryphon: I have to head off soon, but I could put what I have into a gist if anyone's interested

15:16 amalloy: (defn sample [x] (let [[action value] (if (= x 0) [:return :foo] [:recur (dec x)])] (if (= action :return) (do (log "returning") value) (do (log "recurring") (recur value)))))

15:16 cbp: CookedGryphon: sure

15:21 Tekhne: I'm new to functional programming, and I'm writing some code which feels like it's a pattern that people have already written. I need to if it is and what it's called, if it has a name. The pattern: take a value and pass it through a series of funcs, each taking in the output of the last, but if any function changes the value, then the rest "short circuit" and the first changed value is returned from the end of the chain.

15:22 amalloy: Tekhne: it doesn't sound like any function is actually taking the output of the last

15:22 Tekhne: The reason I need to know if there's a name for this pattern is so that I can go look it up and see if my naive code can be improved.

15:23 duck1123: Hello all. I am trying to get my Java/Clojure project (built with Maven) working with LightTable, but can't seem to get it right. When I launch my nRepl server (by loading a url) with the lighttable-ops handler, I get an error trying to load the cljs deps. Is there a way I can just get this to not use CLJS? https://gist.github.com/duck1123/b58a367f5e54412a6907

15:23 stuartsierra: Tekhne: the only similar example I know is when one of the functions returns nil. In Clojure, that's `some->`

15:23 Tekhne: amalloy: I'm sorry. I'm probably not explaining this very well.

15:23 amalloy: you're sorta implementing (defn first-change [x fs] (drop-while #(= % x) (for [f fs] (f x)))), Tekhne

15:23 technomancy: seems like (or (some-> val fns) val) would do the trick

15:24 oh never mind; misread

15:24 amalloy: that is: because if any function "changes" the value being returned you stop calling other functions, you only ever call a function with the original input x

15:27 certainly this isn't some common pattern i've heard of before; i don't know where you'd look up exemplar implementations

15:27 nkoza: Tekhne: what information do you want? what function changed the data or you are doing this because the functions are making side-effects?

15:27 Tekhne: amalloy: I have a date in a string, and I want to pass it through a series of funcs which will transform the date into the "standard" format I need if the func understands the format of the original string. If any of the funcs should actually recognize and xform the original date, then I want the rest of the funcs to "turn off". I'm accomplishing this now with reduce, a "manager" func which knows if a date was recognized, and a collection of xform funcs. Maybe

15:29 amalloy: Tekhne: right, that's just (first (drop-while not-recognized? (for [f recognizers] (f input))))

15:29 CookedGryphon: Here's my gist for anyone who wants a look (cbp, amalloy, arrdem) https://gist.github.com/AdamClements/e89cfe659be08abf2710

15:29 Tekhne: amalloy: okay, cool. I'm trying to understand what you wrote there (I'm pretty new to Clojure and trying to apply some Clojure ideas in my JavaScript).

15:30 CookedGryphon: there are many flaws with the implementation, but I think the idea of recording the result of every s-exp and then exploring the data afterwards is sound

15:30 Tekhne: amalloy: ah, okay, so you're exploiting Clojure's lazy eval, right? That probably won't work for me directly in JavaScript.

15:30 amalloy: ...but maybe I can work around that problem.

15:31 amalloy: aren't you writing clojurescript?

15:31 or you're just writing js and came to #clojure to ask for ideas?

15:31 Tekhne: amalloy: I truely wish, but my team is using JavaScript. I'm really the only one who's learning Clojure.

15:32 amalloy: Yea, just asking for ideas because I know y'all are very functional-savvy.

15:32 amalloy: we are, but javascript isn't

15:32 Tekhne: ...and since I know some Clojure now.

15:32 amalloy: haha, true.

15:33 amalloy: in js i think you'd do best to just use a for/in with an early return

15:34 nkoza: Tekhne: what about: (first (drop-while #(= % original-value) (map #(% original-value) [f1 f2 f3 f4])))

15:34 Tekhne: amalloy: Yea, I'm sure. I already have an imperative version of this that works, but I was trying, as an experiment, to create a functional version.

15:34 amalloy: nkoza: that's the version i wrote twice already :P

15:34 nkoza: amalloy: ahh, didn't see it :)

15:36 but maybe it has a problem, it the functions will raise an exception with wrong input, then the chunked-seq behaviour will crash it

15:36 Tekhne: amalloy: well, thanks for the ideas. I'll have a look and try to grok what you posted. Seems like this isn't a "standard" pattern, though, which is also good to know.

15:37 nkoza: so maybe is better to use reduce/reduced

15:37 Tekhne: nkoza: I'm using moment.js to parse out dates, so I'm checking validity with .isValid(). I don't think moment.js will raise an error if the date can't be parsed.

15:38 nkoza: my current solution is using reduce from lodash.

15:39 nkoza: Tekhne: in clojure you can short-circuit reduce by using 'reduced' (a recent addition to the language), don't know about lodash

15:39 Tekhne: nkoza: oh cool. I hadn't heard of that.

15:39 noncom: is there a difference in time between defererencing an atom and a ref?

15:40 *time cost

15:44 llasram: Sure -- it takes waaaaay more time to think of situations where you actually want refs

15:44 Tekhne: Thanks for the help.

15:45 noncom: :)

15:49 thecontrarian: I have a clojure java interop question

15:49 i have a java class with a public static interface inside it

15:50 how do i get at that interface from within clojure?

15:50 amalloy: the interface's name is class$interface

15:50 thecontrarian: cool let me try that

15:50 that didnt work

15:51 the class is Emitter and the interface is Listener

15:51 amalloy: you have to import it, just like any other class

15:51 thecontrarian: and i did Emitter$Listener

15:51 oh you mean i import Emitter$Listener?

15:51 amalloy: foo.bar.Emitter$Listener

15:51 yes

15:51 thecontrarian: ooh ok

15:51 amalloy: it's not related in any way to the Emitter class

15:51 it is its own class, with a name that includes Emitter

15:52 thecontrarian: awesome, that worked thanks

16:01 another quick question

16:01 so my interface implements one method, call

16:01 returns void, takes in Object... args

16:02 1. how do i return void in clojure?

16:02 amalloy: no such thing as Object... really. to the jvm, that's just Object[]

16:02 thecontrarian: so it would be a single arg method?

16:02 amalloy: yes

16:03 thecontrarian: not [& _]?

16:03 noncom: no

16:04 thecontrarian: k

16:04 is there anything special about specifiying the method name in a reify?

16:04 would it just be call?

16:04 or Call?

16:04 noncom: call i think

16:04 thecontrarian: hmm

16:04 noncom: avoid unjavaish characters is all i can think of

16:05 thecontrarian: ok and what about the return void thing?

16:05 noncom: like ! ? and other

16:05 thecontrarian: ok and what about the return void thing?

16:05 amalloy: thecontrarian: the compiler knows what type you're expected to return, and will emit the right bytecode

16:06 thecontrarian: k cool. thanks you two. excellent support, super greatful

16:06 noncom: do not use hyphens in the names also

16:06 amalloy: noncom: you seem to be answering questions nobody is asking

16:06 noncom: thecontrarian: and one more thing just for you to know - the optional arguments - that happen after the & are purely clojure feature

16:07 amalloy: that's ok, sometimes i speak to imaginary people..

16:07 thecontrarian: ok cool

16:07 and hes actually answering my question

16:08 he actually answered it right before i asked it

16:08 i was gonna say 2. what about the return void and Object... thing

16:08 noncom: weehee, my meds allow me to time travel

16:08 thecontrarian: lololol

16:08 you guys on the core team? or just avid users?

16:09 noncom: i am just a user, rather mediocre

16:09 thecontrarian: i always like to ask that when i get support for something

16:09 cool, me too

16:09 noncom: amalloy however, is more involved afaik

16:10 thecontrarian: what do you yall use it for?

16:10 noncom: clojure?

16:10 clojurebot: clojure is not scheme

16:10 thecontrarian: (<- from texas)

16:10 yeah

16:10 amalloy: no. i've had some patches applied, but i'm certainly not a part of clojure/core

16:10 thecontrarian: word

16:10 you make anything cool with it tho?

16:11 use it at work or something?

16:11 noncom: well, i use it for everything where i can get out with JVM - my main jvm lang

16:11 amalloy: well, www.4clojure.com

16:11 and yes, i've used it at work for three years

16:11 noncom: i used it at my work, programming 3D games and multimedia applications with OpenGL and stuff

16:11 and also networking

16:11 thecontrarian: you made 4clojure?!?

16:12 noncom: lwjgl?

16:12 amalloy: not all by myself, thecontrarian: https://github.com/4clojure/4clojure/graphs/contributors

16:13 noncom: i almost cannot find a reason not to use clojure for a task. the only reasons are: 1) need c/c++ speeds 2) can't jvm

16:13 i was using jmonkeyengine3 which is based on lwjgl yes

16:13 thecontrarian: amalloy: you heard of codewars?

16:14 noncom: is there a good clojure wrapper for that?

16:14 noncom: also many other libs for computer vision, sensors and stuff

16:14 well, it is hard to say. when i started my way, i talked to the community and it happened that several people were already exploring the domain but they all were far from something definite

16:15 Djgerar123: HUMANS?

16:15 noncom: afaik only weavejester got some conceptual thing that he intended to finish and really employ

16:15 arrdem: only robots and lambdas here. move along.

16:15 thecontrarian: noncom: id love it if you could point me in the direction of some good libs for doing that kind of stuff. thats the kind of stuff i do on the side as well (much like everybody in our field it seems)

16:17 noncom: me myself wrote a special environment for my job, it is an OS-like plugin-based environment for multimedia apps and JME wrapper is a part of it. however, i do not think that clojure community would appreciate some of the concepts it is built around, so i would not take it as a reference or even idiomatic implementation either

16:17 thecontrarian: what direction exactly? jme3 wrappers or other?

16:19 thecontrarian: really anything that involves graphics (2d or 3d) or audio

16:20 ive looked at quil, overtone, shadertone, and seesaw recently

16:20 noncom: for starters I googled "clojure lwjgl" and "clojure jmonkeyengine3"

16:20 thecontrarian: i'm a web and game dev, so anything that does some sort of graphics/interface-y stuff would be cool

16:21 noncom: i could also share my JME3 wrapper which could simplify interfacing with the engine, but it is not a really useful thing withou the rest of the OS, it's just a thin wrapper afterall

16:21 but maybe a good starting point

16:21 thecontrarian: id love it if you could share your os-like thing

16:21 it seems cool

16:22 and i'm not a total stickler about the kinds of things that the clojure community at large is

16:23 for instance, i love using mutable closures in javascript, they are really useful

16:24 maybe thats not a very good example

16:24 w/e

16:24 this you https://github.com/noncom?

16:25 noncom: yeah thats me but my main account is on bitbucket

16:25 thecontrarian: word

16:25 gtrak: thecontrarian: I'd rather write mutable code than figure out someone else's, does that make me a stickler?

16:25 nathan7: How on earth do I use (proxy) with a superclass that has a type parameter?

16:26 amalloy: type parameters are fictional

16:26 noncom: i can't share the core of the OS yet, it is not finished and I have a contract with the company. I can, however, share all the wrappers

16:27 wrappers will really get you going - they make it easy with the libs

16:27 gtrak: i think it's probably my general hatred of pain :-)

16:28 noncom: gtrak: what do you mean?

16:28 thecontrarian: gtrak: as far as i'm concerned, being a stickler is being anal retentive about following the suggested design paradigms laid out by a language, especially when not in a work environment. being a stickler isn't a bad thing, dont get me wrong

16:29 i just feel that SE is a wide field of alot of cool things and they all have their goods and bads

16:29 gtrak: noncom: I mean, I guess I'm a stickler, but it's more subtle than that, I don't know how it is for others.

16:30 thecontrarian: being a stickler is a really good way to consistently write "good" code in a given language

16:31 although "good" code isnt necessarily good, its more of just consistent and conforming

16:31 gtrak: I think when you consider how how principled clojurists are, they choose practical relatively often.

16:31 I wouldn't expect that from, say, haskell.

16:31 noncom: hmmmm.... if I tell you that the OS i'm working on includes a OO subsystem, then who am I? am I a stickler?

16:32 or anti-stickler?

16:32 thecontrarian: idk. generalizations about people, you know?

16:32 gtrak: noncom: not enough information :-)

16:32 thecontrarian: yeah

16:32 why did you choose to do that?

16:33 noncom: heh. i needed classes and objects, but implemented in lisp, not java. that gave me the power over the OO system to make it in my own design

16:33 gtrak: plus I think of OO as map merges anyway.

16:34 it doesn't mean much to me.

16:34 noncom: yes, it is based on that. no other good way here

16:34 gtrak: message passing, you mean 'apply'?

16:35 thecontrarian: lol

16:35 noncom: haha

16:35 thecontrarian: yeah, i mean it doesnt really mean anything to be a stickler i guess

16:36 i would say you are not a stickler tho

16:36 you come across more as a pragmatist

16:37 noncom: yeah, kept telling this myself over and over when building that shit :)

16:38 in the end, you know

16:38 thecontrarian: sometimes i miss OO when in clojure actually, but more for the organizational aspects than anything else. when you have a bunch of methods that act on a single data structure, having them all bunched together is pretty convenient

16:39 noncom: thecontratian: i tell you one thing that you might be already aware of, but i tell from my experience: games and multimedia imply state. the most sane way to manage state like that is objects.

16:39 clojurebot: Roger.

16:39 noncom: yes, state with instances and with associated methods

16:40 thecontrarian: i do know that, yeah

16:40 noncom: it just cuts it, gets the work done

16:40 thecontrarian: there are other ways, however

16:40 noncom: withouth a huge pile of lambda piping

16:40 gtrak: I'd say people are more strict the closer you get to core projects.

16:40 which is pragmatic imo

16:40 noncom: oh yes. those who build the core must be zealots

16:40 that's the only way really

16:41 otherwise, the mission would fail

16:41 thecontrarian: like having your state in a hash and mutating it the update loop and passing it back around through a recur

16:41 gtrak: thecontrarian: you should use transients xD

16:41 whilo: noncom: objects don't give you performance, uncontrolled mutation might do

16:42 thecontrarian: what are the rules with transients?

16:42 are there any?

16:42 noncom: thecontrarian: yes, ofcourse, but you know what... if you start building convinience around that state passed each cycle, in the end, you will come up with something that pretty much reminds a OO system

16:42 gtrak: thecontrarian: you still have to return them as values, you can't bash in place.

16:43 but they're faster.

16:43 whilo: noncom: what are you building?

16:43 gtrak: also, I think you can only do it from one thread.

16:43 thecontrarian: as values? you mean as persistent forms?

16:44 turbofail: he means you can't do (let [a (transient {})] (assoc! a :foo 0) a)

16:44 noncom: whilo: at least objects give a way clearer organization of code and reduce LOCs and lambda piping. there was not so big concern with speed in my program. but yes, if i am after speed, then uncontrolled mutation would be the right way

16:44 gtrak: what turbofail said

16:44 whilo: i think oo is mostly the way people learn to organize code, but in games things are not necessarily objects, but they definetly are data

16:45 i have managed to get decent performance by keeping all state in one atom in my game prototype and pass that around: https://github.com/ghubber/clj-projectr/blob/master/src/projectr/core.clj#L152

16:45 noncom: whilo: i am building a multimedia environment for the company i am working in. think of it like something like Unity3D kind of thing, but made with Clojure

16:45 thecontrarian: have any of you hear of the Entity component system?

16:45 if so, what is it?

16:45 whilo: noncom: cool they dropped my code for unity3d

16:45 gtrak: thecontrarian: ibdknox has a good blog post on this

16:45 whilo: sadly

16:46 thecontrarian: yeah, i should read that

16:46 noncom: whilo: yes, you are right. but do not forget about convenience. when you start building conveniece methods around your data blob, you end up with OOP

16:46 thecontrarian: i've been meaning to

16:46 gtrak: thecontrarian: http://www.chris-granger.com/2012/12/11/anatomy-of-a-knockout/

16:46 noncom: whilo: tell more about your story with unity3d?

16:46 whilo: noncom: we wanted to build an augmented reality game simulation similar to ingress

16:47 this was a prototype as an internship with university, but they want to build a company

16:47 thecontrarian: did you use clojureCLR?

16:47 whilo: don't know their current status, but after they switched to unity3d i was not interested anymore

16:48 exactly because it is scripting around stateful objects and this will scale horribly in a game-world as big as the real world ...

16:48 imho

16:48 maybe some people have more experience, but nobody could convince me so far that gaming needs uncontrolled mutation

16:48 imo it needs scalability

16:49 gtrak: whilo: GC pressure is a thing. an immutable physics engine might be impractical.

16:49 whilo: gtrak: right, but still you shouldn't model your code mutably but hide it

16:49 gtrak: not sure how you can avoid it in that case.

16:49 I mean, you can still pass things around, but they mutate.

16:50 noncom: whilo: hmmmm i see... right. I guess, they switched to unity for other reasons however.. many prefer it because it makes many things easier and it employes the dumbass c#

16:50 gtrak: so, if you have more than one reference to a thing you'll still get bitten.

16:50 whilo: noncom: right, this seems to have been the point, convenience. i don't have a problem with that, but it doesn't make you scale

16:51 thecontrarian: i actually really like c#

16:51 gtrak: I have fond memories of XNA

16:51 thecontrarian: its better than java imo

16:51 gtrak: I booted up monogame the other day, it looked great.

16:51 thecontrarian: if c# ran on the jvm it would be amazing

16:51 whilo: gtrak: right, it is tricky. but doing that only can increase your efficiency on a single thread, if you manage to build an immutable version that scales, you easily beat that

16:51 noncom: c# is ok, so as java... and c too, but after you tried lisp... well.. i don't know how to describe the feeling

16:51 whilo: noncom: ^^

16:52 locks: C# rocks

16:52 gtrak: yes, C# and related tooling is loads better than java. but I don't miss it at all.

16:53 thecontrarian: noncom: you dont have to describe the feeling here dude XD

16:53 gtrak: i mean, you learn core.async once, and you get to use it on the JVM and javascript :-)

16:53 beat that.

16:53 whilo: noncom: Hickey: You can reach a point with Lisp where, between the conceptual simplicity, the large libraries, and the customization of macros, you are able to write only code that matters. And, once there, you are able to achieve a very high degree of focus, such as you would when playing Go, or playing a musical instrument, or meditating. And then, as with those activities, there can be a feeling of elation that

16:53 accompanies that mental state of focus.

16:53 http://www.codequarterly.com/2011/rich-hickey/

16:54 gtrak: core.async is amazing

16:54 noncom: whilo: actually in most games it rarely comes to problems with mutability i think... the immutability and other stuff is more like for distributed and networked systems

16:54 yeah, these words by Rich are great

16:55 whilo: noncom: how do you mean it does not come to problems with mutability?

16:55 thecontrarian: whilo: i've played around with core.async some and watched that one David Nolen video on it, but i still dont really understand it that well. you have any tips or places where i can get more familiar?

16:56 whilo: thecontrarian: you can help me :-P

16:56 yes, examples are often only small

16:56 gtrak: thecontrarian: learning by doing worked for me. I had to read a lot of impl, but that's the case for most clojure libs.

16:56 thecontrarian: whilo: lol what do you mean? what do you need help with?

16:56 whilo: it was a bit hard to get some things sorted out, for instance you might not write to a closed channel

16:56 noncom: whilo: the structure of most games is so simple that it does not have many places to fail with inconsistant mutations

16:57 databases, distributed and network comms systems, however, is a different thing

16:57 gtrak: I think people recommend reading about 'go' and the original CSP text as well.

16:57 but i haven't gotten around to that.

16:57 noncom: this article is also good: http://www.defmacro.org/ramblings/lisp-ducati.html

16:57 whilo: noncom: ok, i was rather interested in games that have many players and significant simulations

16:57 still you can default to immutability then

16:58 thecontrarian: whilo: what do you need help with?

16:58 noncom: whilo: in that case only the simulations core would really require the immutability things. maybe the core server can be written in clojure and client - in unity3d :)

16:58 whilo: for instance i could drop in pmap and get 8 cores scaling immediately: https://github.com/ghubber/clj-projectr/blob/master/src/projectr/simulation.clj#L65

16:59 noncom: whilo: idk, i'm just trying to advocate for those who choose mutability.. since there should be some secret hiding somewhere..

16:59 whilo: thecontrarian: i am building a distributed git like repo system for data in clj and cljs with core.async: https://github.com/ghubber/geschichte

16:59 whomp: what's the name of clojure contrib for my project.clj dependencies?

16:59 whilo: it heavily relies on it

16:59 whomp: i can't find it on clojars

16:59 gtrak: I don't think mutability has a conceptual basis...

16:59 noncom: whomp: what dependencies do you have?

17:00 gfredericks: amalloy: did you see my early-morning defense of a def-utils lib?

17:00 whomp: noncom, i just want to use a bunch of the functions from clojure contribs, esp in math

17:00 gtrak: besides what's necessary for intended side-effects..

17:00 whilo: the pub-sub features in core.async are nice (although i don't have experience with other impls.): https://github.com/ghubber/geschichte/blob/master/src/cljx/geschichte/sync.cljx

17:00 noncom: gtrak: the conception of mutability is lowering the cost for hardware price / electric power consumption :P

17:01 gtrak: hehe, well, that's outside of the scope of the argument.

17:01 noncom: whomp: aren't you looking for this? http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

17:01 whilo: thecontrarian: it is not very well factorized yet, but i could define the eventual-consistent synchronisation of the network fairly tersely

17:02 noncom: gtrak: yes. and that's the point. i have witnessed many weirdness in this world which had no logical explanation. and always always when i learned the reasons, them were money.

17:02 well, sex too, but to alesser degree

17:02 whomp: noncom, thx

17:03 noncom: i wonder, what immutability will look like when we have quantum computers?

17:03 whilo: thecontrarian: but it runs, we have tested it both on jvm and js with https://github.com/kordano/lambda-shelf, but then we realized we need consistent cross repository transactions and i am just finishing that and then we reimplement the messaging app

17:03 noncom: how does it play with them

17:04 gtrak: immutability and value-ness at least has math.

17:04 and mutability can be described in terms of it.

17:05 whilo: thecontrarian: for this problem core.async is perfect, but unless you have some serious problem it can look a little bit toyish from the simple examples

17:05 noncom: isnt the vice versa true?

17:05 thecontrarian: whilo: ok cool. i dont fully understand what it is. i mean, i understand all of the separate concepts present in the pitch, but together i guess i'm having trouble visualizing it.

17:05 whilo: what is the use case?

17:05 noncom: i always perceived assembler and lisp as two poles of the world. of one single world... :)

17:05 * gfredericks has a hard time imagining quantum computers being used for much of anything much less in regular development

17:06 gtrak: noncom: I guess set theory is more fundamental, and a better starting point than Von-Neumann, is my argument.

17:06 whilo: thecontrarian: ok. just imagine git for data + an eventual consistent synching, so you instead of writing custom messaging for web-apps (or others) all the time, you just get an eventual consistent db-layer you can commit to

17:06 (locally, it works on indexeddb and couchdb atm.)

17:07 whodidthis: https://www.refheap.com/85744 how do i write code like this betterer so i dont have to keep track of each validation stages position

17:07 whilo: so you can also have offline apps and commit (write) while offline

17:07 noncom: gtrak: so you're coming from above. but there are people who come from below.. personally i cling more to your POV, but i understand the other people too

17:07 thecontrarian: whilo: so its a db of datastructure changelogs?

17:08 whilo: thecontrarian: basically i want to have native like io-storage everywhere synched globally (the tradeoff is conflict resolution)

17:08 Qerub: Has anyone attempted to unify Typed Clojure and Prismatic Schema yet? I.e. generate type signatures from schemas or so.

17:08 noncom: whodidthis: well.. at first transform (if-not) into (if)...

17:08 gfredericks: Qerub: I'm not sure how that would work

17:08 afaik typed clojure requires types to actually be present in the source code

17:09 whilo: thecontrarian: i don't create diffs, but save a transaction function + params. this can be used with diff/patch to do git-like datastructure changelogs

17:10 Qerub: gfredericks: I thought that it only needed annotated vars.

17:10 technomancy: yeah, it can use var metadata now

17:10 skottish: Hi all. I have a simple question that I can't seem to find an answer for. When printing bigints to a terminal, how do I get rid of the trailing 'N'?

17:11 whilo: but it also allows to define terse application specific transaction functions like (fn [old {:keys [amp period]}] (update-in [:values] add-sin-wave amp period))

17:11 dwwoelfel: Qerub: There's this thing, but it's still pretty rough: https://github.com/circleci/schema-typer

17:12 whilo: in a git like diffing approach this would cause all values to be changed and transmitted, if i get properly. but maybe this can also be achieved via some theoretically optimal compression or so, not sure yet

17:13 thecontrarian: core.async definitely played out nicely after i figured out the closing problem which caused random deadlocks

17:13 Qerub: dwwoelfel: Excellent. Thank you!

17:13 Fare: hi

17:14 noncom: Fare: hi!

17:14 Fare: I want to add a trivial "backdoor" to a server. Can everything in clojure be done in a single expression, or is it like CL sometimes demanding two or more separate forms to do something (i.e. in-package in CL)

17:14 e.g. ./foo --eval '(some expression)'

17:15 vs ./foo --eval '(expr1)' --eval '(expr2)' ...

17:16 noncom: Fare: I guess, either way.. look at (do ...)

17:16 Qerub: skottish: Maybe you can just convert it to a string with the str function first?

17:17 skottish: (str (bigint 1)) => “1”

17:18 skottish: Qerub: Thanks. I end up with quotes around it.

17:18 technomancy: Fare: best to embed nrepl into your application

17:18 skottish: Qerub: And I need the literal number.

17:19 Qerub: skottish: Are you printing with `pr`? Use `print` instead.

17:20 Fare: technomancy, actually, my typical --eval argument would be '(clojure.tools.nrepl.server/start-server :port 12345 :bind "127.0.0.1")'

17:20 but I wanted to do something simpler — just read eval and print result from --eval

17:21 sometimes, you don't want a repl, just a simple query as part of a small script

17:21 skottish: Qerub: That's it! Thanks a million!

17:21 Qerub: skottish: YW. Check the documentation for `pr` and `print` if you wonder why they print differently.

17:22 skottish: Qerub: I will. It's been a while since I've worked with Clojure, so i have a ton to remember.

17:25 Fare: are there namespace issues at read-time in clojure as in CL? how are namespaces resolved? can I change the default namespace and use it in the same form?

17:25 technomancy: Fare: if you're sending stuff across the wire it's better to make sure everything is fully-qualified

17:27 Frozenlock: Is there a way to change a private array list in a java lib?

17:27 (from clojure)

17:27 Fare: technomancy: ok, then I need to support multiple commands, so I read and eval them in series

17:27 technomancy: Fare: you can batch them up with do, which is progn

17:27 Fare: is there an existing clojure function to repeatedly read and eval from a string?

17:27 technomancy, how would do do with respect to namespace resolution?

17:28 technomancy: Fare: it depends on the listener; they can bind *ns* to whatever they want

17:28 Fare: can I (do (ns ...) (using new ns...)) ?

17:29 technomancy: ~tias

17:29 clojurebot: Try it and see! You'll get results faster than asking someone in #clojure to evaluate it for you, and you'll get that warm, fuzzy feeling of self-reliance.

17:29 technomancy: but probably

17:30 TimMc: Fare: Probably, as long as that (do ...) is at the top level.

17:31 If not, probably not. Clojure's compilation unit is the top-level expression, where "do" is collapsed to the top level.

17:31 Fare: TimMc: calling from java, how do I make sure it's the toplevel?

17:32 TimMc: Oh, like read-string and then eval that? I guess that's at the top level inside eval's context...

17:33 Fare: yes... except maybe I want to repeatedly read from the string, rather than just once

17:34 * TimMc reads backlog

17:35 Fare: or is it just less hassle to demand specify forms as separate string arguments?

17:35 impedance mismatch is a pain.

17:35 technomancy: either separate strings or a single do form is best

17:35 Fare: (even better: is there a java way of dynamically loading the clojure jar and then calling into it, without having it included into my application jar?)

17:36 technomancy, ok

17:36 technomancy: I mean you could splice a string into "(do %s)" or whatever

17:36 Fare: this way, I wouldn't have to either have a separate application binary, or to convince colleagues to ship with the clojure jar

17:37 TimMc: So this would be a stateless backdoor, then? You don't want drawbridge running all the time?

17:37 technomancy: if you juggle classloaders you could load clojure at runtime, but it's awkward

17:37 TimMc: You also risk leaking a classloader.

17:37 Fare: TimMc: when I want stateful, I'd start a nrepl as the command

17:38 for casual queries, I'd remain stateless

17:38 TimMc: We use liverepl from time to time at work to patch into a running JVM, but it leaks a classloader each time, so we usually bounce the server after debugging.

17:38 Fare: what does "leaking" a classloader mean?

17:38 TimMc: Not sre.

17:39 Something about how the JVM GCs classloaders, or fails to.

17:39 Eventually you run out of PermGen space and things catch on fire.

17:39 Fare: but yeah, the idea is that this would be for interactive debugging, but not for permanent server change — and actually would be disabled or heavily restricted on a server

17:39 roppongininja: it seems to me that clojure has the best fucking community ever o.0

17:40 Fare: roppongininja, I can't say about "best", but it's got a good one.

17:40 TimMc: Fare: liverepl is pretty nice for non-production servers if you can just SSH in. :-)

17:40 Fare: (at this point, I just want to be able to use clojure to explore concepts and demonstrate them, on top of an existing application)

17:41 * Fare googles and finds https://github.com/djpowell/liverepl

17:45 TimMc: Fare: A big downside of plain liverepl is that it doesn't give you line editing and history support. Wrapping the call in rlwrap or something might make it nice, though.

17:45 whomp: is there a place to find clojuredocs for most projects out there?

17:46 arrdem: whomp: there was a clojars based clojure universe explorer floating around yesterday lemme see if I can find it again.

17:46 whomp: but generally no.

17:47 http://crossclj.info/

17:47 Fare: TimMc: once again, for repeated interaction, the one and only command would be a call to clojure.tools.nrepl.server/start-server

17:48 TimMc: You'd have to get that onto the classpath as well.

17:50 Fare: can I do that at runtime from my --clojure option processor?

17:50 whomp: arrdem, thx :)

17:50 you'd think there'd be some integration with clojars or something to get it everywhere

17:51 e.g. what ruby does with gems

17:51 locks: whomp: thanks for volunteering ;P

17:52 whomp: XD

17:52 arrdem: whomp: clojuredocs is dead and a replacement for source level docs is badly needed :<

17:52 but since we can all just use clojure.repl/doc a replacement has not really been forthcomming T_T

17:53 TimMc: Fare: If you can load the Clojure library at runtime, I'm sure you can load the org.clojure/tools.nrepl library at runtime as well.

17:53 locks: what is Dash.app's docset based on?

18:01 technomancy: arrdem: I would say a replacement for source-level docs is *not* needed, the value of clojuredocs is in the user-contributed examples

18:01 rendering docstrings as HTML is pretty pointless on its own

18:02 Fare: if I load clojure via a URLClassLoader, will it be able to use the primitives in my application?

18:03 technomancy: Fare: my understanding is that it depends on the classloader hierarchy

18:04 your URLClassLoader needs to define a parent that knows about the rest of your classes

18:06 arrdem: technomancy: I would argue that at least for newcommers the lack of html docs is very offputting. I agree that it doesn't take a whole lot to get past that point and be able to use repl docs, but coming from Python with docs.python.org at my disposal it was exceedingly strange to pick up a language with no clear symbol by symbol documentation forget user examples.

18:06 that said, I personally probably wouldn't use a HTML documentation site myself at this point so I'm in the "loath to build one" camp.

18:08 technomancy: that kinda falls under the realm of encouraging people to continue in their bad habits though

18:08 arrdem: what, that providing HTML docs delays newcommers transitioning to repl docs?

18:09 technomancy: yeah, clojuredocs.org staying on 1.3 is actually doing the community a service =)

18:11 Fare: technomancy, where is this parent definition explained?

18:11 cbp: it would do more service if it didnt exist at all

18:11 then at least it doesn't look like we're lazy

18:11 arrdem: there's that too...

18:13 Fare: does clojure compile to bytecode?

18:13 technomancy: Fare: yes

18:13 Fare: or does it interpret some data structure and use reflection?

18:13 arrdem: sorta kinda not really

18:13 Fare: arrdem:?

18:15 arrdem: Fare: technomancy is correct and I'm being nitpicky.

18:28 Bronsa: ping

18:29 Bronsa: arrdem: pong

18:29 lemonodor: even just tfor docstrings, using google is a more usable interface. but yeah, the examples on clojuredoc are often very helpful

18:30 technomancy: lemonodor: hm; if there are shortcomings to the repl we should address them.

18:30 arrdem: Bronsa: thoughts on this? I'm trying to figure out what a useful pass structure will look like. https://github.com/arrdem/oxcart/blob/master/src/oxcart.clj#L211

18:31 technomancy: lemonodor: people who rely on google end up with outdated, incorrect information on a regular basis

18:31 lemonodor: it doesn’t have to be that way, does it? how often do new versions of clojure come out?

18:31 technomancy: it's crazy how long it took people to get over confusion about clojure-contrib or swank-clojure

18:31 arrdem: lemonodor: sub yearly

18:31 AFAIK

18:31 technomancy: it took years for the bad docs to sink off the first page of hits

18:32 arrdem: yeah. Google deals really really badly with API version changes, especially for APIs using real versioned URLs.

18:33 technomancy: we can control the fate of the repl, but we can't control SEO gone wrong

18:33 not to mention peoples' blogs that aren't even outdated but just incorrect; ugh

18:34 Fare: which class should I be loading from the clojure.jar to load it all? Or is it always loading it all, and it's just about getting a handle on an object to invoke methods on?

18:35 amalloy: technomancy: "i discovered that you have to run lein clean before any lein command. i wish this were documented somewhere, but since it's not i guess i'll blog about it"

18:35 (not an actual quote)

18:35 technomancy: http://p.hagelb.org/clap.gif

18:36 well played

18:36 lemonodor: the repl will have the closest thing to ground truth. google indexing stuff badly is suboptimal. but if it’s possible to get google to index stuff better i think that would be a huge win.

18:36 Frozenlo`: The truth is M-.

18:36 technomancy: wait, do you work at google?

18:36 lemonodor: used to

18:36 amalloy: the best thing about teasing technomancy is the reaction gifs

18:37 technomancy: lemonodor: maybe you could pull some stings, eh

18:38 frozenlock: the truth is ... complicated

18:38 lemonodor: no :) and i don’t know that some change in organization of pages or links would change anything, but it is worth thinking through.

18:38 technomancy: M-. just tells you what's on disk

18:39 frozenlock: Isn't that the closest you can get?

18:39 technomancy: without a decompiler, probably

18:39 frozenlock: What's up with all these people connecting/deconnecting >.<

18:40 amalloy: frozenlock: just get a client that hides the useless noise

18:40 technomancy: inc

18:40 frozenlock: amalloy: I have one, but I don't like to enable that. What if I talk to someone that just disconnected?

18:41 amalloy: frozenlock: a smarter client than that. mine hides join/part for anyone who hasn't been talking recently

18:41 frozenlock: Tho there's so much noise here that I might as well.

18:42 amalloy: anyway, you'll know they've disconnected because their name doesn't tab-complete anymore

18:45 Bronsa: arrdem: I don't have much to comment right now on your approach, the only thing that strike me as ovious is that your approach for matching defs assumes defs to be top-level. is not supporting things like (let [..] (def ..)) intended?

18:45 *strikes

18:45 *obvious

18:46 arrdem: Bronsa: I neglected the possibility of closed defs, but I think that should work out because the implicit do in the let form will lead to the evaluation of the def with appropriate environment changes. I'll add testing explicitly that to my list.

18:47 Bronsa: I'm just pondering how to support pass driven modification of functions and injection of new function declarations.

18:48 ouch. defmulti doesn't kick out a :def node it seems...

18:50 whomp: has anyone here done an fft? i'm having some struggles

18:50 in clojure i mean

18:55 Fare: in the clojure git checkout, there is a file src/jvm/clojure/java/api/Clojure.java -- is it included in the clojure.jar, or is it an example of how to use it?

18:56 arrdem: Bronsa: good call on the closed over let. totally broken.

18:56 Kitty-: good jawb

18:57 arrdem: s/closed over/closing/g

18:59 Fare: typing clojure.java.api.Clojure suggests that it's not in the .jar

18:59 good to know — it's just an example of how to use it.

18:59 technomancy: Fare: iirc it's new in 1.6 or something? dunno.

19:00 * Fare writes a trivial java class to test the dynamic loading of clojure code.

19:00 amalloy: technomancy: right

19:08 resolve-this: hi

19:12 I'm having trouble dynamically obtaining a var from a function "reference". Anyone know a solution?

19:12 i.e. (defn my-fn [arg1 arg2 arg3] [arg1 arg2 arg3])

19:12 somewhere in my code I'm passed #<user$my_fn user$my_fn@1f4b2e9> and now I want to obtain the var to this how could I do it?

19:13 arrdem: I don't think there's a fn->var mapping anywhere.

19:14 but that value you get should be a var so...

19:14 you shouldn't need one either.

19:14 resolve-this: I know

19:14 but the value is dinamically passed to me

19:14 like nested call

19:14 arrdem: ,(do (def foo [x] (inc x)) (class foo))

19:14 clojurebot: #<CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)>

19:15 arrdem: ,(do (defn foo [x] (inc x)) (class foo))

19:15 clojurebot: sandbox$foo

19:15 resolve-this: so the solution would be to resolve it at calltime?

19:22 roppongi_: is emacs any good for clojure or are there better alternatives? (ie. light table)

19:24 amalloy: if you know emacs already, it is the best choice

19:25 roppongi_: amalloy: I used emacs but I woudln't say "I know it"

19:25 amalloy: resolve-this: not all functions have a var. most don't, really. do you really want to forbid your users to pass you a lambda?

19:26 if you want to restrict yourself to functions with vars, just ask the user to pass you a var instead

19:27 resolve-this: in this situation I do want to restrict it to functions defined with defn. passing #'the-fn works..

19:28 well, thanks

19:50 frozenlock: I just pushed a java library to clojars. When I try to require it, I get "ClassNotFoundException <name-of-some-class-I-tried-to-import> java.net.URLClassLoader$1.run (URLClassLoader.java:366)" Is there something special I need to do when uploading some java to clojars?

19:51 I used "jar cvf <lib-name>.jar com" to make the jar. When I look inside, it looks identical to previous jar I used for the same library. :-(

19:56 The only obvious difference I see is in the manifest. My previous lib version had "Ant-Version: Apache Ant 1.8.2" and the one I just created doesn't.

19:57 icky java

19:58 jeremyheiler: frozenlock: that shouldn't matter. did you happen to include the com directory itself, or just its contents?

19:59 frozenlock: I included it

20:00 jeremyheiler: oh, uh, .java files or .class files?

20:00 * frozenlock facepalms

20:00 frozenlock: .java files...

20:00 jeremyheiler: hehe

20:00 frozenlock: What's the command to make .class files?

20:01 jeremyheiler: javac

20:01 frozenlock: the only thing I found was 'jar cvf...', which gave me those .java in the .jar

20:01 dbasch: frozenlock: how are you building your java library?

20:01 frozenlock: dbasch: I don't knoooooow

20:01 * frozenlock runs away

20:02 resolve-this: lol :)

20:02 dbasch: :P

20:02 jeremyheiler: you could have lein build the java project for you.

20:02 turbofail: yeah that's probably the easiest way

20:03 jeremyheiler: or do you have the original source with the build.xml? (that's the ant build file.)

20:04 frozenlock: Hmm nope, only a bunch of .java files in what appears to be the correct directory pattern.

20:09 dbasch: frozenlock: create a simple build.xml, or a build.gradle and build the jar with ant or gradle

20:09 probably the sample ant file here will work http://ant.apache.org/manual/using.html

20:10 frozenlock: I'll see if I can get my hand on the original build.xml :-/

20:20 Ok, found it... but there's some missing jar in the dependencies.

20:20 Searching for the jars... I will prevail!

20:25 I think I got it

20:28 Success! Thanks jeremyheiler and dbasch!

20:30 jeremyheiler: frozenlock: you're welcome.

20:42 thecontrarian: how do you deal with generic java classes in clojure?

20:42 or generic interfaces

20:46 nevermind, i think i found it

20:54 arrdem: hum.... how to spike def....

20:58 jo_d: Hello. I'm having issues initiating core.typed in my REPL. When I use check-ns, I get this error:

20:58 IllegalStateException doseq already refers to: #'clojure.core.typed/doseq

20:59 I can't seem to find the source of this problem. It seems core.typed added its own doseq. Do I have to exclude clojure's builtin doseq?

21:06 gfredericks: thecontrarian: you don't

21:07 thecontrarian: gfredericks: yeah thats what i figured out

21:07 gfredericks: thank you

21:07 gfredericks: np

21:09 jo_d: sounds kind of weird

21:09 did you use :refer :all?

21:12 jo_d: Yes, I used :refer :all, and it came up with warnings that I core functions like doseq and let were being overriden by the core.typed namespace values.

21:13 gfredericks: I always used :as t

21:13 dbasch: :refer :all is bad

21:14 (unless you really really mean it)

21:15 gfredericks: you have to double-pinky-swear before you :refer :all

21:15 jo_d: Gotcha. I was following documentation and doing (use 'clojure.core.typed) produced the same results.

21:15 gfredericks: clojurebot: you |have to double-pinky-swear| before you :refer :all

21:15 clojurebot: Roger.

21:17 jo_d: And referring as t still throws errors when running (t/check-ns 'my-project.core). core.typed runs and requires all of the functions and gives me the namespace clash warnings.

21:20 gfredericks: sounds wrong; my best guess is you have some code lying around you forgot about?

21:26 dbasch: jo_d: can you refheap your project.clj?

21:28 quizdr: top of the morning, folks

21:29 dbasch: quizdr: morning to you too, even though it’s early evening here in the SF Bay Area

21:30 quizdr: Ah, SF. only been there once, a few years ago, for about 36 hours

21:31 dbasch: I wonder what’s the number of clojurians per square mile here in SF

21:31 jo_d: gfredericks, dbash: Looks like I finally fixed it. I think the docs weren't specific as to how to include the core.typed libraries and use the REPL alongside. Does anyone have any guides on getting started with it?

21:32 quizdr: dbasch i was just wondering that myself

21:35 yedi_: how come (last) on vectors don't use count under the hood?

21:37 justin_smith: yedi_: perhaps so that there is no ambiguity that last is always linear time

21:38 as opposed to peek which is always 0(1), and gets the last element of a vector, first of a seq

21:42 dbasch: if you want efficiency you can always use peek

21:44 quizdr: anyone used Secretary for cljs? Routing client-side seems rather interesting, just read about it

21:49 egghead: sure quizdr i've used it, it's nice, as advertised

21:50 quizdr: ok, it's an intriguing idea to route URIs all in the browser

21:54 kenrestivo: dbasch: happily, this is a good town for clojure

21:55 dbasch: kenrestivo: which town?

21:56 amalloy: justin_smith: peek actually blows up on a seq. on a *list* it returns the first item

21:56 pdk`: comin down to clojuretown

21:56 kenrestivo: sf

21:57 dbasch: kenrestivo: for clojure and lots of other things :)

22:00 I’m planning to attend this, it should be interesting. http://www.meetup.com/The-Bay-Area-Clojure-User-Group/events/181057342/

22:02 quizdr: i've considered relocating to SF. cost of living pretty high there. how's the air quality?

22:02 dbasch: quizdr: the air quality is good, the cost of living is exorbitant

22:03 quizdr: you get more for your rent money than you do in NYC however, even if price is comparable

22:07 dbasch: quizdr: I’m looking at craigslist for NY and I don’t think that’s true anymore

22:07 at least not for comparable locations

22:09 quizdr: i doubt downtown SF would be more expensive than the heart of manhattan, but i'd bet you'd have a nice place for the same cost

22:10 * jaimef looks around

22:10 jaimef: it's pretty expensive here

22:10 quizdr: jaimef ny or sf?

22:10 jaimef: sf

22:10 nicer here imho

22:10 amalloy: last i read, san francisco is the most expensive city in the US, but i think ny has parts that are more expensive (presumably manhattan)

22:11 quizdr: the problem in nyc is generally poor conditions in the average apartment, even when those small 1-bedrooms sell for $2million, they are pretty average by nationwide standards

22:11 jaimef: all the kids moving here

22:11 however it's a nice place

22:11 dbasch: I own a small condo very close to one of the Google bus routes. Last time I rented it I had to do an impromptu open house because I got a flood of emails within the first hour of the craigslist post

22:11 jaimef: :D

22:12 you should rent it to a lisp enthusiast

22:12 quizdr: i am in singapore, so by comparison either of those cities would seem like a break in costs

22:13 jaimef that sounds like a very SF thing to do. give propspective renters a code review/quiz before deciding

22:18 What UI components do you typically use/recommend when building a web app in conjunction with Om?

22:18 Bootstrap?

22:18 beamso: i'd recommend bootstrap.

22:19 generally.

22:19 quizdr: it looks like one of the most convenient to use

22:19 egghead: ehhh

22:19 up to you, bootstrap has pretty deep jquery integration

22:20 quizdr: Wouldn't Om's virtual DOM compete with jquery's DOM handling?

22:20 dbasch: quizdr: don’t include the js part of bootstrap, just the css

22:22 quizdr: so the css will get me basic form and button controls, but not the drop down menus, etc

22:23 nullptr: http://purecss.io/ was getting some love on #reactjs the other day, can do a lot just with class swapping

22:23 sjy: some of that stuff works without JS. personally i use purecss.io

22:24 quizdr: that looks nice; a "flat" inspired design it seems

22:25 fortruce: if I defonce a db connection at the top of a namespace to be used by all the functions in the namespace, is there a way to ensure it calls disconnect before the jvm exits?

22:25 quizdr: looks like purecss dropdowns are also javascript, so not quite "pure" css :)

22:26 yedi_: justin_smith: make's sense

22:28 quizdr: fortruce maybe not quite what you're looking for but Stu Sierra has an interesting workflow for things like db connections and other resources that can be started and stopped without restarting the JVM or server: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

22:28 dbasch: fortruce: I suppose you could add a shutdown hook to the jvm

22:29 fortruce: quizdr: that's quite the post, thanks. I'll sift through it and see if anything fits, should be a good read regardless

22:29 quizdr: fortruce just came across it earlier today myself

22:29 beamso: i'm using database pooling against a database with quite a low number of connections and bonecp is working okay without me manually closing the connection.

22:29 bjeanes: fortruce: there's also https://github.com/stuartsierra/component which is stuart's library for that workflow

22:29 fortruce: right now I have my tests just using the connection that is spun up in my model ns, then my tests closes it at the end of the tests, but it feels like that might be bad form to reach in like that

22:29 bjeanes: and his presentation about it https://www.youtube.com/watch?v=13cmHf_kt-Q

22:30 I've been using it in my own projects and *loving* it

22:30 fortruce: bjeanes: holy links batman! thanks!

22:32 this might be talked about in those links, but I'm just curious...currently I have a dynamic string defined as the database name "shouts", which I with-redefs in my tests to "shouts-testing", is that a reasonable approach?

22:52 bja: can I invoke a static method of a var pointing to a class?

22:52 i.e. (let [foo Bar] (. foo someStaticMethod)) (but this doesn't seem to work)

22:57 oh, nvm

22:57 I just didn't understand what I was doing

23:12 quizdr: Does the #js reader change behavior depending on what follows? it appears it does.

23:12 for exampel #js {:backgroundColor bgc} creates different JS than #js {:className "animals"}

Logging service provided by n01se.net