#clojure log - Jul 09 2014

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

0:06 Frozenlock: Want to learn Clojure? Hang in #clojure and you'll learn by osmosis :-p

0:13 amalloy: osmosis is okay, but you'll go a lot faster if you try to contribute

0:13 otherwise it all just washes over you

0:33 sm0ke: in project.clj i have something like (def profiles {:a {..} :b {...}}) (defproject.... :profiles profiles)

0:33 but this doesnt seem to work

0:34 technomancy: sm0ke: defproject is a macro; it implicitly back-quotes.

0:34 sm0ke: but ~profiles also doesnt work

0:34 technomancy: hm; I know other people have gotten that working

0:35 sm0ke: technomancy: i you remember the bug which we were discussing..seems like its already there https://github.com/technomancy/leiningen/pull/992

0:36 only that there is no doc for it at all

0:37 also it is nice that if i just put :classifier "xyz" in project.clj it is converted to an xml element in .pom file

0:37 technomancy: yeah, definitely needs docs

0:38 sm0ke: but the right way is to use :classifiers , as you would not want to install each one seperately

0:39 i will add the same example to sample.project.clj

0:39 i think everyone looks there first

0:41 so my problem now is i want to have classifier for each profile which i have and do not want to replicate the profile map

0:41 i mean rewrite

0:48 technomancy: you can have composite profiles

0:49 :profiles {:a {:x "y"} :b {:z 10} :aplusb [:a :b]}

0:49 arrdem: technomancy: it wasn't clear to me when I read the docs yesterday: can you have a composite profile with definitions?

0:49 technomancy: arrdem: definitions?

0:50 arrdem: so :profiles {:foo {:inherits [:a :b] :dependencies [[com.foo/shit "0.0.0-SNAPSHOT"]]}}

0:50 technomancy: arrdem: map keys are just map keys

0:50 there's no magic keys with special meanings

0:51 I mean, they all mean the same thing they mean inside defproject

0:51 arrdem: okay. so you have to have an "intermediary" profile that gets merged with whatever you are going to inherit from.

0:51 technomancy: I wouldn't use the term "inherit"

0:51 "merged" is better

0:51 arrdem: sure

0:52 technomancy: but yeah

0:56 sm0ke: https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/project.clj

0:56 seems to be doing the same thing

0:57 i am not sure why :profiles ~profiles wont work

1:28 shanemhansen: How would you use the iterate macro if your function took multiple arguments?

1:30 I want to generalize something like (apply foo (apply foo [arg1 arg2]))

1:33 bbloom: shanemhansen: iterate is a function, not a macro

1:33 shanemhansen: bbloom, sorry. I'm really new to clojure/lisp.

1:33 bbloom: shanemhansen: no worries

1:34 it doesn't really make sense for iterate functions to take multiple arguments b/c it will use the same function on the result

1:34 if you have a function that returns a vector or something like that, you can wrap the function to also take a vector

1:35 here's an example:

1:35 ,(take 5 (iterate (fn [[x y]] [(inc x) (dec x)]) [0 0]))

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

1:35 bbloom: whoosp

1:35 ,(take 5 (iterate (fn [[x y]] [(inc x) (dec y)]) [0 0]))

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

1:35 bbloom: there

1:38 shanemhansen: Thanks bbloom.

1:55 hellofunk: In Om, I'm a bit confused on the role of the "owner" parameter. For example, line 9 of this: https://www.refheap.com/87993 clearly it is referring to the state of the "this" object currently being re-ified. But yet, "owner" is named as an argument to the function itself, suggesting it is referring to something passed in.

2:39 shanemhansen: I'm running a simulation that shows clojure.lang.RT.first() and clojure.lang.LazySeq.seq() as bottlenecks. Is there some idiom in clojure that's faster than (count (drop-while perdicate? (iterate f args))) ?

2:40 I could write it in java, but I'm having fun with clojure.

2:44 https://gist.github.com/shanemhansen/b237c8ebc747cc6e0ed2

2:48 justin_smith: shanemhansen: you could try a reduce or loop with a counter and a state argument

2:48 shanemhansen: Thanks justin_smith

2:50 justin_smith: ,(loop [i 0 t 0] (if (> i 10) t (recur (inc i) (+ i t))))

2:50 clojurebot: 55

2:50 justin_smith: for example

2:51 in bytecode that is equivalent to a java for loop

2:51 (or should be)

2:54 amalloy: shanemhansen: you're counting lazy sequences an awful lot of times. you can't use a data structure that's better at being counted?

2:55 like, your tick function counts a bunch of lazy seqs and then makes them longer, and then in your next iteration you count them again...

2:55 shanemhansen: amalloy, I know the sequence of "ticks" is lazy. I'm counting it once.

2:55 justin_smith: amalloy: that's why I figured a raw loop, then no sequence even needs to exist, you just count iterations

2:56 amalloy: no, the rungs inside of tick

2:56 shanemhansen: I'm not familiar enough w/ clojure to know where I put my other lazy sequences ; ).

2:56 amalloy: counting the return value from period is no big deal

2:56 and i misspoke a bit: in tick, the rungs aren't lazy, but they are singl-ylinked lists, which are expensive to count

2:57 shanemhansen: I asked because profiling didn't immediately make it look like counting was the problem. Even though I *know* count must be O(n).

2:57 amalloy: well, count doesn't have to be O(n) if you use a better data structure

2:58 justin_smith: with vector / conj it would be O(1)

2:58 amalloy: and indeed your queue should be a vector

2:58 you always add to the right, and using concat for that is super expensive

2:58 with vectors, it's practically free, and so is count

2:58 shanemhansen: amalloy, Maybe it's different for clojure. In golang I use a single linked list with an extra pointer to the tail.

2:59 justin_smith: yeah cons on a seq is cheap on the left, conj on a vec is cheap on the right

2:59 shanemhansen: appending onto a vector causes it to do lots of gc due to the amortized doubling of allocation.

2:59 amalloy: shanemhansen: that's fine, but pointers to the tail are ~impossible without mutation

2:59 shanemhansen: I know clojure has like some sort of tree-ish thing for vectors?

2:59 justin_smith: yes

2:59 amalloy: yeah, amortized doubling is a total red herring. are you talking about another language's vectors? clojure doesn't have those

3:00 shanemhansen: I'll try vectors. I am talking about another languages vectors. I'm doing this excersize to learn about clojure's data structures, so your feedback is really helpful amalloy.

3:01 amalloy: adding to the end of a vector is very cheap, and the way you're building queue right now is O(N^2). so if queue is large, i expect switching to vectors will fix your performance issues

3:02 oh, but you're also using first/rest on it? you need a queue, not a vector

3:02 ,(peek (into clojure.lang.PersistentQueue/EMPTY) [1 2 3 4])

3:02 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core/into>

3:02 shanemhansen: amalloy, the "queue" is double ended. So ideally appends and pushing are cheap.

3:02 amalloy: ,(peek (into clojure.lang.PersistentQueue/EMPTY [1 2 3 4]))

3:02 clojurebot: 1

3:03 shanemhansen: The rungs can be pretty well represented with vectors I think.

3:03 amalloy: you append onto both sides?

3:03 it doesn't look that way to me

3:03 you always push onto the right, and pop from the left

3:03 shanemhansen: amalloy, sorry you're right. I mutate both sides, not append.

3:04 amalloy: eh, the rungs are probably fine as lists. they don't get large, and you seem to want to build them on the left and consume on the left, so lists are perfect

3:04 a clojure.lang.PersistentQueue looks like the structure you need for your queue

3:04 (appropriately, since they're even both called queue)

3:46 je: in ClojureScript: (def my-atom (atom {})) in ns1 and :refer it from ns2. When I try to deref it: @my-atom I get: No protocol method IDeref.-deref defined for type undefined, anyone know why?

3:49 scotty9: my friend died in a car accident

3:50 im trying to find clojure

3:50 get it

3:50 cause its like closure but no its clojure

3:55 ddellacosta: je: can you paste the code into a refheap or gist?

3:57 hellofunk: In Om, I'm a bit confused on the role of the "owner" parameter. For example, line 9 of this: https://www.refheap.com/87993 clearly it is referring to the state of the "this" object currently being re-ified. But yet, "owner" is named as an argument to the function itself, suggesting it is referring to something passed in.

4:03 expez: When I do lein -U repl today I get a warning about 'no nREPL dependency detected' it then starts an nREPL server an appears to be working just fine. It also doesn't update any snapshots, even though I know for a fact cider-nrepl was updated yesterday. What gives?

4:16 je: ddellacosta: https://gist.github.com/jacobemcken/8b993ff43c4809bc954a

4:17 Glenjamin: hellofunk: i thought it was the parent component, but i may be wrong

4:17 actually yeah, it does seem to be `this`

4:18 ddellacosta: je: are you calling @state directly in the file like that?

4:19 je: ddellacosta: from LightTable... trying see what's inside the atom :)

4:21 ddellacosta: je: I'm not familiar with LightTable. Are you talking about running it in a console or repl in some way?

4:22 hellofunk: what's the proper approach to have a single Om root that then builds various unconnected components, or is this not possible? Nolen's tutorials just use more than one Om/root for this. I've tried to have more than one om/build in a function but React provides an error

4:23 ddellacosta: hellofunk: it's definitely possible, I do it a lot. If you post the code you're using and the error I can try to give you a hand.e

4:23 *hand

4:25 hellofunk: ddellacost let me see if I can pinpoint further

4:28 ddellacosta ah turned out to not be my problem.

4:28 ddellacosta: hellofunk: well then, problem solved. :-)

4:29 hellofunk: ddellacosta: are you able to clear up a simple confusion about line 9 on this: https://www.refheap.com/87993

4:29 ddellacosta: what's the confusion?

4:29 je: ddellacosta: LightTable have inline evaluation triggered by (Ctrl + Enter)... I believe it is connected to a repl somewhere and sends expressions for evaluation and returns the result to the editor

4:29 hellofunk: "owner" should be referring to the state specified in InitState (and it does) but what then is the owner passed into the function?

4:29 ddellacosta ^

4:30 ddellacosta wouldn't the arg named owner in the function parameter trump everything?

4:30 ddellacosta: je: it would be worth isolating that code and running it in the browser or in a normal CLJS repl (via austin) to see if it behaves similarly. It could be the case that LightTable is doing something to namespaces under the covers.

4:30 hellofunk: owner is the argument passed into your component.

4:31 hellofunk: sorry to be blunt, but what is confusing about that?

4:31 hellofunk: that is, I'm confused about what you're confused about...haha

4:31 hellofunk: ddellacosta then how would owner in this context point to the state in the "this" ? because the InitState is not in the parent owner, it's in "this" object, yet owner is accessing "this", not the parent passed in

4:32 ddellacosta: hellofunk: because of what Om is doing under the covers. owner is the magical object that manages what is going on with state in your component during the React rendering cycle.

4:32 hellofunk: ...to grossly generalize

4:33 hellofunk: this is a case where looking at the Om source code will greatly clear up your confusion about what's going on.

4:33 hellofunk: so "owner" is referring to the object itself, not the object passed in with the function arg

4:34 je: ddellacosta: It propably is :) thanks

4:34 ddellacosta: je: good luck!

4:35 hellofunk: take a look here: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L604-L607

4:35 hellofunk: that's at the end of build*

4:36 hellofunk: it's calling your component (f) with the cursor you pass in (first arg) and owner as "this", within the context of ctor

4:36 ctor by default is built via "pure"

4:37 hellofunk: pure is created via the pure-methods which are the guts of Om's magic, and which implement the React render cycle for Om: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L204

4:38 hellofunk: ddellacosta ok so owner isn't really representing some outside value getting passed into your function, even though it looks that way from a functional view.

4:38 ddellacosta: hellofunk: no, owner is the component itself

4:39 hellofunk: ddellacosta, ok, that's interesting indeed. it's like a function getting a pointer to itself.

4:40 ddellacosta: hellofunk: well, except it's not--the component function you define is just a function. But the React component (with some wrapper functionality via Om for state operations) is passed to that component function you've defined, basically.

4:41 hellofunk: ddellacosta: ah, so it is a pointer to its represeantion in the React system.

4:41 ddellacosta: hellofunk: so when you consider how the owner knows about stuff you've declared in init-state, keep in mind that the owner has state (in the general sense of the word state) based on the step in the React render cycle that protocol you are defining is called in

4:41 hellofunk: yeah

4:42 look here: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L357

4:42 hellofunk: and right below it ^

4:42 hellofunk: where pure is defined, it just points to that Pure. instance which has extra state methods (get-state/set-state/etc.) defined on it

4:43 hellofunk: ddellacosta, ok this helps clear up the, ahem, confusion.

4:43 ddellacosta: hellofunk: great! It is definitely confusing at first.

4:43 hellofunk: ddellacosta i was thinking of it all as clojurescript values getting passed around, though I know there was something more going on behind the scenes, the semantics are not obvious when working at the high level

4:43 ddellacosta: hellofunk: but don't be afraid to dig into the source--it is really the best way to clean up confusion around how it works

4:43 *clear up

4:44 hellofunk: yeah, I mean, build* is doing some sort of magical stuff

4:44 hellofunk: it's rather clever but a bit unintuitive

4:44 hellofunk: it allows for a very intuitive way of writing components though, I believe

4:44 hellofunk: ddellacosta yeah to be honest it would take me quite a while to read and understand the source, so much of it uses techniques well beyond my current experience

4:44 ddellacosta: hellofunk: well, one thing at a time. :-)

4:45 hellofunk: ddellacosta appreciate the help, this was bugging me for a while

4:45 ddellacosta i am not the first person to think that owner was the component's parent component

4:45 ddellacosta: hellofunk: sure thing. Regarding difficulty of Om code, I think probably if you have a good handle on Protocols/types, then it becomes far more obvious what David is doing

4:46 hellofunk: ddellacosta the parent-child relationship between components which build other children components makes it easy to incorrectly assume that owner is the component that called build on you

4:47 ddellacosta: hellofunk: yeah, I can understand how one may think that

4:47 hellofunk: a fella earlier in here thought the same

4:48 anyway, confusion has been dealt a deathly blow

4:48 ddellacosta: hellofunk: excellent!

4:49 * ddellacosta gives confusion the finger

4:49 hellofunk: yeah, take that, confusion

4:49 Glenjamin: owner seems like an odd name then, if i followed that correctly then owner is roughly the react component instance

4:50 hellofunk: Glenjamin i think i might agree

5:01 ddellacosta: Glenjamin: I don't pretend to know exactly what dnolen was thinking, but it makes more sense if you think of it as "owner of the React component itself"

5:01 not sure what a good name for it would be really

5:43 expez: Any way to get a :test profile which is used for `lein test`?

6:05 ddellacosta: expez: have you tried "lein with-profile test test?"

6:06 expez: that is, assuming you've set up a "test" profile

6:16 expez: suppse that would work, and then just make an alias 't' or something

6:16 thanks

6:26 hellofunk: ddellacosta is on a roll today

6:26 (inc ddellacosta)

6:26 lazybot: ⇒ 4

6:26 ddellacosta: hellofunk: haha

6:26 hellofunk: (inc ddellacosta)

6:26 lazybot: ⇒ 5

6:26 hellofunk: 4 just didn't seem high enough

6:26 ddellacosta: well then. :-)

6:26 not sure what that is counting anyways, but hey

6:27 hellofunk: oh, i can tell you. it is counting the number of times someone types (inc ddellacosta), that's all

6:27 ddellacosta: hellofunk: hahaha, that's an entirely correct and reasonable explanation

6:27 hellofunk: ddellacosta: i thought as much, arrived at it a while back when I too was faced with similar confusion

6:28 ddellacosta: :-_

6:28 d'oh

6:28 :-)

6:37 hellofunk: hey while it's not a good idea to update Om's atom outside of an Om component function, I assume it is just fine to read from that atom anywhere?

7:06 vijaykiran: hellofunk: yeah, reading should be fine

7:06 hellofunk: sweet, yo. thanks.

7:33 luxbock: is oss.sonatype.org one of the default repositories that Leiningen uses?

7:35 I have a problem where I'm trying to download dependencies for my project on a remote machine (AWS), but all the packages lein hits up from Sonatype are returning 302, which Maven does not know how to handle

7:37 so leiningen thinks that it's getting the dependencies when it's in fact not getting them, and then eventually it fails with java.util.ZipException when it tries to open them

8:44 * mnngfltg is looking for code I can emulate when it comes to writing documentation / unit tests. Any suggestions?

8:47 ergh: is it possible to make an "anaonymous" macro? i just wrote my first (rather trivial) macro, but i only need to locally, in a function. do i have to define it outside t he function with defmacro? what happens when you use defmacro inside a function?

9:01 justin_smith: ergh: tools.macro has a macrolet I think https://github.com/clojure/tools.macro

9:02 yeah, it looks like macrolet does what you want

9:16 smarr: Hi, I am interested in how Clojure's transactions, agents, locking, core.async, and/or other concurrency libraries are used together. Are there interesting open source libs or applications I could have a look at?

9:16 (am really interested in larger projects using such abstraction, not examples or tutorials)

9:16 justin_smith: well, directly using locking is extremely rare

9:17 and refs/transactions are relatively rare

9:22 one simple example of core.async usage is throttler http://brunov.org/clojure/2014/05/14/throttler/

9:24 smarr: justin_smith: thanks, originally I hope LightTable would be written in Clojure, but it seems to be ClojureScript and doesn't use any of the concurrency libraries, wanted to compare a little how large Java applications such as Eclipse and Netbeans compare to similar applications written in languages with more extensive support for concurrency

9:24 justin_smith: regarding locking, we use immutible data so much in idiomatic clojure that locking is almost never needed - things will never be in invalid read states (the new value is a new binding)

9:25 smarr: I don't know if we have anything as desktoppy as netbeans or eclipse

9:26 there are some games being developed in clojure that would likely be good examples, I don't know how mature they are though

9:26 (or the names of the top of my head, sorry)

9:26 smarr: ok, thanks, will try some more google/github queries

9:28 teslanick: As a note: concurrency may not be a problem in clojurescript, but asynchrony is. I assume many of LT's internals are asynchronous and single-threaded, given how poorly it behaves when it gets blocked up.

9:32 smarr: teslanick: if I understand the code correctly, there is some wrapping for webworkers

9:32 teslanick: I haven't looked, but that wouldn't surprise me.

9:34 smarr: but it is all still very rudimentary. netbeans for instance has at least two adhoc 'transactional systems' for various purposes.

9:36 teslanick: Well, because it's running JS under the hood, transactions are almost never necessary. The only time it is needed is when you're interacting asynchronously with multiple resources.

9:37 d0ky: hello does anybody know if can be http-kit deployed to tomcat whereas http-kit is ring compatible ?

9:41 justin_smith: d0ky: http-kit is not a servlet

9:41 ring can generate a servlet compatible war

9:41 http-kit is a self-hosting alternative to that

9:41 http-kit, like tomcat or jetty, is a server

9:42 d0ky: justin_smith: and is it good option to deploy app on http-kit ?

9:42 justin_smith: if you make a war via "lein ring uberwar" that can be run in tomcat or jetty

9:42 d0ky: http-kit performs much better than tomcat

9:42 but does not have the log rotation, multi-app hosting, seamless redeploy, etc. of tomcat

9:43 but you can get pretty far if you define a custom service that launches your http-kit uberjar

9:43 in both cases, you should have nginx (or something similar) in front of your server

9:44 d0ky: justin_smith: so it could be deployed as http-kit and in front use nginx ?

9:44 justin_smith: yeah - well you would make an uberjar with "lein uberjar" and run that with java -jar

9:45 d0ky: justin_smith: i heard something about ngnix but i haven't an idea how it works ...

9:45 justin_smith: d0ky: nginx stands between the outside world and your server

9:45 it has a number of security features that tomcat and http-kit lack

9:46 if your site is publicly visible, best practice is to have a well configured nginx server in front of your real server

9:46 for performance, you can also add varnish in front of nginx, but that is not a security neccessity, that just helps serve requests faster

9:48 d0ky: justin_smith: thanks for all i will look for some papers about ngnix and http-kit how they force them to work together

9:49 justin_smith: d0ky: the basic idea is that you tell http-kit to run on port 8080 (or whatever other port) and then tell nginx to run on port 80, and forward all requests to 8080

9:49 and then it blocks certain kinds of malicious or questionable requests, so they never even hit your app

9:50 d0ky: justin_smith: woow :) it sounds quite straitforward :)

9:50 justin_smith: yeah, nginx is pretty easy to set up

9:50 and also lets you serve multiple clojure apps from one port (ie. /customers and /clients routes can each forward to a different http-kit instance or whatever)

9:51 but nginx should be used whether you use tomcat or http-kit or whatever else

9:53 d0ky: justin_smith: great because the problem for me with http-kit was ... how to run more than 1 app on one server ? thank you very much for options how to get it works :)

9:53 justin_smith: np

9:54 to be more explicit, you could have http-kit running with one instance on 8080, another on 8081, another on 8082 etc. and have nginx config that forwards the apropriate requests to each of these ports

9:55 it uses regex to decide which backend serves each request

9:56 (or at least that's how I have done it - it can also do load balancing and such but with clojure I think it works out better to just have one process with multiple threads anyway)

10:18 bacon1989: how the heck do I check if a value is contained in a vector?

10:19 ,(contains? ["foo" "bar"] "foo")

10:19 clojurebot: false

10:19 teslanick: ,(.indexOf ["foo" "bar"] "foo")

10:19 clojurebot: 0

10:19 teslanick: Gross. But it works. :c

10:20 You can also convert to a set.

10:20 bacon1989: teslanick: that would probably work

10:20 teslanick: ,(contains? (set ["foo" "bar"]) "foo")

10:20 clojurebot: true

10:20 teslanick: er

10:21 Yeah, that will work.

10:21 Glenjamin: ,(some #{:a} [:a :b :c])

10:21 clojurebot: :a

10:21 Glenjamin: some is O(n), set contains? is O(1), but you need a set first

10:21 if those are concerns

10:22 teslanick: ,(some #{:noexist} [:a :b :c])

10:22 clojurebot: nil

10:22 Glenjamin: ,(some #{false} [:a :b false]) ; there are still issues :)

10:22 clojurebot: nil

10:22 Glenjamin: ,(def find (comp first filter))

10:22 clojurebot: #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>

10:23 Glenjamin: ,(def detect (comp first filter))

10:23 clojurebot: #'sandbox/detect

10:23 Glenjamin: ,(detect #{false} [:a :b false])

10:23 clojurebot: nil

10:23 Glenjamin: hrm

10:25 cbp: ,(some #(= false %) [:a :b false)

10:25 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

10:26 Dzurko: cbp, what is your opinion on the purported newfound homosexuality of Patrick Stewart?

10:36 arrdem: !votetroll

10:39 Bronsa: check out feature/fast-emitter when you get a chance. I'm a little concerned that I broke your representation of a Class's AST, but that was the only really involved part of rewriting TEJVM to use a fipp style list flattening system.

10:39 Bronsa: arrdem: I saw that, gonna take a better look later

10:40 arrdem: is there a reason why you replaced the bc wrapping from [..] to (list ..) ?

10:40 arrdem: Bronsa: I didn't. Single instructions are still [], sequences of instructions must be (list ..)

10:41 Bronsa: note that this means all instructions don't have to be wrapped, which let me throw out wrapping vectors in a bunch of places

10:42 anyway. I'll be around when you get the chance to look at it. take your time.

10:48 Bronsa: arrdem: meanwhile, can you rebase to master? I just pushed a fix

10:48 arrdem: da

10:49 done

11:23 aaronj1335: dnolen_ one of our talks at austinjs this month is clojurescript and om! anything in particular we should make sure to cover?

11:25 (:instrument, externs, etc)

11:36 dnolen_: aaronj1335: def externs :) that's the kind of thing that trips everyone up

11:36 aaronj1335: that's cool that you're covering this at austinjs :)

11:36 aaronj1335: right on

11:37 yea, would have sooner, but we just need to find people with expertise

11:37 we'll do a full meetup on it once we find someone willing to do so

11:44 daGrevis: hey! are there any way to do an early return from a function? if yes, is it even okay to do so?

11:47 teslanick: I don't think so and why do you want to?

11:47 dbasch: daGrevis: what are you trying to do?

11:47 Willis1: (defn func-with-early-return []

11:47 (if condition "EARLY RETURN MWUAHAHAHA" (do-rest-of-function)))

11:47 daGrevis: okay, nevermind http://stackoverflow.com/questions/7491360/how-do-you-return-from-a-function-early-in-clojure#7491616

11:52 justin_smith: daGrevis: as a special case, there is 'reduced' when you are part of the way through reduce and know the return value already

11:53 ,(reduce (fn [t i] (if (> i 10) (reduced t) (+ t i))) (range)) even works with infinite input

11:53 clojurebot: 55

11:58 justin_smith: ,(last (reductions (fn [t i] (if (> i 10) (reduced t) (+ t i))) (range 23))) for amusement purposes

11:58 clojurebot: #<Reduced@9aae17: #<Reduced@11b6956: #<Reduced@a0cb37: #<Reduced@7dc4b9: #<Reduced@fe69a1: #<Reduced@c9081c: #<Reduced@3391c0: #<Reduced@1a60283: #<Reduced@1ef1fb8: #<Reduced@ba899: #>>>>>>>>>>

11:58 justin_smith: if that went deeper, one of those nested reduces would have a 55 in it

11:59 (that's a distraction though, don't use reduced with reductions, it doesn't work)

12:00 ,@@@@@@@@@@@@(last (reductions (fn [t i] (if (> i 10) (reduced t) (+ t i))) (range 23)))

12:00 clojurebot: 55

12:04 arrdem: justin_smith is apparently a 12 star programmer...

12:04 justin_smith: ?

12:04 razum2um: hi folks. searched through github but havent found any awesome-clojure references. so here it is https://github.com/razum2um/awesome-clojure

12:05 PR welcome!

12:05 arrdem: justin_smith: http://c2.com/cgi/wiki?ThreeStarProgrammer

12:06 justin_smith: haha

12:06 arrdem: razum2um: your clojuredocs link is broken. you also don't have grimoire.

12:06 justin_smith: arrdem: I have in fact been writing some c code lately (with some levels of pointer indirection), but I think the relationship to this example is pretty tenuous

12:07 Willis1: tenous but still funny

12:07 arrdem: justin_smith: I read @ as * since we don't have "real" pointers

12:07 justin_smith: it is true, yes

12:07 arrdem: so maybe it's all in my head

12:07 justin_smith: no, definitely funny

12:08 the "tenuous relationship" is between my C coding activities and this bit of silliness, not between * and @, btw

12:08 razum2um: arrdem: fixed link. don't understand about grimoire so would you like to do it https://github.com/razum2um/awesome-clojure/edit/master/README.md

12:10 Bronsa: arrdem: it doesn't look like you actually rebased againsta master to me, e0a00308b7d204ab7d86a3ca795865899efb2dcb is still missing from feature/fast-emitter

12:10 * arrdem checks

12:15 myguidingstar: hi all, I want to handle on-change event from a input[type=file] in Clojurescript

12:15 how do I loop through (.. evt -target -files) which is a javascript object?

12:16 mmitchell: Anyone here use clj-logging-config?

12:16 myguidingstar: given that in javascript, we can use `for (i, i++ ..) {}`

12:17 justin_smith: ,(first (remove reduced? (iterate deref (last (reductions (fn [t i] (if (> i 10) (reduced t) (+ t i))) (range 200)))))) arrdem: I am now an N* programmer for arbitrary N

12:17 clojurebot: 55

12:18 arrdem: (doseq [n ∈ ℜ] (swap! justin_smith + n))

12:18 justin_smith: heh

12:21 adelcampo: is there an existing function that will increment by considering letters? For example “1Z” would increment to “2A” and then “2B”.

12:21 justin_smith: arrdem: TIL ℜ includes numbers that cannot be defined

12:21 TEttinger: ,(Integer/toString (+ 36 35) 36)

12:21 clojurebot: "1z"

12:21 TEttinger: ,(Integer/toString (+ 36 36) 36)

12:21 clojurebot: "20"

12:22 arrdem: justin_smith: I mean... you said "arbitrary n" :P

12:22 dbasch: arrdem justin_smith doseq over ℜ woud be a neat trick

12:22 justin_smith: :)

12:22 arrdem: dbasch: ikr if only we had an unbounded memory machine to try one on..

12:23 justin_smith: (for [n (range) d (range 1 n)] (/ n d))

12:23 or something...

12:23 that doesn't get us the irrationals though

12:23 TEttinger: adelcampo, but I imagine you want it to consider letters as a different type than numbers or something?

12:23 dbasch: justin_smith: that would be Q

12:23 * arrdem points to Cantor's proof that (0 .. 1) is uncountably infinite

12:24 dbasch: for ℜ you'd need a computer with aleph-1 memory

12:24 justin_smith: yeah, good luck using any irrationals at all in a turing machine :)

12:24 adelcampo: TEttinger, yes but your example made me consider not using .getBytes, so thanks!

12:24 TEttinger: adelcampo, it's definitely possible

12:24 to do some kind of 1Z-2A thing

12:25 the question is what order are numbers and letters in

12:25 0-9A-Z or A-Z0-9

12:25 daGrevis: i have a test here http://vpaste.net/xctxS i know what i want from that function, but the problem is that I have no idea how can I express that in functional paradigm. any hints?

12:25 dbasch: adelcampo: essentially you want a representation of base-26 numbers

12:26 adelcampo: TEttinger, yeah I just didn’t wan to write something that was already in the language

12:26 justin_smith: daGrevis: markov, no?

12:26 daGrevis: justin_smith, yes

12:26 adelcampo: dbasch, almost. Numbers should always stay numbers

12:26 TEttinger: dbasch, and clojure supports radices up to 36

12:27 adelcampo: and letters always letters

12:27 TEttinger: ah

12:27 so adelcampo, if I increment Z, what happens?

12:27 AA?

12:28 dbasch: adelcampo: so what positions can have numbers?

12:28 TEttinger: (also, wouldn't AA be 00?)

12:30 daGrevis: http://stackoverflow.com/questions/20203883/clojure-simple-markov-data-transform cc justin_smith

12:30 justin_smith: ,(reduce (fn [m [prev next]] (update-in m [prev] (fnil conj []) next)) {} (partition-all 2 1 ["monty" "python" "monty" "hall"])) daGrevis

12:30 clojurebot: {"hall" [nil], "python" ["monty"], "monty" ["python" "hall"]}

12:30 justin_smith: oh, similar to what you just found, but that one is better because it does counts (mine would have just made more instances of the same val in the collection)

12:30 daGrevis: justin_smith, wow ty

12:31 adelcampo: AA would increment to 0B. but I’m not sure about a solo Z

12:31 justin_smith: but, in my defense, I was just trying to get the literal output you presented (which did not have counts)

12:31 dbasch: adelcampo: what exactly are you trying to represent?

12:31 adelcampo: I mean AB

12:32 dbasch: adelcampo: why do you even need numbers?

12:32 justin_smith: daGrevis: also, seeing that the answer is from lgrapenthin reminds me that I should reach out to him again about an old collaboration we had

12:33 adelcampo: generating part numbers

12:33 daGrevis: justin_smith, http://stackoverflow.com/a/20209575/458610

12:33 justin_smith, see 1st solution with merge-with

12:34 seems to me like an elegant one, no?

12:34 justin_smith: yes, that is very nice

12:35 arrdem: devn: haha yeah if you look at oxcart the pattern is that project.clj has (slurp "VERSION") rather than a version string. I have git hooks that automagically bump the version file rather than rewriting project.clj. the new `lein release` feature may kill this approach however. we'll see.

12:35 cbp: Does anything weird happen with timeout core.async channels and clojurescript's :advanced compilation?

12:36 they seem not to wait their timeout amount at all

12:38 dbasch: adelcampo: do you have a specific part number format that you're trying to follow?

12:43 adelcampo: dbasch, the spec I was given was 3 blocks of 6 digits or characters, incrementing from left to right. characters A-Z and numbers 0-9. digit and character fields never change type. example 001AZ2-BB00ZZ-91EEAA

12:44 characters and numbers can be placed in any position by who ever uses this

12:44 technomancy: arrdem: I believe you owe me a bug report?

12:44 or did you get that sorted out?

12:44 arrdem: technomancy: I haven't looked at that yet.

12:44 adelcampo: right->left I mean

12:44 dbasch: adelcampo: what do you mean by "digit and character fields never change type?"

12:45 arrdem: technomancy: also not convinced that I was using `lein release` right either. I'll take a look after lunch.

12:45 zanes: Anyone know how to pass in a :result-set-fm with yesql?

12:45 technomancy: arrdem: no rush, just curious =)

12:45 adelcampo: dbasch Z never turns to 0, it goes back to A

12:45 9 goes back to 0, never turns to A

12:46 zanes: I am dreading that it may not be possible.

12:46 dbasch: adelcampo: can you have arbitrary parts that are numbers and others that are letters? otherwise, it doesn't make a lot of sense

12:47 adelcampo: you have a mixed system of base 10 and base 26 for no good reason

12:48 adelcampo: dbasch, yes they’ll choose where the letters go and where the numbers go. any one field can be a number or a letter.

12:49 dbasch: adelcampo: if it's totally arbitrary, you have to segment your string into base-26 numbers and base-10 numbers

12:49 if you increment a base26 number to the point of overflow, you have to increment the units to the base10 number to the left

12:50 and keep doing that for the entire "number"

12:50 seems unnecessariy complex

12:50 zanes: Damn. https://github.com/krisajenkins/yesql/issues/10

12:54 arrdem: Bronsa: yeah I didn't do the rebase right. your bugfix breaks a bunch of patches I'll fix it in a minute.

12:54 rebased against my master which wasn't synced to your updated origin/master

12:55 Bronsa: arrdem: ouch sorry

12:55 arrdem: Bronsa: should only be three impacted patches. should.

12:56 adelcampo: dbasch, thanks I’ll definitely try that

12:58 Bronsa: arrdem: I still don't understand why you're grouping the bytecode with a list rather than a vector

12:58 technomancy: oh man

12:58 I didn't realize regexes as fns was on the todo back in the day

12:58 http://clojure.org/todo

12:58 arrdem: technomancy: w0000t!

12:59 technomancy: "support for list-callers" yes please

12:59 "def vars in other ns with explicit qualifier?" huh?

12:59 justin_smith: "too-large data literals duting compilation"

12:59 daGrevis: justin_smith, http://vpaste.net/kuge9 final version

13:00 justin_smith: interesting

13:00 Bronsa: technomancy: what are list-callers?

13:00 daGrevis: justin_smith, i didn't do much but i understood how it works

13:01 arrdem: Bronsa: so the idea is that (list [:pop] (list [:pop] [:pop])) -> (list [:pop] [:pop] [:pop]), right? using lists means that arbitrary sequences of bytecodes satisfy (seq?) and will be mapcat'd by flatten.

13:01 daGrevis: justin_smith, it's based on version before that was in that link obviously

13:01 technomancy: Bronsa: slime-who-calls is how I read that

13:01 Bronsa: ah

13:01 daGrevis: justin_smith, i'm more interested on how you can think of using those functions in combination that will make such an amazing result. experience?

13:02 justin_smith, because for me... first thing i thought of was to create a empty hashmap and iterate over those words

13:03 Bronsa: arrdem: well, why can't we just make that [[:foo] [[:bar] [:baz]]] -> [[:foo] [:bar] [:baz]] and s/seq/(comp vector? first)/

13:03 justin_smith: daGrevis: well, literally speaking, what reduce does with {} as the third arg, is start with an empty hash map and iterate greedily over the last arg

13:03 arrdem: Bronsa: because that doesn't allow us to differentiate between [[:foo] [:bar]] and [[[:foo]] [:bar]]

13:04 Bronsa: remember that nested bytecode sequences can occur _anywhere_

13:04 justin_smith: daGrevis: reduce is typically my go-to if lazy evaluation doesn't make sense (with a map as result, laziness gains you nothing)

13:04 Bronsa: arrdem: sorry brb

13:05 arrdem: Bronsa: there are even a couple places where you use a generator that will return a bytecode sequence as the first term in another expression which would without a concat create exactly the above condition.

13:10 daGrevis: how does clojure programmers feel about nil? is it okay that function returns nil not {} if it usually returns some hashmap with data?

13:10 technomancy: daGrevis: nil is the worst thing about clojure hands down. however, conflating nil with collections is usually safe.

13:11 returning nil instead of a scalar value is the worst.

13:11 daGrevis: but what will happen when i will want to do coll stuff on nil? will it blend?

13:11 teslanick: I seem to remember that someone quipped here that nil actually behaves like an infinite tree of nils.

13:11 And so can be conflated with collections. ;)

13:11 arrdem: daGrevis: nil works fine with collections. (sequables) Nil doesn't work at all with anything else.

13:12 technomancy: daGrevis: the one thing it'll blow up on is that it's not callable like maps are

13:12 daGrevis: ok then it's fine then

13:12 justin_smith: ,(assoc-in {} [:a :b :c] :d) daGrevis: some functions definitely just take nill and roll woth it

13:12 clojurebot: {:a {:b {:c :d}}}

13:12 technomancy: but no one actually puts maps in the call position; everyone puts keywords first

13:12 joegallo: yeah, that not callable thing is sortof a big deal

13:12 technomancy: broadly speaking

13:12 Glenjamin: they only do that because of the NPE :p

13:12 arrdem: technomancy: only silly people who deserve it :P

13:12 joegallo: unless you're dealing with keyword keyed maps, and always calling via the keyword.

13:12 technomancy: well.... there's stuff like (map mymap [:x :y :z])

13:13 justin_smith: I use get explicitly when a map would be in calling side

13:13 technomancy: actually no, that's better served by juxxt

13:13 justin_smith: technomancy: unless you need the laziness

13:13 technomancy: curses!

13:14 let's just go with "it's complicated"

13:14 daGrevis: i guess i'll be fine

13:15 Glenjamin: (map (partial get mymap) [:x :y :z])

13:17 justin_smith: (map (fnil mymap {}) [:x :y :z]) ?

13:18 err, no

13:18 (map (or mymap {}) [:x :y :z]) is what I wanted

13:19 arrdem: Bronsa: conflicts resolved & pushed. looks OK to me.

13:31 technomancy: did the G1 GC get made default in java 7?

13:33 Glenjamin: nope

13:33 well, not on mine anyway

13:34 technomancy: must have been 8

13:34 timsg: Hey, tried this question on the emacs channel to no effect, and it’s apropos Clojure, so here goes. I’m implementing a networked Clojure-CLR repl client that I would like to drive from emacs’ inferior-lisp. I want multiline input, so I’m using an EOT character rather than newline to signal form entry, but this does not seem to be the default expected by inferior-lisp. Does anyone have experience with this sort of thing? Question

13:34 withdrawn if it’s too off-topic. Thanks!

13:35 technomancy: timsg: inferior-lisp is kind of an odd choice for a network client

13:35 that's usually just intended for stdin/stdout interactions

13:36 why not just port the existing nrepl server to clojure-clr?

13:38 timsg: technomancy: yes, it’s super janky at the moment. Clojure-CLR doesn’t have an nREPL implementation yet, so we’re making do with an extremely simple shell client setup pending a functional nREPL.

13:38 technomancy: if you use the existing protocol then you don't have to reinvent the wheel for the huge pile of clients that have already been written

13:38 oh, for a stopgap measure; gotcha

13:38 what's an EOT character?

13:39 timsg: "\x04"

13:39 justin_smith: C-d in emacs parlance

13:39 technomancy: oh, eof?

13:39 I think multiline input is a server-side concern and you should just use newlines like normal.

13:40 justin_smith: in unicode we have ⌁ or ␄ in modern unicody times

13:41 timsg: technomancy: hm, so would you recommend just sending to the server constantly like a fire hose and then sending a response when it parses as a balanced expression?

13:41 justin_smith: in redundant cases we also have redundancy

13:42 technomancy: timsg: that's my understanding of how comint modes typically work

13:43 timsg: technomancy: hm, thanks. I wonder what a simplest way to test for balanced expressions is

13:44 I suppose one could use read-string in a try-catch; seems janky tho

13:44 technomancy: timsg: you can't do it client-side

13:44 read-string in a try/catch is fine

13:45 timsg: technomancy: interesting. Ok I’ll try that, thanks much for the advice!

13:45 technomancy: np

13:45 when in doubt, take a look at what reply does

14:16 laliluna: Hi, what is the best way to find the namespace which provides a function using emacs?

14:20 technomancy: laliluna: M-.

14:24 laliluna: This only works, if I have required the namespace already.

14:24 technomancy: yes

14:25 laliluna: This is what I want to find out, what I have to require. ;-)

14:26 arrdem: this is not a generally answerable question :P

14:30 technomancy: you can use bultitude to find all namespaces and require them, then search with all-ns

14:31 amalloy: technomancy: why would you need to use all-ns? once you've required everything, find-doc or apropos or something should find it, i would think

14:31 technomancy: sure, find-doc is one way to use all-ns

14:35 it's a one-liner in any case (for [n (all-ns) [k _] (ns-publics n) :when (= 'reduce k)] n)

14:35 (mapcat ns-publics (all-ns)), ctrl-r

14:38 amalloy: man, there are some functions in all-ns that are pretty silly

14:38 including, amusingly, swank.util/one-of?, which is implemented in exactly the way i told hellofunk and Frozenlo` is a bad way to do it, last night

14:38 laliluna: Great, thanks.

14:39 technomancy: lol swank

14:39 amalloy: oh my gosh. i wish i had never looked at swank.util

14:40 there's like one function that includes three of my greatest enemies: flatten, eval, and resolve: https://www.refheap.com/4c4327327fae81eb5944ad0e6

14:41 (resolve isn't bad, but it often gets misused)

14:42 Glenjamin: looks like a reasonable backport of flatten

14:42 $source flatten

14:42 lazybot: flatten is http://is.gd/JrNQrb

14:43 Shayanjm: amalloy: what's wrong with flatten?

14:43 amalloy: ~flatten

14:43 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

14:43 Shayanjm: ah I see

14:43 laliluna: (concat [1 2 3] 1)

14:44 Glenjamin: but all the lisp books make you perform operations on a nested list of lists :p

14:44 laliluna: Sorry, wrong window LOL, missed the REPL

14:44 amalloy: flatten is kinda like "i have no idea what my data looks like, but i happen have this huge hammer, let's try hitting it"

14:44 Frozenlock: amalloy: we talked about that yesterday? o_O

14:44 I remember 'set' vs 'some'.

14:44 amalloy: wasn't that you, Frozenlock? https://www.refheap.com/727ad34f9db303249e225a67b

14:45 Frozenlock: No, unless I spend time here even in my sleep :-p

14:45 amalloy: Frozenlock: yes, one-of? is solving exactly the problem that led to the set/some question

14:46 and it's doing it by macroexpanding to (or (= x 1) (= x 2) (= x 3) ...), which is a hardcoded version of the some approach

14:49 Frozenlock: oh right

14:55 schmee: hello, quick beginner question: what's the best way to replace a subvector in an array with another subvector?

14:57 DerGuteMoritz: amalloy: some is not short-circuiting like one-of? though, or am I missing something?

14:57 tuft_: do any of you guys have a favorite talk about using functions over data instead of classes, methods and a proliferation of types?

14:58 amalloy: Frozenlock: why don't you educate DerGuteMoritz?

14:58 DerGuteMoritz: yes, please :-)

14:59 unless the collection passed to some is lazy, but even then the semantics wouldn't be exactly the same due to chunking, right?

14:59 expez: I have some tasks that I just spin off into separate threads, these communiate with the rest of the app over a core.async/chan. 1) Is 'future' the best thing to use here? 2) I just had one of these futures silently die, how can I get a stacktrace into the logs?

15:00 stuartsierra: tuft: maybe Stuart Halloway's "Evident Code at Scale"

15:01 http://www.infoq.com/presentations/Evident-Code-at-Scale

15:24 Guest9112: I'm trying to help a colleague running windows compile a clojure project. Lein install works but when we try to run maven we get a clj:[0,0] Unsupported character: \com for every file in the package. Has anyone seen this kind of error before?

15:26 athinggoingon: I'm trying to understand what the following code does

15:26 (def world

15:26 {:location :a

15:26 :nodes {#{:a :b} :y

15:26 #{:a :e} :g

15:26 #{:b :f} :g

15:26 #{:f :e} :g}

15:26 :home :f})


15:26 amalloy: athinggoingon: please direct large pastes to refheap.com or gist.github.com

15:26 arrdem: the paste...

15:31 slpsys_: ow, my eyes

15:33 amalloy: anyway, athinggoingon, it seems to be creating a map, where the keys in the :nodes map are sets of keywords

15:33 tuft: stuartsierra: thanks!

15:34 bacon1989: question, how could I generate a dictionary from a list where '([key value] [key value])

15:36 amalloy: &(doc into)

15:36 lazybot: ⇒ "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

15:36 amalloy: well, that doesn't answer the question at all. jeez, amalloy, get with the picture

15:37 bacon1989: I think I could do it with a for loop

15:37 amalloy: &(into {} '([k v] [x y]))

15:37 lazybot: ⇒ {k v, x y}

15:37 bacon1989: oh neat

15:37 athinggoingon: thanks amalloy

15:37 i'm new to clojure

15:37 amalloy: bacon1989: remember for is not a loop, but a list comprehension

15:37 athinggoingon: how can i create an instance of that map

15:37 amalloy: it's impossible to use it to build anything but a lazy sequence; you have to use something else (here, into) to do that

15:38 technomancy:

15:39 aka, "unask the question"

15:39 myguidingstar: hi all, what's wrong with this om component? https://gist.github.com/myguidingstar/34bad0729c0a9b8f94b1

15:39 amalloy: athinggoingon: the question doesn't make sense: there's no such thing as "an instance of that map". the map is defined to be stored in the var 'world

15:40 myguidingstar: the component didn't re-render after user clicked

15:40 (it's written in om-tools syntax)

15:41 teslanick: :onClick not :on-click

15:41 myguidingstar: teslanick, it's om-tools syntax

15:42 I used js/alert to ensure it got called

15:42 teslanick: Ah.

15:43 You could figure out what the state is by hooking into IWillUpdate

15:43 (dunno what the om-tools idiom is)

15:43 myguidingstar: teslanick, FYI https://github.com/Prismatic/om-tools/

15:43 teslanick: I'm aware of it, I just haven't read the docs

15:43 but (will-update [_ _ next-state] (prn next-state))

15:44 If that writes the state, that would ensure that the state is being set correctly.

15:44 myguidingstar: nice tip, thanks

15:46 Fare: is there a right way to define data structures with circularities?

15:47 AeroNotix: Fare: never

15:47 arrdem: AeroNotix: with refs all things are possible

15:47 technomancy: you can use laziness to make a list that repeats itself

15:47 AeroNotix: arrdem: It was kind of a joke

15:47 arrdem: Fare: not using pure immutable datastructures

15:47 athinggoingon: here's the code: https://github.com/mfikes/scratch-code/blob/master/vienna.clj

15:47 AeroNotix: "there's never a right way to define circular data strucrtures."

15:48 Fare: are you sure you want this?

15:48 what are you trying to solve?

15:48 arrdem: AeroNotix: largest prime number

15:48 athinggoingon: it's supposed to solve the Viennese Maze problem: http://zulko.github.io/blog/2014/04/27/viennese-mazes-what-they-are/

15:48 Fare: AeroNotix, yes.

15:49 AeroNotix: hmm, I'm not familiar with this and I'm losing interest

15:49 Good Luck! :)

15:49 Fare: I was defining this grammar as a data structure, and some circularities show up at the toplevel

15:49 thanks

15:50 I'll find a way

15:50 AeroNotix: I'm sure you will :) refs are a good start

15:50 Fare: it's just that grammar combinators were working great.

15:51 I suppose I'll make do with some eta-conversion

15:51 η-abstraction FTW

15:52 amalloy: arrdem: well, not using pure immutable *eager* data structures. haskell manages just fine with stuff like: let a = 1:a in a

15:52 myguidingstar: teslanick, it turns out that nothing was printed

15:53 what now?

15:53 technomancy: ,(doc repeat)

15:53 clojurebot: "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."

15:54 technomancy: somewhat circular

15:59 AeroNotix: technomancy: I don't think I'd define that as circular

16:00 teslanick: myguidingstar: Consider implementing it in raw Om to see if that solves it?

16:00 I've done similar things and not had a problem.

16:04 myguidingstar: many thanks, I'm doing it

16:09 Glenjamin: i feel like i've asked this before, but:

16:10 is there a collection function which takes a fn and a seq, and returns a seq of the truthy results of f?

16:11 or actually, i just want to partition a seq into two seqs with alternate items in each

16:11 mi6x3m: hey clojure, how would you call a keyword designating a function creating some visual content

16:11 :init?

16:11 { :init create-example-window }

16:11 Glenjamin: so i can probably do that with drop/take + recursion

16:12 teslanick: Glenjamin: (take-nth 2 coll) (take-nth 2 (drop 1 coll)) ?

16:12 Glenjamin: yeah, annoying i'm using mori, which doesn't include take-nth

16:13 AeroNotix: Glenjamin: group-by

16:13 or partition-by

16:13 Glenjamin: group-by would work, but isn't lazy

16:13 and therefore feels less neat :D

16:13 AeroNotix: meh

16:13 stop fapping

16:14 write code, make it beautiful, make it fast

16:22 mi6x3m: notepad++ syntax file by any chance?

16:43 clojure, is it idiomatic for keywords to contain verbs?

16:43 :create-content, :extract-src

16:43 AeroNotix: Dunno but it's idiomatic for questions to have more context than that

16:43 arrdem: not really... functions should (probably) be your only verbs and keywords are data and thus should (probably) be nouns.

16:44 AeroNotix: arrdem: keywords are functions

16:44 ZING

16:44 arrdem: AeroNotix: no.. they are IFn. that doesn't make them functions. functions are functions. keywords happen to behave the same way in some cases.

16:45 myguidingstar: teslanick, it turns out that it was because I wrapped my component in a function before sending to om/root

16:45 mi6x3m: arrdem: well how would you name a keyword holding a function to create some demo window

16:45 :create-demo create-browser-example

16:45 myguidingstar: not om-tools' fault at all

16:45 mi6x3m: or just :init

16:45 AeroNotix: arrdem: in which cases do they not?

16:46 arrdem: AeroNotix: in the case of wanting to do anything besides getting a keyword named value out of an Associative collection :P

16:46 AeroNotix: arrdem: such as?

16:46 arrdem: oh add one and one

16:46 AeroNotix: wat

16:46 mi6x3m: any help on the actual naming issue

16:47 AeroNotix: mi6x3m: just do it

16:47 it's not exactly a really big deal

16:47 mi6x3m: i wanna stay idiomatic :}

16:47 AeroNotix: fapiomatic

16:47 mi6x3m: true also

16:48 AeroNotix: mi6x3m: the other thing is: would you have a datastructure like {:extract-x 10}

16:48 and then (:extract-x 10)

16:48 and have 10 mean the value called :x?

16:48 I don't think so

16:48 mi6x3m: AeroNotix: no, they are always generate functions

16:48 generator *

16:48 AeroNotix: explain

16:49 mi6x3m: well I am modeling a tree which the users actually sees (JTree) and selects example demos with

16:49 AeroNotix: So, the name reflects the value

16:49 LGTM

16:49 :shipit:

16:50 mi6x3m: a leaf node is { :desc "Description" :create-demo create-simple-window :extract-src ... :avail? true :not-avail-msg "") for example

16:50 AeroNotix: yeah yeah I get it, LGTM

16:50 mi6x3m: yeah, fine, just double checking, new to all this

16:51 arrdem: so... why is my :shipit: rendering to a squirrel in a fedora..

16:53 ah. GitHub internal thing.

16:59 AeroNotix: arrdem: :boom::camel::shipit:

16:59 arrdem: heh

17:03 amalloy: Glenjamin: (apply map list (partition 2 coll))?

17:04 AeroNotix: amalloy: with a predicate

17:04 amalloy: he said alternate items in each, and take-nth seems to be a solution that was suggested

17:04 &(apply map list (partition 2 '(range 10)))

17:04 lazybot: ⇒ ((range) (10))

17:04 amalloy: &(apply map list (partition 2 (range 10)))

17:04 lazybot: ⇒ ((0 2 4 6 8) (1 3 5 7 9))

17:04 AeroNotix: amalloy: uh no

17:05 Takes a function and a seq and returns the truthy elements

17:05 and later mentioned truthy and falsey thingies

17:05 I assume truthy and falsey things, cause they were talking about truthiness before

17:06 But whatever, (<= care 0)

17:11 Frozenlock: DerGuteMoritz: 'some' will stop at the first result matching the predicate. https://www.refheap.com/88011

17:16 Glenjamin: the truthy/falsy question was wanting to use filter to do the odd/even thing

17:17 eg (->> (map vector coll (range)) (filter (comp odd? last)) (map first))

17:17 ybit: help clojure is making me lazy

17:17 Glenjamin: the apply map list is neat

17:18 ybit: i don't want to type commas in other languages

17:19 amalloy: Glenjamin: well, remember that (apply map list xs) is basically transpose. you're asking for a 2-by-N matrix, and it's easy to get an N-by-2 matrix, so...

17:19 Glenjamin: i managed to sort-of convince work that react+mori is a good idea

17:20 so i get to write almost-clojure

17:20 amalloy: anyway, i'm glad to hear that i correctly understood the predicate thing to be the X part of your XY problem

17:20 Glenjamin: but it's annoyingly almost

17:20 amalloy: er, or the Y? i forget which is which

17:20 Glenjamin: so in this example, i don't have return-value destructuring

17:21 the JS isn't too terrible in this case at least: m.apply(m.map, m.list, m.partition(2, m.range(10)))

17:27 AeroNotix: amalloy: just realised that you submitted the problem on 4clojure which has the same answer as the answer you gave Glenjamin

17:27 http://www.4clojure.com/problem/43

17:27 Glenjamin: hrm, is apply lazy?

17:28 AeroNotix: weird memory

17:28 Glenjamin: no

17:28 amalloy: yes

17:28 AeroNotix: amalloy: yes?

17:28 amalloy: as lazy as it can be, anyway. try it and see, AeroNotix

17:28 AeroNotix: lolwat

17:28 Glenjamin: ,(-> (apply map list (partition 2 (range))) first first)

17:28 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

17:28 Glenjamin: whoops >>

17:29 AeroNotix: hmm

17:29 Glenjamin: so, i can do this - which is lazy:

17:30 amalloy: Glenjamin: well, yes, transposing a matrix with infinite rows into one with infinite columns isn't going to work. apply in general is lazy, but obviously if you do non-lazy things with it it can't be

17:30 Glenjamin: ,(->> (range 1 10) (map vector (range)) (filter (comp even? last)) (map first))

17:30 clojurebot: (1 3 5 7)

17:31 amalloy: see, for example, ##(let [f (fn [& args] (first args))] (apply f (range))

17:31 Glenjamin: right, i see

17:31 amalloy: &(let [f (fn [& args] (first args))] (apply f (range)))

17:31 lazybot: ⇒ 0

17:31 amalloy: Glenjamin: basically when you want to split one seq up into two, you can't have all three of: laziness, immutability, efficiency

17:32 you can give up laziness with my apply-map-list, or you can give up efficiency by traversing the input list twice, once for each output (which might cause you to hold its head for too long, if you only actually traverse one of the two lists)

17:33 or you can give up immutability by returning two references which mutate each other

17:33 AeroNotix: amalloy: do people really care about the differences the moment they are writing code?

17:34 apply-map-list is the best way to initially write it

17:34 amalloy: i don't understand that question at all

17:34 AeroNotix: amalloy: seems like you're advocating premature optimization a little

17:34 amalloy: seems like i'm answering Glenjamin's question of "why can't i use apply-map-list on an infinite seq"

17:35 AeroNotix: I didn't see that asked

17:35 whatevs

17:35 :)

17:35 amalloy: i don't understand why you're challenging me so rudely today, AeroNotix

17:35 Glenjamin: it was implied

17:35 AeroNotix: amalloy: I don't intend it, honestly

17:35 amalloy: you've twice already told me my answers to Glenjamin's questions are wrong-headed, and been wrong both times

17:36 AeroNotix: indeed

17:36 cbp: ~gentlemen

17:36 clojurebot: You can't fight in here. This is the war room.

17:36 AeroNotix: Nothing personal, I'm just parsing things wrong

17:36 Glenjamin: i ask similar questions quite often, amalloy always seems to have the answers

17:36 (inc amalloy)

17:36 lazybot: ⇒ 146

17:36 AeroNotix: I'm not disagreeing

17:36 with that

17:37 Glenjamin: also as a bonus i get to name a function (zebra)

17:37 amalloy: hah. dem stripes

17:37 Glenjamin: the version in useful is called alternates

17:38 Glenjamin: i nearly did that, but then realised zebra was apt

17:38 amalloy: but what if you want to split it up into ten? i've never seen a zebra with ten colors!

17:38 metellus: amalloy: fruit stripe gum

17:38 Glenjamin: oh, i don't parameterise on n

17:38 amalloy: oh man

17:38 you're right, metellus

17:39 Glenjamin: i guess zebra is just (partial alternates 2)

17:39 amalloy: Glenjamin: sure; i was suggesting you could

17:40 AeroNotix: amalloy: "the version in useful" is useful a library or something?

17:40 Glenjamin: oo, interesting

17:40 amalloy: $google flatland useful

17:40 lazybot: [useful 0.11.2 - Clojars] https://clojars.org/org.flatland/useful/versions/0.11.2

17:40 amalloy: $google flatland useful github

17:40 lazybot: [useful 0.11.2 - Clojars] https://clojars.org/org.flatland/useful

17:40 AeroNotix: woah wtf, clojars looks way better

17:40 amalloy: screw you, google

17:40 Glenjamin: http://flatland.org/useful

17:40 amalloy: AeroNotix: devn did something to it a week or two ago. big reskinning

17:40 AeroNotix: cheers for the myriad of links

17:40 amalloy: looks a lot better

17:41 now it doesn't look like they asked me to do the css

17:41 Glenjamin: ,(apply map list (partition 2 (range 1 10))) ; <- loses an item

17:41 clojurebot: ((1 3 5 7) (2 4 6 8))

17:41 AeroNotix: you can pad

17:41 parition

17:41 partition*

17:42 Glenjamin: ,(doc partition)

17:42 clojurebot: "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."

17:42 metellus: ,(apply map list (partition-all 2 (range 10)))

17:42 clojurebot: ((0 2 4 6 8) (1 3 5 7 9))

17:42 Glenjamin: bah, another function not included in mori

17:43 amalloy: if you pad in partition, you have to use a function smarter than just list, as your mapper

17:43 Glenjamin: ,(apply map list (partition-all 2 (range 1 10)))

17:43 clojurebot: ((1 3 5 7 9))

17:43 Glenjamin: yeah, i think i'll just iterate twice

17:45 amalloy: &(apply map (fn [& args] (remove ::fake args)) (partition 2 2 (repeat ::fake) (range 1 10)))

17:45 lazybot: ⇒ ((1 3 5 7 9) (2 4 6 8 :clojure.core/fake))

17:45 amalloy: &(apply map (fn [& args] (remove #{::fake} args)) (partition 2 2 (repeat ::fake) (range 1 10)))

17:45 lazybot: ⇒ ((1 3 5 7 9) (2 4 6 8))

17:45 AeroNotix: this library looks like my utils.clj files :)

17:45 nice

17:46 amalloy: &(apply map (partial apply remove #{::fake}) (partition 2 2 (repeat ::fake) (range 1 10)))

17:46 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

17:46 AeroNotix: haha, rate-limited <3

17:47 Glenjamin: one too many applies?

17:47 AeroNotix: sorry, was referring to a function in flatland.useful

17:47 Glenjamin: oh right, i see

17:47 amalloy: i don't think so. i don't really understand what's wrong with that version

17:49 AeroNotix: the idea behind useful is to stop copy/pasting the same junk in utils.clj from project to project, and publish your own utils library that you can just depend on

17:49 you're welcome to use mine instead, of course; i'm just trying to cut down on copy/paste programming

17:49 AeroNotix: amalloy: yeah, we do that internally here.

17:49 But a community one is obviously way better

17:49 Glenjamin: there was a post a while back on the mailing list to the tune of

17:50 "don't publish utility belt libs!"

17:50 amalloy: yeah, that was one of the stuarts, right?

17:50 Glenjamin: yeah

17:50 he's right, in a sense

17:50 amalloy: sure, i see his point

17:50 Glenjamin: but it's because dependencies are broken

17:50 in everything

17:50 always

17:50 except maybe nixOS

17:50 stuartsierra: that was probably me

17:51 It's the kind of thing I would say. :)

17:51 Glenjamin: heh

17:52 mimieux: Hi guys! what is wrong with: (-> "filename" (io/file) (io/reader) (line-seq) (fn [s] s))

17:52 AeroNotix: dependencies in jvm shit are of the "almost ok, we can work with them" type, though

17:52 mimieux: that (fn [s] s) doesn't do what you think it does

17:52 it's a macro that operates on the structure of the code

17:52 amalloy: AeroNotix: it's only sorta community. i accept pull requests, but only for stuff i'd actually use. if you want something i don't care about, put it in your own utility library

17:52 AeroNotix: amalloy: gotcha

17:53 mimieux: :O

17:53 Glenjamin: maybe we should have a separate dependency system for util functions

17:53 where there's a big DB of functions, and some tooling to pull them into your own utils namespace

17:53 with a comment so they can be matched up to the source

17:54 amalloy: it sounds like the big DB is the internet, and the tooling is copy/paste

17:54 AeroNotix: stackoverflow driven development

17:55 Glenjamin: well yeah, but you could have a little manifest in the file

17:55 mimieux: AeroNotix: ((fn [s] s)) thank you!

17:56 Glenjamin: ; (depend [amalloy/useful/alternate 1.0.1])

17:56 cbp: mimieux: you dont need that fn at all

17:56 mimieux: cbp: just for the sake of illustrating my doubt!

17:57 amalloy: ,(identity ((identity identity) identity))

17:57 clojurebot: #<core$identity clojure.core$identity@16712cc>

17:57 Glenjamin: and we could make $findfn work on it

17:57 AeroNotix: ,(buffalo (buffalo buffalo))

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

17:57 Glenjamin: ,(alias buffalo identity)

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

17:57 Glenjamin: ,(def buffalo identity)

17:57 clojurebot: #'sandbox/buffalo

17:58 amalloy: i think this works better in haskell - id is more fun to type than identity, and you can mix in some operators for fun

17:58 AeroNotix: what was that error in Haskell that blew up the compiler with thousands of calls to id?

17:59 amalloy: id id (id . id . id . id $ id id id) $ id

17:59 AeroNotix: oh I think it was when it was trying to determine the type signature of something like that

18:00 amalloy: yeah, i read about that recently but couldn't figure out how to reproduce it

18:01 gratimax: that isn't a very complicated expression, I think

18:02 TEttinger: ,(def id identity)

18:02 clojurebot: #'sandbox/id

18:03 gfixler: ,(id identity)

18:03 clojurebot: #<core$identity clojure.core$identity@16712cc>

18:03 gfixler: ,(identity id)

18:03 clojurebot: #<core$identity clojure.core$identity@16712cc>

18:03 TEttinger: ,(id id)

18:03 clojurebot: #<core$identity clojure.core$identity@16712cc>

18:03 gfixler: checks out

18:04 stuartsierra: I am so tired of this error cropping up everywhere https://github.com/mmcgrana/clj-stacktrace/issues/23

18:05 gratimax: ,(def buffalo identity)

18:05 clojurebot: #'sandbox/buffalo

18:05 gratimax: ,(def Buffalo identity)

18:05 clojurebot: #'sandbox/Buffalo

18:06 gratimax: we're ready to begin

18:06 mdrogalis: Why's the IRC log not being recorded anymore?

18:06 AeroNotix: gratimax: now we can play the game

18:06 AimHere: Duplication of effort. We discovered the NSA were already doing it

18:06 AeroNotix: AimHere: hard to retrieve logs though

18:06 AimHere: Just file an FOI request!

18:07 amalloy: logs.lazybot.org

18:07 mdrogalis: Got it. Ty.

18:07 amalloy: stuartsierra: i do everything i can to keep clj-stacktrace out of my programs

18:08 stuartsierra: I wish I could. But tool wants to depend on it, and it keeps sneaking into client projects.

18:08 *every tool wants to depend on it

18:09 Glenjamin: the solution is to improve stack traces in core, clearly :D

18:09 amalloy: i'm actually unsure whether you mean that tooling libraries want it, or you're calling everyone who uses clj-stacktrace a tool, but i'm pretty okay with either interpretation

18:09 gratimax: ,(((((Buffalo buffalo) (Buffalo buffalo)) buffalo), buffalo) (Buffalo buffalo))

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

18:11 stuartsierra: .printStackTrace is perfectly good AND IT NEVER BREAKS

18:12 amalloy: yessss. the stacktraces from clojure.core are already better than those generated anywhere else, because they work

18:12 stuartsierra: If you really want to format it, use (or improve) clojure.stacktrace

18:13 amalloy: choosing to instead use a stacktrace generator that color-codes, aligns, and demunges them, but 1% of the time completely breaks and you can't find your stacktrace at all? no thanks

18:13 stuartsierra: amalloy: I couldn't agree more.

18:13 Nice to know I'm not the only one.

18:13 Glenjamin: i suspect many people haven't hit that 1%

18:14 amalloy: stuartsierra: i know i'm preaching to the choir, just because it's fun to be agreed with

18:14 Glenjamin: i've never had that issue, so would use it assuming all was fine had i not seen this discussion

18:15 stuartsierra: The point, which few people seem to get, is that exception handling is an *exceptional* situation. Things are broken. You have to code very defensively, do as little as possible.

18:16 zanes: One of my coworkers just asked why let uses a vector for its syntax (let […] …) instead of a map (let {…} …) and I was stumped. Anyone have any idea?

18:16 Glenjamin: zanes: you can repeat symbols

18:16 amalloy: speaking of which, stuartsierra, how goes that (try (f) (catch Exception e (println e))) in core.async? another person was in here earlier this week asking why he doesn't get stacktraces

18:16 zanes: Glenjamin: Ah, yes! Thanks.

18:16 amalloy: Glenjamin: perhaps more importantly, maps aren't ordered

18:16 stuartsierra: amalloy: I keep pushing it with Rich et al.

18:17 zanes: Ooh, that too.

18:17 stuartsierra: I think I'm getting the beginnings of agreement that the current behavior is less than desirable.

18:18 amalloy: http://dev.clojure.org/jira/browse/ASYNC-76 is my ticket, with references to some other variants.

18:19 amalloy: well, good luck

18:19 stuartsierra: amalloy: Thanks. You can help (maybe) by voting :)

18:20 amalloy: your wish is my command

18:20 * stuartsierra contemplates his newly discovered superpower

18:21 Glenjamin: almost immediately after naming my zebra function i realised i needed a version with n=3 :(

18:24 DerGuteMoritz: Frozenlock: yes, it does not traverse the whole collection but unless you pass a lazy-seq, all arguments are evaluated -- and even in the lazy-seq case, more elements than the one it stops at might be evaluated due to the underlying chunking (AFAIK, not sure if that also happens with `next')

18:24 s,arguments,elements, I guess

18:29 Frozenlock: DerGuteMoritz: That's not how I understand 'or'

18:29 ,(doc or)

18:29 clojurebot: "([] [x] [x & next]); Evaluates exprs one at a time, from left to right. If a form returns a logical true value, or returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. (or) returns nil."

18:30 amalloy: Glenjamin: (def zebra (partial alternates 2)) (def barber-pole (partial alternates 3)) ...

18:31 Glenjamin: hrm, i never noticed barber pols have a third stripe

18:31 always had it red&white in my head

18:31 amalloy: then they'd just be candy canes

18:31 Glenjamin: it's now become everyNth and acts a bit like take-nth

18:32 if i had destructuring, i'd stick with the partition

18:36 DerGuteMoritz: Frozenlock: `or' stops evaluation at the first truthy expression, e.g. (or true (launch-missiles!)) will never launch missiles while (some true? [true (launch-missiles!)]) will launch missiles before even calling `some'

18:38 amalloy: can you elaborate why you think one-of? is inferior? AFAICT it's just different

18:39 amalloy: it's not inferior to using some; they're just both bad

18:40 the discussion from yesterday is at http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-07-08.txt - start at 21:11:12 and go until 21:26:07

18:41 after that it should be clear why i don't like one-of?

18:41 DerGuteMoritz: amalloy: ah, I didn't get that nuance earlier :-) *reads log*

18:42 Frozenlock: ,(some true? (repeatedly #(do (println "ping") true)))

18:42 clojurebot: ping\ntrue

18:42 Frozenlock: DerGuteMoritz: Seems only the first of the lazy-seq is evaluated.

18:44 DerGuteMoritz: Frozenlock: indeed! perhaps chunking was removed again or something? or only functions that need to consume the whole seq anyway apply it? a mystery!

18:44 amalloy: not all sequences are chunked

18:44 most aren't, really

18:45 but consider ##(some true? (map #(do (println %) true) [1 2 3 4])), for example

18:45 lazybot: ⇒ 1 2 3 4 true

18:47 shanemhansen: What's the recommended way to preload libraries and functions into a clojure repl.

18:47 I'd like to fire a repl up for data analysis and have several simple stats things in my namespace.

18:48 arrdem: shanemhansen: you can either have a user.clj file with stuff in it, or you can have :injections in your lein profile

18:48 DerGuteMoritz: right, so I guess I wouldn't rely on lazy-seqs when fine-grained control of realization is necessary

18:48 amalloy: thanks!

18:49 shanemhansen: Thanks arrdem

18:49 arrdem: shanemhansen: yw

18:50 DerGuteMoritz: OK, I see now that the original discussion was actually about some vs. sets which is of course a different story and I agree that both some and one-of? are not good choices overe sets in that case :-)

18:50 ok have a good night everyone!

18:52 cespare: I'm switching from plain jetty to http-kit...maybe a dumb question, but if http-kit is multiplexing multiple requests onto a single thread somehow, does that change/break usage of dynamic vars?

18:53 technomancy: cespare: yeah

18:54 cespare: hmm, ok. http-kit docs are extremely light on details like that.

18:55 do i also need to worry about blocking the thread? (e.g. making blocking db calls)

19:47 myguidingstar: have no idea why cljsbuild yells "No such namespace: markdown.core"

19:48 I added markdown-clj to project.clj, restart cljsbuild and saw it being fetched from clojar

19:50 brehaut: myguidingstar: just to check: are you trying to use a clojure library in clojurescript code?

19:50 (i don know anything about the lib in question)

19:50 myguidingstar: brehaut, markdown-clj works with both

19:51 other libraries like core.async work as usual

19:51 ivan: myguidingstar: unzip -l ~/.m2/repository/markdown-clj/markdown-clj/0.9.45/markdown-clj-0.9.45.jar

19:51 the jar is missing the clojurescript

19:52 myguidingstar: ivan the result show no .cljs file

19:52 but what do you mean "the jar is missing"?

19:53 ivan: you might want to file a github issue mentioning that the .jar is broken (missing the .cljs files)

19:54 myguidingstar: yup, got it

19:57 ivan: myguidingstar: if you clone https://github.com/yogthos/markdown-clj and `lein install` it should make a proper .jar; it does here

19:57 myguidingstar: issue filed. many thanks

20:29 bsima: Does anyone know if there's a way to do a regex match on a seq which is composed of strings and maps? I only want the string content

20:29 Specific string content, that is, selected by the regex

20:38 Jaood: bsima: with logic!

20:38 bsima: maybe paste an example of the seq?

20:39 * hellofunk

20:40 bsima: The specific error I'm getting is LazySeq cannot be cast to java.lang.CharSequence

20:40 (("\n\t\t\t\t\t\t\t\t\t\t\t\t\t" {:tag :strong, :attrs nil, :content ("AMPAR peptide values in blood of non-athletes and club sport athletes with concussions.")} " Dambinova SA, Shikuev, Weissman JD, Mullins, JD. " {:tag :em, :attrs nil, :content ("Military Medicine.")} " 2013, 178 (3):285-290.\t\t\t\t\t\t\t\t\t\t\t\t")

20:40 there's 189 of those...

20:40 hellofunk: I am concating two vectors, which creates a lazy seq. Then I am deffing a doall of that lazy sez. When I log the def'd result, it logs as a lazy seq. Shouldn't doall be head-retaining and realize the lazy seq, making it no longer lazy?

20:44 mange: hellofunk: It doall won't change the type, it will just realise all of the elements. Use (seq (doall ...)) to make it print as a seq.

20:44 hellofunk: mange: sweet, good tip

20:47 mange: bsima: Are you trying to regex match over all of the strings in that structure, or only the top-level strings? Do you want to match things only within one string, or is it fine for it to be over the boundary of several strings? Is your data enlive nodes?

20:49 bsima: The data are enlive nodes, a seq of li elements with nested strong and em elements. I want specifically the authors of the studies: Dambinova SA, Shikuev, Weissman JD, Mullins, JD.

20:50 I'm trying to doseq each one into a str and then run re-find on them right now, hopefully it will work

20:51 Yeah, it looks like this should work, I just need to work on the regex now

20:51 (doseq [seqs (map :content (references))] (pprint (re-find #"(Grindel)" (apply str seqs))))

20:53 arkh: for this clojurescript it keeps tripping up on className: (.. js/document (getElementById "logview") className)

20:54 how do I specify that className is a property and not a function?

20:56 amalloy: arkh: in cljs you use (.foo bar) to call foo as a method, and (.-foo bar) to look it up as a field

20:56 that macroexpands to (. bar -foo), so you should just be able to write (.. whatever (...) -className)

20:56 arkh: ohhh

20:57 that makes sense now; .-className was also throwing an error but that's because I didn't need the '.'

20:57 thank you

21:43 eraserhd: In the old days, I saw a lot of programs fire up $EDITOR on a template that has Field: Value, and perhaps Field:: multi-line-value, and then parsed it. Like git commit does. Does anyone know if there's some kind of parser for that already?

21:51 serjeem: is there a shorthand for (apply concat lst)?

21:53 bsima: @eraserhd does this help? https://github.com/cgrand/parsley

21:53 amalloy: serjeem: no

21:58 arrdem: bbloom: prototype branch using fipp-like sequence structures rather than macro splicing comes in at least 20s slower than the macro splicing.

22:46 rbrito: Hi. I would like to make a simple program, but it seems like I need mutable state. Can anybody help?

22:47 Huinan: Hi, I'm in a situation where I have to package my clojure project without command line lein. Does anyone know if there is any way to invoke lein tasks within the code (either java code or clojure code)?

22:48 rbrito: Actually, it does not *really* need mutable state, but to be practical, I guess that it does.

22:48 The problem is the following: given a sequence of integers on stdin, with the sequence terminated by 0, compute the sum of such integers.

22:49 With an imperative language, I can solve this quite easily, but I don't know how would be the proper way to do that in Clojure.

22:49 Or any functional language, for that matter.

22:49 Can anybody help here?

22:51 ttasterisco: sounds like homework

22:51 bsima: (reduce (java.io.BufferedReader. *in*)

22:51 systemfault: rbanffy: In functional programming, what you want to do is called a fold (also called reduce)

22:51 bsima: something like that

22:51 systemfault: Err, rbrito

22:51 rbrito: The problem that I see is that the input sequence can be arbitrarily long and it will potentially exhaust the memory if memory isn't reused.

22:52 bsima: use doseq

22:52 rbrito: ttasterisco: it indeed, is homework. That I will assign to my students.

22:52 bsima: see here: http://stackoverflow.com/questions/2034059/how-to-read-lines-from-stdin-in-in-clojure

22:54 rbrito: bsima: thanks. your reduction stuff is a good approximation of what I need, but what if the requirement is changed so that I should stop when, say, the number 42 is entered?

22:55 bsima: eh, I'm not sure you can arbitrarily stop doseq…

22:55 rbrito: Note that I may not be in control of the input... (Think of the input being a pipe).

22:56 Using scala and mutable state, I was able to create such a program, but I would like to use clojure for this course...

22:57 amalloy: rbrito: you absolutely don't need any state for that

22:57 rbrito: https://github.com/rbrito/macmulti/blob/master/chap01/ex01.scala

22:57 amalloy: (apply + (for [x (read-numbers-forever) :while (not= 42 x)] x))

22:57 would be one reasonable approach

22:58 rbrito: amalloy: Ah, my clojure-fu is not up to that list/whatever comprehension. :)

22:58 amalloy: *shrug* so use take-while

22:58 (apply + (take-while (complement #{42}) (read-numbers-forever)))

22:59 rbrito: No, but I would like to use comprehensions if that's the better (read: more memory efficient) computation.

22:59 amalloy: you're optimizing about two years too soon

22:59 hellofunk: amalloy i'm curious, both idioms you just noted are great and equally as succinct. which do you think is the better choice, or is it just taste?

22:59 amalloy: once you understand how to write a correct solution to the problem, and you've tried it and discovered it's no good, then you can think about performance

23:00 hellofunk: taste, really. and context: the take-while would fit better into an existing ->> pipeline, but i prefer for in general

23:00 rbrito: amalloy: well, I actually know about the "premature optimization is the root of all evil". :)

23:01 amalloy: rbrito: then you should recognize that the optimization question you asked is absurd

23:01 rbrito: I just want to feed humongous quantities of input to the program and not have it barf on me.

23:01 amalloy: you're adding up a list of numbers. on a computer that can download entire video files over the internet in a matter of minutes

23:01 it can handle an awful lot of numbers

23:02 rbrito: amalloy: one of the things that I have in mind is running all my programs on my armel system with only 128MB before I assign them to my students.

23:02 Ooops, this just goes to show that my computer may not be as fast as you think. :)

23:03 Just to give a little bit of my context:

23:03 https://lists.debian.org/debian-arm/2014/07/msg00033.html

23:05 amalloy: you're just completely off on your sense of scale. even if you were keeping all numbers in memory at once (but why would you?), you have more than enough memory to add any quasi-reasonable series of integers

23:06 rbrito: OK, scratch that. I have one next question: how do I perform dynamic programming with immutable state?

23:07 amalloy: typically you don't need to. most algorithms that use dynamic programming in a mutable language are better formulated as a pure function windowed over a lazy sequence anyway

23:08 for example, consider a classic example, computing fib(n) by starting at 0 and building a lookup table

23:08 rbrito: amalloy: I see. If not all values of the dynamic programming formulation need to be computed.

23:09 Or if they can be discarded after a while.

23:09 amalloy: well, more importantly, they don't all need to be *saved*

23:09 rbrito: But there are some notorious cases where they may need to be kept.

23:09 amalloy: probably so

23:10 rbrito: The knapsack problem is one of those.

23:11 amalloy: in you snippets, the read-numbers-forever function isn't something that already exists, right?

23:11 amalloy: right

23:11 if you need to keep a lookup table forever, you can always use it as a loop variable in your loop/recur, or an accumulator in your reduce, or...

23:12 rbrito: Just tried it on the repl and it complained...

23:13 I am still evaluating if I can give the course in clojure or if I will have to surrender and give it in another language. Of course, I wouldn't be here if I didn't *want* to use clojure, which should say something. :)

23:17 hellofunk: (set! (eval (give "course in clojure")) true)

23:20 rbrito: hellofunk: yes, more or less like that. :)

23:21 So, read-numbers-forever can be written something like (repeatadly read)?

23:21 repeatedly

23:24 Well, it worked with that simple implementation. :)

23:24 I now can give my students a new entire class of programs to write. :)

23:24 It will be possible to avoid scala. :)

23:26 Not that scala is bad, but learning one member of the lisp family will be a nice addition to get out of the mental structure of the programs written like Java (which is all that they know at this point).

23:30 amalloy: doesn't these snippets that you presented me keep the numbers in question in memory?

23:30 s/doesn't/don't/

23:31 sztamas: I love it how you keep be concerned about memory but you don’t even care if what you read in are numbers at all

23:33 rbrito: sztamas: that should give you a hint of my background being non-real-world and only theoretical. :)

23:34 sztamas: what is the course if I may ask?

23:35 rbrito: This one will be an introduction to functinonal programming, but I am thinking of giving the equivalent of CS 101 with clojure...

23:35 I am moderately proficient with Python: https://github.com/rbrito

23:36 But I want to start using functional languages.

23:36 Or using conventional languages in a more functional way.

23:37 brehaut: rbrito: fuctional javascript by fogus is a good introduction to functional programming

23:37 rbrito: At least python has higher order functions and comprehensions.

23:37 brehaut: thanks. Javascript is also a good option.

23:37 systemfault: Try Haskell if you want to fall into the rabbit hole. :P

23:37 gfixler: rbrito: that's my path - Python dev (for games) for years, moving much more into FP now, and bringing that back to my Python work.

23:38 brehaut: rbrito: once you have finished functional js, have a look at joy of clojure 2e

23:38 (also by fogus)

23:38 TEttinger: clojure's a fun language once you get the hang of it. it did take me a while to "get it," though

23:38 brehaut: FunJS is intended partly as a primer for JoC

23:38 (if i recall things correctly)

23:39 rbrito: systemfault: I don't think that I'm interested in haskell, but that's my current impression and I may reconsider my position here...

23:39 brehaut: thanks. I think that I will check this out.

23:39 I actually like the little javascript that I know of.

23:40 s/know of/know/

23:40 brehaut: rbrito: you dont know enough js then ;)

23:40 systemfault: rbrito: With haskell, you’re forced into FP. Unlike most other languages where the escape hatch from FP is too easily accessible.

23:41 rbrito: brehaut: indeed, my experience is only with C (a little with C++, but nothing substantial) and with Python. (With a moderately successful project in Python on github).

23:41 sztamas: you can certainly teach some FP using just python

23:42 +1 for Functinal JavaScript by Fogus BTW, I really enjoyed it

23:43 brehaut: rbrito: if you want an exercise, compare the clojure sequence api to pythons generators and itertools

23:43 rbrito: generators are inherently mutable while seqs are not. they otherwise perform similar tasks, but seqs are far more exprsesive

23:44 rbrito: systemfault: I may be misdjudging haskell here, but the excess of symbols as opposed to the use of words (like in Python) makes me prefer other languages. At least with lisp there's a real break on the syntax. :)

23:44 brehaut: thanks for the recommendation.

23:44 brehaut: rbrito: im a former python programmer too

23:44 clojure is a nice next language

23:45 (also F#)

23:45 sztamas: I’m a python programmer too

23:45 ddellacosta: rbrito: I don't find Haskell too painfully heavy on symbols vs. strings, certainly about the same as Clojure

23:45 rbrito: sztamas: yes, I think that I may fallback to using python, but I don't know if I am allowed to. :( The University has a partnership with oracle... :(

23:46 gfixler: rbrito: I had a little revelation today when I found a nice color scheme for Vim - I was writing small functions that were purely functional, and toggling between them and my test file

23:46 rbrito: ddellacosta: I'm not discarding haskell... I would just prefer other things (in my ignorance).

23:46 gfixler: my old schemes didn't highlight it, but this one did - my code was all blues and creams, and my tests were all greens and oranges

23:47 I realized the colors were marking the divide between functional and declarative

23:47 ddellacosta: rbrito: yeah, just saying--give it a chance, I think Haskell uses symbols very judiciously (and the community tends to shy away from syntactic sugar as well, generally)

23:47 gfixler: the functions were all commands and keywords; the tests were all strings and numbers being pushed into them

23:48 rbrito: I use emacs since 1994, but I don't reject using newer technologies (like an IDE like Eclipse). :)

23:49 brehaut: ddellacosta, rbrito: haskell also uses symbols for things that are very abstract and thus hard to name with words. thats not always a negative

23:49 rbrito: ddellacosta: thanks. That's nice to know and to consider. Only one thing that I found error prone was that you apparently can't define variables that start with capital letters.

23:49 brehaut: like >>= ?

23:50 brehaut: rbrito: sure.

23:50 rbrito: Isn't it "bind" in other languages?

23:50 brehaut: i know it also has a name (bind) but its sometimes useful to get the words out of it

23:50 rbrito: You were reading my mind. :)

23:51 ddellacosta: I think the thing with symbols is that they can be doubly useful when applied judiciously--they can remove boilerplate, and they can provide more immediate visual recognition of what is going on in code

23:52 I think Clojure's data structure syntax helps with quickly recognizing what you're working with, for example

23:52 but you can go too far: Perl

23:53 rbrito: But I am mostly (for some unrational reasons) interested in giving this course in clojure and, perhaps, contrasting with other languages. Here, the suggestions that all you nice people gave about JS, Haskell or even Python (well, this one was already considered by me) were valuable.

23:53 I will check this book on functional programming in JS.

23:54 It sounds very interesting, given that the students will already, at that point, have some experience with JS (probably more experience than I do).

23:54 systemfault: JS (ES5) has some FP stuff.

23:54 map/filter/reduce/bind

23:55 rbrito: ddellacosta: being a former Perl programmer that loves Python, I want to avoid symbols as much as I can. ;)

23:56 brehaut: rbrito: dont just haskell by perl's mistakes ;)

23:56 systemfault: a different bind though ;)

23:56 sztamas: the FUN JS book uses Underscore

23:56 systemfault: brehaut: Yeah… JS’s bind is like manual currying

23:56 brehaut: systemfault: also javascript functional stuff is a bit munted (see also: promises)

23:57 rbrito: I also, for some reason, don't consider parentheses in clojure as "symbols" any more than, perhaps, braces in C.

23:57 systemfault: brehaut: Haha, i love promises though… compared to callbacks.

23:57 rbrito: brehaut: I promise to look seriously into haskell and I hope to come back to this IRC channel frequently from now on. :)

23:58 A lovely community, BTW.

23:58 brehaut: systemfault: well yes, its the lesser of two evils ;) but the duck-wrapping :'(

23:58 * systemfault cries

Logging service provided by n01se.net