#clojure log - Sep 15 2013

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

0:02 elifrey: hello all. I've got a program I'm writing in elm, but the ecosystem is very young so I'm thinking of rewriting it in clojurescript

0:02 tomjack: cool

0:03 elifrey: the three things I really need are a parser combinator library, an FRP library, and a graphics library. I was wondering if anyone had some experience in these areas and could make some suggestions

0:04 I saw several Parser combinator libraries, but many of them looked un-maintaned

0:05 Foxboron: "parser combinator", i am not exactly sure if i know what that is, but instaparse?

0:05 elifrey: parser combinators just reify parsers so you can write functions from parsers to parsers or other fun things

0:05 tomjack: I don't know of any FRP libraries for clojurescript yet

0:06 callen: elifrey: Instaparse

0:06 tomjack: oh, javelin is clojurescript

0:06 callen: which is a terrible name for a CLJS library, given that Javelin was already a JS library.

0:06 I wish people would at least google first :|

0:07 lgs32a: elifrey: can you give me an example who i would write functions from parsers to parsers?

0:07 elifrey: lgs32a: there are many reasons, here are a couple

0:07 lgs32a: how i mean

0:08 elifrey: oh

0:08 callen: lgs32a: https://github.com/Engelberg/instaparse

0:08 elifrey: do you mean how would you write a parser combinator library, or how would you write a parser using parser combinators?

0:08 lgs32a: nah i think i understand the concept

0:09 i was just curious what you mean by write functions from parsers to parsers

0:09 tomjack: in elm, do you have to be careful not to get bitten by a lack of referential transparency?

0:10 elifrey: tomjack: not at all. All of your interactions with the "real world" are managed by FRP. It's quite nice, I just started finding too many bugs in the compiler :(

0:10 tomjack: so e.g. the slideshare I found by googling "frp clojurescript" uses Rx

0:11 in which you do have to be careful

0:11 elifrey: tomjack: sure

0:11 tomjack: and I believe you have to be careful in all attempts known to me, both in clj and cljs

0:11 muhoo: ,frp

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

0:11 muhoo: ~frp

0:11 clojurebot: frp is functional reactive programming, or fiberglass reinforced plastic

0:12 elifrey: in <dynamic language> you have no way to prove you arn't performing effects inside of your event streams

0:12 tomjack: I don't think it's just about effects there

0:13 the problem is that you can't pass an(y) observable around and always get consistent answers out of it

0:13 elifrey: tomjack: if your code is pure and without effects, it is referentially transpent (for some value of referential transparancy)

0:14 tomjack: but Rx code is never pure

0:15 elifrey: is it a situation that you might, say, map an impure function over an observable, or is the implementation of observables themselves break their denotation?

0:15 tomjack: e.g., say I do a selectMany where the function passed always returns the same hot observable

0:15 the latter

0:16 some cold observables may work

0:16 elifrey: I have not used Rx, only Reactive Banana, elm, and Bacon.js

0:16 what are hot/cold observables?

0:17 tomjack: a cold observable is basically a relatively pure (fn subscribe [callback] ...)

0:18 like interval, which emits messages at fixed intervals

0:18 every time you subscribe it starts at the beginning

0:18 IIRC?

0:18 hot is like a mouse event stream or something

0:18 every time you subscribe, you just start listening from now on to the same thing everyone else is subscribed to

0:19 elifrey: ah, yes, there is a funny business to do with when you start observing

0:19 tomjack: I think elm just bans the behavior monad?

0:19 I never looked closely enough at elm

0:19 elifrey: yeah, that was another problem I was having with elm, you can't join nested "signals"

0:20 tomjack: so that means no selectMany

0:20 / mapcat ?

0:20 elifrey: mapcat, bind, flatmap, whatever you want to call it

0:21 in Reactive Banana they weild the fact that FRP is the curry-howard corespondance to temporal logic to statically guarantee away the kinds of errors you are talking about

0:21 tomjack: wow I never knew

0:21 I have been reading "LTL Types FRP"

0:21 muhoo: reactive..... banana?

0:21 tomjack: I assumed you needed dependent types

0:22 elifrey: tomjack: oh thank goodness no

0:22 callen: elifrey: er...you can do that without dependent types?

0:22 elifrey: callen: yeppers

0:22 callen: oh, but it is Haskell

0:23 * callen waves the library away with a sigh

0:23 tomjack: does it amount to using extensions as hacks to get some dependent-type-like features?

0:23 elifrey: what you end up doing is "trimming" your event streams to a new start time whenever you join

0:23 nope

0:24 this perticular part of the lib is Haskell98 I think

0:24 tho internally it uses a GADT somewhere

0:24 callen: tomjack: I was equally suspicious but took them at their word.

0:25 tomjack: that's the behavior comonad?

0:25 ..i.e. □ ?

0:26 elifrey: tomjack: hmm? I can't tell if your joking or asking a question?

0:26 dissipate_: does anyone have some examples/tutorials of the threading macro: http://richhickey.github.io/clojure/clojure.core-api.html#clojure.core/->> ? the explanation in 'Clojure Programming' is terribly terse.

0:27 tomjack: (□ A) t = ∀ {u} → t ≤ u → A u

0:27 callen: elifrey: http://hackage.haskell.org/packages/archive/reactive/0.11.5/doc/html/src/FRP-Reactive-Behavior.html

0:28 tomjack: but that only makes sense with dependent types, hmm

0:30 elifrey: callen: ReactiveBanana, not reactive

0:31 reactive is Conal Elliots pure vision baby child that doesn't actually work on GHC do to what he would call a bug

0:31 http://hackage.haskell.org/packages/archive/reactive-banana/

0:32 * elifrey apologises for highjacking the clojure channel

0:33 tomjack: I was reading the Model, doesn't make much sense yet

0:34 I'd like to see a clojure library where you didn't have to be careful

0:35 elifrey: tomjack core.typed?

0:35 tomjack: :(

0:36 elifrey: I don't think you can get around this one statically without... static checking

0:36 uvtc: dissipate_, re. `->>`, did you have a look at the examples at <http://clojuredocs.org/clojure_core/clojure.core/-%3E%3E>?

0:36 tomjack: hmm, I figured you could

0:37 with elm, does the static checking and no join allow it to compile out to a really fast impure implementation?

0:38 elifrey: it's all CPS and settimeout under the hood, so I assume, but I'm not sure

0:38 tomjack: it seems like it should definitely be at least possible to implement referentially transparent signals. maybe making it efficient is difficult?

0:39 elifrey: ah, yes, the efficiency. so you're talking about, how do do something other than "sample the value at intervals"

0:40 Conals dream is to do to event based programming what vector graphics did to graphical programming

0:41 by which I mean, allow you to work on continuous values

0:41 this is very tricky to do efficiently

0:41 what most libraries do is to completely ignore the denotation of a behavior as a time-varying function, and just give you combinators to wire up an event graph

0:42 once you have the event graph, you can just have everything be event-driven under the hood and performance is not a problem

0:43 tomjack: do you get referential transparency for an event stream merged from two others?

0:44 elifrey: yes and no

0:44 tomjack: I remembered 'future seqs' have been attempted at least a couple times in clojure

0:44 which pass some transparency tests Rx etc fail

0:44 but fail on merge

0:44 elifrey: referential transparency is a funny fraise

0:44 because really it only cares about transparency with respect to a given denotation

0:45 err

0:45 sorry

0:45 semantics

0:45 s/denotation/semantics/

0:45 if you can provide a semantics that make the given sentence referentially transparent, your golden

0:45 this is often trivial given the right operational semantics

0:46 consider

0:46 x = x++

0:46 typically we do not consider the ebove expression to be referentially transparent

0:46 because we are not able to give a /denotative/ semantics to it

0:47 but we are perfectly capable of giving a /operational/ semantics

0:47 so, under our interpretation of FRP as wiring up an event graph, we can give a reasonable operational semantics to the event graph and referential transparency is restored

0:48 would we say that we still, as humans, have the same ability to reason about the semantics?

0:48 I would argue no

0:50 tomjack: I guess merge is no problem without join?

0:51 elifrey: absolutely

0:51 join introduces non-determinism

0:52 this is a fundamental atribute of monads, they make some "future" expression dependent on "past" expressions

0:52 tomjack: so using a library like Rx safely basically means making sure you don't accidentally implement a (broken) join?

0:53 well they already implemented it for you I guess

0:55 elifrey: I am not confident enough to say yes, but probably :)

1:03 tomjack: I've been trying to think how core.async fits in

1:03 elifrey: tomjack: to frp?

1:04 tomjack: I found it interesting that the implementation in "LTL Types FRP" is async and that causal functions are modelled as processes

1:04 yeah

1:04 but I don't think a core.async 'process' is the same kind of process..

1:05 elifrey: I actually have not read that paper, when people press me abuot the corespondence I just hand wave :(

1:08 tomjack: it looks like a causal function is (implemented as) either a function which takes an interval of input to a new causal function, or an interval of output with the next causal function, or it's done

1:09 dissipate_: uvtc, i don't see what the threading thing buys you. it just looks like it reverses the order of things.

1:09 tomjack: which sounds vaguely reminiscent of core.async's channels

1:09 but they are no help I think

1:09 elifrey: does causal function mean Behavior?

1:10 is an interval an interval of time?

1:10 tomjack: yeah

1:10 uvtc: dissipate_, Right. I suppose there are some circumstances where it might make things more readable, depending upon the reader. :)

1:10 tomjack: to the second question

1:10 a causal function is a function from behavior to behavior with.. certain restrictions

1:11 dissipate_: uvtc, is it a replacement for using 'partial'?

1:11 callen: not really.

1:12 uvtc: dissipate_, No, I don't think so. I think `->>` is just a convenience thing, if you like reading things from top to bottom. :)

1:12 callen: chaining an initial piece of data through functions in Clojure is...quite common. Especially if the code is well written.

1:12 having sugar for that makes a ton of sense.

1:13 SegFaultAX: It isn't really a Clojure thing, it's a programming thing.

1:14 elifrey: callen: I think this is one of the things that makes idiomatic clojure much more readable than idiomatic <other lisp>

1:14 SegFaultAX: x = foo(1); y = bar(x); z = baz(y); return quux(z)

1:14 elifrey: It would be trivial to implement a threading macro in most other lisps.

1:15 callen: elifrey: the threading macros are the least of it.

1:15 dissipate_: uvtc, what is the idiomatic thing to do?

1:15 elifrey: SegFaultAX: yes but they don't, that's why I said idiomatic

1:15 callen: arity regularity makes it useful/non-painful to begin with. Lisp-1, and a bunch of other stuff too.

1:15 SegFaultAX: seen any golang or C code recently?

1:15 SegFaultAX: callen: Yes?

1:15 callen: you can't just "do" something and chain results. You have to play mother-may-I with the computer.

1:15 nothx

1:16 SegFaultAX: elifrey: Macros are idiomatic in Lisp.

1:16 dissipate_: callen, were you referring to the ->> macro?

1:16 uvtc: dissipate_, Personal preference, IMO. Personally, I'm not crazy about using `->` and `->>`, and generally find them a tad less readable than doing this the usual way, but please take that with a grain of salt. :)

1:17 s/doing this/doing things/ ^^

1:17 elifrey: SegFaultAX: yes, but it is not idiomatic to use a threading macro in other lisps. If you just started doing it willy nilly, people unfamiliar with your code would think you're bonkers

1:17 dissipate_: elifrey, is it idiomatic for clojure?

1:18 elifrey: dissipate: I certainly see it in lots of code

1:18 SegFaultAX: elifrey: Doubt it. As with any new syntax, it might take some time to get used to it at worst.

1:18 dissipate_: uvtc, do you see how this is frustrating for someone trying to lean clojure? :(

1:19 elifrey, what's the rule for when to use it?

1:20 SegFaultAX: dissipate_: The same for any syntax: if it makes the code and the intent clear.

1:20 benkay: (+ 1 (2 3 4))

1:20 uvtc: dissipate_, For now, I suggest you skip using `->` and `->>`. Then at some point later on you might run into a case where `->` and/or `->>` will be more convenient. :)

1:20 benkay: ,(+ 1 (2 3 4))

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

1:20 SegFaultAX: x = foo(1); y = bar(x); z = baz(y); return quux(z) <=> quux(baz(bar(foo(1)))) but the latter might be too hard to understand.

1:21 elifrey: dissipate: (f (g (k (v x)))) to (-> x v k g f)

1:21 SegFaultAX: (-> 1 foo bar baz quux) expands to a let form that is similar to the first case.

1:21 uvtc: dissipate_, Oh, almost forgot. Regarding what's idiomatic or not, have a look at the [Clojure Style Guide](https://github.com/bbatsov/clojure-style-guide).

1:25 s4muel: dissipate_: a good general case for -> is ring handlers 'in sequence'. (-> handler apply_this_mw then_this then_this_one return_handler) is a lot more readable than the alternative IMO

1:25 SegFaultAX: s4muel: Funny you should mention that, because -> is actually the opposite in that case.

1:25 elifrey: SegFaultAX: huh?

1:26 SegFaultAX: elifrey: Handlers are run in reverse order.

1:26 elifrey: ah

1:26 dissipate: any time you want to send something through a "pipeline"

1:26 s4muel: He's right for the ring case, (oops) but semantically I thought it was a good example

1:27 elifrey: cat log | cut -f1 | sort | uniq | head -n1

1:30 uvtc: Regarding Emacs and repl integration, I'm trying to understand which pieces talk to which. Does nrepl.el take care of whipping up a repl and then connecting to it?

1:30 s4muel: uvtc: Yes, it runs lein repl :headless and connects (assuming you're talking about nrepl-jack-in)

1:30 dissipate_: elifrey, i thought all of clojure was 'pipelines', applying in sequence forms to data structures?

1:31 elifrey: dissipate: thus I would find -> indispensible :P

1:32 dissipate_: uvtc, i didn't see that before, thanks!

1:32 elifrey, i don't see what it buys you really though. to me it just seems to reverse the order of evaluation.

1:32 uvtc: s4muel, Ah, thanks. What is the difference between M-x run-lisp and M-x nrepl-jack-in?

1:32 Which should I use?

1:32 dissipate_: elifrey, although, i can see in some cases it is easier to read if things are in the reverse order

1:33 uvtc: dissipate_, y/w. :)

1:33 s4muel: uvtc: I think the former just kicks off the generic 'inferior lisp', but I'm not sure.

1:33 elifrey: dissipate: I'm just not so big on parens

1:33 s4muel: uvtc: in terms of integration with clojure, 99% of the time, you want nrepl-jack-in

1:33 uvtc: 60% of the time, nrepl-jack-in works every time.

1:34 he he {cough, sputter, cough} Sorry. :)

1:34 elifrey: dissipate: clojure's syntax gets rid of many parens, but -> helps you for one of the most agregious offendors IMHO

1:34 uvtc: s4muel, Ok, will try nrepl-jack-in. I'd seen mention of M-x run-lisp at <https://github.com/clojure-emacs/clojure-mode>.

1:35 s4muel: uvtc: You might have a better overall experience using something like emacs-live. I don't know how 'invested' you are in your current emacs config. :)

1:37 uvtc: <https://github.com/clojure/tools.nrepl/&gt; indicates that nREPL (aka tools.nrepl) provides both a server *and* a client. But it seems to me that, when integrating with Emacs, nrepl.el is the client (and so whatever client nREPL provides goes unused). Does that sound about right?

1:37 dissipate_: elifrey, what is the worst offender?

1:38 elifrey: dissipate: nested function calls

1:38 dissipate_: elifrey, i see. i'll definitely keep that in mind.

1:39 uvtc: s4muel, Thanks. I don't know what emacs-live provides. I tend to prefer a simple from-scratch setup, and don't do a lot of heavy customization.

1:40 lgs32a: uvtc: emacs pure is fine

1:40 uvtc: if you are new to emacs, a guy just made an insanely great video tutorial series on youtube

1:41 uvtc: I just want to understand the simplest way to configure Emacs + nREPL + nrepl.el, but don't completely yet get how all the parts fit together.

1:41 lgs32a, I wrote up my basic Emacs config at <http://www.unexpected-vortices.com/clojure/10-minute-emacs-for-clojure.html>.

1:42 lgs32a: you don't really need to do a whole lot

1:42 uvtc: So far it looks like I just need to "M-x package install RET nrepl RET" and then "M-x nrepl-jack-in". :)

1:42 lgs32a: for nrepl

1:42 yes

1:42 exactly

1:42 ideally have a buffer with a current project open

1:42 uvtc: Trying it now ...

1:43 elifrey: lgs32a: does it automagically hook into lein?

1:43 lgs32a: you can either connect to an existing server or let it create one

1:44 sometimes you need to set the shell command for lein, but if it's on the path and you are on gnu, everything should be fine

1:44 elifrey: cool

1:44 lgs32a: uvtc: if you need auto-completion, here is what needs to be added to the emacs.nl (given auto-complete is installed) http://stackoverflow.com/questions/18259113/emacs-clojure-autocompletion-data-from-all-source-files-in-project/18263522#18263522

1:44 callen: did anyone else notice a hammock company is sponsoring Clojure Cup?

1:45 lgs32a: its ac-nrepl

1:45 emacs.el ofc

1:45 callen: lol!

1:46 uvtc: Not using ac-nrepl at the moment. Just focusing on getting nrepl.el/nREPL working.

1:46 lgs32a, ^^

1:54 So, after I create `lein new app my-proj` and open my-proj/src/my_proj/core.clj, and then run "M-x nrepl-jack-in" and get a "user>" repl, how can I call my `main-`?

1:55 (main-) fails. Can't find it.

1:55 s4muel: uvtc: Load the file containing main with C-c C-k.

1:56 uvtc: Then, switch to the file's namespace with C-c M-n, should reflect in the repl.

1:56 callen: uvtc: http://www.infoq.com/presentations/Clojure-Namespaces-Vars-Symbols

1:57 uvtc: s4muel, there we go. Thanks!

1:57 callen: uvtc: watch the video.

1:57 s4muel: when you toss them morsels that quickly, they never learn to cook steak.

1:57 uvtc: callen, will do. Thanks for the link.

1:58 callen: s4muel: better to just understand namespaces, symbols, and vars - and never be confused for bad reasons again.

1:58 uvtc: I want to learn to cook the steak.

1:58 callen: uvtc: then you'll do fine. Just watch the video, best resource I know for the subject. I don't even usually like A/V content.

1:58 Craig did a great job.

2:23 s4muel: callen: Ah, yeah, I agree. Just thought he was asking for nrepl help, missed the larger context :)

2:25 callen: what is good in life? To drink, listen to Rich Hickey interviews, crush your bugs, see them driven before you, and hear the lamentations of their exception classes.

2:25 To drink tea*

2:25 uvtc: s4muel, I understand a good bit about symbols, vars, and namespaces, but there's room for improvement, and the video is good so far (though almost nothing yet about how to cook a steak!).

2:31 s4muel: callen: I appreciate a good conan reference

2:31 * callen tips his cup of sencha in s4muel's direction and smiles

2:32 uvtc: Heh. That one reaches back into the archives. :)

3:34 ambrosebs: Anyone seen this implemented in Clojure? http://docs.racket-lang.org/reference/parametric-contracts.html#(form._((lib._racket/contract/parametric..rkt)._parametric-~3e/c))

3:35 callen: ambrosebs: conditions + multimethods?

3:36 ambrosebs: callen: I don't know. I'll dig into the Racket impl.

3:37 I didn't realise contracts could be parameterised like this. Nice.

3:39 dcunit3d: is there a good way to run my lein tests and then enter a debugger if they fail?

3:39 i've tried running them via emacs with C-c C-, but it doesn't resolve methods from other files

3:41 and is there anything like spork for clojure? so when i run my tests it connects to an initialized JVM with my code loaded?

3:41 callen: ambrosebs: my point is it seems like :pre and :post in Clojure.

3:41 I can't tell what would otherwise be missing from the Clojure impl

3:42 ambrosebs: callen: the first example on that page has a contract (parametric->/c [X] (boolean? X . -> . X)) for some X

3:43 callen: that's what I'm interesting in.

3:43 uvtc: callen, thanks again. Learned some things from Craig's talk. :)

3:45 ambrosebs: callen: it looks like it has a little type system in the contracts syntax.

3:45 callen: uvtc: good good :)

3:45 ambrosebs: Clojure conditions are more like multimethods. You just do whatever you want.

3:46 (fn [arg1 arg2] (boolean? arg1))

3:46 ambrosebs: ^^

3:47 ambrosebs: callen: no, the X is a variable. The return value must match the 2nd argument.

3:48 callen: it seems beyond any current contracts library for Clojure.

3:48 TEttinger: ambrosebs, couldn't you ensure that with :post ?

3:49 callen: which is my point

3:50 that's why I'm saying conditions because it's pre and post. Not just preconditions.

3:50 nothing is beyond pre/post conditions in Clojure because they happen at runtime and are just functions that can do anything

3:50 ambrosebs: I should clarify, I'm looking for a way to convert a core.typed type to a contract.

3:51 callen: convert them to :pre/:post conditions.

3:52 I'm not sure what the advantage of that would be though - just pushes compile-time out to runtime.

3:54 the advantage of :pre/:post to a type system are that you have the full extent of the language available at runtime.

3:56 ambrosebs: is it not enough that core.typed does one thing well, and :pre/:post do one thing well? :)

3:56 ambrosebs: callen: I don't see how pre/post conditions are powerful enough to implement the parameterise-c example.

3:57 callen: core.typed works just fine with pre/post conditions anyway.

3:57 callen: this is about generating contracts at typed/untyped boundarise to conserve type soundness to runtime.

3:57 *boundaries

3:58 callen: really? you don't see how you run boolean? on arguments and outputs from a function with :pre and :post?

3:58 could run*

4:00 ambrosebs: callen: read the example on the parameterised contracts page.

4:02 callen: I'm sure there are more complicated examples that use lots of type variables.

4:02 callen: ambrosebs: I understand it just fine. it's a cond/case in the :pre or :post

4:03 because again... :pre and :post are just functions and have the whole language as well as data at runtime.

4:04 and like I said earlier, :pre/:post + multimethods let you dispatch without writing a big branch if you don't want to

4:04 ambrosebs: callen: right. Obviously the only limitation is that you can't share scope between a pre/post. I guess you could do constraint inference in the :post to make sure the X's match up.

4:04 callen: I feel like I should've been less subtle in the point I made earlier about mm + conditions.

4:05 share scope between :pre and :post? That's a macro away from happening :)

4:05 realistically? part out the logic.

4:05 compositional assertions -> contracts

4:11 dobry-den: How would you get console output behavior like: "Loading... Done." where there's a long wait between Loading... and Done.?

4:11 callen: don't print a newline

4:11 Ember-: ,(println "Loading...") #_(long-running-stuff) (println "Done")

4:11 clojurebot: Loading...\n

4:12 Ember-: ?

4:12 callen: you printed a newline :|

4:12 Ember-: and yeah, if you want them on the same line, then use just print

4:12 callen: didn't realize he wanted them to be on the same line :)

4:12 until you said that

4:13 TEttinger: ##(do (print "Loading...") #(Thread/sleep 2000) (print " Done"))

4:13 lazybot: ⇒ Loading... Donenil

4:14 TEttinger: hm how do you make lazybot properly wait... I use overtone's at-at lib for this

4:14 `google overtone at-at

4:14 $google overtone at-at

4:14 lazybot: [overtone/at-at · GitHub] https://github.com/overtone/at-at

4:14 callen: at-at is great :)

4:15 dobry-den: (do (print "Loading...") (Thread/sleep 3000) (println "Done.")) still makes the whole line wait until 3000ms passes to flush whole line

4:15 TEttinger: dobry-den, I think it's the do

4:15 but there's no way... wait

4:15 ##[(print "Loading...") #(Thread/sleep 2000) (print " Done")]

4:15 lazybot: ⇒ Loading... Done[nil #<sandbox5671$eval11656$fn__11657 sandbox5671$eval11656$fn__11657@896efd> nil]

4:15 TEttinger: god...

4:15 callen: was that the original problem?

4:15 dobry-den: you don't need #

4:15 TEttinger: oh.

4:15 darnit

4:15 callen: that it buffered the output?

4:16 dobry-den: Basically i'd like it to work like (print "Loading...") (flush) (Thread/sleep 3000) (println "Done.")

4:16 but flush makes newline

4:17 TEttinger: dobry-den, this will work ##((fn [] (print "Loading...") (Thread/sleep 2000) (print " Done"))) but lazybot's preview will need to eval the whole thing first

4:17 lazybot: ⇒ Loading... Donenil

4:17 TEttinger: note the timestamps, waited 2000 ms

4:17 at least

4:17 I think it will work

4:18 dobry-den: it still waits 2000 before flushing anything at all

4:19 I guess for now I will settle for "Loading...*wait*\nDone."

4:20 But that's not the badass aesthetics i had in my head

4:20 TEttinger: dobry-den, hm

4:21 there's futures

4:21 callen: you do not need futures for this :|

4:22 TEttinger: callen, I think the problem is the waiting, not the printing

4:22 callen: dobry-den: it worked perfectly for me

4:22 TEttinger: what?

4:22 TEttinger: he was complaining about the aesthetics and there being an extra new line.

4:23 I have it all one line, working fine.

4:23 TEttinger: dobry-den, can you tell us if you are having trouble making it wait or having trouble printing on one line?

4:23 dobry-den: The problem is that (do (print "Loading...") (Thread/sleep 1000) (println "Done.")) doesn't print "Loading..." until after the 1000ms wait

4:24 callen: I added (flush) and it worked fine.

4:25 TEttinger: yep, that works

4:25 dobry-den: callen: i tried in regular repl and it works. weird - it doesnt work in nrepl

4:25 alrighty then

4:25 callen: emacs nrepl isn't intended, by any means, to be perfectly representative of stdout/stdin behavior

4:26 that's true of emacs buffers in general.

4:26 they're an editing environment, not a terminal one.

4:26 dobry-den: right, i just didn't think about it

4:26 lgs32a: is it impossible to define varadic methods for a protocol?

4:27 callen: for one thing, you shouldn't really be defaulting to using protocols for everything

4:27 I really wish people would stop doing that. It's unnecessary and pins you down.

4:28 lgs32a: i don't why would you think so?

4:29 callen: they're not going to support destructuring in defprotocols.

4:29 if you need destructuring, you're using protocols incorrectly.

4:30 Stop using protocols for everything.

4:30 Use multimethods.

4:31 wei_: does anyone use vim + nrepl, and have vim freeze one out of every six times you try to evaluate the buffer?

4:36 it's like coding russian roulette

4:38 rhg: Yup

4:38 callen: lol vim :)

4:56 wei_: considering switching to emacs just for the clojure integration, but it seems to have a high activation energy..

5:00 augustl: wei_: I don't want to use emacs but its features gives me no choice

5:01 wei_: that's how I'm starting to feel too. btw thanks for your help over at datomic

5:01 lgs32a: there is only one true editor

5:01 wei_: (inc augustl)

5:01 lazybot: ⇒ 2

5:06 TEttinger: I like lighttable

5:11 augustl: wei_: no probs :)

5:20 Raynes: I like darktable.

5:20 TIL http://en.wikipedia.org/wiki/Darktable exists.

5:54 quazimodo: hay hay

6:11 ambrosebs: clojure-contracts supports parametric contracts, for those interested. See Dependant Contracts http://t.co/ssZbKrDL8E

6:13 squidz: ambrosebs: how is the progress on typed clojurescript?

6:13 ambrosebs: squidz: better than 2 months ago!

6:13 squidz: basically I need to annotate the DOM now.

6:13 squidz: right now i'm using schema but I can't wait to have it for clojurescript

6:13 ambrosebs: squidz: cool!

6:14 squidz: it's not ready yet, but it's fun to hack around with.

6:14 squidz: there isn't much out on the web yet on it right?

6:14 ambrosebs: squidz: I think there is literally nothing :)

6:15 squidz: but the good news is that it's the same as Clojure support, except replace clojure.core.typed with cljs.core.typed

6:17 squidz: ambrosebs: what do you mean?

6:19 ambrosebs: squidz: so CLJS support is basically a bunch of macros in the cljs.core.typed namespace. You should replace (:require [clojure.core.typed :as t]) with (:require-macros [cljs.core.typed :as t]) and most of the type system semantics are identical.

6:20 squidz: then run the Clojure macro (cljs.core.typed/check-ns 'my-ns) in a Clojure REPL to check a CLJS namespace.

6:20 squidz: okay and that works for all of the javascript interop types too?

6:21 ambrosebs: squidz: the types are slightly different.

6:21 squidz: eg. there are string and number primitive types. Also things like Seqable are slightly different. clojure.lang.Seqable vs cljs.core/ISeqable.

6:22 squidz: I intend to include more type aliases to save rewriting the types for CLJ/CLJS.

6:23 ambroseb_: squidz: I'll get an example.

6:24 squidz: ambroseb_: okay you should document it so that more people know about it

6:26 there's a lot of stuff for clojure but nothing for clojurescript. I know it isn't really ready but people might still play around with it

6:27 ambroseb_: squidz: yes, you're right.

6:27 squidz: https://github.com/clojure/core.typed/blob/master/src/test/cljs/cljs/core/typed/test/dnolen/utils/dom.cljs

6:28 squidz: to check, run (cljs.core.typed/check-ns 'cljs.core.typed.test.dnolen.utils.dom)

6:29 squidz: ambroseb_: thanks

6:29 ambroseb_: squidz: I think if the Clojurescript *ns* is pointing to the desired ns, (check-ns) should also work

6:29 supersym: ambroseb_: ahhh... nice. I'm really getting warmed up for Cljs, this 'll fit in nicely

6:30 ambroseb_: supersym: :)

6:30 bug reports for CLJS are very welcome.

6:31 even if you get a NYI error :)

6:31 should help smooth out things, even at this early stage.

6:32 to here: http://dev.clojure.org/jira/browse/CTYP

6:32 supersym: ambroseb_: Checking arbitrary expressions: yeah somehow I knew that but never really use :pre :post that way... fun

6:32 btw typo there : standart

6:33 (sorry)

6:33 ambroseb_: supersym: where?

6:36 supersym: ambroseb_: http://t.co/ssZbKrDL8E -> Checking arbitrary expressions.

6:36 "clojure's standart mechanism of "

6:38 ambroseb_: supersym: ah. Not my library.

6:39 supersym: oh sorry I thought it was :)

6:39 ambroseb_: supersym: I wish! :)

6:54 ddellacosta: is there a way to use clojure.repl/doc in CLJS repl?

7:13 supersym: ddellacosta: I don't think so. http://goo.gl/jz0RPG It seems this would be the cljs equivalent but I'm far from expert on this, david nolen would know

7:15 ddellacosta: supersym: thanks. Yeah, I don't care so much, as there are plenty of places to look up functions, but it would be handy. Ah well.

7:15 supersym: yup

7:15 I can imagine that too

9:11 squidz: is there way to do async tests with clojurescript.test? I tried wrapping a go block around my deftest form, but am getting the error: nth not supported for this type:Symbol. Anybody have any ideas?

9:35 javax: http://groups.google.com/group/clojure

11:30 yury: Hi everyone!

11:30 could someone give me quick tip on filtering?

11:32 scottj: yury: use the correct predicate

11:33 yury: suppose I have list of records and one record, I need to get records from list with specified fields equal to that of record

11:35 for one field this is pretty straightforward function

11:35 seangrove: dnolen: Attached the patch to http://dev.clojure.org/jira/browse/CLJS-547

11:37 scottj: yury: with any or all of the specified fiels equal to that of record?

11:37 arrdem: yury: you want to use every, map and =

11:37 yury: with some fields

11:39 AimHere: Isn't this just a job for filter?

11:40 Something like (filter #(and (= (:foo X) (:foo %)) (= (:bar X) (:bar %)) recordlist) ?

11:42 hyPiRion: (filter #(apply = (map (partial select-keys :foo :bar) [X %])) recordlist)

11:42 urgh, wrong order on that select-keys, but oh well

11:43 * AimHere learned the select-keys function today.

11:44 arrdem: yury: https://www.refheap.com/18687

11:45 tested for records having a superset of the keys in the template

11:45 will fail for records having a subset of the keys in the template

11:56 yury: thanks a lot, select-keys was just what I've needed

12:25 fredyr: Does hiccup work for generating any xml, or just for html?

12:31 AimHere: fredyr, I think properly formatted hiccup input spits out something you can use for xml

12:31 fredyr, not sure how well it supports generating doctype declarations and such

12:32 fredyr: Right, might be better to stick to the xml libs

12:34 supersym: sigh...sometimes I wonder if Java exceptions could possibly be any more vague than they are now

12:35 ah..found it :P

12:39 hyPiRion: well, they could just return "Segfault"

12:40 supersym: oh.. thats true

12:40 Chousuke: it's most fun when you have Java servers in production/test environments producing 7GB of debug logs per day because logging is good, right? :P

12:41 supersym: yeah I dont envy that at all

12:43 Chousuke: it's completely useless to log that much. no-one is ever going to read something like that.

12:48 hyPiRion: depends. You can aggregate it

12:48 dcolish: 7G seems like a misconfiguration, but logging is really useful when things go wrong and I can't figure out how.

13:01 Caballero: anybody alive?

13:02 hyPiRion: yes

13:02 Caballero: need help with clojure, beginner here

13:03 hyPiRion: ~anyone

13:03 clojurebot: anyone is anybody

13:03 hyPiRion: ~anybody

13:03 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

13:03 Caballero: fair enough

13:04 how do I bind console input to a variable?

13:04 I'm working in eclipse - counterclockwise

13:06 hyPiRion: Hmm, I've not used CCW, but (read-line) will read a line from the console

13:07 If you want to automagically convert it to things other than strings, I'd recommend using clojure.edn/read

13:10 Caballero: surely there must be a simple way of doing this, like (def input(read-line))

13:10 this doesn't work, obviously

13:12 hyPiRion: Well, in the main function, you can do (let [input (read-line)] do-things-with-input)

13:15 Caballero: I've tried that, but I'm struggling with concept of "let". How would I put it into a function?

13:17 mtp: by putting it in a function

13:17 "let" mostly means "bind variables"

13:17 seangrov`: ,(defn my-fn [x] (let [y 10] (+ x y)))

13:17 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

13:17 seangrov`: ,((fn my-fn [x] (let [y 10] (+ x y))))

13:17 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: sandbox$eval55$my-fn>

13:17 seangrov`: ,((fn my-fn [x] (let [y 10] (+ x y))) 10)

13:17 clojurebot: 20

13:17 seangrov`: There we go

13:23 Caballero: ,(defn foo [] (let [input (read-line)]) (println input))

13:23 (foo [])

13:23 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

13:23 Caballero: this gives me nil

13:24 mtp: yes

13:24 it does

13:25 what does println return? consequently, what does the let form return, and finally, what does your function return?

13:27 Caballero: everything seems to evaluate to "#<Namespace user>"

13:27 is this maybe the wrong place to ask newbe questions?

13:28 seangrov`: Caballero: No, it's fine, mtp's questions are appropriate for you though

13:28 ,(doc println)

13:28 clojurebot: "([& more]); Same as print followed by (newline)"

13:28 lunk: how can I set a public var on an instance object?

13:28 seangrov`: ,(println "this returns nil")

13:28 clojurebot: this returns nil\n

13:28 seangrov`: Weird

13:29 Didn't know clojurebot also captures stdout

13:29 hyPiRion: ,(do (println "this returns nil"))

13:29 clojurebot: this returns nil\n

13:29 sontek: Is there a place that describes what the implementation behind a vector is? I come from a python background where the "vector" is called a list and its implemented as an array behind the scenes

13:29 which means appending things to the beginning are extremely slow

13:29 I guess this isn't the case with clojure since its all immutable, so it just returns new vectors?

13:30 seangrov`: sontek: Yes, there are performance implications for the data structures you choose

13:31 Caballero: in eclipse, what's the difference between "REPL" and "Console"?

13:31 seangrov`: For example, peek

13:36 sontek: seangrov`: is there documentation on this anywhere?

13:37 mpenet: sontek: not really docs but still: http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html

13:43 sontek: mpenet: thanks

13:48 seangrove: dnolen: Should this ticket be closed, or am I missing something with goog.json and clj->js, etc.?

13:51 yury: is there any guidelines about placement of different kinds of arguments?

13:52 f/e I have function with two arguments: one list of records and another record. which should come first?

13:54 AimHere: The two considerations I can think of is variable argument lists and other similar functions of the same type

13:54 rlb: yury: I'd say nothing you've mentioned so far would argue either way.

13:54 AimHere: If you have a family of similar functions, it probably helps to be consistent

13:54 rlb: ^

13:55 AimHere: And if you want to generalise to more arguments of one or other of those two types, put the 'multiple argument type' last

14:25 hadronzoo: When two namespaces require each other in clojurescript, it causes the compiler to crash. Is there a way to just import one ref from another namespace without using require or use?

14:26 muhoo: this seems... like ugly code to me that could be made less so: https://www.refheap.com/18689

14:26 Bronsa: hadronzoo: circular dependencies are not supported in clojure or clojurescript

14:27 hadronzoo: Bronsa: I see. Thanks.

14:28 Bronsa: If I explicitly prefix the namespace in clojurescript, it actually works, but it doesn't work in Clojure.

14:29 Bronsa: hadronzoo: it's proabably an implementation detail that it works in clojurescript, I don't think you should rely on that

14:30 hadronzoo: Bronsa: Right, I'll refactor.

14:50 yury: how to use function with two arguments (one 'constant' and one being 'current' from list) in "apply"?

14:52 joef_: yury: `partial`?

14:52 yury: dunno. I have list to which I want to apply some F with two arguments

14:53 ucb: ,(doc partial)

14:53 clojurebot: "([f] [f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & ...]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."

14:53 ucb: yury: ^

15:02 yury: (defn f-one [some-list some-record] (...))

15:02 (defn f-two [list-one list-two] ("here I need to consecutively f-one(list-two, each-record-from-list-one")))

15:03 how to implement what between quotes?

15:03 for function with single arg it's pretty straightforward with apply

15:03 and what to do with two args?

15:04 borkdude: what was the leiningen plugin again to host a directory on a simple http webserver?

15:04 dnolen: seangrove: thanks for the source map patch applying!

15:05 joef_: yury: like this? (defn f-two [list-one list-two] (apply (partial f-one list-two) list-one))

15:05 (urm, and some sort map/doseq, i guess?)

15:06 je: borkdude: I believe you are thinking of lein-simpleton

15:06 borkdude: je that's the one, thanks

15:06 je: borkdude: np :)

15:07 yojimbo_: Hi - I am playing around with async http lib for scraping (I am using org.httpkit.client) what is the standard way of dealing with the issue that: in the repl async code works fine as the repl waits for the callback. But in a "lein run" the main just ends without the callback completing?

15:16 joef_: yury: (defn f-two [list-one list-two] (map (partial f-one list-two) list-one))

15:21 yury: yeah, thanks, that seems did the trick. completely forgot about the map. shame on me :) and I'll will blame 1AM :)

15:23 mayhew: Hey guys, I'm trying to get readline support in the Clojure REPL. I have clojure and jline installed on Fedora, but when I type "clojure" jline isn't being loaded.

15:27 rcg: mayhew, if you are on linux i'd go with rlwrap

15:27 mayhew: rcg: works perfect, thanks!

15:28 rcg: http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Enhancing_Clojure_REPL_with_rlwrap

15:28 mayhew, ^

15:28 that should give you much more nice features :)

15:29 mayhew: rcg: cheers

15:30 rcg: yw :)

15:31 tufflax: I'm using robert.hooke to add some logging wrappers to my functions. But I want to print the thread name in the log, since some functions are shared among several threads. I read that set! can change the thread-local binding of a var, so I tried (def thread-name nil) (set! thread-name "server") but got "Can't change/establish root binding of: thread-name with set", why? Also, is what I'm doing a go

15:31 od idea?

15:42 coventry`: Are there situations where it would make more sense to use lein simpleton than python's SimpleHTTPServer?

15:53 tufflax: Are you trying to set custom names for your threads? Why not do it at creation time? http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#Thread(java.lang.Runnable, java.lang.String)

15:55 gfredericks: tufflax: you can't set! the thread-local value if the var doesn't have one

15:56 tufflax: can you wrap each thread's entry point with (binding [thread-name "..."] (do-everything-for-this-thread))?

15:57 tufflax: gfredericks: about the var not having a value: i thought i gave it a value when i used def

15:57 no? :P

16:04 tomjack: Raynes: what should I do about https://github.com/Raynes/laser/issues/30 ?

16:08 gdev: tufflax, so when you do (.. Thread currentThread getName) it doesn't give you the correct name?

16:09 tufflax: gdev: I have not tried, but I don't think so, because I used future to start it, and future does not take a name

16:09 gfredericks: tufflax: you gave it a thread local value

16:10 I mean a root value, sorry

16:10 tufflax: oh, so it needs a thread-local first? So I need to use binding?

16:12 coventry`: Thanks. I'll think about it

16:12 Raynes: tomjack: I can't reproduce this problem.

16:15 tomjack: thanks

16:15 that led me directly to the problem

16:15 tufflax: gfredericks: ah yes, you said that already. But I mean is binding the only way to set a thread-local binding?

16:15 tomjack: clj-http 0.7.6 transitively requires a different jsoup

16:16 callen: tufflax: you can set a thread-local var in a variety of ways, binding is just a scoping mechanism.

16:16 tomjack: through crouton

16:16 tufflax: callen: ok... I'll try to read up on this a little bit more, let's see

16:17 callen: tufflax: have you read clojurebook.com ?

16:17 Raynes: this would be easier if I could just directly link a portion of an online book.

16:18 tufflax: callen: no. I read programming clojure and the joy of clojure a while back

16:18 gdev: (defn thread-inc [x] (let [t (.. Thread currentThread getName)] [(inc x) t])

16:18 call pmap with that

16:23 callen: pedagogy-in-motion

16:23 coventry`: Why do you want to log the thread, if you're running in a future? Do you mean the thread which delegated the future?

16:24 callen: coventry`: I think the point is to demonstrate the behavior.

16:25 coventry`: callen: I'm confused by "I want to print the thread name in the log, since

16:25 some functions are shared among several threads." vs "I used future

16:25 to start it, and future does not take a name"

16:26 callen: coventry`: I think the newer people get hung up on unnecessary "place-ness"

16:29 gdev: place oriented programmer is still rampant in the newbie community, sorry

16:29 dakrone: tomjack: you should be able to exclude it from clj-http (if you haven't already solved your problem)

16:29 tomjack: yeah, thanks, I noticed that's in the clj-http readme for other reasons

16:29 I actually think I don't need laser anyway, two tiny clojure.data.zip.xml exprs have got me almost entirely what I need :)

16:30 dakrone: cool

16:45 tufflax: coventry` gdev oh didn't realize you were speaking to me :p

16:46 coventry`: "Why do you want to log the thread, if you're running in a future?" Why not? The future is one of the threads I want to log :P

16:46 coventry`: How will knowing the thread the future is running in elucidate the operation of your program?

16:50 tufflax: coventry`: Hm, maybe I'm confused, but: I have a few threads, started with future. And I want to print the output of a function called process-network-msgs, for example. But that function is shared. So I want to print like "output of process-network-msgs (thread: server): some output"

16:50 as opposed to (thread: client)

16:50 coventry`: So (thread: server) is the thread from which the future is delegated, not the thread the future is run in, right?

16:51 tufflax: It's the thread that runs the future, i.e. the whole server runs in the future

16:52 coventry`: That sounds like an abuse of futures. Who do you return the result of the server's execution to?

16:53 tufflax: coventry`: No one, I just use futures as an easy way to start new threads.

16:54 coventry`: Don't do that, then. :-)

16:54 "Easy." :-) http://www.infoq.com/presentations/Simple-Made-Easy

16:55 tufflax: Yes, easy

16:55 I've seen that :p

16:55 coventry`: What are the downsides of my use of futures?

16:57 coventry`: You're running into this limitation because you're using futures for something they're not designed for. No one needs to know the name of the thread running a future the way it's supposed to be used.

16:58 tufflax: Ok, are there any other problems, besides the names thing?

16:58 callen: tufflax: stop getting involved in place-ness.

16:58 just perform computation, do not worry where it happens.

16:58 if it's truly impossible to approach it thusly, futures aren't your bag.

16:59 tufflax: callen: Maybe I'm abusing futures, but about place-ness: I want to know where things happen for debugging, is that wrong? :p

17:00 coventry`: Placeness is a total red herring here.

17:16 tufflax: Anyway, thanks callen coventry` gdev. I appreciate all the advice I get.

17:18 coventry`: No problem. Just change your non-returning futures to named threads and use getName and you'll be set.

17:18 tufflax: :)

17:19 gdev: tufflax, no problem, good luck

17:57 dnolen: holy crap source maps in CLJS actually work!

18:03 supersym: oh thats pretty cool actually

18:04 TimMc: !

18:49 akurilin2: I'm curious, does anybody out there with a Ring app do a params validation pass before passing the request further to the controller's handler? Seems like it might reduce the cyclomatic complexity of the handler which might be pretty beefy already.

18:53 brehaut: akurilin2: I think one of the service API tools might do that? (webmachine based ones)

18:54 akurilin2: brehaut, interesting, not familiar with that one at all

18:54 brehaut: akurilin2: i'll try ot find it. one moment

18:56 akurilin2: This is probably part of my odyssey of rolling my own until I discover someone else has solved it much more elegantly :)

18:57 brehaut: akurilin2: http://clojure-liberator.github.io/liberator/

18:58 akurilin2: brehaut, awesome, thannks for digging it out!

18:58 know of anybody on here who might have used it?

18:58 brehaut: theres also https://github.com/cmiles74/bishop but i think liberator has grabbed the most mindeshare

18:58 no idea sorry

18:58 akurilin2: keep in mind i think its for service endpoints rather than 'pages'

18:59 akurilin2: brehaut, not sure I'm following that last statement.

19:00 brehaut: akurilin2: it serves up JSON, XML, EDN etc structured data for restful services for consumption by programs, rather than serving up HTML etc for consumption by browsers/humans

19:00 (i think)

19:01 akurilin2: brehaut, is the implication that it would be non-trivial to jam some HTML templating in there?

19:01 brehaut: pass

19:02 akurilin2: Ok!

19:03 Thanks for pointing me in that direction though.

19:12 supersym: akurilin2: you know pedestal.io? not sure what you were looking for exactly, but that is more for pages (also services though)

19:12 dnolen: how to enable source maps in CLJS 1889 http://swannodette.github.io/2013/09/15/source-maps/

19:12 akurilin2: supersym, I think I was looking more for good design patterns for that specific situation rather than a framework.

19:13 brehaut: akurilin2: re:patterns, i think you are on the right track re:middleware

19:13 akurilin2: theres nothing at all wrong with using a middleware around a single handler in ring

19:13 supersym: ah ok... hehe, I have that a lot as well, not being sure what I'm looking for :)

19:14 dnolen: thanks!

19:27 sontek: I saw this earlier today for sourcemaps as well: http://beandipper.github.io/

19:28 danielszmulewicz: I have a lazy sequence containing maps and strings. I want only the maps. What would be the most idiomatic way to filter the collection?

19:29 dobry-den: danielszmulewicz: (filter map? coll)

19:29 danielszmulewicz: dobry-den: Nice. Thanks!

19:30 dobry-den: danielszmulewicz: http://clojure.org/cheatsheet

19:31 danielszmulewicz: dobry-den: I always forget about the cheat sheet. (I should install the emacs add-on) Thanks!

19:32 brehaut: always useful ##(apropos #"\?$")

19:32 lazybot: java.lang.RuntimeException: Unable to resolve symbol: apropos in this context

19:32 brehaut: &(use '[clojure.repl :only [apropos]])

19:32 lazybot: ⇒ nil

19:32 brehaut: &(apropos #"\?$")

19:33 lazybot: ⇒ (superset? subset? i? absolute-path? indexing-reader? enabled? single? include? prefix-of? zipper? attr? leftmost? auto? rightmost? number-literal? opt? empty-coll? leftmost? auto? rightmost? is-command? ignore-message? seqable? connection? db-ref? collection-exists?... https://www.refheap.com/18703

19:33 brehaut: ie, list all the predicates available

19:33 danielszmulewicz: brehaut: cool!

19:33 brehaut: apropos also takes strings and symbols

19:34 &(apropos 'map)

19:34 lazybot: ⇒ (map-invert encode-map generate-map map-nth multi-map map-vals map-vals-with-keys map-keys map-to ordering-map map-keys-and-vals into-map mapcat-chain build-request-map map-entry mapcat-chain cmd-map map-reduce write-concern-map query-option-map sorted-map ns-unmap z... https://www.refheap.com/18704

19:35 danielszmulewicz: brehaut: very nice.

19:36 dobry-den: yeah, getting some way to quickly sort functions really helps in clojure. like typing in 'pred' and learning cool fn like 'every-pred'.

19:36 i use Dash on OSX for quick lookups

19:36 arrdem: brehaut: mother of god what are you doing to the bot

19:37 brehaut: arrdem: get it to find functions with names similar to various expressions

19:38 danielszmulewicz: brehaut: where is map-vals defined?

19:38 brehaut: danielszmulewicz: at a guess, clojure.set ?

19:38 danielszmulewicz: brehaut: oh

19:39 brehaut: oh

19:39 no its in useful

19:39 &(use '[clojure.repl :only [find-doc]]

19:39 lazybot: java.lang.RuntimeException: EOF while reading, starting at line 1

19:39 brehaut: &(use '[clojure.repl :only [find-doc]])

19:39 lazybot: ⇒ nil

19:39 brehaut: &(find-doc "map-vals")

19:39 lazybot: ⇒ ------------------------- useful.map/map-vals ([m f & args]) Create a new map from m by calling function f on each value to get a new value. ------------------------- useful.map/map-vals-with-keys ([m f & args]) Create a new map from m by calling function f, with... https://www.refheap.com/18706

19:39 brehaut: arrdem: sorry!

19:40 it would be nice is apropos spat out qualified names

19:40 arrdem: haha

19:41 it's cool I just keep forgetting about apropos

19:41 brehaut: apropos: its almost as cool as juxt

19:41 * arrdem still doesn't grok juxt

19:42 danielszmulewicz: this is helpful too: https://github.com/krisajenkins/clojure-cheatsheet

19:42 brehaut: arrdem: its really easy. it juxtaposes (puts side by side) the results of some functions on the same input

19:42 arrdem: the only trick is that it creates a new function.

19:43 arrdem: (juxt inc dec) == (fn [x] [(inc x) (dec x)])

19:44 ,((juxt inc dec) 1)

19:44 clojurebot: [2 0]

19:44 brehaut: ,((fn [x] [(inc x) (dec x)]) 1) ; arrdem

19:44 clojurebot: [2 0]

19:45 Acio: how would you do assoc-in for transients maps? a direct translation doesn't work since you can't get a key out...

19:46 arrdem: ,(symbol? 'foo)

19:46 clojurebot: true

19:47 arrdem: ,#word

19:47 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

19:50 gdev: ,#+

19:50 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

19:50 gdev: ,#'+

19:50 clojurebot: #'clojure.core/+

19:53 gdev: Acio, have you found your answer yet?

19:53 Acio: gdev: nope! googling off and on

19:55 gdev: Acio, I think you would have to call persistent!

19:55 for a good example look at the source of frequencies

19:56 Acio: yeah that seems to be the only answer I have so far, which I might as well use the non transient maps since the majority of that work is assoc-in

19:56 gdev: Acio, sorry for tossing in a red herring, but why are you using a transient? performance?

19:57 Acio: mostly learning. i think the persistent version is fast enough, but i was wondering how i would retrofit the block of code to be completely transient

19:58 basically i'm taking timeseries and merge them into a map by date... something liek group-by

19:58 several timeseries*

19:58 SegFaultAX: Acio: Neat, why not just use group-by though?

19:59 Acio: the maps are created on the fly instead of having them pregenerated

20:00 its funny (and maybe its me as i'm still newbie) that i can spend 30 minutes and then end up with 8 lines of clojure

20:00 but that still beats anything i could have done in java typing the entire time

20:00 gdev: Acio, can you post a link to the code?

20:00 Acio: 30 mintues thinking*

20:01 cant sorry, employer rules

20:05 Raynes: lol

20:06 If it is impossible to come up with an example demonstrating your problem then you're probably not going to have a whole lot of luck getting help.

20:06 :(

20:06 SegFaultAX: It's too bad Clojure doesn't have sum built in.

20:06 Raynes: Sure it does! :D

20:07 &(reduce + (range 100))

20:07 lazybot: ⇒ 4950

20:07 SegFaultAX: ,(apply + (range 100))

20:07 Raynes: That's pretty darn built in :p

20:07 clojurebot: 4950

20:07 SegFaultAX: But that's not built in. :)

20:07 Raynes: Higher order functions, man.

20:08 SegFaultAX: Raynes: That's why I want it, to make an even cooler looking fib.

20:08 hyPiRion: sum is very specific. It's almost like having a standard deviation function

20:08 gdev: Raynes, I'm the kind of person that buys the pre-themed legos, not the generic bag of blox ;D lol jk

20:08 * Raynes hugs hyPiRion

20:08 SegFaultAX: (iterate (juxt second sum) [0 1])

20:08 * hyPiRion hugs Raynes

20:08 Raynes: <3

20:08 SegFaultAX: hyPiRion: Nah, it isn't.

20:09 Many languages provide sum. It's common enough I think.

20:10 hyPiRion: Many?

20:10 Bronsa: SegFaultAX: clojure provides far more important built-ins than sum :)

20:11 SegFaultAX: I'm not bent out of shape about it. Just sayin...

20:11 hyPiRion: The only one I really know of is Python

20:12 gdev: not even java's math library has sum in it

20:12 SegFaultAX: hyPiRion: Haskell.

20:12 brehaut: hyPiRion: with the inclusion of sum, python doesnt need reduce!

20:12 rhg: (def sum (partial apply +))

20:12 SegFaultAX: brehaut: Funny thing about Python's functional built ins...

20:12 They are sort of an accident in history.

20:12 brehaut: SegFaultAX: pythons functional stuff just makes me angry

20:13 SegFaultAX: brehaut: Heh, tell me about it! :)

20:13 brehaut: SegFaultAX: im just glad i can jam partial into the global jinja template context and partially apply 'macros'

20:13 SegFaultAX: brehaut: Yea, functools is handy.

20:14 Also, why don't they just call them partials like every other template language?

20:14 Damn you mitsuhiko!

20:15 hyPiRion: brehaut: With the inclusion of the for loop, Golang doesn't need functional programming!

20:16 brehaut: hyPiRion: i was snarkilly paraphrasing guido :(

20:16 hyPiRion: What's the need of sum, when you can just do `sum := 0; for _, v := range coll { sum += v }` ?

20:16 yeah, I know

20:18 SegFaultAX: Go has some really interesting features, but I'm not sure I could use it for a serious project.

20:19 Not that everything /must/ be functional for me, but I don't even have the option in Go. The structure of the language doesn't really seem to allow it.

20:21 tomjack: https://www.refheap.com/66892428082d890fc32deff89

20:21 right when I was about to hit enter, I understood why..

20:22 SegFaultAX: And tomjack was enlightened.

20:23 benkay: i'm trying to work with my first java interop stuff, and i'm running up against a wall. in project.clj, i say ":java-source-paths [["src/main/java"]]...)", and in that directory i have org/quantlib/awholebunchofdifferentfiles.java

20:23 gdev: namespaces: enemy of the noob

20:23 not say you're noob, tomjack =o

20:24 benkay: when i run lein repl (or jack in from emacs), it blows up with Exception in thread "Thread-2" java.lang.IllegalArgumentException: No implementation of method: :as-file of protocol: #'clojure.java.io/Coercions found for class: clojure.lang.PersistentVector

20:24 obviously i am derp on this.

20:24 ideas?

20:25 gdev: benkay, error message seems pretty clear

20:25 benkay: oh whoa. a single vector instead of a vector of vectors works just dandy.

20:25 gdev: I suppose i was referring to too many internets saying that l2 takes a vector of vectors for java source paths.

20:27 gdev: benkay, wouldn't know without looking at the codez

20:33 and even then, my advice is still suspect at best =D

20:51 muhoo: dear lazyirc, is there some way to start a repl :connect with a given namespace and some injections, from the command line?

20:51 i.e. lein repl :connect 7777 :injections (some-forms....) ?

20:52 or :init, maybe, hmm.

21:18 dobry-den: If you run `lein repl :headless` on your remote server and then Tramp in to a your remote clojure project, how do you connect to the headless repl? I would have assumed `M-x nrepl` with localhost and port

21:28 coventry`: dobry-den: If you're tramping in, you've got the wrong localhost. You would need to do "lein repl :headless :host FQDN :port port, and connect your repl to the FQDN, but I've never tried that, and it might not be a very good idea froma security standpoint.

21:35 scottj: dobry-den: I think you want to use ssh tunnelling, like "ssh user@remotemachine.com -N -L 41726:localhost:41726", and then localhost and 41726, where 41726 is whatever port lein repl :headless says

21:35 with that ssh command executed on your dev machine

21:40 dobry-den: scottj: huge. thanks

21:42 Pupnik_: are there any instructions anywhere for setting up clojurebot? the readme is very brief

21:55 benkay: working on my first interop stuff with QuantLib (i know, i know, don't bite off too much, kid...), and I've run into the UnsatisfiedLinkError as mentioned here: http://www.bnikolic.co.uk/blog/ql-java-clojure-loader.html

21:56 the suggested solution is to add a simple class to the jar, but as I'm using the SWIG compiled java wrapper, I just wrote that wrapper as a file in the same directory (I have zero experience with Java development - trying to hack my way to competence over here), but then I run into another UnsatisfiedLinkError, no QuantLibJNI in java.library.path.

21:57 question is: is there a subtlety to adding in new java classes to a set of files vs. a jar?

21:57 (I spent 4 hours this morning trying to compile the SWIG wrapper into a jar, but as mentioned, Java ain't my hometown)

22:00 Apage43: benkay: http://stackoverflow.com/questions/7511789/clojure-lein-how-do-i-include-a-java-file-in-my-project see the answer here

22:01 basically if you want to mix java & clojure, just add a :java-source-paths to your project.clj and lein will take care of getting stuff compiled for you (and included in any jars spit out by lein jar or lein uberjar)

22:01 https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L238

22:01 benkay: heh Apage43 if you look at the bottom of that page you'll see my contribution to the :java-source-paths question

22:01 Apage43: oh

22:02 herp derp :D

22:02 benkay: yeah this is a silly thing

22:02 Apage43: well, that + your original link should kind of do the trick

22:02 benkay: well, i'm a silly thing playing with tools beyond my comprehension

22:02 so, loading the files is not the problem

22:02 Apage43: build a java class with a static initializer and import it before you try to use the bits that depend on the native library

22:03 benkay: like this: http://pastebin.com/EPKC0nPP ?

22:04 Apage43: yeah.. or

22:04 you might be able to use https://github.com/flatland/classlojure

22:06 and do (with-classloader (.getClassLoader SomeClassFromQuantLib) (System/loadLibrary "QuantLibJNI"))

22:06 benkay: so the static loader works just fine, I think I need to start digging around to find QuantLibJNI

22:07 Apage43: ah

22:07 that'll be looking for QuantLibJNI.so, or .dylib, or .dll, depending in some directory on your java.library.path

22:07 benkay: 'cause what I see when i load my core.clj file in my repl is "UnsatisfiedLinkError no QuantLibJNI in java.library.path..."

22:08 cool!

22:08 Apage43: that's the JVM opt -Djava.library.path=/path/to/place

22:08 benkay: now that java.library.path is *not* going to be the same as the :java-source-paths in project.clj correct?

22:08 Apage43: correct

22:09 benkay: (thanks for bearing with my *complete* unfamiliarity with the Java ecosystem)

22:09 Apage43: you can make leiningen pass the the -Djava.library.path=/whatever/ flag though: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L225

22:10 benkay: huh.

22:10 Apage43: benkay: *however* a lot of java libs have their native parts in a jar

22:10 which leiningen should be able to automatically pick up if you've got it pulling down their right dependency

22:10 it'll usually be something like projectname-natives

22:11 possibly pronjectname-natives-{linux,macosx,windows}

22:11 benkay: i had to derp the *.java files into a directory and then point Leiningen at them in my project.clj

22:12 Apage43: and leiningen will be looking in Clojars and Maven for these native jars?

22:12 Apage43: if it's something you installed with your OS package manager and aren't pulling down with the java dependency mechanism though, that wouldn't be the case

22:12 benkay: yeah

22:13 benkay: Apage43: actually, I just downloaded the whole thing from quantlib.org - it had SWIG-generated Java files

22:13 Apage43: http://search.maven.org/#search%7Cga%7C1%7Cjogl%20natives

22:13 example for JOGL

22:14 ah

22:14 it's not playing with the maven-y ecosystem then

22:14 benkay: i doubt it.

22:14 Apage43: so you'll have to figure out where QuantLibJNI lives and put it on your java.library.path :/

22:14 benkay: yup

22:14 Apage43: or maybe QuantLibJNI is something you need to build? Dunno.

22:14 benkay: moar research.

22:15 Apage43: good luck :)

22:15 benkay: thanks :)

22:15 just as I gain a baseline of competence with Clojure i bite off a project that entails learning the Java stack.

22:17 bja: I figured out how to win an obfuscated javascript contest: write cljs passing partial functions around core.async channels

22:23 benkay: Apage43: it turns out that QuantLibJNI.java exists in the same directory as the BKLoader.java I wrote. how do I point System.loadLibrary("...") at that file?

22:23 Apage43: Actually that doesn't correspond to the thing you want to load

22:23 benkay: oh :(

22:23 Apage43: QuantLibJNI is the Java side, and that'll get built for you

22:24 that builds a .class though

22:24 loadLibrary is looking for a .so (linux, other *nix), .dylib (OSX), or .dll (Windows)

22:24 benkay: ah

22:24 Apage43: which will be build from some C or C++ code

22:24 benkay: got it!

22:25 so when I compiled QuantLib earlier today that was actually a necessary step

22:25 Apage43: yeah

22:25 benkay: because these *.java files are the java bindings to interact with that binary

22:25 Apage43: and if the SWIG bindings also generated some C/C++ code in addition to the .java files

22:25 benkay: nah they came down in toto

22:25 no compiling

22:25 Apage43: ah

22:25 benkay: awesome

22:26 i learned a lot today! and you put the last piece in place! yay!

22:26 Apage43: well there should be *some* C or C++ lying around you need to build to get QuantLibJNI.something

22:26 benkay: yeah, I built that.

22:26 and then deleted it out of frustration because derp

23:14 seancorf`: ld

23:37 benkay: ping Apage43

23:38 Apage43: Her

23:38 Hey

23:38 benkay: dah nevermind

23:38 still hacking

23:39 Apage43: K

23:39 callen: how's everyone's Sunday going?

23:39 benkay: well actually if I have your attention...

23:40 Apage43: we were talking about passing in the java.library.path option via Leiningen

23:41 is that going to be looking at the OS path? or should I be passing that the path to the .dylib I want loaded?

23:46 grandy: new to clojure, trying to figure out if there is a simple way to convert the nested vector output of instaparse into a map or something along those lines

23:47 benkay: (musing aloud in hopes that someone corrects me), according to (http://stackoverflow.com/questions/10558795/using-lwjgl-in-leiningen-clojure), apparently I could reference `native/linux` (or in my case, native/osx). so i'm going to copy the dylibs in my homebrew folder to native/osx and point Leiningen at them.

23:47 callen: grandy: you want a nested map instead of a nested vector?

23:47 does that really win you much?

23:48 grandy: callen, hmm, maybe not, i guess i'd like to avoid having to use integer indexes

23:49 callen: was thinking i could adapt the instaparse parser to return something more flat

23:49 callen: all this may be stupid "new to clojure" reasoning

23:49 callen: grandy: if you want something flat, then you need to learn to use zippers more than likely.

23:50 grandy: callen: ahh ok, i guess maybe i can destructure the nested vector

23:51 callen: but parsers are naturally a nested "thing"

23:51 coventry`: He means these. They're worth a look. http://clojure.org/other_libraries#Other%20included%20Libraries-Zippers%20-%20Functional%20Tree%20Editing%20(clojure.zip)

23:51 callen: whether your data structured is zipped or not, the data *will* be nested fundamentally.

23:52 grandy: ahh cool thanks to both of you, yes true

Logging service provided by n01se.net