#clojure log - Nov 28 2014

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

0:22 thearthur: what version of nrepl and cider does cider-spy work with? and is this the place to ask about cider-spy? #cider seems to be about the beverage

0:28 justin_smith: thearthur: there is #clojure-emacs

0:28 thearthur: but lots of cider users here too

0:29 it mentions cider/cider-nrepl 0.1.0-SNAPSHOT which is very old

0:30 (in its project.clj)

0:36 thearthur: justin_smith: I'll just keep an eye on the project and see what happens

1:56 Ninerian: /msg NickServ identify Shad0wrun

3:05 kenrestivo: derp, time to change yer password

3:05 Ninerian: ^

3:10 Ninerian: The funny thing is, i dont now if its the right one.

3:14 rritoch: Ninerian: You should change that password everywhere you use it. The bots in this channel log to the web. I setup an automatic nickserv registration script on connect because I knew eventually end up in that situation if I didn't.

3:15 daniel`: whats his password? i didnt catch it?

3:17 ucb: daniel`: it was *********

3:17 daniel`: thanks ucb

3:17 ucb: no bother, he must've changed it anyway

4:14 Ninerian: Already done

4:16 plllx: Ninerian: what is

4:18 nonuby: if I have a record that implement a prototype, and a create an inst of this, how do I call the protype method if the prototype is defined in a different ns?

4:26 https://github.com/stuartsierra/component/blob/master/src/com/stuartsierra/component.clj and my ns code (:require [com.stuartsierra.component :refer [start] :as component]) how does clojure know that start refers to that in Lifecycle protocol what is component.clj defined multiple prototypes that had a start method?

4:41 rurumate: can zippers be used on nested maps, or nested seqs / vectors only?

4:47 sm0ke: so i have this function from an external library `.foo` which i call on a dom element

4:48 how do i save it from being munged

4:52 rurumate: ,(clojure.zip/zipper #(throw (NullPointerException.)) #(throw (NullPointerException.)) #(throw (NullPointerException.)) '(1 2 (2 3)))

4:52 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.zip>

4:52 rurumate: ,(require [clojure.zip])

4:52 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.zip, compiling:(NO_SOURCE_PATH:0:0)>

4:52 rurumate: ,(require '[clojure.zip])

4:52 clojurebot: nil

4:52 rurumate: ,(clojure.zip/zipper #(throw (NullPointerException.)) #(throw (NullPointerException.)) #(throw (NullPointerException.)) '(1 2 (2 3)))

4:52 clojurebot: [(1 2 (2 3)) nil]

4:53 rurumate: it's not invoking any of the three functions. what's missing?

4:56 daniel`: sm0ke: externs

5:07 sm0ke: daniel`: what should be the extern string for it

5:08 var foo = {};

5:08 ?

5:08 daniel`: i think so, yes

5:08 not really sure right now, but im sure google can bring up some examples

5:30 michaelr525: hello friends

5:31 does anyone know how to switch between tabs in tool windows in intellij idea? such as multiple debug sessions in the debug tool window..

5:55 noncom|2: can somebody point me to that latest doc that speaks about using clojure from java ?

5:55 i remember there is some new kind of interop, but i cannot find the doc with google...

6:14 gavilancomun: Perhaps this from the clojure 1.6 change notes: https://github.com/clojure/clojure/blob/master/changes.md#21-java-api

6:16 noncom|2: gavilancomun: right! thanks, this is it :)

6:16 gavilancomun: np :-)

6:27 clgv: why does `into` internally convert to transients if possible, but does not accept transients as first argument? this is pretty weird

6:27 from a user perspective

6:27 Glenjamin: ,(transient! (transient! []))

6:27 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: transient! in this context, compiling:(NO_SOURCE_PATH:0:0)>

6:27 Glenjamin: ,(transient (transient []))

6:27 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector$TransientVector cannot be cast to clojure.lang.IEditableCollection>

6:28 Glenjamin: hrm, i can't decide if that makes sense or not :s

6:28 clgv: it does query whether it can create a transient. it could easily query whether the collection is a transient, as well

6:28 $source into

6:28 lazybot: into is http://is.gd/caQYZB

6:29 Glenjamin: if transients were transient-able that just did identity, it'd make sense?

6:29 clgv: yeah, that would work as well, but fail for `into`

6:29 `into` would fail as well because of "(instance? clojure.lang.IEditableCollection to)"

6:30 Glenjamin: would it? if TransientVector implemented clojure.lang.IEditableCollection

6:30 clgv: oh, or is IEditableCollection only the "can create transient" interface?

6:30 Glenjamin: i think so

6:30 clgv: ah right

6:31 lets check whether there is something in jira already

6:37 dm3: does anyone know if there's such a thing as a best-effort reader, which would read as much as possible and leave unreadable things as strings?

6:37 SagiCZ1: dm3: if unreadable things get to be strings, what are the other things?

6:38 dm3: forms

6:40 SagiCZ1: dm3: do you mean s-expressions?

6:41 dm3: yes

6:42 SagiCZ1: dm3: sorry, i have no idea, lets wait for the more experienced

6:42 dm3: I guess I'm being silly

6:43 SagiCZ1: dm3: i guess it would be really hard for the reader to partially read some invalid s-exps

6:43 dm3: it would, would require constant backtracking

6:44 SagiCZ1: yeah

6:44 why would you need such thing?

6:46 dm3: after thinking a bit I now understood that I don't need it :) I only need a way to skip reading java objects printed by clojure printer

6:46 like #<Object java.lang.Object@1934eeb0>

6:46 SagiCZ1: dm3: oh i remember dealing with this.. yes some java objects are not serializable to string

6:47 maybe you could just try to catch the exception

6:47 dm3: I guess there should be a way to use my custom data_reader

6:47 and just leave them as string

6:47 clgv: SagiCZ1: most java objects are printed that way ;)

6:47 dm3: and just leave them as strings

6:47 SagiCZ1: clgv: that is true

6:48 clgv: if you use a data reader you just have to implement print-method for your datatype

6:48 dm3: :)

6:48 which is any java object

6:48 rritoch: dm3: If your just trying to extract specific values why not just read in quoted form, and then walk through your data to resolve what you need resolved?

6:48 dm3: ex. (read-string (str "(quote " my-str ")"))

6:49 clgv: dm3: why do you try to print any java object?

6:50 dm3: It's for a browser client for nREPL which can connect to remote repls

6:51 so arbitrary output possible

6:51 clgv: but in a repl you get no useful print for arbitrary objects neither

6:52 dm3: yes, but I can have a map {:x #<Object>, :y #<Object>}

6:52 still want to pretty print that

6:52 and colorize

6:53 clgv: hm other nrepl clients manage that as well. so you can compare what you do different from them

6:54 dm3: they just display the string

6:54 only if you have middleware on the repl server

6:54 then you have control of the data

6:54 clgv: ah so you want to navigate the data structure and render it?

6:54 dm3: yes

6:55 clgv: but you want to keep using a text-based protocol?

6:55 dm3: yes :)

6:56 clgv: well then you could walk the datastructure and replace non-printable objects with strings

6:57 dm3: that would imply access to the nrepl server

6:58 clgv: dm3: you will need that likely

6:58 dm3: ok, I'll try playing with data readers a bit more

6:58 clgv: dm3: or you have to write your own clojure reade that handles those #<Class ...> forms

6:58 dm3: yeah

6:58 clgv: data-readers wont work

6:59 dm3: will also take a look at tools.reader

7:00 clgv: dm3: tools.reader will throw as well, since it is for valid clojure code. but maybe it has hooks to treat the errors

7:00 dm3: you can ask Bronsa. he's usually somewhere around here ;)

7:00 dm3: thanks for your help! :)

7:07 noncom|2: clgv: hi

7:07 whta ccw version are you currently on ?

7:07 i am on Version 0.30.0.STABLE001 and it cannot create clojure projects

7:10 oh, that happens only if i try to create the project inside the workspace...

7:10 chennaiyin: Hi Everyone, I am new to clojure and I'm stuck with a small problem.Any help will be appreciated than you. I have a list of map say, [{:name Tom :child {:name Mark :child{:name Jimmy}} } {:name Ben :child {:name John}} {:name Tom :child {:name Lucy}}] it should be converted to something like [{:name Tom :child [{:name Mark :child {:name Jimmy}} {:name Lucy}]} {:name Ben :child [{:name John}] }]

7:10 I tried merge , conj unsuccessfully :(

7:10 noncom|2: chennaiyin: what do you expect to happen with the data?

7:10 Empperi: so you try to do what?

7:11 combine those maps?

7:11 in what way?

7:11 chennaiyin: yeah combine them basically

7:11 triss: hey all. are there any good articles on breaking apps up in to modules when using clojure (or other functional languages I suppose)?

7:11 SagiCZ1: is there a difference between using -> and doto for java interop<

7:11 ?

7:11 Empperi: you have same keys in each map in your sequence, if you just combine them you'll end up with data in your last map

7:12 ,(reduce merge [{:foo "foo"} {:foo "bar"}])

7:12 clojurebot: {:foo "bar"}

7:12 Empperi: see

7:12 ,(reduce merge [{:foo "foo"} {:bar "bar"}])

7:12 clojurebot: {:bar "bar", :foo "foo"}

7:12 chennaiyin: yeah thats what seem to happen but I need them to be added/appended

7:12 Empperi: that does give you a map with all the data combined but keys need to be unique

7:13 that doesn't explain what you are trying to achieve too well yet

7:13 do you want the value of :name to become the key?

7:13 and then group all the children underneath that?

7:14 chennaiyin: I want the child to be grouped/added and the name to be the key.

7:14 yeah

7:19 Empperi: chennaiyin: and you need to flatten the hierarchical tree?

7:21 chennaiyin: @Empperi : I'm sorry what do you mean?

7:22 I want it to be nested as it is, but no redundant keys in the list.

7:22 just the children added

7:27 Empperi: chennaiyin: something like this? https://www.refheap.com/6671907e7d6b04957ae7a8a48

7:28 ah, add (merge-with conj) to the end

7:29 to make it complete

7:35 chennaiyin: @Empperi ok sure, I'll try that. thank you :)

7:44 dgellow: there is no format fn in clojurescript ?

7:45 cljs.user> cljs.core/format

7:45 nil

7:46 Bronsa: dgellow: there's goog.string/format

7:46 dgellow: cljs.user> goog.string/format

7:46 nil

7:47 other fns from goog.string are available

7:49 Bronsa: dgellow: yeah, you have to import the goog.string.format gclosure namespace

7:50 dgellow: With (require '[goog.string :refer [format]]) ?

7:51 because it doesn't work

7:51 Bronsa: no, cljs doesn't have a top-level require

7:51 dgellow: (ns foo (:import goog.string.format))

7:52 dgellow: import is not for "classes" ?

7:52 Bronsa: dgellow: g.s.format is weird because it's a gclosure namespace but must be used as a function

7:52 dgellow: okay …

7:52 Bronsa: dgellow: there are no classes in cljs, import is for gclosure ctors

7:53 dgellow: Bronsa: it works :)

7:53 Bronsa: thank you

7:53 Bronsa: dgellow: but gclosure has a bunch of namespaces (like g.s.format) that have weird semantics

7:53 dgellow: np

8:05 kungi: Ok I get CamelCase, I also get snake_case but why kebap-case? (Taken from camel-snake-kebab.core)

8:08 dm3: Bronsa: is there a way to "skip" reading java objects with tools.reader? E.g. "{:x #<Object>}" -> {:x "#<Object>"}

8:09 I see you can provide :default opts to the edn read function

8:11 Bronsa: dm3: no

8:11 dm3: that's for tagged readers

8:12 rritoch: kungi: The underscore key was a fairly "late" addition to keyboards, so in lisp hyphens where used as a way to connect words into a symbol. Clojure inherited this tradition from LISP.

8:12 kungi: rritoch: yes I know that it's a historic lisp thing. I was asking why is it called kebap case?

8:12 dm3: Bronsa: do you know of any way to achieve that?

8:13 Bronsa: dm3: there's no way to do that without monkey-patching the reader

8:15 dm3: Bronsa: thanks! I see a `dispatch-macros` which returns a throwing reader for '<', will try to patch that

8:21 p_l: rritoch: it's more lack of infix operators enabling the use of less annoying keys ;)

8:22 kinda like why Unix cli options typically start with - instead of +, the latter required pressing the rather heavy shift key

8:23 clnoob: hello everyone!

8:23 can you someone give a hint why there is a need for nested braces in such construction: (-> ["aaaaa" "bbbbbb" "account"] ((fn [arg] (map #(re-matches #".*ccoun.*" %) arg))) )

8:24 why (-> ["aaaaa" "bbbbbb" "account"] (fn [arg] (map #(re-matches #".*ccoun.*" %) arg)) ) is incorrect? As i understand first (fn ...) is function declaration and ((fn ..)) is function call.

8:25 SagiCZ1: clnoob: yeah, and you want to call the function.. not declare it

8:26 clgv: noncom|2: thats weird

8:26 clnoob: hm, but i want it to be called while calling to (-> ... ) construction. i though it will callall mentioned functions ?

8:27 noncom|2: clgv: yeah, in case if i force the new wizard to create the project inside the workspace dir, it says "project project-name overlaps with existing project project-name"

8:27 SagiCZ1: clnoob: i know that if you have one argument function decalred elsewher you can use either "foo" or "(foo)" equaly.. not sure how is it with in-place function definitions

8:27 noncom|2: clgv: as if both eclipse and ccw try to create it and somehow interfere

8:28 clgv: creating elsewhere, not in the current workspace dir, goes smoothly

8:28 eclipse is kepler

8:28 have you experienced something like this ?

8:28 SagiCZ1: noncom|2: eclipse is so bugged i am surprised your pc didnt explode yet

8:29 clnoob: SgiCZ1, hm...tnx anyway for answer=)

8:29 llasram: clnoob: The `->` macro is operating on the source forms directly, so it threads your `["aaaaa" ...]` vector as the second form in the literal `(fn ...)` source

8:30 ,(macroexpand-1 `(-> ["a"] (fn [x] x)))

8:30 clojurebot: (clojure.core/fn ["a"] [sandbox/x] sandbox/x)

8:31 llasram: ,(macroexpand-1 '(clojure.core/-> ["a"] (fn [x] x)))

8:31 clojurebot: (fn ["a"] [x] x)

8:31 llasram: There we go -- a bit more readable

8:40 clnoob: llasram,yeas i know about the way it passes args and nest calls, just use it because its more readable for me at the moment then nesting.chaining like unix-bash =) its easy when i have (-> arg fn1 fn2 fn3),but as you can see when fnX is complex - iam stuck =)

8:42 gfredericks: plumbing might have something for that

8:42 oh maybe not

8:42 their fn-> is a bit different

8:43 ,(defmacro ->fn [form arglist & body] `((fn ~arglist ~@body) ~form))

8:43 clojurebot: #'sandbox/->fn

8:44 gfredericks: ,(-> 7 inc dec (->fn [y] (+ y y)) inc)

8:44 clojurebot: 15

8:45 gfredericks: clnoob: ^

8:52 clnoob: gfredericks, did not get your idea. i understand the order expansion, i dont get why i can do (-> "2" string?) and can do (-> "2" (string?)) but cant do (-> data (fn ...)) and must (-> data ((fn ...)) )

8:54 gfredericks: clnoob: I'm not clear on what you're not clear on; my idea was to use ->fn instead of fn

8:55 clnoob: although now that I think about it I think what you really want is as->

8:55 ,(-> 7 inc dec (as->y (+ y y)) inc)

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

8:55 gfredericks: ,(-> 7 inc dec (as-> y (+ y y)) inc)

8:55 clojurebot: 15

8:55 clnoob: gfredericks, oh, now i see. my problem is why should i wrap one more time (fn ...) when passing to (->...).Why i cant just pass (-> arg (fn ...)).

8:56 gfredericks: clnoob: did you not understand llasram's expansion?

8:56 clnoob: gfredericks, yeas.i think i do

8:57 gfredericks: ,(macroexpand-1 '(-> x (fn [y] (inc y))))

8:57 clojurebot: (fn x [y] (inc y))

8:57 gfredericks: ,(macroexpand-1 '(-> x ((fn [y] (inc y)))))

8:57 clojurebot: ((fn [y] (inc y)) x)

8:58 clnoob: gfredericks,oh.your example seems more clear to me..tnx.i'll rethink it

9:00 gfredericks: clnoob: I do think as-> should have you covered

9:05 justin_smith: mail nonuby I think by prototype you mean protocol, and the protocol functions are defined where the protocol is defined. The methods are usable via interop like any other method though. If a caller had to know the ns your record was from, that would defeat a major point of prototypes, so only the ns where the prototype is defined is needed to make the call.

9:05 $mail nonuby I think by prototype you mean protocol, and the protocol functions are defined where the protocol is defined. The methods are usable via interop like any other method though. If a caller had to know the ns your record was from, that would defeat a major point of prototypes, so only the ns where the prototype is defined is needed to make the call.

9:05 lazybot: Message saved.

9:05 justin_smith: sorry for the double

9:08 rritoch: Is there any realiable way to get the current namespace within a function other than using (:ns (meta #'myfunc)) which is some ugly syntax to be reading, I would prefer something like *ns* but to my surprise that doesn't resolve to the current functions namespace at runtime.

9:10 I thought I may be able to do it with a macro, but (meta &form) within a macro doesn't return the namespace, so I'm a bit stuck on ways to cleanup this code.

9:10 justin_smith: rritoch: *ns* refers to the namespace that is current when it is run

9:10 not the namespace of the definition it is inside

9:10 maybe you want a macro (compile time) version of *ns* ?

9:10 rritoch: justin_smith: Yeah, I just relized that recently, which is how I ended up with this ugly code

9:11 justin_smith: Exactly what I want, but I'm not sure how to do it

9:11 justin_smith: I was able to get rid of all of the gen-classes in the MVC framework, using functions which accept namespaces

9:12 justin_smith: But using those functions is turning out to make some horrible to read code.

9:13 justin_smith: Here is an example... https://github.com/rritoch/clj-grid-core/blob/master/src/applications/grid/views/grid/grid.clj

9:14 I want to get rid of this (:ns (meta garbage and replace it with something clean

9:17 justin_smith: &(.ns #'clojure.core/+)

9:17 lazybot: java.lang.SecurityException: You tripped the alarm! class clojure.lang.Var is bad!

9:17 justin_smith: ,(.ns #'clojure.core/+)

9:17 clojurebot: #<Namespace clojure.core>

9:17 justin_smith: rritoch: does that suffice?

9:18 rritoch: Hmm

9:18 justin_smith: ,(name (.ns #'clojure.core/+))

9:18 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Namespace cannot be cast to clojure.lang.Named>

9:18 justin_smith: hmm

9:18 anyway, the ns should have some method you can find via clojure.reflect/reflect to get what you want from it

9:19 rritoch: so I can replace (:ns meta #'display)) with (.ns #'display))

9:19 justin_smith: btw clojure.reflect/reflect was how I found the .ns method

9:19 ,(:ns (meta #'clojure.core/+))

9:19 clojurebot: #<Namespace clojure.core>

9:19 justin_smith: yeah, you can

9:20 rritoch: Well, that is certainly much cleaner

9:20 justin_smith: anyway, clojure.reflect/reflect. You probably want to use pprint with it.

9:27 rritoch: Hmm

9:27 ,`~*ns*

9:27 clojurebot: #<Namespace sandbox>

9:28 rritoch: Will that always resolve to the namespace of the current function?

9:28 SagiCZ1: hi i want to do something like this

9:28 ,(for [x [:a :b :c] y [:a :b :c]] [x y])

9:28 but i dont care about the order, so i need only one from [:a :b] and [:b :a]

9:28 clojurebot: ([:a :a] [:a :b] [:a :c] [:b :a] [:b :b] ...)

9:29 SagiCZ1: i just need to measure distance from each point to every other

9:37 justin_smith: rritoch: no, *ns* refers to the namespace that is calling the current function

9:38 rritoch: almost always this is either user or the one containing -main

9:42 rritoch: justin_smith: Won't wrapping it in the resolution unquote `~*ns* cause it to get resolved to the load-time namespace instead of the current value of *ns*? I would think that would cause it to be in the namespace of the function it's used in.

9:43 justin_smith: rritoch: that's not what ` does

9:43 a macro that uses *ns* may help

9:44 rritoch: justin_smith: I got the idea from making a macro (defmacro cur-ns [] `~*ns*)

9:44 justin_smith: you don't need ` there

9:45 (defmacro cur-ns [] *ns*) would do the same thing

9:45 SagiCZ1: is reduce-ing generally faster than apply-ing?

9:45 specifically in the case of (apply min ...)

9:45 justin_smith: SagiCZ1: look at the definition of min

9:45 $source min

9:45 lazybot: min is http://is.gd/NAAfLh

9:46 SagiCZ1: justin_smith: thats a bummer then.. they thought of that

9:47 justin_smith: reduce1 is just an internal version of reduce https://github.com/clojure/clojure/blob/clojure-1.7.0-alpha1/src/clj/clojure/core.clj#L891

9:47 SagiCZ1: justin_smith: thank you

9:47 justin_smith: np

9:56 rritoch: justin_smith: Ok, well thanks. (cur-ns) is better than what I have now, anything is better than this (:ns meta syntax.

9:58 justin_smith: But this `~*ns* also seems to be working

9:59 ,(do (ns foo) (defn foo [x] `~*ns*) (ns bar) (foo/foo))

9:59 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: foo/foo>

9:59 rritoch: ,(do (ns foo) (defn foo [] `~*ns*) (ns bar) (foo/foo))

9:59 clojurebot: #<Namespace bar>

10:00 rritoch: Aah, I guess it doesn

10:00 err, doesn't.

10:00 It worked from repl though when I ran those functions separately

10:10 gfredericks: rritoch: justin_smith: you can definitely use a macro to capture the namespace that the macro is being called in

10:10 clojure.tools.logging does this

10:10 so that it can include the namespace in the log message

10:10 SagiCZ1: any idea why wouldnt type hinting speed up a function which gets called many times?

10:11 gfredericks: SagiCZ1: well if there wasn't any reflection in the first place then type hinting wouldn't change anything

10:11 SagiCZ1: isnt there always reflection? i thought the function is always getting Objects..

10:12 gfredericks: there's only reflection if you do interop

10:12 use *warn-on-reflection* to figure out if there is or not

10:12 SagiCZ1: i do.. i call Math/pow on the parameters

10:12 gfredericks: ok

10:12 ,*warn-on-reflection*

10:12 clojurebot: false

10:13 SagiCZ1: how do i set it

10:13 gfredericks: (set! *warn-on-reflection* true)

10:13 do that in the repl if your code is being eval'd in the repl, or else at the top of your file (under ns)

10:13 you can also run `lein check` and it will print reflection warnings for all your code (and libs)

10:14 SagiCZ1: so is that an atom? thanks

10:14 gfredericks: no it's a dynamic var

10:14 SagiCZ1: ok

10:14 ok so i set it to true, ran my code again, and it didnt show any warnings, how is that possible

10:14 ,(set! *warn-on-reflection* true)

10:14 clojurebot: #<IllegalStateException java.lang.IllegalStateException: Can't change/establish root binding of: *warn-on-reflection* with set>

10:15 gfredericks: SagiCZ1: I think if the interop is unambiguous it doesn't need to reflect

10:15 e.g., if Math/pow only has one signature

10:16 SagiCZ1: yeah.. looks like there is only pow(double, double)

10:16 gfredericks: whereas if you tried one of the ambiguous methods you should see the warning, and much slower code

10:17 SagiCZ1: gfredericks: thank you.. that is very smart.. the bad news is, i cant speed up the code

10:17 gfredericks: haha

10:17 did you type-hint with primitives?

10:17 i.e., ^double vs ^Double

10:17 SagiCZ1: i had a capital D there.. let me try it with lower-case

10:18 gfredericks: I think that will only have an effect under specific circumstances

10:18 SagiCZ1: yeah, still the same speed

10:18 gfredericks: like maybe only if the call site has hinted primitives as well...or something

10:20 SagiCZ1: the whole function takes 1ms on average, so i guess thats pretty fast.. the problem is probably that the algorithm is O(n^2) which is pretty nasty for n=5000

10:23 gfredericks: clojurebot: O(n^2) is pretty nasty for n=5000

10:23 clojurebot: A nod, you know, is as good as a wink to a blind horse.

10:24 SagiCZ1: hehe

10:43 kungi: I would like to validate if a given string is a mail address? Any suggestions for a good validation library?

10:45 SagiCZ1: kungi: wouldnt some wicked regex be enough?

10:45 kungi: SagiCZ1: Hmm no. I will need to do more validation soon :-)

10:46 SagiCZ1: kungi: in what sense "more" <

10:46 ?

10:46 kungi: SagiCZ1: Also I stopped using perl in production because of wikced regex

10:46 SagiCZ1: Like validate if fields are not empty or contain a name already present in the model or ....

10:47 justin_smith: gfredericks: re *ns* in a macro - agreed. I was just saying that `~*ns* was pointless, and he should just use *ns*

10:47 leandro1: hi! given «palabras» is a vector, what is wrong with this ? → for [ p palabras :when (even? .indexOf palabras p)] p)

10:48 SagiCZ1: leandro1: interop calls cant act as symbols directly

10:48 wrap it in #(.. %)

10:49 justin_smith: leandro1: many missing parens there

10:49 :when (even? (.indexOf palabras p))

10:50 SagiCZ1: (even? #(.indexOf %) palabras p) makes no sense, if that's what you meant

10:50 leandro1: mmm

10:50 justin_smith: ,(even? (.indexOf [0 1 2 3] 2))

10:50 SagiCZ1: justin_smith: it was a first mistake i spotted.. but you are right

10:50 clojurebot: true

10:51 justin_smith: ,(even? .indexOf [0 1 2 3] 2)

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

10:51 justin_smith: SagiCZ1: you saw the right problem, just not yet the right solution

10:51 SagiCZ1: justin_smith: yeah

10:51 leandro1: ok, lets add some parens

10:52 kungi: SagiCZ1: Hmm ok about that wicked regex you have been talking about :-). Which one would you use?

10:53 SagiCZ1: check out this article http://www.regular-expressions.info/email.html

10:55 ajmccluskey: kungi: is it possible to simply send an email with a validation link/code?

10:55 justin_smith: ajmccluskey: yeah, that's the only right way to validate an email. The actual spec for what is valid in an email is actually kind of insane.

10:56 rritoch: kungi: If you are using leiningen you can try https://javamail.java.net/nonav/docs/api/javax/mail/internet/InternetAddress.html#validate() by adding [com.sun.mail/javax.mail "1.5.2"] to your dependencies. with syntax (.validate (InternetAddress. addr-str))

10:56 ajmccluskey: justin_smith: yeah, I saw this question come up recently, and the consensus was basically "that's a deep, dark hole so just send an email"

10:57 ToxicFrog: Yes. Don't. Just don't. If you try, you will fuck it up, and people will enter their real, working email addresses only to have them rejected by the system, and then they will be angry and either not use your service or send you angry emails.

10:58 Or both.

10:58 kungi: ajmccluskey: It's for an API parameter validation. I get some object by mail and would like to have a valid mail address as parameter.

10:59 rritoch: Thank you that sounds feasable.

11:02 EvanR: yeah a valid email pattern wont ensure anything about anything

11:03 instructive to (re)establish what the point of having their email is and what it would mean

11:04 even if they respond to an email, it may eventually become invalid anyway

11:05 ToxicFrog: just make sure your "angry email" address is weird enough that most mail clients reject it, thus when they go to send you angry emails they get even more angry ;)

11:05 mavbozo: so, people build email validation as as service

11:05 kungi: EvanR: A valid mail pattern will ensure that the mail address in the string I am processing is well formed. (whatever I define as well formed).

11:06 EvanR: kungi: but what is the point of that?

11:06 kungi: EvanR: I can give out an error message saying. This mail address is not well formed please try again to the user of my api. Instead of just giving an error or empty result.

11:07 EvanR: "not an empty string" is the only invariant i can think of that id be ok with relying on

11:07 mavbozo: email can be invalid, for example, because yahoomail deactivates account after 6 months of inactivity

11:07 ToxicFrog: EvanR: I think email addresses are guaranteed to contain a @ and at least two other characters, as long as they aren't addresses on localhost? Don't quote me on that, though.

11:07 kungi: EvanR: No. "hello" for example cannot be a mail address.

11:08 ToxicFrog: kungi: it can in fact be a local mail address; I have daemons that send mail to 'root' and 'webmaster'.

11:08 EvanR: ToxicFrog: right.. and your "send them an email" routine will catch anything that doesnt work

11:08 kungi: ToxicFrog: ok point taken :-)

11:08 mavbozo: got burned by lots of customers who forget their password and cannot reset their password

11:08 SagiCZ1: cant we just rule out the 0.000001% of insane addresses and simplify thus the problem immensely?

11:08 EvanR: kungi: because you said so? or by fiat? or you have critical code that causes a hospital to catch fire if no @ is found?

11:08 mavbozo: false negative?

11:10 kungi: EvanR: I don't write code for hospitals or anything "critical" in that sense. But I see your point.

11:10 EvanR: SagiCZ1: its simplified by just not caring, like random symbols is a bad "first name field" but its not simple to write code to define and ignore those

11:10 kungi: I just tried for my software to be a bit more convenient and give a more sensible error message than "no result found".

11:11 EvanR: kungi: when you try to send a confirmation mail, and it doesnt work, you will get one of a myriad of possible problems. you can translate these for the users benefit, or just dump the message if youre lazy

11:11 kungi: But I see now this is a dead end full of spiders.

11:12 EvanR: that is, youll get a message describing why it didnt work

11:12 one of them is something like "bad email address format"

11:12 CookedGryphon: could somebody help explain how this code is okay? https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/middleware/session.clj#L34

11:12 It looks like it's calling .close on java.io.Writer, which is an abstract method and so shouldn't have an implementation

11:12 wait, no it's not

11:13 EvanR: but its not nearly the only possibility

11:13 mavbozo: kungi: yeah, there is discussion on hackernews years ago. https://news.ycombinator.com/item?id=5763327

11:13 CookedGryphon: it's type hinting this to Writer, which is abstract and calling .flush, is what I meant

11:14 clgv: noncom|2: no. creating clojure projects via "New" works like a charm here. (Luna SR1)

11:15 ToxicFrog: CookedGryphon: exactly, and the actual value is going to be some sort of concrete implementation of Writer with an actual impl for it.

11:15 CookedGryphon: but it's a wrong type hint

11:15 sorry, I mean the bytecode makes it look wrong

11:15 noncom|2: clgv: oh well.. what a luck here :)

11:15 CookedGryphon: even though it should work at runtime

11:15 this is coming up as a verification error in art, thinks it's calling an abstract method

11:16 kungi: mavbozo: That is interesting

11:21 clgv: noncom|2: did you try out a fresh workspace?

11:22 noncom|2: nope.. but that happens whatever is the name of the project, even a new random one.. so i guess that does not matter much..

11:22 maybe the fact that i am still with kepler - does matter

11:22 kungi: I am now going for the mail must contain at least an @ and a . "solution".

11:23 clgv: noncom|2: not sure about that. I had kepler running until a few weeks ago

11:24 noncom|2: clgv: i suppose the issue is here with the stabile 30 version since it ings some differences in project creation

11:24 *brings

11:26 clgv: noncom|2: try the fresh workspace and if that fails report an issue - since it should be reproducible then

11:27 noncom|2: yeah, gonna try that

11:35 SagiCZ1: i want 'iterate' to stop iterating when f returns nil, is that possible?

11:35 luxbock: SagiCZ1: you can use take-while on it

11:36 SagiCZ1: luxbock: cool, thanks

12:13 leandro1: how to print each item of a vector line by line?

12:14 (println (for [m mix] (str m "\n"))) <- doesn't work :/

12:14 clgv: the clojure function `hash` should call the hash code method of my deftype, correct?

12:15 args! how I hate those stale class files :(

12:28 andyf: leandro1: one way is (doseq [m mix] (println m))

12:28 Something closer to the way you tried would be (apply println (for [m mix] (str m ?\n?)))

12:29 because (apply f [i1 i2 i3]) turns into (f i1 i2 i3)

12:34 upwardindex: bit-shift-* with only 1 argument should bit shift by 1 bit.

12:35 andyf: because 1 is so hard to type?

12:35 upwardindex: andyf: what do you propose the 1 arity be used for?

12:36 andyf: throwing an exception seems reasonable to me

12:36 because it means I forgot the shift amount arg

12:36 but tastes can differ

12:39 you may define macros that behave as you wish, and they could even have much shorter names like << >> >>> like Zach Tellman's primitive-math lib does: https://github.com/ztellman/primitive-math

12:43 liflash: hi everybody

12:43 someone familiar with kioo?

12:45 andyf: ~anyone

12:45 clojurebot: anyone is anybody

12:45 andyf: Usually that gives a sentence about 'better to ask your question, and someone will answer if they know'

12:45 !anybody

12:45 ~anybody

12:45 clojurebot: anybody is anyone

12:46 andyf: but not today :)

12:46 clgv: andyf: now you broke it

12:46 it was anybody

12:46 ~anybody

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

12:46 clgv: ah it still is

12:47 andyf: glad you were here to fix it :)

12:47 clgv: not really ;)

12:47 liflash`: since my internet connection is pretty unstable i'll start again: hi everybody

12:47 clgv: andyf: maybe the bot is playing tricks on you ;)

12:47 liflash`: anybody familiar with kioo?

12:48 clgv: ~anybody

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

12:48 andyf: Try asking your question with more details. If someone knows, they will answer.

12:48 liflash`: ok ;)

12:49 i'm using kioo for a web app and have a selector like [(attr= :attr "something")] and don't know why it works, because i never import attr=

12:50 when defining a function like this (defn attr [attr-name] (attr= :attr attr-name)) it doesn't work

12:50 why?

12:50 clojurebot: http://clojure.org/rationale

12:51 clgv: liflash`: some macro magic? where is the selector placed?

12:51 liflash`: within a defsnippet

12:53 Bronsa: liflash`: https://github.com/ckirkendall/kioo/blob/master/src/kioo/core.clj#L72-L73

12:53 liflash`: https://github.com/cgrand/enlive/blob/master/src/net/cgrand/enlive_html.clj#L801-L803

12:54 liflash`: so attr= is automagically resolved to net.grand.enlive-html/attr=

12:54 clgv: macro magic ^^

12:55 liflash`: automagically nails it ;)

12:55 hmmm

12:56 does it make sense to you that it only works if it's directly within the defsnippet but not if it's wrapped in a function call?

12:56 i'm not that familiar with macros yet

12:57 Bronsa: liflash`: yes, it's the defsnippet macro that transforms attr= into net.grand.enlive-html/attr=

12:57 liflash`: ok, thought so

12:57 Bronsa: well, not the defsnippet macro itself but part of its implementation

12:57 liflash`: so if i want to use it in my own function i would have to import the enlive macros, right?

12:57 clojurebot: Huh?

12:58 Bronsa: liflash`: (:require [net.grand.enlive-html :refer [attr=]]) in your ns form. btw attr= is a function not a macro

12:59 liflash`: ok, as i expected

12:59 it's not exactly a function, is it? (def attr= ...)

13:01 Bronsa: liflash`: it is -- (multi-attr-pred ..) returns a function

13:02 liflash`: (defn foo [..] ..) is ~= (def foo (fn [..] ..))

13:04 liflash`: of course... sorry. still new to all this ;)

13:04 thanks a lot Bronsa

13:04 Bronsa: np

13:28 Fender: hi there

13:29 ,(let [m (transient {}) ]

13:29 (doseq [i (range 10)]

13:29 (assoc! m i (inc i)))

13:29 (count m))

13:29 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

13:29 Fender: ohh

13:29 ,(let [m (transient {}) ] (doseq [i (range 10)] (assoc! m i (inc i))) (count m))

13:29 clojurebot: 8

13:29 Fender: wtf=

13:29 ?

13:29 it should be 10, anyone has an idea why that is?

13:30 yedi: whats it called when an editor provides a matching parentheses for you when you type (

13:30 tryna figure out why lighttable isn't doing that

13:30 anymore

13:31 Fender: paredit is the best know tool used for that

13:31 maybe you can search for lighttable + paredit

13:31 Bronsa: Fender: that's not how transients should be used

13:31 Fender: I know, I constructed a minimal example

13:31 Bronsa: Fender: you should always operate on the return value of a transient operation

13:31 Fender: oh

13:32 but it shouldnt make a difference, right?

13:32 it's mutable

13:32 Bronsa: Fender: e.g (assoc! (assoc! x 1 1) 2 2) rather than (do (assoc! x 1 1) (assoc! x 2 2))

13:32 Fender: clearly it does

13:33 andyf: Fender: Think of it this way: (assoc x ...) returns a new value, and the original value is still around for use, or for doing further operations like assoc on. (assoc! x ...) returns a new value, and the original value is now UNDEFINED, and should never be used.

13:33 Fender: ,(count (reduce #(assoc! %1 %2 1) (transient {}) (range 10)))

13:33 clojurebot: 10

13:33 andyf: even though clearly it causes no error if you try to use the original value again.

13:33 gfredericks: ,(doc assoc!)

13:33 clojurebot: "([coll key val] [coll key val & kvs]); When applied to a transient map, adds mapping of key(s) to val(s). When applied to a transient vector, sets the val at index. Note - index must be <= (count vector). Returns coll."

13:33 Fender: to keep it as functional as possible

13:34 gfredericks: Fender: and also the return value is different sometimes

13:34 andyf: clgv: http://clojuredocs.org/clojure.core/assoc!

13:34 Bronsa: Fender: it's mostly for efficiency reasons, this way creating a transient and converting it back to a persistent data structure can be constant time operations

13:35 Fender: hmm, ok, I didnt know that

13:35 but that's a pretty strange bevahior

13:35 anyhow, thanks very much

13:35 Bronsa: Fender: http://clojure.org/transients "Note in particular that transients are not designed to be bashed in-place. You must capture and use the return value in the next call"

13:35 gfredericks: I wonder if the ztellman vectors will have transient versions

13:35 Fender: I was thinking I found a bug because googling for transient! map clojure didnt bring up anything useful

13:35 many many thanks!!!!

13:36 andyf: ClojureDocs.org for some functions and macros has useful additional info

13:36 clgv: andyf: for what?

13:36 andyf: clgv: You want a list of the ones I think are most useful? :)

13:37 clgv: andyf: huh?

13:37 andyf: Sorry. I don't know what you are asking about when you asked "for what?"

13:37 Fender: what about bashed-in handling of transients vectors in transient maps?

13:37 gfredericks: clojurebot: huh is <reply> what?

13:37 clojurebot: I don't understand.

13:37 clgv: andyf: I didn post anything for ~40mins ;)

13:38 Bronsa: Fender: what?

13:38 gfredericks: Fender: whatever you're doing should never bash in place

13:38 I think nested transients tends to be pretty awkward

13:38 Fender: for example, I have a map where the values are vectors

13:38 gfredericks: what's your broader algorithm here?

13:38 Fender: and I would these vectors to be transients as well

13:39 let's say it's a weird group-by

13:39 gfredericks: multi-group-by? :)

13:39 I wrote such a thing and it's probably the only time I've tried to use nested transients

13:39 andyf: Fender: You could probably do that and make it work correctly, but you would need to do assoc on the map every time you did assoc! on one of the vectors it contains as a value, to update the top level map.

13:40 (or assoc! on the top level map, if it was also a transient)

13:40 gfredericks: ^ thus "awkward"

13:40 andyf: At the end, you'd need a pass of going through all vectors in the map to do persistent on them, again each time updating the top level map, and finally when all that was done, persistent on the top level map

13:41 Fender: hmmm

13:41 it may well be that I got some algorithms wrong then

13:41 andyf: possible, but best to isolate in one carefully written function.

13:41 Fender: it's just for performance actually becuase it's lots of data

13:41 gfredericks: I might have ended up using a java.util.HashMap at the top level; can't remember

13:42 andyf: Sure. performance is the only reason transients exist.

13:42 Fender: true^^

13:44 leandro1: if i do lein run my_param, it gets the para. but if i compile to .jar it can't get the param :(

13:44 clojurebot: Titim gan éirí ort.

13:45 gfredericks: leandro1: how do you run the jar exactly?

13:47 Fender: ok, thanks again, guys, without this channel I'd be looking for days

13:47 bye

13:48 leandro1: java -jar myjar.jar my_arg

13:49 andyf: gfredericks: assoc! and similar doc strings are not as explicit as I would have written them, but then most doc strings aren't :)

13:49 Hence my editing of ClojureDocs.org

13:50 leandro1: java -jar myjar.jar my_arg, gfredericks

13:50 gfredericks: andyf: I think there's a ticket with a patch for that

13:50 andyf: cuz I think I patched it maybe

13:50 leandro1: and your main function runs correctly but without the arg?

13:51 leandro1: yes

13:51 gfredericks: I can't think of how that would happen

13:51 leandro1: with lein works perfectly, gfredericks

13:51 gfredericks: if you can create some minimal example project, that might help us diagnose it

13:54 leandro1: yes, i have an example. 1 seg.

13:56 oh, my fault

13:57 i'm an idiot :) a typo

13:57 gfredericks: :)

13:59 leandro1: ,inc gfredericks

13:59 clojurebot: #<core$inc clojure.core$inc@18ceb26>

14:01 leandro1: ,(inc gfredericks)

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

14:01 gfredericks: (inc example)

14:01 lazybot: ⇒ 0

14:02 leandro1: whats the comma for?

14:02 (inc gfredericks)

14:02 lazybot: ⇒ 109

14:03 cristian3: Is there a way to make let bindings lazy? For instance:

14:03 (let [x "yay" y (println (str "yo"))] x)

14:03 gfredericks: leandro1: comma is for normal eval, wherewithalupon "gfredericks" is meaningless

14:03 cristian3: I'd expect println to not be called

14:03 gfredericks: cristian3: just manually with delay & deref

14:03 cristian3: Since it's not being used in the body of let

14:03 Ok... I'll look into it

14:03 Thanks sir

14:05 mr_rm: I know there must be an overflow here but i'm not sure how to fix it... why does this return an empty list? (take 6000 (drop 30000 (range 50000000)))

14:07 andyf: mr_rm: It doesn't for me.

14:07 mr_rm: andyf: hmmm are you using java 8?

14:08 andyf: mr_rm: Not in the test I just did, which was java 7, but I will try again on another machine with java 8

14:09 mr_rm: oh... hmmm. i just started a lein repl in my project and it works there. i was evaluating this in Eclipse ccw which is where i was seeing the empty list

14:09 that's odd

14:10 andyf: Eclipse ccw may have something that is limiting the size of the output? I haven't used Eclipse ccw

14:11 mr_rm: what's weird is it's fine with showing me the whole list if i just drop the first 30000. when i add the take 6000 it fails, but (take 5000) still works. yes there is some limit there but this sucks. i would have expected at least to get an exception

14:18 {blake}: Works for me everywhere I try it (but not using CCW).

14:22 mr_rm: {blake}: thanks for letting me know. yes it's fine in the plain lein repl here too. seems to be some problem with my eclipse CCW. everything is the latest (eclipse 4.4, java 8, ccw stable branch). i'm gonna go try the nightly branch of ccw or something later

14:23 gfredericks: mr_rm: curious what happens if you e.g. wrap the expression in (vec ...)

14:23 mr_rm: never ran into such an issue before where it just gave me a bad result

14:23 {blake}: mr_rm: I've ping-ponged between cursive and ccw and settled on cursive (where it also works).

14:24 mr_rm: gfredericks: restarting eclipse... 1 min

14:26 gfredericks: wrapping it in vec just returns [] :)

14:27 gfredericks: how about (count ...)?

14:27 mr_rm: ahhh (take 6000 (vec (drop 30000 (range 50000000)))) OutOfMemoryError Java heap space java.lang.Long.valueOf (:-1)

14:28 gfredericks: yeah that makes sense

14:28 mr_rm: without the vec, i get nothing :\

14:29 i'll try updating to a later "unstable" ccw version

14:29 gfredericks: I asked about count

14:30 which hopefully would distinguish between strange collection-printing-behavior and some deeper stranger problem

14:32 mr_rm: gfredericks: yes count worked. returned 6000

14:32 grandy: hello, new to clojure and working with compjure and cemerick/friend and experiencing a bit of confusion about how the simple form login works ... not sure if I have to implement the POST handler for /login

14:32 gfredericks: pr-str is another thing to try

14:32 or (apply str ...)

14:33 mr_rm: gfredericks: (range 6000) showed ok. yes i'll try your suggestion

14:34 gfredericks: ok... apply str turns it into one giant string. so it seems to be some weird display problem

14:35 gfredericks: yeah :/

14:35 at least that was the sanest possibility

14:38 mr_rm: i can doseq over it fine too. oh well... going to try later plugin now and see if that helps

15:00 mindbender1: How do I build a reusable tab widget in om?

15:01 justin_smith: grandy: friend can be confusing even for experienced clojure users.

15:02 grandy: justin_smith: is there a super simple auth library out there? or should i just keep at it?

15:02 justin_smith: seems like friend is very cleverly designed

15:02 justin_smith: there's a working friend example here https://github.com/eggsby/warden/blob/master/src/clj/warden/api.clj#L117-L152

15:03 another one here that may be more clear https://github.com/hiredman/ideapad/blob/master/src/com/thelastcitadel/ideapad.clj

15:03 grandy: it is clever, but not intuitive for most of us

15:04 grandy: justin_smith: well glad to hear it's not just me...

15:04 justin_smith: brb in 2 mins

15:05 mindbender1: what's clever about it?

15:06 justin_smith: mindbender1: it provides a pluggable authentication layer, without the prerequisite that you use some framework

15:07 and without much in the way of OO style state management

15:09 mindbender1: i.e. it cleverly leaves the authentication layer for you to worry about. What then does it provide? authorization?

15:10 justin_smith: it has functions that do authentication and authorization

15:10 via bcrypt/scrypt and ring middlewares, respectively

15:11 mindbender1: It also compojure based.

15:11 justin_smith: no, it is not compojure based

15:11 it's a ring middleware

15:11 nothing about it requires or uses compojure

15:12 mindbender1: Well I use pedestal and I had a hard time implementing it.

15:13 clauth even does a better job IMHO.

15:14 Yet I end up writing something that was more understandable to me.

15:16 justin_smith: mindbender1: I have used compojure and other ring based routing libs, and had a hard time implementing friend. The problem is the design is unintuitive. It isn't because you weren't using compojure.

15:17 grandy: which one do you guys think is the easiest/simplest?

15:17 mindbender1: I meant to say it used old style middleware composition which compojure is based on.

15:17 jjttjj: any guidelines/best practices out there for how to organize directory structures for projects with clojure and clojurescript?

15:18 justin_smith: mindbender1: well, anything that handles requests in the clojure universe is capable of middleware composition, it's just a functional design pattern.

15:18 s/anything that handles requests/anything/

15:19 grandy: oddly teh thing i'm finding confusing with friend is that when i submit the form to log in the login always fails, and as far as i can tell my code is equivalent to what is in the friend demo app

15:20 mindbender1: justin_smith: I agree. Just the effort required when you need to untie.

15:21 justin_smith: grandy: so you have a map of usernames and password hashes, and use the friend middleware to authenticate, and have a session store that stores the authenticated state?

15:21 grandy: username and password hashes: yes

15:21 middleware: yes

15:22 justin_smith: how are you storing the session?

15:22 friend doesn't do that automatically

15:22 and without a session you can't persist the state of a user being logged in

15:23 grandy: justin_smith: using ring middleware session and wrap-session -- session appears to work ( created a page that increments a value) but for some reason doens't appear to be using the config i'm passing in

15:23 justin_smith: OK

15:23 grandy: ahh i need to check where friend updates the session

15:26 this is my code: https://gist.github.com/anonymous/bf566201083c937e868d

15:26 justin_smith: just trying to get the basic auth/unauthed handlers working

15:28 justin_smith: so does pages/login get called when soemone tries to access /requires-authentication ?

15:29 grandy: yes

15:30 it's just a view template, actually i used the one that was used by the friend demo app

15:30 there is a function that wraps it with a layout, etc. before it is rendered

15:31 justin_smith: this is the login handler:

15:31 https://www.irccloud.com/pastebin/1Camp8sz

15:32 and login-form2 is identical to the one in the friend demo except that i implemented it as a function rather than as a global value

15:36 I also don't see anything referencing the session in this example: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/interactive_form.clj

15:37 justin_smith: oh - is friend using its own state / session separate from user provided?

15:37 I may be the wrong one to ask about using friend. Make that am.

15:38 grandy: justin_smith: not sure, just reading over the source

15:39 maybe i'll just implement a simple session based one for now

15:39 it's not fun being this stupid

15:40 justin_smith: yeah.

15:46 grandy: hmm

15:46 well thanks for all your help, justin_smith, both today and in the past

15:51 justin_smith: grandy: thanks. It's clear I'll have to figure out friend one of these days, maybe make a blog post or something walking through it.

15:57 mindbender1: The confusing aspect of friends is the workflow.

15:58 Figure that out and you know if friend is for you.

16:00 grandy: mindbender1: yeah i am now pasting in some of the friend source into my app so I can debug line by line and figure out what is going wrong...

16:21 gfredericks: is there a lib somewhere that adapts a java.net.Socket to a pair of core.async channels?

16:21 (for line<->msg equivalence)

16:28 bbloom: gfredericks: why do you need a lib for that? isn't it just a thread + a loop?

16:28 it's only tricky if you need to do multiplexing

16:28 gfredericks: bbloom: seems to be some tricky shutdown logic too

16:29 bbloom: I didn't mean a *big* lib :P

16:29 bbloom: the shutdown logic can be pretty simple depending on your needs

16:30 gfredericks: well I've got two different go loops going

16:30 and exceptions thrown in either of them will just disappear

16:31 grandy: justin_smith: got it working

16:31 bbloom: gfredericks: are there IOExceptions you have to catch for correct functionality of a socket? (i wouldn't be surprised, but i forget)

16:31 grandy: had the handlers set up nested incorrectly

16:31 justin_smith: grandy: interesting, what was the issue?

16:31 grandy: oddly it still worked

16:31 for serving requests, just not for authenticated ones

16:32 justin_smith: this app definition works:

16:32 https://www.irccloud.com/pastebin/GexTqrnq

16:32 gfredericks: bbloom: I don't know either, that's why I asked about a lib :)

16:33 bbloom: looking at docs, i'm pretty sure all you need to do is create a socket, then grab it's InputStream, then read from that stream in a loop

16:33 gfredericks: well I need to write also

16:33 justin_smith: grandy: so friend goes between the routing and the handler

16:33 gfredericks: thus two channels, two go-loops

16:33 grandy: yes

16:33 bbloom: gfredericks: sure, what i'm saying also applies for outputstream & writing

16:34 looking at this you can just call read and catch IOException if the channel is closed on you

16:34 gfredericks: bbloom: and my point is that the failure modes seem squared now that I'm doing both

16:34 they might not be

16:35 bbloom: that's gonna depend on your mode of use of the socket. are you reading/writing independently? is there some alternating between reading and writing? depends on the protocol

16:35 gfredericks: it's irc

16:35 so...anything's possible?

16:35 bbloom: *shrug* ii dunno much about irc's protocol

16:36 but i'd imagine async inbound messages can occur

16:37 anyway, the reason there's no lib for this is b/c it would be super specialized to a particular style of protocol

16:37 gfredericks: yeah? why would just two channels not be generally useful?

16:38 bbloom: b/c you may need to coordinate between reading and writing

16:38 like a handshake, for example

16:38 gfredericks: and channels make that harder?

16:39 bbloom: no channels can make that easier... it's just that having two of them that pump the in/out streams isn't what you want in that case really

16:40 gfredericks: you'd want a more complete abstraction over sockets. checkout http://golang.org/pkg/net/#Conn

16:41 gfredericks: if a lib just provided those two channels, it would also need to provide some mechanism for working w/ the java Socket object too, but it couldn't ensure you'd use it correclty w/ it's invariants (probably) so you'd really want to completely encapsulate the socket object

16:44 gfredericks: hmmm. good thoughts, thanks

16:44 (inc bbloom)

16:44 lazybot: ⇒ 49

16:47 Guest40995: Is (inc username) sort of like +1ing?

16:47 gfredericks: I think so

16:47 Guest40995: (inc gfredericks)

16:47 lazybot: ⇒ 110

16:48 Guest40995: (dec gfredericks)

16:48 lazybot: ⇒ 109

16:48 TEttinger: (inc gfredericks)

16:48 lazybot: ⇒ 110

16:48 Guest40995: ;(+ gfredericks 1000)

16:48 TEttinger: (identity TEttinger)

16:48 lazybot: TEttinger has karma 30.

16:48 TEttinger: only inc and dec and identity

16:49 Guest40995: Thats pretty cool

16:50 justin_smith: not what the actual clojure functions do though

17:08 officialxian: Hehy

17:08 Hey*

17:19 helpmeplease: can i disable cider's prompt to save a file when I do C-c k?

17:21 jeremyheiler: helpmeplease: yes. check out the cider readme... search for "save"

17:23 helpmeplease: jeremyheiler: thanks!

17:24 jeremyheiler: np

Logging service provided by n01se.net