#clojure log - Aug 04 2012

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

1:09 Frozenlo`: Is there clojure/clojurescript libraries to simulate mechanical or electrical systems? (à la Bret Victor would be nice)

1:57 Bastianx9: || Paypal Account Full Information || Payment Method Liberty Reserve Only || Paypal Account Full Information || Payment Method Liberty Reserve Only || Paypal Account Full Information || Payment Method Liberty Reserve Only ||

2:16 mdeboard: itext is the worst.

2:19 aperiodic: you mean that PDF parsing library?

2:40 mritz: whats the best way to have leon 1 and 2 both installed

2:40 is there like a virtual environment ?

2:42 eggsby: why not just have lein and lein2 in your $PATH ?

2:47 amalloy: mritz: just install them both, that's all there is. give the two scripts different names

2:50 mritz: amalloy: Thanks! that worked

4:20 leafw: hi all. If I have an int like (bit-shift-left 255 24), and I want to store it in an array of primitive ints, how can I cast it to signed int to do so? Clojure, righly so, complains that it can't be casted because it is out of range

4:21 i.e. how to store an unsigned int 0xff000000 in a java primitive int, which is signed?

4:31 pyrtsa: leafw: Don't know of a direct way, but this works for 32 bit: (defn int* [x] (let [i (bit-and 0x7fffffff x)] (Integer. (if (< x 0x8000000) x (+ -0x80000000 i)))))

4:32 leafw: pyrtsa: thanks. I am hoping there is a better way, for example casting to int at the right places within bit-and, bit-or, etc.

4:32 otherwise performance will suffer lots

4:33 pyrtsa: Like I said, I don't know of any. :/

4:35 leafw: ,(byte 0xff)

4:35 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for byte: 255>

4:35 leafw: that made no sense to me

4:35 so clojure considers hexadecimal not as bits filled in but as actual numbers

4:39 hyPiRion: leafw: Makes perfect sense

4:39 ,0xff

4:39 clojurebot: 255

4:39 leafw: hyPiRion: so what is the right way to do bit-wise math in clojure?

4:40 amalloy: leafw: there is no such thing as unsigned on the jvm

4:40 leafw: how to pack 4 bytes into one int?

4:40 mind giving an example?

4:40 amalloy: I am aware. In the java side, one always masks first to 0xff

4:40 hyPiRion: leafw: ##(ubyte 0xff)

4:41 lazybot: java.lang.RuntimeException: Unable to resolve symbol: ubyte in this context

4:41 hyPiRion: oh, its name is something else, lemme check it up

4:44 leafw: no suggestions in the clojure cheatsheet for byte similar to ubyte

4:44 mdeboard: Did I reinvent the wheel here https://gist.github.com/3256063

4:45 raek: leafw: unchecked-bit-shift-left

4:45 mdeboard: wrt metadata on proxies

4:45 hyPiRion: ,(unchecked-byte 0xff)

4:45 clojurebot: -1

4:45 hyPiRion: ,(unchecked-byte 0xffff)

4:45 clojurebot: -1

4:45 leafw: aha

4:45 thanks

4:45 so the unchecked math is what will do it

4:46 thanks a lot!

4:46 hyPiRion: no problem, it's hard to find

4:46 leafw: the cheatsheet doesn't list the bit-wise ops under the unchecked section

4:51 raek: Unable to resolve symbol: unchecked-bit-shift-left in this context

4:51 raek: so unchecked math must be invoked in a binding or something line that

4:52 raek: leafw: hrm, that functions does not exist, but other unckecked version for other operators do

4:53 you can always do this: (unchecked-int (bit-shift-left 255 24))

4:54 'unchecked-int' works as (int) in java (it throws away all but the 32 lowest bits)

4:54 amalloy: mdeboard: i think you may have just reinvented being crazy

4:54 leafw: ,(unchecked-int (bit-shift-left 255 24))

4:54 clojurebot: -16777216

4:54 leafw: good!

4:54 thanks raek

4:55 amalloy: like, ignoring whether proxy is the right answer ( i don't know what a PdfReader is, these implementations of the meta functions don't make sense

4:55 raek: I'm not totally sure how *unchecked-math* is used

4:55 leafw: lack of examples hinders it suse

4:55 raek: I think you are supposed to 'set!' it before you eval the defns or something

4:55 leafw: google is full of past examples, but unchecked math has changed lots over time

4:56 there is a *math-context* for with-bindings

4:56 http://clojuredocs.org/clojure_core/clojure.main/with-bindings

4:56 without an explanation on what it is for

5:37 I got the bit-wise math to work. In short, to imitate the java side of things with truncating primitives, one has to use unchecked-long (the only kind of cast that doesn't result in a reflection warning when using bit-or, bit-and, etc.)

5:37 all bit-wise operators are used as normally one would.

5:38 and it is true that operations on primitive types return primitives: no boxing warnings

5:40 suprisingly one gets boxing warnings when feeding byte, short, or int into bit-and, for example. Only a long would avoid the reflection warning.

5:41 I'd asume that byte/short/int would automatically promote to long

5:44 alexyakushev: What is the best exception to throw if macro was used incorrectly (wrong number of arguments, for instance)?

5:45 hyPiRion: Exception.

5:45 It kind of depends, though. Do you want it to be compile-time or runtime?

5:45 alexyakushev: Compile time, I guess

5:46 leafw: the good news is that bit-or with more than 2 arguments runs at the same speed as an unrolled set of bit-or's

5:47 hyPiRion: Then go with Exception. Runtime should be RuntimeException

5:47 alexyakushev: And what about this "CompilerException java.lang.RuntimeException" Clojure uses for symbols not resolved?

5:52 hyPiRion: ,foo

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

5:52 hyPiRion: ,(doc resolve)

5:52 clojurebot: "([sym] [env sym]); same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)"

5:53 hyPiRion: bleh

5:53 ,(source resolve)

5:53 clojurebot: Source not found

5:55 hyPiRion: Ah, resolve is a runtime error, but I don't know about CompilerException. It's not the compiler there's some issue with when you're using the wrong number of arguments.

5:55 ,(let [foo (fn [] (resolve 'bar))] nil)

5:55 clojurebot: nil

5:55 hyPiRion: ,(let [foo (fn [] (resolve 'bar))] (foo))

5:55 clojurebot: nil

5:57 alexyakushev: OK, thank you. Exception will do

6:00 hyPiRion: Clojure isn't all that into Java-exceptions as far as I get it - it's better to have a descriptive error message.

8:51 hcumberdale: ;)

8:52 My blog in clojure is finished ;)

9:09 horofox: hcumberdale: share it.

10:51 pandeiro: is there a good reason that predicate functions should only return true or false/nil? i find myself creating pseudo-predicates that return a val or nil; is that a bad pattern?

10:53 duck1123: I think it depends on the predicate fn, a lot of them return the val for truthy

10:54 cshell: seems more robust to return the val or nil

10:56 duck1123: of course, sometimes writing it to return the val may make that predicate slower. In both cases you'd have the test, but if you want to return the value, you'd need an if and then return the input

10:57 (fn [x] (> x 7)) vs (fn [x] (when (> x 7) x))

10:59 pandeiro: duck1123: right, in my case i need to retrieve the val anyway, so why not return the val

10:59 seems it would make no sense to convert val to boolean and then retrieve the val again

10:59 but maybe the wiser people know a reason that would make sense

11:04 alexyakushev: duck1123: Why would returning a value make the predicate slower? Is there any difference in performance between returning a boolean or a reference to an object?

11:06 pandeiro: alexyakushev: think he means if you add the conditional (when...)

11:06 Chousuke: generally you should only return true or false explicitly in two cases: you're expecting the function to be used in Java code or when you want to return true for nil/false input

11:17 * gfredericks just realized that quote isn't a necessary primitive

11:21 Bronsa: is there a function that trasforms [1 2 3 4] to ((1 3) (2 4))?

11:21 gfredericks: what's the rule there?

11:22 what does it do with [1 2 3]? or [1 2 3 4 5 6]?

11:22 do you only care about 4-tuples?

11:22 Bronsa: one element in the first list, one in the other

11:22 i can do that with ((juxt keys vals) (apply assoc {} coll))

11:22 buyt it feels too much like cheating

11:23 gfredericks: ,(partition 1 2 [1 2 3 4])

11:23 clojurebot: ((1) (3))

11:23 gfredericks: hm

11:23 Bronsa: yeah i tried partition

11:24 gfredericks: there are proably 40 cludgy ways to do it

11:31 ,(let [pairs (partition 2 (range 6))] [(map first pairs) (map second pairs)])

11:31 clojurebot: [(0 2 4) (1 3 5)]

11:31 gfredericks: that's the cleanest I can think of

11:31 Bronsa: oh, cool thanks!

11:33 mdeboard: amalloy_: lol. I'd like to hear more about the dumb things I did wrong.

11:33 amalloy_: (seriously)

11:43 amalloy_: https://github.com/mattdeboard/clj-itext/blob/master/src/clj-itext/core.clj is the full file. PdfReader is a class from iText, a PDF-processing library. It has a very painful API. So when you say I've reinvented being crazy wrt my usage of metadata, I'm assuming what you really mean is "that's dumb." Why? I was basically just using it to store metadata about the PDF on the class instance.

11:46 pyrtsa: gfredericks, Bronsa: Here's a little simpler still:

11:46 ,(apply map list (partition 2 (range 6)))

11:46 clojurebot: ((0 2 4) (1 3 5))

11:47 Bronsa: eg! thanks

11:59 gfredericks: pyrtsa: oh of course

12:00 pyrtsa: gfredericks: To be honest, it wasn't that obvious to me at first either.

12:01 Bronsa: this is funny http://i.imgur.com/GzpUF.png

12:04 gfredericks: pyrtsa: the (map list ...) things does matrix transpose; I just didn't realize that's what he was asking for

12:05 Bronsa: gfredericks: yeah, sorry if I didn't explain myself properly

12:06 thanks both anyway :)

12:12 gfredericks: Bronsa: oh no it was me

12:20 sproust: ist

12:20 technomancy: I just saw nrepl.el

12:20 technomancy: got a few questions about it.

12:21 Why two modes? I saw there's a major and a minor mode. If it's meant to be used with clojure-mode, why not just have a minor mode?

12:34 duck1123: "code generated by ClojureScript macros must target the capabilities in ClojureScript" -- does that mean I can't make a macro that calls console.log ?

12:34 I'm getting odd errors when I try

13:01 sproust: technomancy: Ah. never mind. Figured it out, forgot the repl installs its own mode.

13:45 Frozenlo`: I get this error when I try to evaluate a function: clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentCollection.

13:45 The function evaluates fine by itself, but when I add a given macro in it, it chokes. Any idea why?

13:48 pandeiro: does himera only work with lein <2? anyone know?

13:49 i get an error: Problem requiring leiningen.js hook

13:49 mdeboard: Frozenlock: Not without seeing the code

13:51 Frozenlock: mdeboard: https://gist.github.com/3258950 the macro is used near the end of the function.

13:51 mdeboard: Frozenlock: You're missing something

13:52 oh, nm, there the signature defintiion

13:52 Frozenlock: You litteraly, or in my understanding?

13:52 mdeboard: didn't see it

13:52 why do you have a vector in your args like that

13:53 Frozenlock: that? [[fetch-fn coll & {:as args}]]

13:53 mdeboard: yeah

13:53 is thata macro thing I'm not familiar with?

13:54 Frozenlock: (with-random (fetch ....)) would be single argument. With the added vector I use destructuring to directly get the components.

13:55 Could it be that the arguments aren't evaluated, thus I don't have a map as a I was expecting, but simply a symbol?

13:56 treehug: are there refactoring tools for clojure like for example: extract sexp to local variable, rename symbol in sexp, etc?

13:56 mdeboard: Dunno, seems weird. On line 31, the (fetch (...)) expression is going to be evaluated before it's passed to (with-random)

13:56 Frozenlock: So the query-map in `:where query-map' will not be a simple symbol if I understand correctly.

13:57 mdeboard: I dunno, that is some weird-to-me syntax (but I'm not an expert by any stretch)

13:57 Frozenlock: ok, thanks anyway.

14:00 mdeboard: What is that function signature supposed to do? Destructure? I've literally never seen a vector used as a symbol

14:02 supposed to represent*

14:02 Frozenlock: If you are talking about the macro, yes it's for destructuring.

14:02 mdeboard: That shouldn't be in the function signature though

14:02 Frozenlock: Signature?

14:03 mdeboard: in ``(defn foo [a b] (+ a b))`` ``[a b]`` is the signature

14:04 destructuring should be in binding statements like let/for/etc.

14:04 metellus: mdeboard: you can destructure in a function signature

14:04 mdeboard: I see

14:06 That seems weird, since if you're just destructuring in the signature why not just pass the function the destructured args in the first place?

14:06 metellus: Frozenlock: based off of this http://stackoverflow.com/questions/11170424/maintaining-agent-state-while-returning-in-clojure and completely making things up, I'd say that you need to put "fetch-fn coll & {:as args}" into parentheses

14:07 gfredericks: mdeboard: in a lot of cases that could mean spreading implementation information all around your code rather than keeping it in one place

14:07 metellus: mdeboard: so instead of (some-fn some-vec) you'd have to do soething like (let [;destructuring goes here] (some-fn args))?

14:10 mdeboard: or just restructure in a different let statement, it's just a convention that I've never seen before (except obv like `(defn foo [x & [y z]] (stuff x y z))`

14:11 Frozenlock: I think I should be using a function instead of a macro in this case. Let me try that...

14:16 muhoo: i've seen a lot of people writing functions with quoting and unquoting ` ~ ' etc, i call the "funcros"

14:17 gfredericks: muhoo: misquote is good for ` without symbol expansion

14:17 i.e., for just the unquoting mechanisms

14:21 muhoo: yeah, the first time i saw gensyms and syntax-quotes in a non-macro, i was confused. then i figured out how useful it could be.

14:22 gfredericks: ,`foo#

14:22 clojurebot: foo__27__auto__

14:22 Frozenlock: Meh, it works as a simple function and without the quoting unquoting stuff. Perhaps I was trying to be to fancy.

14:51 mdeboard: funcros

14:51 I liek that.

15:14 sjl: I'm trying to eliminate reflection and can't seem to figure out the magic type hinting incantations... anyone feel like taking a look? https://gist.github.com/3259412

15:20 oh sweet, I think I found it

15:26 antares_: sjl: you more likely want to use hints before locals: ^String s, not s ^String (…). Also, the last parameter needs to be passed as a java array, so see clojure.core/into-array

15:27 sjl: antares_: actually this does the trick: https://gist.github.com/3259412

15:27 antares_: there's an alternate version of that method that takes a set instead of that weird java varargs

15:27 antares_: I just had to inform clojure that (set foo) does indeed produce a persistenthashset

15:28 antares_: sjl: it is still less common to hint expressions if you bind them to locals but ok. And interop with variadic methods is a common source of confusion so I decided to mention it.

15:29 sjl: to hint on core Clojure types, it is probably a better idea to use interfaces (IPersistent*)

15:29 also, you probably can just hint it has java.util.Set?

15:29 sjl: maybe

15:29 antares_: the Java method is likely to be expecting j.u.Set, not a specific Clojure interface

15:30 Clojure sets implement the read-only part of j.u.Set

15:30 sjl: ah

15:33 pandeiro: anyone noticed a bug with goog.json.parse() ? JSON.parse() is parsing my string just fine, goog.json.parse() isn't

16:44 wtetzner: pandeiro: what string are you trying to parse?

16:51 pandeiro: wtetzner: sorry i figured it out - goog.json.parse uses eval, which is prohibited in chrome extensions

16:52 antares_: pandeiro: are you writing a chrome ext in cljs?

16:52 pandeiro: kinda silly that goog.json.parse doesn't first check for a native method imo, but whatever

16:52 antares_: i am

16:52 and i'm loving it

16:53 emezeske: pandeiro: That is really cool!

16:55 pandeiro: emezeske: yeah my first try was a couple of months ago, i wanted to convert himera to a chrome extension that would allow using CLJS on any random webpage

16:55 but i ran into the no eval() problem

16:55 there is a workaround tho, eventually i will get on that

16:56 emezeske: pandeiro: Oh, neat, the extension would like see a special script tag and send it off to himera seamlessly?

16:56 pandeiro: emezeske: ah no, just to be able to screw around in cljs on any random page

16:56 emezeske: pandeiro: I see

16:57 pandeiro: Cool stuff

16:57 pandeiro: eventually have a store of convenience functions, like get-all-links

16:57 yeah, eventually i'll get there

16:57 with cljsbuild it has been very easy throwing together an extension

16:57 emezeske: nice!

16:57 pandeiro: since you can output to multiple files easily

17:05 say i have a flattened seq like (:head :sub :sub :sub :head :sub :sub :head :sub :sub :sub) and i want to restore the hierarchy like ([:head (:sub :sub :sub)] ...)

17:09 i got to using partition-by to get ((:head) (:sub :sub :sub) (:head) (:sub :sub) ...) ... trying to figure out the next step

17:11 gfredericks: pandeiro: (->> % (partition 2) (map (fn [[[h] subs]] [h subs])))

17:12 pandeiro: gfredericks: my mind reached its recursion limit with that destructuring

17:12 but thank you, am trying to parse

17:12 gfredericks: it's just pulling the head and the subs out of your ((:head) (:sub :sub :sub))

17:26 Frozenlock: Is there a way to use drag/drop in html5 without javascript?

17:29 * Raynes is going nuts on fs today.

17:30 Raynes: Rewriting all the temp file/dir stuff and making other things less weird.

17:30 Going to commit-bomb the repo soon.

17:33 antares_: Raynes: (with the towlie voice) don't forget to use travis-ci

17:33 Raynes: antares_: I'm not already doing that?

17:33 Hrm.

17:33 Guess I just haven't worked on fs in a while.

17:33 I'll get that set up before releasing.

17:35 Also, if anybody has ever found something weird or un-nice in fs, nows your chance to get it fixed while I'm on a roll.

17:35 I didn't write the vast majority of this code and I haven't used fs a whole lot, so I'm not the one who would know about issues.

17:36 Frozenlock: Well, a more detailed readme could be nice. (to know what that's all about)

17:37 Raynes: It's all about the fs, man.

17:37 Frozenlock: *cricket*

17:40 technomancy: Imma let you finish but reiserfs was the best fs of all time

17:40 Raynes: technomancy: You're so hip and with it.

17:40 danlarkin: murders your wife ✓

17:45 amalloy: mdeboard: you aren't actually storing the metadata, though. like, your implementation of withMeta returns a map, instead of a new object with new metadata

17:46 which is, in turn, what makes with-proxy-meta's implementation so bizarre. with-proxy-meta should be able to just be a simple call to ##(doc vary-meta)

17:46 lazybot: ⇒ "([obj f & args]); Returns an object of the same type and value as obj, with (apply f (meta obj) args) as its metadata."

17:47 technomancy: so what if namespaces were persistent?

17:47 what if new definitions were append-only and old function definitions stayed around until there were no other references to them?

17:48 if you used nix-style hashing and dependency closures, you could keep multiple versions of a library in memory in the same classloader

17:50 you could theoretically have every version of every clojure function loaded at once without conflict

17:51 gfredericks: technomancy: so you just solved dependency management then?

17:52 technomancy: no, I just told you how to solve it. go implement it.

17:52 Spaceghostc2c: Hagelberg!

17:53 technomancy: me?

17:54 gfredericks: ~hagelberg

17:54 clojurebot: Gabh mo leithsc?al?

17:59 jayunit100__: trying to convert csv to json

18:00 any hints on the standard lib to do this csv i/o (clojure)

18:00 trying [clojure-csv/clojure-csv "2.0.0-alpha1"]

18:19 Frozenlock: What's the way to add a favicon in noir?

18:23 Raynes: Frozenlock: https://github.com/Raynes/refheap/commit/3fa0100722faad54418a1e712dcf0176463b789d

18:24 jayunit100__: (:import [java.io StringReader]) <-- this seems to fail

18:24 Frozenlock: Raynes: Thanks!

18:27 jayunit100__: ah dsantiago !

18:27 I'm using your csv parser now :)

18:27 dsantiago: ^^ … thanks :)

18:28 dsantiago: Oh, cool.

18:28 I've been speeding it up lately.

18:28 jayunit100__: cool!

18:28 Caused by: java.lang.IllegalArgumentException: Unable to resolve classname: long

18:28 ^^ anyone ever see this error before?

18:30 ah i think its clojure class path related

18:30 or maybe its leon related.

18:31 dsantiago: Did you hint something to be a long or try to create one like (long. …) or anything like that?

18:35 jayunit100__: looks like you have to reload lein reps or something maybe .

18:35 no its not in my source, it seems to be in a jar.

19:23 Frozenlock: Is there a forum library for clojure?

19:37 mdeboard: amalloy: I see, noted

19:38 cmajor7: forgot where I read how to force (re)compilation on save.. e.g. I have it working nicely with clojurescript via "lein-cljsbuild".. I am sure there is something similar (and probably simple) for clojure itself

19:39 is it just another lein plugin?

19:40 xeqi: cmajor7: web service?

19:40 ring.middleware.reload I think

19:41 cmajor7: xeqi: thx. no, simpler :) just clojure code

19:41 weavejester: cmajor7: (:require blah.core :reload)

19:42 cmajor7: Er, I mean: (require 'blah.core :reload)

19:42 Too used to the ns macro

19:42 cmajor7: once I save any clojurescript file, it gets recompiled right away, and I can see in a console whether there are any errors. just wanted to do the same thing with clojure itself

19:43 weavejester: so I would need to append :reload to every namespace… I have ~ 15 files, is that the only way?

19:43 weavejester: cmajor7: There's also :reload-all, which reloads a namespace and all its dependencies.

19:43 amalloy: i don't think it's ever right to put :reload into your namespace definition

19:44 cmajor7: I think there is something similar in emacs land (swank?), but I am using vi. not sure if that matters

19:44 amalloy: that's only intended for repl usage

19:44 weavejester: amalloy: Right, but I'm assuming cmajor7 is reloading via the REPL...

19:44 cmajor7: Is that right?

19:45 amalloy: (as an aside, you forgot the []s in (require '[blah.core :reload]))

19:45 or i dunno, maybe it works outside

19:45 cmajor7: weavejester: I just want to start "something", that would be running, and every time I save my code, I it gets recompiled, and that "something" reports exceptions/errors/etc..

19:46 emezeske: cmajor7: I think most people use vimclojure or swank or something similar for that

19:47 cmajor7: I have heard of people adding hooks to their editors that automatically reload the current file on save

19:47 weavejester: cmajor7: Usually I just use SLIME for that. I believe VimClojure might have something similar. And some of the various IDEs might have that, too.

19:47 emezeske: s/swank/slime

19:47 cmajor7: emezeske: I use vimclojure, but as far as I understand you need to always force the compilation e.g. "\ef"

19:47 which pops up an internal vim buffer that you have to switch to and close

19:48 or worse scroll up to actually see the exception

19:48 emezeske: You don't have to switch to it, you can do \p to close it

19:48 cmajor7: feels like 4 extra steps for every save..

19:48 emezeske: And you can set options for where it appears, and how big

19:48 You can just leave it open...

19:48 cmajor7: right, but if there is an exception, you have to switch to it to scroll up

19:49 weavejester: cmajor7: Isn't that an issue with screen size more than anything? I mean, if the stacktrace scrolls off screen, then you'd have the same problem with whatever, right?

19:49 mdeboard: amalloy: With the definition of withMeta, I spent a few hours last night trying to figure out how to extend an Object instance with the IObj interface. I basically just hacked at it until it works. I couldn't find an example implementation of withMeta (except for one really crummy blog post from 2009)

19:49 cmajor7: I just really like what "lein-cljsbuild" does, and I find it hard to believe there is nothing similar for clojure itself?

19:50 amalloy: mdeboard: just look at the examples in clojure.lang

19:50 they're in java, but it's pretty easy

19:50 mdeboard: amalloy: I tried to find it in the source last night but I think I was exhausted

19:51 I found the IObj.java and IMeta.java classes, but there's no actual code there, just interface defs

19:51 weavejester: cmajor7: I haven't heard of anything. I find it more useful to have errors integrated with my editor. However, it would be pretty trivial to create something like it. Just combine clj-stacktrace, ns-tracker, and :reload-all in a loop.

19:51 I imagine it would be 8 lines of code or something.

19:52 mdeboard: er, I should say, no function definitions, not no code :P

19:52 amalloy: look at, eg, PersistentHashMap

19:55 muhoo: cmajor7: i think noir does it on page reload

19:55 cmajor7: weavejester: I see. still find it odd. do you actually go an extra step every time to see if your code is solid? e.g. 1. save it 2. force compilation 3. go scroll the exception ?

19:56 mdeboard: amalloy: I see... so, do I need to specify a constructor for this PdfReader class that has a signature that includes metadata? Based on PersistentHashMap, I'm not sure how to do something similar for this class instance. PersistentHashMap implements the IObj interface out of the box; PdfReader not.

19:56 weavejester: cmajor7: No, I just use SLIME.

19:57 amalloy: just...implement withMeta to call proxy-meta or whatever it is

19:57 cmajor7: muhoo: noir does, but if you work with 3 files simultaneously, going from one vim buffer to another and back, saving each, noir does not help you here (nor it should)

19:57 weavejester: I see. how does it work in slime?

19:57 it auto recompiles on save?

19:57 amalloy: you really don't want to recompile on save

19:58 weavejester: cmajor7: No, but it saves if you trigger a compile without saving, IIRC

19:58 cmajor7: amalloy: why not?

19:58 muhoo: cmajor7: i dunno then. i was poking in the cljsbuild source, and stumbled across the function that checks the filesystem for changed files, but didn't read it in depth. you could probably adapt that to a lein plugin that does that for clj instead of cljs

19:58 weavejester: cmajor7: And the error is reported through SLIME, so the top part of the stack trace is shown

19:59 muhoo: There's a library called ns-tracker that does that for clojure

19:59 cmajor7: weavejester: pretty similar to vimclojure.. although the bottom of the exception is shown.. )

19:59 amalloy: for example, you don't want to recompile a protocol implicitly, because then implementations of it won't match up anymore

20:00 weavejester: cmajor7: Why not add a key binding that saves, compiles, then goes to the top of the exception?

20:02 cmajor7: amalloy: does sound like a special case, and implementations can be also recompiled after the protocol, can they?. I am not saying it should be enabled by default, but there should be something that does it as an option.

20:05 weavejester: might work, but still a bit rough. let's say you are working through several files related to one another. ideally there should be a single console that shows you errors/[OK]s/exceptions every time you save and go to another file. so your mental flow is not interrupted.. (may be it's just me though)

20:09 muhoo: it is funny to me how personal and unique everyone's workflow can be. mine is quite idiosyncratic.

20:10 amalloy: cmajor7: just write a little shell script that compiles everything, eg: echo "(require 'my-app.core)" | lein repl, and then open another console that runs: watch my-script.sh

20:11 there's no need for it to happen when you save, or be incremental and mess with your open session

20:12 cmajor7: amalloy, weavejester: thx, I'll experiment

20:26 gfredericks: does the new finite-domain stuff in core.logic not play well with negative numbers?

20:29 I get no results with (interval -100 100) (even though I should), but changing it to (interval 1 100) gives results.

20:43 mdeboard: Man the people who wrote iText must hate programmers

20:44 or love carpal tunnel syndrome or I dunno

20:55 amalloy: i can sympathize with hating programmers

20:58 mdeboard: amalloy: That is obvious, but that's why we like you. To be fair to the itext people I'm sure they're in backward compatibility hell. I know they are actually because they put all their backward compatibility burden on me

21:09 Is there a way to invoke (proxy) in such a way that the class being extended doesn't get constructed first? I've been reading the source for the macro and am assuming not.

21:10 I think that's the sort of thing Python's ``object.__new__`` method is there for; curious if there's an analog in Clojure specifically for Java interop.

21:14 amalloy: sorry mdeboard, that is not possible on the jvm

21:42 mdeboard: amalloy: Cleaned that up then https://github.com/mattdeboard/clj-itext/blob/master/src/clj-itext/core.clj#L43

21:43 removed `with-proxy-meta' since it was redundant

21:43 amalloy: don't call `merge`. withMeta is "here is your new metadata"

21:45 mdeboard: which merge is redundant? in the withMeta definition?

21:45 amalloy: not redundant, incorrect

21:46 (and yes, that one)

21:46 (meta (with-meta x y)) should return y in all cases

21:46 mdeboard: Oh, I see what you're saying then. with-meta completely replaces the metadata.

21:46 I misunderstood how that worked.

21:48 ##(doc vary-meta0

21:48 ##(doc vary-meta)

21:48 lazybot: ⇒ "([obj f & args]); Returns an object of the same type and value as obj, with (apply f (meta obj) args) as its metadata."

21:48 mdeboard: I see.

21:51 * mdeboard kicks his Clojure Programming book

21:52 amalloy: what, does chas say something misleading about metadata?

21:52 mdeboard: No, I just don't believe in taking personal responsibility

21:54 But seriously, having no Java background whatsoever the proxy/gen-class bit specifically could use somewhat better documentation. Maybe it's more transparent if you've got a background in Java

22:06 amalloy: Done, thanks for the tough love

22:06 I work better when I think someone thinks I'm an idiot

22:08 amalloy: haha

22:08 you should pair with hiredman

22:10 danlarkin: bahahahah

22:10 mdeboard: Why, does he think I'm an idiot? :P

22:10 or does he just think everyone is

22:11 muhoo: ,*ns*

22:11 clojurebot: #<Namespace sandbox>

22:11 muhoo: ,(= :sandbox/foo ::foo)

22:11 clojurebot: true

22:12 cmajor7: once friend authenticates a user, it puts "{ :username.. :password… :roles.." under the identity into a session. Is there a way to make friend to keep additional user details there? (e.g. user-id)

22:13 muhoo: well, you can using ring

22:13 just add whatever you want to the :session

22:14 xeqi: cmajor7: try returning more data from you're credentials-fn

22:14 cmajor7: yea, I just did, it still hangs on to those 3

22:15 muhoo: cmajor7: are you writing a custom workflow?

22:15 cmajor7: muhoo: yes, but it is not going to be a part of friends identity + needs to be handled separately => not nice

22:15 muhoo: i wrote one for google step2 auth, but it's been months now and my memory fails me

22:16 cmajor7: muhoo: no this particular one is a built in "interactive-form"

22:16 muhoo: oh, so you're out in ring?

22:17 not inside a (defn workflow ... ) ?

22:17 cmajor7: muhoo: I am home at the moment

22:17 muhoo: hehe

22:17 i mean not you specifically, but your code :-)

22:18 cmajor7: there is a "credentials-fn" that returns the auth

22:18 which is the only "data hook" into friend that is used

22:18 muhoo: :credential-fn i expect

22:18 no "s"

22:18 cmajor7: the app is of course ring based. noir to be exact

22:19 right. "bcrypt-credential-fn" if you want to be really accurate

22:19 muhoo: cool, so my guess is you have something like this in your server.clj: https://www.refheap.com/paste/4047

22:20 cmajor7: yep. very similar

22:20 no "step2" though

22:20 muhoo: well, of course

22:20 that was my test code

22:21 alright, so you're using creds/bcrypt-credential-function. what does it return?

22:21 cmajor7: so once the user is authed, only username, password and roles make it to the identity

22:21 muhoo: somewhere, something returns a ring response, which has (or can have) a :session key in it

22:22 cmajor7: muhoo: it returns a map of those 3. I tried to add other keys there, but they get ignored, since only those 3 seem to be read by friend

22:22 muhoo: by interactive-form

22:23 clj_newb_29840: is there any standard toolkit for keeping _data structures_ updated on client/server over clojurescript/clojure?

22:23 i.e. I'd like ot find the right abstractions so I have some data structure so that its state is automatically synched over both the server and the client

22:24 xeqi: cmajor7: strange, returning extra-keys there works for me

22:25 muhoo: cmajor7: ok i see this (assoc-in [:session ::identity] auth))

22:25 cmajor7: muhoo: right, http://bit.ly/PUxKWX

22:25 xeqi: interesting.. which key did you try, if you don't mind

22:26 muhoo: so whatever is returned in auth, from the who-knows-where-that-comes-from, should end up in your session

22:26 cmajor7: I tried, id, user-id, but no go..

22:26 xeqi: :extra

22:27 but the only one creds/bcrypt-crednental-fn removes is :password

22:27 blah, I can't spell today

22:27 muhoo: i remember i spent days tracing through the (authenticate* ..) function to figure out how all this works, but i've long since forgotten

22:28 with like printlns everywhere

22:36 cmajor7: xeqi: yep, works now. had to restart the server

22:36 I wonder why… since I did clear the session (it does it on logout)

22:39 xeqi: noir's reload doesn't work with middleware

22:44 Frozenlo`: Anyone wants to critic my website? (general layout, colors, etc...) Made with love with Noir :) https://bacnethelp.com

22:47 Frozenlock: I'm pretty sure I have tunnel vision right now, so please be direct.

22:48 emezeske: Frozenlock: Whoa, I worked on a BACnet stack once

22:48 Frozenlock: emezeske: Yay! BACnet friend :)

22:48 emezeske: Frozenlock: I wrote the MS/TP layer :)

22:48 Frozenlock: The C stack?

22:48 emezeske: Yeah, it was all C. Well, actually, C++

22:48 xeqi: Frozenlock: I can't read the example at all

22:48 well, barely

22:48 Frozenlock: Oh I only do BACnet/IP with this.

22:49 xeqi: Colors?

22:49 emezeske: Yeah, MS/TP is a bitch to set up, and tends to require custom code most of the time :/

22:49 muhoo: cmajor7: right, i had to do stuff like this https://www.refheap.com/paste/4048 and this (def rel (reloader #'-main)) and this https://www.refheap.com/paste/4049

22:49 cmajor7: xeqi: ah.. makes sense, good to know (about noir reload)

22:49 emezeske: Frozenlock: BACnet/IP is so much better

22:49 Frozenlock: emezeske: And it's slooooow :)

22:49 emezeske: Frozenlock: omg yeah

22:50 mdeboard: Frozenlock: Where are you hosting your images?

22:50 oh, I see you just acknowleged

22:50 Frozenlock: Only thing I'd say is have your links open up in new windows

22:50 target="_blank" etc

22:51 Frozenlock: mdeboard: All the links?

22:51 cmajor7: muhoo: hmm.. I wonder whether I should just jump a level down to compojure.. so far noir introduces more problems than it solves..

22:51 Frozenlock: Seems it would be intrusive.

22:51 xeqi: Frozenlock: http://imgur.com/s4qnX is what I get on ff14.0.1

22:51 mdeboard: Frozenlock: well just external, like the one to github imo

22:51 muhoo: cmajor7: you wouldn't be the first to do that. i think that's why they broke out a lot of noir-ish stuff into lib-noir

22:51 Frozenlock: Hmm that would be wise...

22:52 cmajor7: muhoo: also, how do you usually debug through a 3rd party libs? (you said to did do it with friend's "authenticate*")

22:52 xeqi: cmajor7: I use compojure over noir

22:52 muhoo: cmajor7: i'm old-skool. lots of printlns :-)

22:53 and the repl helps a lot too, though not so much with web authentication stuff that requires a browser

22:53 cmajor7: muhoo: so you get the source, and depend on the source.. and then mod it in the friend's branch itself?

22:53 xeqi: Frozenlock: oh, if I hover over it then it expands and becomes brighter

22:53 Frozenlock: xeqi: Is that too discrete? If you hover it should change transparency...

22:53 emezeske: cmajor7: If you are doing anything complex with routing, noir tends to just get in the way

22:53 cmajor7: xeqi: you mean you use noir, but drop back to compojure for routes?

22:53 muhoo: oh, that? yes, i git cloned'ed friend, then ln -s'ed it into the "checkouts" directory in the lein project

22:54 xeqi: cmajor7: sorry, I mean use compojure, don't use noir

22:54 cmajor7: emezeske: yea I noticed that doing xhr.. :)

22:54 emezeske: cmajor7: ;)

22:54 cmajor7: xeqi: I see.. do you roll out your own "defremotes"?

22:55 muhoo: isn't defremote from fetch?

22:55 cmajor7: muhoo: yea, but fetch is noir..ish

22:55 Frozenlock: And here is a project I'm logging https://bacnethelp.com/project/4ffac84b44ae35711d15d214

22:56 So my most urgent change should be to open external links in another window.

22:57 mdeboard: Frozenlock: Also see about solving package dependencies

22:57 not website-related but you'd be a hero

22:57 I could also use a drink

22:57 xeqi: cmajor7: I haven't used clojurescript much yet, but that would be the way I lean

22:57 Frozenlock: package dependencies? For the network scanner?

22:58 xeqi: though I'm interested in what shoreleave does for remotes

22:58 just haven't explored it yet

22:58 mdeboard: Frozenlock: Oh, no, I Meant for software development in general

22:58 Frozenlock: I _really_ appreciate your feedbacks btw!

22:59 mdeboard: (I'm deliberately being obtuse)

22:59 Frozenlock: mdeboard: Could you give me an example?

22:59 xeqi: ah, looks like it does the same thing as fetch

22:59 Frozenlock: Dependencies are in the project.clj file... am I missing something?

23:00 mdeboard: I was just making a joke that was in hindsight really stupid

23:00 Frozenlock: It's hard to transmit sarcasm with text :P

23:00 mdeboard: yeah, you'd think I'd have learned in 20 years

23:02 cmajor7: xeqi: yep http://bit.ly/OBWSWk

23:03 muhoo: yeah, i think rhickey and stuart holloway both did talks about "easy" vs "simple"

23:03 stuff like noir and fetch is great if you're coming from rails and are used to the "easy" approach. but aren't necessarily "simple" once you dive into them.

23:05 mdeboard: Frozenlock: You should move that "How to scan your network" numbered list up "above the fold" imo, and put your "Download" button right there in the "1!" <p>

23:06 Frozenlock: Ah! Yes!

23:07 xeqi: Frozenlock, mdeboard: I agree. and if you can get it so that is the first thing the eye jumps to even better

23:07 currently my eye jumps to the "Scan and see ..." blue banner

23:08 muhoo: yeah, cemerick was horrified at the hoops I had to jump through to get a working noir/fetch + friend example

23:13 muhoo: xeqi: is that posted somewhere? i'd be curious to see it

23:14 xeqi: muhoo: https://github.com/xeqi/friend-fetch-example

23:14 interesting part is https://github.com/xeqi/friend-fetch-example/blob/master/src/friendly/server.clj

23:17 muhoo: hmm, there's a lot going on there

23:19 it looks a lot less complex than what i had to go through to get google step2 workflow working, but a lot more complex than perhaps it could be.

23:20 xeqi: muhoo: yeah, it could be cleaned up

23:20 step2 definitly looks more complicated

23:20 is it a multistep workflow?

23:31 m0smith: I am trying to wrap my brain around event processing in a purely functional environment

23:32 How can the state of the world be passed around?

23:33 mdeboard: (##doc ref)

23:34 Raynes: That was creatively failed.

23:34 mdeboard: m0smith: Clojure has tools that allow you to introduce state to your application if necessary.

23:34 ##(doc ref)

23:34 lazybot: ⇒ "([x] [x & options]); Creates and returns a Ref with an initial value of x and zero or more options (in any order): :meta metadata-map :validator validate-fn :min-history (default 0) :max-history (default 10) If metadata-map is supplied, it will be come the meta... https://www.refheap.com/paste/4050

23:34 m0smith: mdeboard: I am trying to avoid that is possible

23:34 mdeboard: m0smith: Are you talking about cljs or clj?

23:35 m0smith: both actually

23:35 The problem arises from cljs not having blocking deref

23:36 so how to get the same code base to run in both environments. javascript is all about callbacks but that assumes a shared state, I think.

23:36 emezeske: m0smith: For state in cljs, there's a good chance you want to use an atom

23:37 muhoo: you could pass the state in the callback?

23:38 oic, it'll depend on the state which may have mutated by the time the callback gets called. hmm.

23:39 m0smith: muhoo: I am writing a multi-player game so the state is the current state of the game which I want to protect from cheating code

23:39 mdeboard: Never done anything with asynchrony with Clj* but I was under the impression from what I do know that you could use watches to do event handling

23:39 ##(add-watch)

23:39 lazybot: clojure.lang.ArityException: Wrong number of args (0) passed to: core$add-watch

23:39 mdeboard: ##(doc add-watch)

23:39 lazybot: ⇒ "([reference key fn]); Alpha - subject to change. Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any regis... https://www.refheap.com/paste/4051

23:39 mdeboard: fail tonight

23:42 muhoo: m0smith: sounds like fun. it sounds like you'll want a mirror of the state in the server and on all the clients.

23:43 the only time i've done this (js, not cljs), i had the server broadcasting all the updates of each player to each client.

23:43 m0smith: muhoo: Exactly. The game engine would have the real state and when it is a players turn, the client is sent the current state

23:44 I also thought of supporting events from the clients to get the current state or send a message, etc.

23:44 muhoo: the server was basically this, but it didn't keep much state: https://github.com/kenrestivo/simple-clojure-websocket-chat

23:44 m0smith: I am just having a brain cramp meshing the game loop with asynchronous calls without something like an agent

23:44 that can block

23:45 muhoo: started as a chat thing, then ended up as a gameserver of sorts, more or less unwillingly

23:46 m0smith: or do I just trash the game loop and handle everything through asychronous events?

23:47 muhoo: it's worth a try. also, there's a neat aleph framework for doing async stuff too

23:47 m0smith: which is then how to maintain state without a stuffing it in a global ref ...

23:47 muhoo: well, state is state. you have to store it somewhere

23:48 m0smith: with a game loop/lazy-seq the state is simply passed around to the functions

23:50 muhoo: do any of those functions do i/o?

23:51 m0smith: I am separating all the user stuff into different threads so no

23:51 muhoo: oh. hmm.

23:52 concurrency with refs. i haven't done much with it, but i'm told that clojure makes it more manageable.

23:53 m0smith: The more I think and talk about it the more a shared state atom or agent supporting an event system may solve the problems I am facing

23:54 muhoo: sounds reasonable to me. might be a fun way to play around with clojure's concurrency features.

23:54 m0smith: And it should mesh better with most UIs as they are almost all event based at some level

23:56 https://github.com/m0smith/crossfire is the code I am talking about. It is a Battleship-ish game. Now all it does is allows 3 computer players to battle.

23:56 muhoo: enjoy :-)

23:57 m0smith: thx. This has really helped me make decide the direction to go

Logging service provided by n01se.net