#clojure log - Mar 24 2012

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

0:16 solussd: is there a postwalk-re-replace, or something? :)

0:34 Frozenlock: What would be clojure's equivalent of `atom' from emacs?

0:37 tmciver: Frozenlock: I'm not very familiar with emacs lisp but one of my emacs books says: "Atoms are values of any type including integers, floats, characters, strings, booleans, symbols, and special emacs types such as buffers and windows." So I'm guessing that's the same as a regular Var in clojure.

0:38 Frozenlock: Atom: Return t if OBJECT is not a cons cell. This includes nil.

0:38 In other words, test if it's a list.

0:38 technomancy: (complement seq?)

0:39 but not very useful because lots of things are list-y

0:39 so just because coll? returns false doesn't necessarily mean it's scalar

0:39 Frozenlock: technomancy: yeah I tried seq?, but vector returns false

0:40 technomancy: coll? is more general

0:40 Frozenlock: I would like something to test if I can use `doseq' (so if it's a list, vector, map...)

0:40 technomancy: ok, coll? should give you that

0:40 Frozenlock: Thanks, trying now

0:40 seancorfield: for those of you who saw my emacs / cl.elc problem earlier, the solution was to remove / (re-)install emacs-snapshot on my ubuntu netbook... brutal but it worked :)

0:42 Frozenlock: technomancy: coll? works as intended, thank you very much :D

0:42 technomancy: cool

0:43 napping: if it's for doseq, is sequential? better?

0:46 Frozenlock: napping: sequential? returns false on a map, but I can use doseq on it.

0:48 Btw, is there a common practice when one's talking about a function in #clojure? Should I put it between any symbols? "sequential?" `sequential?' _sequential?_

0:48 napping: so there's nothing which tells you exactly whether seq will succeed

0:49 Frozenlock: Well `coll?' seems to work.

0:50 napping: returns false on nil, for a start

0:53 also on java arrays

0:53 if what you want to know is really whether doseq will work

0:54 * technomancy likes backticks for that

0:55 mk: is a sequence merely an interface?

0:56 for some reason I was expecting (type (rest '(1 2 3))) to be some sort of seq object

0:57 napping: there's an ISeq for things which are properly seqs

0:57 Frozenlock: Perhaps I have the wrong approach anyway... I have a funtion that uses `doseq'. I want it to works even if the argument is a single object (so not a vector, not a list, not a map...). My current plan was to test if it was doseq-able. If not, wrap it in the `seq' function.

0:57 napping: for some sort of deep tree walk?

0:57 mk: napping: a PersistentList isn't a seq?

0:57 technomancy: Frozenlock: seems suspect

0:58 Frozenlock: Yeah I find too.

0:58 mk: Frozenlock: what's the name of your function

0:58 napping: mk: it is.

0:59 mk: napping: so both ISeq and PersistentList implement Seq?

1:00 napping: no, ISeq is the name of the iterface

1:00 Frozenlock: Silly me.

1:00 Map.

1:00 qbg: PersistentList implements ISeq

1:01 technomancy: Frozenlock: seq has a bunch of special cases; you would need to look at its source and check for all of them

1:02 napping: the source calls clojure.lang.RT.seq

1:02 mk: oh, ok. There are no things that are improperly seqs. I thought there might be a special ISeq implementation for some reason.

1:02 technomancy: but I don't think having a function implictly seq a scalar value is wise

1:02 mk: eventually it will probably become a protocol

1:04 napping: mk: PersistentList extends ASeq implements ISeq

1:04 technomancy: that sounds good

1:05 mk: I'm still fuzzy on the distinction between interfaces and protocols - I think I'm thinking of protocols as unenforced interfaces or something. But I havn't gotten to that part of the reference yet.

1:05 qbg: Every protocol has a corresponding interface, but not vice-versa

1:06 jonasen: lynaghk: ping?

1:07 mk: qbg: a protocol isn't a type of interface?

1:07 qbg: No, interfaces are Java

1:07 protocols are Clojure

1:08 mk: but it's not just a naming thing

1:08 napping: you can add an instance for existing types

1:08 qbg: You can't extend an interface to a class later

1:13 mk: is there a good explanation of protocols out there? clojure.org/protocols isn't that clear.

1:13 qbg: That is why clojure.lang.RT.seq is the mess it is

1:14 Which part do you find not clear?

1:18 mk: I'm not sure how they interact with data, or what sort of data they're supposed to apply to (classes, records... maps?). I'm probably also hazy on what they actually do - define standard operations on a certain sort of data? provide fancy getters?

1:18 qbg: Do you understand interfaces in Java?

1:18 mk: yep

1:19 qbg: They are basically the same thing

1:19 methods are functions that take the object being operated on as the first argument

1:19 Methods translate to protocol functions

1:20 mk: are we talking about java methods? Because methods are also stateful

1:20 qbg: Not all methods

1:20 And protocol methods are usually not :)

1:20 mk: aren't the ones that are not simply called functions?

1:21 qbg: These functions belong to a class

1:21 That's what makes them methods :p

1:21 mk: why put them in a class?

1:22 qbg: You'd use protocols to do the same sort of things you use interfaces in Java to do -- provide a uniform interface for operating on data

1:22 mk: java interop? It seemed like protocols were about more than that

1:22 qbg: Protocols are not primarly about interop

1:22 mk: qbg: but the data isn't in the protocol class?

1:22 qbg: No, a protocol is a set of functions

1:23 The data is what the protocol is extended to

1:23 mk: ok, so a tightly grouped set of functions, intended to apply to... a specific sort of lump of data?

1:24 qbg: A set of functions that can be specialized based on the type of the first argument

1:25 Essentially a set of limited multimethods

1:26 Am I helping at all?

1:26 mk: if I'm storing a bunch of triangles in triples [[1 2] [2 2] [3 3]] (and squares, and circles), can I put a drawable protocol on them

1:26 qbg: I think you are, yes

1:27 qbg: Yes, you could extend your Drawable protocol to PersistentVector

1:28 Just like you could extend it to your own Triple type

1:28 mk: so is it essentially like a "facade" pattern? (if I have that name right)

1:29 where you wrap an object that doesn't nicely fit your interface in a new class that does

1:29 qbg: You don't need to wrap with Protocols

1:29 Which is why they are so neat

1:29 You can extend new protocols to already existing types

1:30 You could extend your protocol to String for instance

1:32 mk: does the thing you extend it to now gain the ...method, in some way?

1:33 qbg: If you extend it after the fact, no new Java methods are added to the class (since that is currently impossible)

1:33 Instead the fn will fall back to dispatch

1:34 If your deftype/defrecord form specifies an impl of a protocol, it will implement the corresponding interface

1:35 mk: oh. I think I get it - it's a set of functions such that if you call them on a certain type, the function knows how to handle that type properly. That's how it's polymorphic

1:35 qbg: In either case, calling the protocol function will do the right thing

1:35 Yep, just like iterfaces

1:35 *interfaces

1:35 mk: where do the protocol methods live, if they don't get attached to the classes?

1:36 y3di: anyone know when the clojure west vids might be up

1:37 qbg: mk: Don't know for sure, but I think they are just plan IFns

1:37 And some clever caching is done to make the dispatch fast

1:38 (the extend function would suggest that)

1:38 mk: in any case I'd guess they play well with namespaces and all that. I see though that you don't need to group them, like (protname.method1 ...)

1:39 qbg: Nope, just namespaced functions

1:39 That is their advantage over monkeypatching

1:40 mk: qbg: thanks much, I have a substantially better grasp of how they work

1:40 qbg: The protocol impl is beautiful in ClojureScript by the way

1:41 You should look at core.cljs to see the awesome power of protocols

1:42 mk: they're essentially polymorphic functions - after extending a protocol to various things, you can count on the function to simply know what to do with those things, without attaching everything that you might want to do with data to the data itself

1:42 qbg: Yep, sets of restricted multimethods

1:42 mk: that's great, because even in the example I gave, with OO you'd be worried about whether the triangle is "responsible" for drawing itself, and that just seems a stupid way to think of it now

1:43 qbg: functions want to be free :)

1:44 Java-style classes complect data and the functions that operate on it

1:44 Clojure splits that apart

1:45 mk: yeah, I saw Rich's talks on that, but I didn't see how well this works for polymorphism until now

1:49 qbg: The trend in protocol usage seems to be that they are for internal low-level functions which are used by normal functions to provide a high-level API

1:50 mk: what counts as a normal function?

1:50 qbg: fn

1:51 Non-polymorphic functions

1:51 mk: so protocols aren't exposed? That seems strange

1:52 qbg: They are exposed, but not the main API in libraries structured this way

1:52 See clojure.java.io for example

1:52 *but are not the main API

1:54 I think that structure only makes sense in some circumstances

1:57 Namely, when you aren't value-adding functionality to the polymorphic functions

1:58 mk: just at the top of clojure.java.io it seems to be clobbering string/file/url/uri into a single coherent... thing

2:00 as if it's taking the intersection of the 4 of those things

2:02 qbg: It is using protocols so as-file and as-url do the right thing for those types

2:03 Java IO is really sick, so it's a case where you don't want to make those protocol methods your main API

2:07 At least it got better in Java 7

2:08 mk: did it? I've used parts of it, and the performance is better, but now there's also the Path class

2:09 I had no fun at all converting between strings, files, and paths not too long ago

2:12 my vague impression of java 7 io was that it seemed unfinished

2:13 qbg: It doesn't take much for it to be an improvement

4:39 bytechunky: bytechunky's clojure koan: given a map m, you want know all keys in m whose values satisfy condition c. Idiomatic suggestions? :)

4:40 AimHere: filter on the keys?

4:41 Togo: hey guys. Why returns me following function only true if i call the function with one letter("L"). If i call the function with two or more letters the function returns me nil!! any suggestions?

4:41 (defn only-digits? [string] (if (re-matches #"[A-Z]" (clojure.string/replace string " " "")) true) )

4:44 bytechunky: AimHere: u mean like (map #(% 0) (filter #(c (% 1)) m))? <-- filter works on values but returns k/v pairs, map projects onto keys. This is my first approach but: it's ugly :(

4:45 AimHere: ,(filter even? (keys {1 "foo" 4 "bar" 5 "baz" 8 "ummm" 69 "yay" 42 "whatever"}))

4:45 terom: Togo: your regex only matches for one character

4:45 clojurebot: (4 8 42)

4:46 bytechunky: AimHere: well, na, the values are the ones that should satisfy the condition but i want to know the corresponding keys

4:47 AimHere: Howabout filtering on the (key val) pairs and then taking the keys? ,(keys (filter #(f %2) m) ?

4:48 Togo: terom: can you give me a correct regex?

4:48 AimHere: #"[A-Z]+" will match one or more capital letters

4:49 Togo: thanks

4:49 bytechunky: AimHere: is works! that's insane! because i thought 'keys' would only work on maps and not on k/v pairs. but apparently it does both

4:49 AimHere: thank you!

4:59 terom: Togo: as AimHere said. Also, depends what you're doing with the return value of the function (or if you have plans to develop it furher), but the (if (something) true)) construct is usually unnecessary when (something) is already returning "truthy" things.

5:10 amalloy: fwiw, bytechunky, i'd write AimHere's suggested solution a little differently. either (map key (filter (comp c val)) m) or (for [[k v] m :when (c v)] k)

5:11 oops, bad nesting in the first one. should read (map key (filter (comp c val) m)), or (->> m (filter (comp c val)) (map key))

5:43 bytechunky: amalloy: are u implying, you would not want to rely on the fact that keys works on seqs of map entries?

5:44 amalloy: well, that and i would prefer (comp c val) to #(c (val %))

5:45 also, does #(c %2) really work? i can't imagine how it would

5:48 bytechunky: #(c %2) was written down grubbily... c would have to be a predicate in that case. and yes, i also prefer (comp c val) over the other variants. val is something i wasnt aware of. so thank you for pointing that out.

6:01 AimHere: i only realized now that amalloy did not refer to my code with "#(c %2)". Didnt mean to offend u...

6:03 amalloy: bytechunky: well, c does seem to be a predicate, so that's not a problem. the problem is that filter passes only one arg to its function, and #(c %2) expects two args (rather than a single pair arg)

6:05 bytechunky: mh true

7:58 augustl: is there anything in clojure or java to make interval ticks that keeps a steady beat?

7:59 so, I want my function to be called every 100ms, and if my function call takes 2ms to execute I want the next tick to be after 98ms

8:03 I suppose I can use two threads, the amount of time used for the ticker thread to just poke another thread is probably negligible

8:04 rpt: Hi everyone, how do I trace a stack overflow in a recursive function? I tried clojure/tools.trace, to no avail. http://pastebin.com/sAmJBfmD

8:09 augustl: https://github.com/overtone/at-at seems to be what I'm looking for

8:35 _andrew_k: augustl: java.util.Timer

9:01 DerGuteMoritz: Raynes: looking at your clj-oauth2 pull request right now!

9:01 Raynes: do you know whether lein 2 still respects :dev-dependencies?

9:01 Raynes: that way we could stay 1.x compatible

9:46 Somelauw: I want to represent a chess piece in clojure. I could represent this as a simple character I think, but then do I need to create getter functions for the color and the piece name?

9:47 Should I wrap my character in another datastructure or use the char directly?

9:50 * gfredericks hmms

9:52 gfredericks: Somelauw: the getter-functions approach sounds reasonable. are you going to use KQRBNPkqrbnp?

9:55 I was thinking the getters could use clojure.core/case if this is performance-sensitive

9:58 Somelauw: gfredericks: Yes. I am using uppercase/downcase chars. I am still wondering if I should \k everywhere to represent it as king or that I should make encode-piece/decode=piece functions to map between \k and :king.

9:58 gfredericks: I'd prefer \k just cause it's easier to type :)

9:58 I don't know what the downside would be there

9:58 unless you hate backslashes

10:00 Somelauw: in java I would probably use an enum for piece.

10:01 gfredericks: are you working on something public?

10:01 I had a couple ideas for chess programs at different points, so I'm just curious

10:05 Somelauw: For now, I am just practicing clojure myself a bit and a chess program seems like something interesting to try.

10:05 gfredericks: ah right

10:07 well keywords are definitely the common replacement for enums; by switching to a dynamicky style you lose compile-time checks. If you don't want to have to worry about typos like \F or whatever, you can def the pieces: (def black-queen \q), etc...

10:07 when you do it that way the compiler will catch most typos

10:08 small closed datatypes always feel weird to design code around :/ not sure why

10:11 Somelauw: Yeah, I often wonder if it is idiomatix, to make wrapperfunctions for the keywords.

10:11 Like should I use (:x pos) or (get-x pos)

10:11 Since the implementation of pos could always change.

10:12 gfredericks: I think for most people do (:x pos), but I am not familiar enough with the issue to defend it

10:12 Somelauw: maybe you want to make pos a list like [5 6]

10:12 gfredericks: I don't think they do it thoughtlessly or lazily

10:13 oh for chess coordinates? yeah I'd definitely do that

10:13 much cleaner destructuring

10:14 Somelauw: For manipulating a chess board, it might be easier to represent coordinates as [y x] if the board is a nested list.

10:15 Since the board just contains the rows.

10:15 gfredericks: yeah that's a tricky one. I'm always torn between nested lists and maps with pairs as keys

10:15 I guess nested vectors is best since you get the fast lookup

10:15 can always write helper functions when things get too verbose

10:16 I wonder if it's faster to update an 8x8 nested vector or a 64-length flat vector...

10:16 Somelauw: I think in clojure it is a good idea too write wrapper functions often instead of using keywords directly.

10:17 I think an 8*8 nested vector, since it has more data sharing.

10:17 gfredericks: I'd think that too but I think sometimes small data structures can be counterintuitive

10:18 &(->> 7 (repeat 8) (vec) (repeat 8) (vec) (iterate (fn [board] (update-in board [3 7] inc))) (drop 100000) (first) (count) (time))

10:18 lazybot: ⇒ "Elapsed time: 271.697144 msecs" 8

10:19 zmaril: How are the docs generated for clojure.org?

10:19 gfredericks: &(->> 7 (repeat 64) (vec) (iterate (fn [board] (update-in board [37] inc))) (drop 100000) (first) (count) (time))

10:19 lazybot: ⇒ "Elapsed time: 132.490219 msecs" 64

10:20 gfredericks: Somelauw: if that there ^ is any indication, flat vector is twice as fast

10:20 though that doesn't account for converting 2 coordinates to 1

10:23 zmaril: Nvm found autodoc

10:24 solussd: I have a bunch of model namespaces, each of which has a 'mime_type' constant (defined w/ def ^:const …). Have we settled on a naming convention for constants yet? e.g. *mime-type* MIME_TYPE, mime-type, etc… any strong opinions?

10:24 Somelauw: gredericks, all functions that manipulate the board should be abstracted as much as possible so it can easily be optimized later

10:25 gfredericks: sure

10:37 cofc: I'm writing a library with a java component and a nice clojure wrapper about the java piece. what's the best way to ship this? should i write a stand alone java library and then have the clojure wrapper require that library?

10:41 gfredericks: cofc: depends on who you're shipping to I guess

10:41 cofc: gfredericks: i want to put the clojure library up on clojars

10:42 gfredericks: hmmm; I'm not sure there's any disadvantage to keeping them together?

10:43 cofc: I can imagine the java library would be useful to people not using clojure

10:45 gfredericks: but the compound jar could be used for that too, right?

10:47 cofc: so you mean "keeping them together" as in putting the jar file in the clojure library?

10:47 Frozenlock: Is there any compojure/ring (or other webserver libraries) showing how to deal with secure session? (ie: not a plain text password)

10:47 -tutorial-

10:48 * Frozenlock forgets the most important word of the sentence. Why use words when you can growl?

10:51 gfredericks: cofc: are you compiling them separately? I was just thinking a single jar with your java class files and your clj source files would be useful from either side

10:53 Somelauw: In a directory src, I have 2 clojure files. From the first file, I want to use a function from the second file. Then I should do :(require [packagename.second :as s]), from the first file, right?

10:59 TimMc: yep

10:59 Somelauw: "In a directory src, I have 2 clojure files." <-- I hope there's at least one subfolder between src and those files.

10:59 Somelauw: TimMc: Yes, there is

11:01 TimMc: I get java.io.FileNotFoundException: Could not locate package/second__init.class or package/second.clj on classpath:

11:01 From emacs, doing c-c, c-k on first.clj

11:07 TimMc: Somelauw: By chance, do you have any dashes or underscores in your namespaces or path names?

11:22 Somelauw: TimMc: No, I haven't.

11:25 lynaghk`: Is there a way I can match upto something in core.logic? E.g., have [thing . ?x . another-thing . ?rest] bind ?x to whatever is between thing and another-thing in a seq?

11:25 Somelauw: I got it to work. It was something stupid.

11:33 Iceland_jack: Newb: seems like the clojure.contrib has been depricated and they suggest we use the respective repos instead? :)

11:33 I want to use `socket-server' but that doesn't seem to have a repo outside of `clojure.contrib'

11:38 gfredericks: what do folk use with erc to be able to easily see if someone mentioned them 4 hours ago while they weren't paying attention?

11:42 Iceland_jack: (oh sorry; `server_socket')

11:46 TimMc: Somelauw: Didn't save the second file?

12:15 rpt: Hi everyone, I cannot seem to be able to use anonymous functions declared using #() from within reduce. Why?

12:15 ,(reduce #((if (> (count %1) (count %2)) %1 %2)) [] #{[1 2 3] [4 5]})

12:15 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.NoClassDefFoundError: Could not initialize class clojure.lang.RT>

12:16 lynaghk`: rpt; you don't need that extra set of parens around the anonymous fn

12:17 rpt: lynaghk`: ah OK, thanks!

12:30 gtrak: is there a way to suppress a reflection warning?

12:34 I guess I can bind warn-on-reflection to false

12:37 TimMc: gtrak: Why was it true in the first place?

12:50 Scorchin: What's the best way to update the nth value in a lazy seq? E.g. I want to update the 3rd value in: (take 5 (repeat "player"))

12:59 qbg: Scorchin: Stuffing it into a vector and operating on that is easy

12:59 mk: qbg: that doesn't make it non-lazy?

12:59 Scorchin: qbg: yeah, that works for me, was just wondering if there was a simpler way

13:00 qbg: mk: Yeah, you're forcing the sequence

13:00 You could write a function that uses lazy-seq to provide what you want

13:00 (in a single traversal)

13:01 But that smells suspicious to me

13:01 As in you are trying to solve the wrong problem

13:03 (you could also build it using split-at instead of lazy-seq)

13:04 (but you'll be traversing the seq twice when you force it)

13:11 y3di: people actually chose clojure as the most disliked language?!?

13:11 how is that even possible

13:13 fliebel: y3di: Parentheses!!! Everywhere!

13:14 I also did (def v [1 2 3]) (sort v) (println v) and v wasn't even sorted... so clojure is broken.

13:14 mk: y3di: perhaps they're upset about some design decision, and want to express this by severely underrating the language

13:14 fliebel: I also filled a bug report about it, but everyone was not so nice to me. so the community also sucks.

13:16 Chousuke: y3di: maybe they're haskell elitists or something :P

13:16 fliebel: They told me it returns a sorted list, so I did (= v (sort v)) but it just told me 'false', this is like prolog.

13:16 xeqi: it doesn't even have reader macros

13:16 Chousuke: or that CL guy who thought Clojure spoils the ideal of lisp

13:17 mk: fliebel: well, that's a case where we should be nice, since in the end it's probably a person having their learning severely frustrated by weird expectations :)

13:18 tmciver: fliebel: ##(sort [3 2 1])

13:18 lazybot: ⇒ (1 2 3)

13:19 mk: most severe negative reactions to new things, I think, are the result of being frustrated with not understanding something

13:19 tmciver: fliebel: sort _returns_ a sorted collection; it doesn't mutate v.

13:19 fliebel: tmciver: I was joking

13:20 tmciver: fliebel: Ah. I knew that. :/

13:20 fliebel: I mistook you for a newb.

13:20 fliebel: tmciver: Trying to imagine looking at clojure through the eyes of an imperative person, voting for clojure in the worst language poll.

13:22 tmciver: fliebel: yes. It's too bad irc can't convey tone of voice and facial expressions. such much humor lost . . .

13:22 s/such/so

13:24 fliebel: tmciver: If only we had unicode keyboards, all our problems would go away, and I could just send you mocking characters.

13:24 or a snowman

13:25 mk: well, the easiest thing is to avoid sarcasm, and add a :) to things that might be taken harshly, but which you don't mean that way

13:26 Iceland_jack: mk: is that so :)

13:26 mk: Iceland_jack: is that :) sarcastic? :)

13:27 Iceland_jack: .. :)

13:27 fliebel: Best would be to end every sentence with a :) instead of a dot. Unless you're angry or donald duck, in which case you should end with a bang.

13:27 Iceland_jack: hah

13:30 Scorchin: Is there a simple way to print a vec (or lazy seq) as a grid? E.g. a 4x4 grid for (take 16 (repeat "name"))

13:31 Iceland_jack: partition?

13:31 clojurebot: partition is probably not what you want; see partition-all.

13:32 Iceland_jack: if I understand correctly

13:33 tmciver: ,(repeat 4 (repeat 4 "name"))

13:33 clojurebot: (("name" "name" "name" "name") ("name" "name" "name" "name") ("name" "name" "name" "name") ("name" "name" "name" "name"))

13:34 Scorchin: kind of

13:34 I just want to print it using println

13:35 I'm currently just using a loop, but want to know if there's something more clojure-ey

13:35 Iceland_jack: Scorchin: probably mapping through any of the above solutions?

13:35 Scorchin: Iceland_jack: thanks, I'll have a look

13:35 fliebel: Scorchin: http://clojure.github.com/clojure/clojure.pprint-api.html#clojure.pprint/print-table

13:37 How would I best run a Maven server? Just use Clojars, or is there something simpler/nicer?

13:38 tomoj: perhaps s3

13:39 xeqi: fliebel: you can just use a static file directory, or something like https://github.com/technomancy/s3-wagon-private

13:43 fliebel: xeqi: So how does Maven normally look for artifacts? Just HTTP repo/groupid/artefact/version.pom?

13:44 xeqi: something like that, I had to setup a local filesytem one at https://github.com/cemerick/pomegranate/tree/master/test-repo for testing

13:45 I would try to add the repo

13:45 and then deploy to it

13:45 it will make the files you need

13:47 fliebel: xeqi: So, you;re saying I could just upload my ~/.m2 folder to a webserver, and that's it?

13:48 I can't believe it's that simple. It's Java, there should be SOAP and XML.

13:49 xeqi: I think doing a deploy also adds a metadata.xml I don't see in my ~/.m2 files, and I also see an _maven.repositories in ~/.m2 I don't see in a repo

13:50 it wouldn't take much to try it

13:51 fliebel: xeqi: Thanks, I'll try some stuff.

13:51 hm, dropbox?

14:00 technomancy: just use s3

14:09 mk527: hello

14:10 tmciver: mk527: hi. Go ahead and ask your question.

14:12 mk527: tmciver: i don't have a question - i just wanted to say hi :-)

14:12 for good will

14:14 also, i think overtone is very cool

14:16 dnolen: mk527: it is!

14:16 mk527: :-)

14:25 y3di: hahaha fliebel, I just read your messages xD

14:31 fliebel: dnolen: Is the stripboard thing still something you're thinking about, or is it past your attention span already?

14:31 I finished the board, so it went a few notches down my own priority list.

14:31 dnolen: fliebel: it's not past I just don't have bandwidth for it at the moment :( I actually don't think it would be very hard.

14:32 fliebel: I'm working on getting core.logic ported over to CLJS for JSConf

14:32 fliebel: dnolen: Nice :)

14:32 qbg: dnolen: Super nice

14:33 dnolen: it's already partly working

14:33 ibdknox: stripboard?

14:33 dnolen: using GClosure for CLJS now seems like genious, even with all the insane amounts of code generation from core.logic, GClosure just shrinks it to a tiny size.

14:33 fliebel: dnolen: what kind of thins do you need to change?

14:34 qbg: dnolen: How small are we talking about?

14:34 dnolen: fliebel: biggest change was switching back to lists for the substitution map.

14:34 fliebel: dnolen: I mean, core.logic is not really tied to java, as a Scheme-inspired lib.

14:34 dnolen: Because CLJS maps are not persistent?

14:34 dnolen: qbg: even if core.logic is present (for example randomly including zebrao), you still talking < 30k, and GClosure compression keeps improving.

14:35 eggsby: woah dnolen

14:35 dnolen: < 30k minified + gzipped to be clear

14:35 eggsby: yeah.

14:35 qbg: Not bad at all...

14:35 eggsby: You have something I can follow for the progress on that dnolen ?

14:35 fliebel: ibdknox: I'm trying to generate stripboard layouts automatically. It's a type of prototype board for electronics

14:36 dnolen: eggsby: there's a core.logic clojurescript branch

14:36 ibdknox: fliebel: ah cool

14:36 eggsby: That sounds really cool, logic based programming in the browser would be nuts

14:36 dnolen: eggsby: yes, and it will only get better as JS engines get faster - also sounds like there talk of task level parallelism in the browser - that would be a huge win I think for logic programming.

14:37 wink: yay, many hours of fighting pprint finally paid off

14:37 dnolen: fliebel: yes because CLJS maps are not persistent

14:37 devn: dnolen: i am going to go ahead and assume you've toyed with clojure-scheme

14:38 dnolen: fliebel: even so I'm not sure that Clojure's Java implementations will be best persistent datastructures for the browser.

14:38 devn: how do i get it to pop out a .scm from a .clj file?

14:38 dnolen: fliebel: perhaps Skew Binary Random Access Lists are the best for CLJS core.logic

14:38 devn: haven't messed w/ it.

14:39 * qbg needs to do some CLJS

14:41 dnolen: fliebel: I may even up going full on Scheme-y with the CLJS core.logic implementation, protocol fns are *plenty* fast for many things but you're still paying near 2X overhead over a regular function.

14:42 fliebel: dnolen: Hm, interesting. How is that in Clojure? I guess protocols and functions are both classes anyway, in the end.

14:43 dnolen: fliebel: protocols are backed by interfaces, so on the JVM performance is just incredible.

14:43 fliebel: CLJS protocols fns would be pretty quick, but there extra dispatch logic for primitive JS type extension cases as well as default case.

14:44 lynaghk: dnolen: I just started this morning trying to grok some core.logic, but I'm stuck on a problem---is there a clean way to match part of a list in matche?

14:44 e.g. have (1 . ?x . 4 5) match (2 3) in (1 2 3 4 5)

14:47 dnolen: lynaghk: no there's no way to do that. but you can get clever with fresh vars.

14:48 lynaghk: (fresh [x] (matche [l x] ([[_ _ a b . _] [a b]] ...)))

14:48 x will be unified with (2 3)

14:49 lynaghk: dnole: hmm, I'll play around with that approach. Thanks.

14:51 chouser: probably better than getting fresh with clever vars

14:53 dnolen: chouser: haha

14:53 chouser: sorry, I'm afraid that's the extent of my ability to contribute to logic conversations. bad puns.

14:54 mk: apply can be thought of as essentially removing brackets, yes? so (apply str ["a" "b"]) simply unwraps the args, to make (str "a" "b") - and it does nothing else

14:54 dnolen: chouser: bad puns always welcome

14:54 mk: is that the right way to think of it?

14:54 qbg: mk: pretty much

14:55 gfredericks: dnolen: I'm not sure what was going on earlier but I sure am glad you alerted me to the existence of skew binary numbers.

14:55 qbg: (apply str "a" ["b" "c"]) is also equivalent to (str "a" "b" "c"), if you care about the other arities

14:57 mk: so apply is for smoothly inserting a list into args*

14:59 lynaghk: dnolen: what if I don't know how many items come before the one I need? Do I need to filter the list in Clojure first? (to turn (crap crap crap crap thing a b c crap crap crap) into (thing a b c crap crap crap))

15:00 Somelauw: TimMc: nope, in my source file, I actually did com.package. But I didn't have a com folder.

15:00 dnolen: lynaghk: did you look at that simple rule parser on kibit #20?

15:01 mk: so apply works well with (assoc map key val key val ...), since you have a way to unwrap a sequence of key vals into the correct place

15:01 * lynaghk goes looking

15:01 devn: man i was out of date with clojurescript

15:01 TimMc: Somelauw: Ah, yep.

15:01 * devn `export GYP_GENERATORS=make`

15:02 fliebel: There is one sequence function I miss in Clojure. It's Pythons zip.

15:03 mk: was there an interesting reason why assoc didn't take a sequence for its last arg instead, e.g. (assoc [1 2] [0 3]) -> (3 2)

15:03 qbg: fliebel: Use map

15:04 fliebel: qbg: yea, (map vector) works, I guess... still...

15:04 gfredericks: mk: wouldn't there always be two of them then?

15:04 weavejester: mk: That seems the job of apply, e.g. (apply assoc [1 2] [0 3])

15:04 qbg: mk: That is not the usual use case for assoc

15:05 mk: weavejester: yeah, exactly - but if it took a seq, it wouldn't need apply

15:05 lynaghk: dnolen: that code is a bit above my head right now. I'm going to sit down with the REPL for a few hours and make some sense of it. Thanks for the pointer

15:05 mk: gfredericks: two of the arguments?

15:06 dnolen: mk: except ... how many other fns might usefully take a seq as last arg?

15:06 mk: a lot

15:06 thus apply

15:06 gfredericks: mk: yeah, when you're doing (assoc m some-pair), the second argument there is always going to be a pair, isn't it?

15:07 dnolen: lynaghk: yes it's a bit tricky. but it's basically a parser, it consumes a sequence, it does different things depending on the presence of :when, :alt which is what you want.

15:08 mk: dnolen: I like apply, it just seems that if the last arg* frequently takes many arguments, maybe it should take a single seq instead

15:08 dnolen: lynaghk: it wasn't until I read a short tutorial on Definite Clause Grammars in Prolog that a lot of lights when off for me.

15:08 lynaghk: dnolen: that's from the destructuring in the multiple bodies of defne?

15:09 mk: gfredericks: yes, it is - well, it's an even-sized listing of pairs

15:09 gfredericks: mk: haha I forgot assoc can take multiple pairs

15:09 nevermind what I was saying then

15:09 lynaghk: dnolen: link?

15:10 gfredericks: &(merge [3 4 5] [7 8 9 28])

15:10 lazybot: ⇒ [3 4 5 [7 8 9 28]]

15:10 gfredericks: wth

15:11 devn: dnolen: you on OSX? Are you building with GYP? native, ia32?

15:11 mk: &(concat [3 4 5] [7 8 9 28]) ;?

15:11 lazybot: ⇒ (3 4 5 7 8 9 28)

15:11 devn: (for clojurescript i mean)

15:11 ibdknox: ,(doc merge)

15:11 clojurebot: "([& maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping from the latter (left-to-right) will be the mapping in the result."

15:12 gfredericks: I expected it most it would treat the vectors as associative things

15:12 _andrew_k_: &(merge {:a 1 :b 2} {:b 3 :c 4})

15:12 lazybot: ⇒ {:c 4, :a 1, :b 3}

15:13 devn: gfredericks: so you expected? [[3 7] [4 8] [5 9] 28] or something?

15:13 _andrew_k_: &(merge #{1 2 3 4} #{3 4 5 6})

15:13 lazybot: ⇒ #{1 2 3 4 #{3 4 5 6}}

15:13 dnolen: devn: make native I think

15:13 Scorchin: If I have a list of lists, which looks like this: (partition 4 (take 16 (repeat "grass"))) how can I print each line using System.out.println instead of println (I want to test against the Writer)

15:13 dnolen: lynaghk: damn, my favorite tutorial on them no longer exists on the web

15:13 devn: dnolen: thanks

15:13 lynaghk: dnolen: nnoooooooooo

15:13 mk: devn: I would have expected [7 8 9 28], because the right indicies totally overwrite the left ones

15:14 gfredericks: devn: no, [7 8 9 28]

15:15 michaelr525: hey

15:15 devn: hm

15:15 ,(merge [] 1 2 3)

15:15 clojurebot: [1 2 3]

15:15 gfredericks: I guess merging two vectors isn't really a useful thing

15:16 mk: looks like a job for apply!

15:16 devn: ,(into [] [1 2])

15:16 gfredericks: it'd be pretty trivial most of the time

15:16 clojurebot: [1 2]

15:16 devn: mk: lol yes i was just thinking the same

15:16 dnolen: lynaghk: http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlch7

15:16 devn: round and round we go

15:16 dnolen: lynaghk: I recommend that you try that out with SWI-Prolog

15:17 lynaghk: rad, thanks dnolen. Though that domain sounds kind of like a scam...

15:17 devn: mylearnprologgifts.info

15:17 dnolen: lynaghk: it's a good legit resource actually

15:17 lynaghk: if you get through that and spend a little bit of time figuring out how to translate that into core.logic a LOT of things will make sense.

15:18 devn: mydiamondexecutiveprologtutorial.info

15:18 dnolen: lynaghk: and honestly when I'm stumped about how to do something in core.logic, now I just read up an example in Prolog.

15:18 TimMc: reallearnprolog.biz

15:19 lynaghk: dnolen: it's a rare sunny day in PDX, so I might print this bad boy out and go find a hammock. Thanks for the pointer.

15:20 dnolen: lynaghk: no problem, let me know if you've got more questions later.

15:20 lynaghk: dnolen: I definitely will, thanks

15:24 Scorchin: Does anyone know how to catch the output from (println ..) so that a unit test can be written for it?

15:25 qbg: &(doc with-out-str)

15:25 lazybot: ⇒ "Macro ([& body]); Evaluates exprs in a context in which *out* is bound to a fresh StringWriter. Returns the string created by any nested printing calls."

15:25 mk: Scorchin: not sure what the best way is, but it prints to *out*, I think - so change that?

15:27 huh... you can just throw entire lumps of code into with-out-str, and it just... works

15:27 dnolen: mk: dynamic binding FTW.

15:27 mk: I am blown away

15:28 gfredericks: clojure: just throw your entire lumps of code

15:28 michaelr525: anyone wrote already an ecommerce package in clojure?

15:28 Somelauw: It doesn't always work

15:28 ,(with-out-str (.println System/out "hello world"))

15:29 clojurebot: ""

15:29 qbg: That is because System.out.println doesn't write to *out*

15:29 mk: Somelauw: that's expected though, and correct

15:29 Somelauw: only clojure functions that use *out* in their code.

15:30 qbg: http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#setOut%28java.io.PrintStream%29

15:30 IO and state are poison; avoid them in testable code

15:31 Scorchin: mk, qbg: thank you! with-out-str works perfectly if you evaluate it within a let and then do any comparisons tests against the bound variable

15:37 mk: what's the version of cons where the args are flipped? (= (cons 1 (2 3)) , (??? () 3 2 1))

15:37 gfredericks: conj?

15:37 clojurebot: (conj {:a 1} (when true {:b 2}))

15:38 gfredericks: clojurebot: wth

15:38 clojurebot: No entiendo

15:38 mk: conj does different things for lists vs. vectors

15:38 gfredericks: then I'm not sure if the thing you're asking for exists

15:39 (defn mk's-cons [a b] (cons b a))

15:39 I can't imagine why a function would exist in two trivially different forms

15:40 mk: I guess it's just an apply-friendly form, to mirror e.g. assoc

15:41 I was thinking of something that took multiple rightmost arguments, rather than a right sequence

15:42 gfredericks: and you can't use conj because you want to use vectors?

15:42 rahcola: ,(concat '(1 2 3) '(4 5 6))

15:42 clojurebot: (1 2 3 4 5 ...)

15:43 rahcola: works for both lists and vectors

15:43 mk: gfredericks: yeah, something like that. conj is an "I don't care where, just do it efficiently" function

15:44 gfredericks: mk: I just figured if you're trying to use cons you probably have a list/seq already so there wouldn't be a difference

15:45 gtrak: how do I find what's creating java.lang.reflect.Method instances from a heap dump?

15:45 mk: rahcola: though to add a single element you'd need to use (concat '(2 3 4) '(1)), which is why assoc prefers args* as the rightmost...

15:46 gfredericks: yeah probably. I might be looking for symmetry where I don't need to

15:46 gtrak: I guess I could add a debugger to the constructor

15:53 gfredericks: mk: I think conj only means "I don't care where" when you also don't care what kind of data structure you're passing in

15:53 so if you know what kind of structure you're dealing with it's reasonable to expect particular behavior from conj

15:55 mk: gfredericks: yes, right. I think what I meant was, if you're looking at lists and vectors as the same things but with different performance, conj throws that off (unless you also don't care about where)

15:59 Frozenlo`: Is there a Clojure library for encrypting files?

16:03 yoklov: anybody have experience making an applet with clojure?

16:03 i've made one which appears to work in firefox and not chrome.

16:04 gives a classnotfound exception in chrome.

16:04 mk: yoklov: which class?

16:04 yoklov: the class which is the subclass of the applet (subclass via :gen-class)

16:05 mk: you might check with #java about chrome not loading a class file, or jar, or what have you

16:06 yoklov: alright, thanks

16:06 mk: don't tell them that it's generated by clojure until they ask to prevent being sent here :)

16:08 yoklov: right, haha

16:10 mk: what's the difference between rest and next?

16:11 yoklov: ,(next nil)

16:11 err

16:11 clojurebot: nil

16:11 yoklov: ,(rest nil)

16:11 clojurebot: ()

16:11 yoklov: i think that's it

16:12 devn: anyone here use clojure-scheme?

16:12 i cannot figure out how it wants me to compile to scm

16:12 mk: yoklov: hmm, I see - thanks

16:13 yoklov: lol, apparently #java refuses to answer questions about applets because of differences in browser compatibility

16:15 replaca_: ,(rest '(a b))

16:15 clojurebot: (b)

16:15 replaca_: ,(rest (rest '(a b)))

16:15 clojurebot: ()

16:16 replaca_: ,(next (next '(a b)))

16:16 clojurebot: nil

16:16 mk: yoklov: heh, I see that "no applets" is up in the channel description over there. sorry :)

16:16 replaca_: mk: more to the point...

16:16 ,(if (next '(a)) true false)

16:16 clojurebot: false

16:16 yoklov: yeah, its no problem, it does seem to be a java-related issue as opposed to a clojure one

16:17 replaca_: as you would expect

16:17 ,(if (rest '(a)) true false)

16:17 clojurebot: true

16:17 replaca_: but that's where you need to be careful!

16:17 mk: yes, it seems that next returns nil whenever it makes no sense (nil, (), (1)), while rest always returns () in those cases

16:17 oakwise: what's the cleanest way to use a SNAPSHOT of a non-lein project like core.logic in my own project?

16:18 replaca_: rest is a little bit faster when you're just working through lists and don't care

16:18 ,(seq (rest (rest '(a b))))

16:18 clojurebot: nil

16:18 replaca_: (next x) == (seq (rest x))

16:18 mk: devn: I know nothing, but where are you having the problem? Is the compile giving you errors, or?

16:19 dnolen: oakwise: you should be able to build and install the jar with maven.

16:20 devn: mk: i just cant use cljsc

16:20 mk: well, i mean, i cant use script/repljs either

16:20 but i suppose it is "repljs"

16:20 im not sure how he is loading it up and compiling

16:23 oakwise: dnolen: ah thanks! looks like `mvn install` did the trick

16:25 _andrew_k_: $(rest '(1 2 3 4 5))

16:26 ,(rest '(1 2 3 4 5))

16:26 clojurebot: (2 3 4 5)

16:26 _andrew_k_: ,(next '(1 2 3 4 5))

16:26 clojurebot: (2 3 4 5)

16:26 devn: ,(next '())

16:26 clojurebot: nil

16:26 devn: (rest '())

16:26 ,(rest '())

16:27 clojurebot: ()

16:27 devn: read the Joy of Clojure chapter on laziness

16:29 mk: are fnext and second at all different?

16:29 devn: no

16:29 they are both equivalent to (first (next))

16:29 but i believe fnext is a bit more idiomatic when cooking a lazy-seq

16:30 oakwise: dnolen: does membero not work with sets by design?

16:30 dnolen: mk: careful, some of the early fns in core.clj exist purely for boostrapping reasons.

16:31 mk: dnolen: deprecated?

16:31 dnolen: mk: no conveniences to bootstrap the language.

16:31 mk: note how far down destructuring appears.

16:32 devn: yeah, it's like: "ah, here we go, syntax quote"

16:32 dnolen: oakwise: if you think about sets a little bit, you can see why they cause problems for unifications

16:32 unification I mean

16:33 oakwise: if you want to use membero on a set, just call seq on the set first.

16:34 oakwise: core.logic is very list oriented as that's a sensible datastructure for relational programming.

16:35 mk: dnolen: I'm going through the reference at the moment, and am frowning at ffirst nfirst fnext nnext. Are you saying those are there for the language, not for me?

16:35 dnolen: mk: yes

16:35 mk: can't they be hidden

16:35 oakwise: thanks! I'll have to dig more to understand that properly

16:36 dnolen: oakwise: think about sets containing only logic vars.

16:37 devn: mk: why frown at them?

16:40 mk: I don't think it's right to have mere shortcut names for compound expressions (or language structures in general). Instead, "chunked" names should be used - like second

16:41 emezeske: dnolen: hey, regarding that weird cljs bug you ran into yesterday, did you end up opening a jira case?

16:41 dnolen: emezeske: I did I'm reading closure.clj a second time right now.

16:42 mk: I type less characters with fnext, but now I have to remember that fnext exists, and whether first or next is applied first

16:42 emezeske: dnolen: could you link it? I want to reference it in the lein-cljsbuild case that I think is related

16:42 devn: mk: right to left

16:43 dnolen: mk: second is preferred. fnext is probably there for backwards compatibility reasons.

16:43 mk: devn: in fnext, next is applied first, then first

16:43 devn: that's what im saying, read the fn name right to left

16:44 next, first

16:44 mk: dnolen: so I guess effectively deprecated

16:44 devn: dnolen: dont you tend to see fnext etc used more often in the construction of lazy-seqs?

16:44 mk: devn: ...err, weird. I think I thought right meant left because it was on the left hand side. Oops.

16:46 dnolen: emezeske: link to github issue?

16:47 devn: I've never used fnext, but that doesn't mean much :)

16:47 emezeske: dnolen: nevermind, I found the jira case

16:47 devn: dnolen: sure it does, you write more code than i do, im just going off my gut on this

16:47 emezeske: dnolen: just wanted to make sure the github issue cross referenced it.

16:49 oakwise: dnolen: is the issue that it blows up the solution space?

16:52 mk: nth has O(n) performance? Isn't just about everything a trie?

16:53 dnolen: oakwise: you can look unification for sets to see some issues. but there's really no real issue, membero only works on lists, because lists support relational programming.

16:53 Chousuke: mk: nth is a seq function

16:53 dnolen: mk: it depends on the data structure - lists are linked lists

16:53 Chousuke: that's not true

16:54 oakwise: dnolen: roger, thanks

16:54 mk: which structures are the log32 tries that I've heard about?

16:54 Chousuke: oh, right, vectors

16:56 dnolen: mk: sets, maps, vectors

16:56 Twey: log32?

16:56 mk: Twey: O(log32 n)

16:57 devn: (fast enough for dubstep)

16:57 mk: the only difference between drop and nthnext is the argument reversal, and drop being lazy?

17:00 dnolen: You don't see nthnext or nthrest much I don't think - they're there to support destructuring.

17:01 mk: oops I guess nthrest is use mostly for partition implementation

17:04 Twey: mk: O(log 32n)? O(log₃₂ n)?

17:05 Hm… either way, it's a constant factor

17:06 yoklov: err, wait. so is nth linear on vectors?

17:06 Somelauw: Then why not drop next and just keep rest in the language?

17:06 dnolen: yoklov: no

17:06 mk: Twey: the right one I believe. The slogan is "log32 is fast enough"

17:06 yoklov: okay good.

17:06 devn: O(log32 n)

17:06 Twey: Haha.

17:07 gfredericks: log33: never settle for anything less

17:07 mk: Somelauw: next returns nil when invalid, while rest returns ()

17:07 yoklov: that is sort of a silly reason to have both as part of the language, though.

17:07 Twey: Why are nil and () not the same thing?

17:07 devn: no, it's really not

17:08 dnolen: Somelauw: I believe next forces? and rest does not, both have valid if subtle use cases

17:08 Twey: Why not?

17:08 mk: Twey: they are different types. This might be confusing because nil (and null) are treated as multityped

17:08 yoklov: oh, forcing vs not forcing is a big enough difference

17:08 devn: ,(-> (iterate #(do (print \.) (inc %)) 1) rest rest rest)

17:09 mk: Twey: 0 is not the same as "", or even 0.0

17:09 dnolen: Twey: you'd have 3 false-y values for one instead of just 2.

17:09 Somelauw: mk:

17:09 devn: &(-> (iterate #(do (print \.) (inc %)) 1) rest rest rest)

17:09 clojurebot: ..

17:09 (..4 .5 .6 .7 .8 ....)

17:09 lazybot: Execution Timed Out!

17:09 Twey: Traditionally nil is a name for '() in Lisps

17:09 Chousuke: Twey: besides nil being java null, I think the idea is that nil represents nothing and () is not nothing

17:09 Twey: As false is a name for 0 in C

17:09 devn: &(-> (iterate #(do (print \.) (inc %)) 1) next next next)

17:10 Twey: Ah, I see

17:10 lazybot: Execution Timed Out!

17:10 Twey: It's to map onto Java's null, I guess

17:10 dnolen: in *some* Lisps - Clojure breaks with some Lisp traditions

17:10 devn: bah, just read Joy of Clojure chapter 5

17:10 Chousuke: Twey: and clojure has more than one data structure, so it would be weird to have nil be (), but then have empty vectors, sets and maps

17:10 devn: err chapter 6

17:11 Twey: Chousuke: *nod* True

17:11 devn: from the Joy of Clojure "We recommend you use next unless you're specifically trying to write code to be as lazy as possible"

17:11 mk: Twey: roughly, but it's also to do something like handle mathematical "undefined"

17:11 dnolen: devn: on the ML rhickey said next/rest style are equally valid.

17:12 goodieboy: anyone care to give some feedback on this defrecord+ macro I created? https://gist.github.com/2187881

17:12 Chousuke: with next you can do (if (next something) ...) though

17:12 devn: later on: "As we mentioned in our rules of thumb, when consuming a sequence within the body of a lazy-seq you'll want to use rest"

17:12 dnolen: fair enough

17:13 goodieboy: there's an implementation at the bottom of the gist btw

17:14 dnolen: goodieboy: nice, tho I generally find myself just making custom ctor fns and dealing with pre/post and other niceties there.

17:16 goodieboy: dnolen: ahh yeah, that's probably a simpler/cleaner approach. I guess in the end that's all this thing is really doing anyway :)

17:17 augustl: what do I use to turn [1 2 3] and [4 5 6] into [1 2 3 4 5 6]?

17:17 mk: augustl: concat

17:17 dnolen: well into if you want preserve the type

17:17 augustl: mk: doh :) Thanks

17:17 obvious name is obvious

17:17 dnolen: ,(into [1 2 3] [4 5 6])

17:17 devn: slow internets today

17:18 mk: augustl: though that might not be what you mean, since it returns a seq (1 2 ...)

17:18 clojurebot: [1 2 3 4 5 ...]

17:18 devn: clojurebot: i think you're broken, friend

17:19 TimMc: clojurebot: seq (1 2 ...)?

17:19 devn: i think he's timing out on simple operations

17:19 TimMc: Oh, I see dnolen's eval.

17:20 devn: ,(conj [1 2 3] 4 5 6)

17:20 TimMc: &"ping"

17:20 lazybot: ⇒ "ping"

17:20 TimMc: \o/

17:21 devn: &(+ 1 1)

17:21 lazybot: ⇒ 2

17:21 devn: ,(time (+ 1 1))

17:23 mk: ,(into '(1 2 3) '(4 5 6))

17:23 clojurebot: (6 5 4 1 2 ...)

17:23 augustl: ah, yeah I just noticed it returned a seq

17:23 thanks again :)

17:23 yoklov: anybody interested in playing a game i wrote in clojure?

17:23 http://thomcc.github.com/dunjeon/

17:23 it is tiny and extremely nerdy haha

17:23 clojurebot: Cool story bro.

17:23 It's greek to me.

17:23 [1 2 3 4 5 ...]

17:23 "Elapsed time: 0.089 msecs"

17:23 2

17:23 devn: yoklov: im in

17:23 nethack clone!

17:23 yoklov: haha yes

17:25 devn: "The booze heals you for 13 points."

17:25 dnolen: yoklov: rad, lovely how concise that code is :)

17:25 devn: yoklov: is there a merchant yet? :)

17:25 yoklov: haha thanks! it was interesting writing something like that without loads and loads of state

17:26 devn: hah, nope. there's not even an inventory, though there was for a little bit.

17:26 interesting as in extremely fun

17:26 devn: yoklov: yeah im interested to check this out

17:27 dnolen: yoklov: would be nice to see that ported to ClojureScript

17:27 yoklov: yeah, that's actually my plan

17:27 dnolen: :D

17:27 devn: nice project idea

17:28 mk: yoklov: doesn't seem to work on my chrome...

17:28 I suspect you might be aware of this ;)

17:29 yoklov: applying for a cljs thing for GSOC, so i figure i should do something in clojurescript, but i had already started writing that, and wanted to mostly finish it before starting that

17:29 mk: it didnt work for me in chrome locally, but it did remotely :/

17:29 drostie: So, uh... is clojure supposed to be missing bignums and a (pow) function, or am I missing something big?

17:29 yoklov: i have no idea

17:29 dnolen: mk: weird it worked in Chrome for me, you do need to enable Java applets.

17:29 drostie: <-- (first time user)

17:29 or is dejour messed up?

17:29 yoklov: drostie, you can use +' *' -' etc for arbitrary precision arithmetic

17:30 you can use Math/pow for power too

17:30 drostie: thanks. Why isn't graceful rollover to bignums default?

17:30 dnolen: drostie: alos you probably want the contrib

17:31 mk: it's giving me an "unresponsive" message. I'll try the jar

17:31 dnolen: drostie: for host performance reasons

17:31 drostie: sorry I meant this contrib link, http://github.com/clojure/math.numeric-tower

17:32 mk: ...can someone link the jar?

17:32 yoklov: mk: for what?

17:33 that game i posted? there's a link on the page to a jar which uses a jframe

17:33 mk: standalone version - but I found it

17:33 the page was no longer loading properly

17:33 drostie: dnolen: thanks. I tried some other "contrib" advice but it didn't work in dejour with clojure-contrib and I was confused. ;_;

17:34 dnolen: and I'm surprised that host performance is that bad with something that only needs to happen when exceptions are thrown, but okies. ^_^;;

17:35 dnolen: performance wasn't bad w/ the old behavior, but it wasn't good enough to be able write core Clojure datastructures in the language itself.

17:36 drostie: ah, okay.

17:36 rpt: quick newbie question: what is wrong with this: (defn par2 [n s] (filter #(= n (count %1)) (lazy-seq (cons (take n s) (par2 n (drop n s))))))

17:36 (works without the 'filter' part - it is a reimplementation of partition_

17:36 _

17:37 but with the filter, it causes a stack overflow

17:38 drostie: rpt: can you do the same with (loop ... (recur)) somehow? that seems to be the obvious way to avoid stack overflows.

17:39 AimHere: Well when you do it without the filter, it is an infinite length list of lists, mostly empty

17:39 drostie: You don't really have tail-recursion there, but I'm not quite sure what you're doing.

17:39 AimHere: So presumably adding the filter is unlazying the lazy sequence

17:39 rpt: AimHere: ah well... any way I can make the list of finite length or does laziness preclude that?

17:41 mk: yoklov: how can I start the applet from the game's core.clj ?

17:41 yoklov: lein run

17:41 or

17:41 clone the repo and do lein run

17:41 mk: assuming I've got a repl open?

17:41 yoklov: (-main)

17:42 AimHere: rpt > howabout using 'take-while' rather than 'filter'

17:42 mk: unable to resolve (...I was lazy, and pasted all the code into my current repl...)

17:42 rpt: AimHere: ah yes, good idea

17:43 AimHere: thanks, works like a charm!

17:44 yoklov: hm, what couldn't it resolve?

17:44 AimHere: What's happening, is presumably filter is still riffling through all those infinite empty lists, because it doesn't know that it's not going to ever find one that isn't empty

17:45 yoklov: mk: paste this one in: https://github.com/thomcc/dunjeon/blob/master/src/dunjeon/core.clj

17:45 AimHere: Actually, if you could write a smart-filter that found that out, you'd have a real-world use for something that solved the halting problem ;)

17:45 yoklov: that is the jframe one

17:46 (and then run (-main))

17:48 mk: yoklov: Unable to resolve symbol: -main, and before that a reflectionwarning NO_SOURCE_PATH:247 - call to drawString (you can probably ignore all this, I'll now paste what you linked)

17:50 drostie: AimHere: but you don't need to solve the halting problem as far as I can tell: rpt just didn't include a base-case in their recursion.

17:50 mk: yoklov: works. That's a lot of game for not that much code...

17:50 yoklov: mk: well, we're using a powerful language :)

17:51 drostie: AimHere: maybe that's not possible due to the laziness, though?

17:52 AimHere: drostie > There is a solution there though. take-while

17:53 dnolen: emezeske: turns out there is no bug

17:53 AimHere: There's a base-case implicit in there, but it still just looks like a bunch of filters n'stuff acting on a sequence

17:54 emezeske: dnolen: That is very curious... What's the deal?

17:54 dnolen: emezeske: my source-path was not precise enough.

17:54 drostie: fair enough. I'm new to the language too and should probably shut up in general. ^_^

17:55 emezeske: dnolen: Hoo, boy.. Any idea what lein-cljsbuild could do to save you from that horror?

17:55 dnolen: That is such a bad outcome for such a simple mistake

17:55 dnolen: emezeske: source-path lets you specify any directory and it will find all cljs files even if you don't set the path up so that it matches the namespaces.

17:55 emezeske: it's not clear to me how that can be avoided, classpath mistakes are common even in Clojure sadly.

17:55 emezeske: dnolen: Oh! I have seen that before.

17:56 dnolen: Well, what if something inspected those files and yelled at the user if the ns names did not align with subdir names?

17:56 dnolen: emezeske: so I can build my project, but I couldn't build my tests properly.

17:57 emezeske: that would be nice, but really I just think this just needs some documentation - like a lein cljsbuild trouble shooting page.

17:57 emezeske: I'm happy to add a entry for the creating a tests build case.

17:57 emezeske: dnolen: That would be a great start. I'll create one on the wiki!

17:57 devn: what's the swing lib everyone have been talking about lately?

17:58 cameroon or something?

17:58 * devn tries to remember

17:58 devn: duh, seesaw

17:59 emezeske: dnolen: https://github.com/emezeske/lein-cljsbuild/wiki/Troubleshooting-Build-Issues

18:11 dnolen: emezeske: done, https://github.com/emezeske/lein-cljsbuild/wiki/Troubleshooting-build-issues

18:12 emezeske: dnolen: excellent, thanks man!

18:14 dnolen: emezeske: thank you for lein-cljsbuild! it rocks!

18:33 emezeske: dnolen: glad to hear it.

18:54 bytechunky: hey guys, i am pretty sure there is a method to do (if a a b) prettier, but which one is it?

18:54 i.e. (take-first-non-nil-value a b)

18:55 mk: aka || in some languages

18:56 bytechunky: mk: here we go... thank you :D

18:57 TimMc: bytechunky: "or"

18:57 mk: was that actually it?

18:57 bytechunky: mk: (or a b) <-- yea, works as it should

18:57 mk: ,(or nil nil false 1 2 3)

18:57 TimMc: bytechunky: And it can take any number of arguments.

18:57 clojurebot: 1

18:58 mk: good stuff

18:58 bytechunky: TimMc: yes, i know. that's nice.

18:58 mk: here I am doing ctrl-f on "if" against my own advice

19:00 bytechunky: sometimes i dont see thru little brain teasers like this, so... thanks for the poke

19:03 yoklov: just to make sure, clojurescript has all of the awesome clojure data structures, right?

19:03 i don't have to worry about my vectors being arrays or anything like that?

19:04 emezeske: yoklov: Yeah, it has the clojure data structures (although they are implemented differently, I don't think they're persistent)

19:04 yoklov: But for all intents and purposes they look just the same

19:04 yoklov: oh hm

19:04 dnolen: yoklov: ClojureScript has immutable data structures, but they are copy-on-write

19:04 yoklov: yeah, but if i'm porting code, that's an issue

19:04 i see

19:05 dnolen: yoklov: the interface is the same, but perf implications

19:05 yoklov: yup, that makes sense

19:05 dnolen: yoklov: tickets in JIRA to make them persistent, I've actually seen 2 for PersistentVector

19:05 yoklov: so I don't think it will take long.

19:05 yoklov: I mean I've seen to 2 pure CLJS PersistentVector implementations

19:06 yoklov: dnolen: yeah, i remember seeing someone on here talking about a cljs persistent vector being quite fast

19:06 but still, good to know

19:06 dnolen: yoklov: heh, actually the hand written JS one I did was suprisingly fast - definitely good enough for many applications.

19:07 yoklov: the one that Lazlo is submitting looks like good and should perform well.

19:08 mk: yoklov: unsure, I think I heard someone mention mutability, but I don't know at all. Test it out?

19:08 yoklov: hm, interesting

19:09 mk: i think the consensus was that they're immutable, that was sort of my question

19:10 mk: yoklov: yep (I think my message was delayed)

19:47 what does seque do?

19:49 yoklov: no clue, but http://clojuredocs.org/clojure_core/clojure.core/seque might be a place to start

19:50 mk: yoklov: had a look, confused me. Seems something like java's blockingqueue...

19:53 yoklov: yeah i don't know i don't "get" a lot of the stuff involving concurrency in clojure. i think that the fact that that program uses thread.sleep only to demonstrate how the evaluation of seque takes place

19:53 chouser: seque allows a seq producer to get ahead of a seq consumer

19:54 mk: what is a seq producer?

19:54 amalloy: well, lemme just ^H^H my much-less-clear description of seque

19:55 chouser: heh, mine was short and I still screwed it up

19:55 amalloy: seque calculates a lazy seq's elements on background threads, before they are actually requested

19:56 yoklov: oh, that's awesome

19:56 chouser: seque will force a lazy seq up to n steps ahead of anything that is realizing the seque

19:56 or what amalloy said.

19:56 bbl

19:56 mk: thanks, that makes sense

19:59 are promise/deliver used much?

20:00 matt444: What am I doing wrong here? I want to grab the value from an HTMLElement object. Since it's a map, I thought I could use (get)

20:00 http://pastebin.com/N2FwQEgd

20:01 AimHere: mk promise/deliver are part of the implementation of lazy sequences, so they might be used indirectly a lot more than they are explicitly

20:01 dnolen: matt444: get wont work, get is only for CLJS maps

20:01 AimHere: mk> Unless I'm confused and thinking about something else with a similar name ;)

20:01 dnolen: matt444: you probably want aget

20:02 mk: AimHere: I'll believe you :)

20:02 AimHere: mk> I'm just half-remembering bits and pieces from SICP so take it how you like

20:02 mk: seems like there's a few internal things in the api... like ffirst etc.

20:02 matt444: dnolen: awesome

20:02 thanks a ton

20:03 AimHere: ffirst isn't internal, is it? That's just syntactic sugar for (first (first ..))

20:03 yoklov: ffirst is just the same as (first (first))

20:03 amalloy: dnolen: given how protocol-based cljs is, why isn't the protocol behind get extended to js arrays? i assume there's some good reason but i don't see it

20:03 dnolen: matt444: and small correction, get is for anything that implements ILookup

20:04 AimHere: ffirst is just clojure's first baby steps along the many variants of cdar and caddr and cdadadddr and whatnot, from more traditional lisps

20:04 matt444: dnolen: Yea, that was the error I was receiving at runtime

20:04 And aget did indeed work

20:04 * yoklov misses cdadadddr

20:04 dnolen: amalloy: I don't think there is a good reason, just hasn't been done :)

20:04 matt444: Just grabs the value from an object with the dictionary syntax object[key]

20:04 dnolen: matt444: yep

20:05 amalloy: hm. maybe i'll look into doing it as a weekend project, if there's no technical reason against it

20:18 dnolen: emezeske: lein-cljsbuild calls into the CLJS compiler directly right?

20:26 emezeske: dnolen: yep!

20:26 dnolen: it calls cljs.closure/build

20:27 dnolen: emezeske: I wonder if you should turning on warning on undefined symbols by default.

20:27 emezeske: dnolen: is that an option? *I want that*

20:27 dnolen: emezeske: it is, and I think it should default to on :)

20:28 bind *cljs-warn-on-undeclared* true

20:28 emezeske: dnolen: I hate that that's not on by default. WTF?

20:29 simard: Is it a good idea to use a PersistentQueue with an Atom if two threads are going to communicate through this queue ?

20:29 dnolen: emezeske: well you have to be careful I think currently, since it can only warn well if it's seen everything.

20:29 emezeske: so it might not work so well beyond the first pass w/o doing something smarter

20:29 emezeske: worth experimenting w/ tho.

20:29 emezeske: dnolen: I see. It still seems like defaulting to on is a good thing

20:30 dnolen: any assistance there is good

20:30 dnolen: https://github.com/emezeske/lein-cljsbuild/issues/62

20:30 dnolen: I'd do it this second, but I have to prepare for a shadowrun session ^_^

20:31 dnolen: emezeske: I would try it and determine the downsides, you may want the compiler to emit namespace info for unchanged files that you can use to populate namespaces - I'm not sure what the best approach is.

20:32 emezeske: dnolen: sounds good.

20:35 amalloy: dnolen: maybe the reason js hashmaps don't support get is that you have to extend the protocol to js/Object? i don't see any other code extending protocols to that

20:40 dnolen: amalloy: you definitely don't want to extend js/Object.

20:42 amalloy: dnolen: i don't think you can do it any other way, though. that is, to make get work on js hashes, you have to extend js/Object, since there's no other superclass

20:42 so that would be why it's not done yet

21:14 dnolen: what about the requirement to type :cljs/quit instead of just an EOF with ctl-D? every time i touch cljs that annoys me, and i'm happy to patch unless someone is really attached to ctl-D not closing the repl

21:25 dnolen: amalloy: adding support for ctl-D sounds fine to me.

21:25 amalloy: good; i've patched it and am filing an issue as we speak

21:27 dnolen: amalloy: excellent

21:29 amalloy: dnolen: http://dev.clojure.org/jira/browse/CLJS-167

21:39 Scorchin: Given a vec and a set of positions within the vec, how can I update those positions to a given value?

21:39 amalloy: sounds like reduce/assoc

21:41 &(let [v (vec (range 10)), positions #{1 4 8}] (reduce #(assoc %1 %2 :new-value) v positions))

21:41 lazybot: ⇒ [0 :new-value 2 3 :new-value 5 6 7 :new-value 9]

21:41 Scorchin: oooh

21:41 now that's clever

21:42 I was thinking an anonymous function, but I have a feeling what I intended would have been much more long-winded

21:42 thanks amalloy!

21:46 mk: Scorchin: see also replace, and note that assoc takes pairs (and can be applied)

21:46 ,(assoc [1 2 3 4] 0 'a 2 'c)

21:46 clojurebot: [a 2 c 4]

21:49 mk: for the same value,

21:49 ,(apply assoc [1 2 3 4] (interleave '(0 2) (repeat 'n)))

21:49 clojurebot: [n 2 n 4]

22:04 dnolen: zebrao runs in ClojureScript :D

22:05 ibdknox: dnolen: nice!

22:06 dnolen: ibdknox: yeah, I shouldn't be surprised but I'm stunned how much CLJS really feels like Clojure.

22:09 lots of performance work to do but zebrao does run faster than it did under jim duey's original miniKanren port

22:14 Peter Norvig's CL version that compiled Prolog could solve zebra in 17.4s in the 90s, now you can do the same thing w/ JS in ~170ms. And we haven't even started optimizing :)

22:15 rhc: how can i force "if" to eval either body for its side effects?

22:16 (if cond (do ..) (do ..)) ?

22:16 mk: rhc: both bodies?

22:17 rhc: mk: either body

22:18 mk: rhc: at the moment it evaluates either one, or two, depending on cond... or so I think

22:19 rhc: do you want it to evaluate both bodies, but print only the value of one according to cond?

22:19 rhc: mk: hmm, no i only want it to evaluate the correct body for its side effects

22:20 basically, something like (if input (set some ref) (write to some socket))

22:20 mk: ,(if false (print 'a) (print 'b))

22:20 Chousuke: use when

22:20 clojurebot: b

22:21 rhc: Chousuke: ahhh

22:21 Chousuke: when is equivalent to (if foo (do ...))

22:21 ie, no else branch

22:22 Raynes: I think he wants an else branch.

22:22 Chousuke: hmm

22:22 then you need something besides if or when

22:22 Raynes: I think he just needs do.

22:22 mk: what's the problem with if?

22:22 Raynes: Yeah, I'm not seeing it either.

22:23 rhc: i think i just need to put (do's) in my "then" "else"

22:23 thought i might be missing something

22:23 Chousuke: you can only have one expression per branch

22:23 so if you want side-effects you need to wrap the expressions in a do

22:24 mk: rhc: yes :) if your problem is that you want to perform multiple operations in a place where you usually can only do one, use do

22:24 Chousuke: clojure is sort of optimised for the one-expression case :P

22:24 since multiple expressions implies side-effects.

22:25 but yes, do is always there when you need it.

22:27 rhc: yeah, sometimes i think i'm "doing it wrong" when its not immediately obvious how to do it in clojure

22:27 Chousuke: well, it's a good indicator.

22:28 especially if you're just getting started with functional programming

22:28 if you feel like things are hard, you might be doing something wrong. :)

22:28 rhc: i've done some erlang, but not much concurrent erlang, just some projecteuler

22:29 so here's what i'm doing, using Raynes' library :):

22:30 i get a callback for an irc message, if it contains some "word", i want to asynchronously run a function that downloads some configuration and loads it into a ref

22:30 if it doesn't contain that "word", then i'm basically processing the message on the configuration

22:32 so its something like: (if (not= (.indexOf message "word") -1) (do (future update)) (do (irclj/message ... (get-response message))))

22:32 is there a more "functional" way?

22:33 Chousuke: well, looks like you're dealing with something that's inherently stateful anyway

22:34 mk: rhc: as an aside, use "foo".contains("oo") instead of indexOf

22:34 Chousuke: the best thing to do is try to have a clear boundary between such code and code that you can keep pure.

22:34 rhc: mk: ah, tahnk you

22:34 Chousuke: yeah, get-response is nice and functional

22:34 Chousuke: so that any code that transforms data is pure, and then the side-effecty code uses those functions to update refs and whatnot

22:35 rhc: hmm, ok, i was wondering about that

22:35 if it was better to have 'update' do the ref-set, or keep all the ref-set's in one "bad" area

22:35 Chousuke: it's not a hard requirement of course but I personally think it's good practice :P

22:36 less side-effecty code = less code to worry about

22:36 mk: rhc: I don't know much about this, but you might use agents if it's a case of "I don't care what happens to it"

22:37 Chousuke: rhc: ref-set might not be the best idea either. using alter with an update function is usually more idiomatic.

22:37 dnolen: <3 org.clojure/tools.macro, just works w/ CLJS

22:38 symbol-macrolet FTW

22:41 talios: anyone know if ensure-directory! is a standard clojure fuction these days? google doesn't help me :( it's mentioned in a pull request...

22:55 mk: can a namespace map a symbol to both a var and a Class, in any sense at all?

23:59 how can I print each element of a seq/vec on its own line?

Logging service provided by n01se.net