#clojure log - Apr 19 2015

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

0:03 mfikes: myguidingstar: I suspect a deeper explanation is that printing results in more of the "tree" being realized recursively than dorun, which perhaps results in only shallow realization.

4:17 deanman: Is there a specific help channel for CIDER ?

4:30 expez: deanman: #clojure-emacs

5:00 how can I force all-ns to update itself after modifying the classpath?

5:01 (filter #(.contains (name %) "schema") (map ns-name (all-ns))) => ()

5:01 (require '[schema.core])

5:01 (filter #(.contains (name %) "schema") (map ns-name (all-ns))) => (schema.macros schema.utils schema.core)

5:55 visof: hi guys

5:56 i'm trying to package clojure app as war but some directories in the ROOT folder aren't packaged, if i want to deploy the war with tomcat, where should these directories should be located?

5:56 i tried it at WEB-INF/ and failed

6:32 sobel: visof: sounds like you need to set :resources-path

6:32 (i looked it up because i will need this soon enough, too)

7:11 shafire: runs my code automatically concurrent?

7:11 or do I need to do something?

7:12 ticking_: shafire: you need to do something

7:12 shafire: what features are you using?

7:12 core.async?

7:12 clojurebot: core.async is 100% imperative

7:13 shafire: I just looked at clojure

7:13 looking for something where concurrency is easy

7:14 ticking_: shafire: concurrency is never easy, but in clojure it's a lot easier ;P

7:14 immutable persistent datastructures help with locking

7:15 and pure functions are easily parallisable

7:15 e.g.

7:16 ,(map inc (range 5))

7:16 clojurebot: (1 2 3 4 5)

7:16 ticking_: will run sequentially

7:16 while (pmap inc (range 5)) will run in parralel

7:16 ,(pmap inc (range 5))

7:16 clojurebot: #error{:cause "no threads please", :via [{:type java.lang.SecurityException, :message "no threads please", :at [clojurebot.sandbox$enable_security_manager$fn__857 invoke "sandbox.clj" 94]}], :trace [[clojurebot.sandbox$enable_security_manager$fn__857 invoke "sandbox.clj" 94] [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkAccess nil -1] [java.lang.ThreadGroup checkAccess "Th...

7:16 ticking_: ah too bad

7:17 can use threads on the irc bot

7:17 *can't

7:18 shafire: there are also atoms and agents to help you with pararllelism

7:18 shafire: okay, thank you

7:19 ticking_: shafire: and if you just want concurrency instead of parallelism you can use core.async, which will schedule lightweight threads onto a threadpool

7:19 shafire: thanks

7:19 ticking_: shafire: it's quite similar to Golangs goroutines

7:21 luxbock: you can use core.async to do parallelism as well can't you?

7:21 ticking_: luxbock: yeah, but you have less control

7:21 as I said, it will be scheduled onto a thredpool

7:21 luxbock: ah right

7:22 ticking_: I mean, it's the same with futures and thus pmap

7:22 they also have a treadpool to run on (not sure if they are the same)

7:43 noncom|2: how do i call a method of something that was defined with deftype?

7:56 AimHere: noncom|2, create an instance of the type. If you (deftype foo [a b ..] Wibble (bar ..)) then you'd need to (def instance (foo. a b ..)) to create a foo called 'instance' and then (bar instance ...) to run the 'bar' method

7:56 quitter

8:04 expez: #^JarEntry <- what does this mean?

8:05 #(.getName #^JarEntry %) <- entire snippet. Is it typehinting what % is? Why bother?

8:20 I'm guessing the dispatch character # is optional when typehinting?

8:32 torgeir: ja, så æ har endelig fått dæ på clojurebølgen

8:32 oups

8:33 TEttinger: expez, correct

8:33 #^ is the old syntax for type hints

8:34 I believe it still works

8:34 but ^ is strongly preferred these days

8:34 expez: it does, I've just never seen it before heh

8:34 TEttinger: yeah it's not just old, it's very old

8:35 I believe it was around for 1 or 2 early versions before ^ became available and encouraged

8:36 expez: the reader just removes the typehints when I do read-string, isn't the reader involved in compiling this stuff to bytecode?

8:39 TEttinger: I'm not actually sure how read-string works with type hints. type hints may only be relevant when generating .class files, or they may be used in other places too

8:41 expez: My mental model of this is (eval (read <code>)) and eval takes care of generating the .class files, but that model seems wrong if read strips the type thints

8:44 read-string just delegates to read

8:55 Bronsa: expez: the reader doesn't remove the type hint. it's just that printing data doesn't print metadata by default

9:02 TEttinger: ahhhh Bronsa

9:02 (inc Bronsa)

9:02 lazybot: ⇒ 107

9:57 ambrosebs: Bronsa: it seems inadvisable/impossible to analyze an entire file without using analyze+eval at each form. Unsurprising I guess, your opinion?

9:58 Bronsa: ambrosebs: all kinds of stuff won't work, it's just not possible given clojure's evaluation strategy

9:59 ambrosebs: even the reader requires previous forms to be evaluated for e.g. ::foo style keywords or for ` auto-qualifying

10:00 it's not just macros the issue

10:01 ambrosebs: Bronsa: I'm thinking about running entire files through core.typed before it's ever evaluated by anything else. I'm realising this basically means I can only show errors now one top-level form at a time, since if I find a type error I'm not going to evaluate the form, then the rest of the file is basically untouchable.

10:01 noncom|2: does leiningen work differently when i use "lein run" and "lein jar" ?

10:01 when i do lein run, all works perfectly, however, lein jar fails...

10:01 TEttinger: ah, ambrosebs is the typed clojure smartperson and Bronsa is the analysis smartperson. this explains why I am not following this conversation :)

10:01 ambrosebs: Bronsa: unavoidable sounds like the right word

10:01 Bronsa: ambrosebs: you're not going to have any fun trying to implement that

10:01 ambrosebs: Bronsa: which part?

10:02 TEttinger: noncom|2: lein uberjar or lein jar?

10:02 lein jar doesn't produce a runnable jar IIRC

10:02 Bronsa: trying to avoid form-by-form evaluation :P

10:02 ambrosebs: ah yes

10:03 I guess I'll add that to my constraints :)

10:04 Bronsa: one thing I'll need to implement this is an analyze+eval variant where I can specify the AST -> AST function to "evaluate" the current top form.

10:04 Bronsa: I'll send you a patch or something once I've figured it out.

10:04 first thing's first, I'm on tools.analyzer 0.3.0.

10:04 Bronsa: sure -- if it's something I can incorporate in t.a.jvm I will take it

10:05 ambrosebs: core.async is finally on 0.6.x

10:05 ambrosebs: now that core.async is a little less ancient I think it's time to upgrade!

10:05 Bronsa: yup

10:05 ambrosebs: I was going to wait for a release

10:05 but screw it.

10:10 noncom|2: TEttinger: lein jar

10:15 TEttinger: noncom|2: I think, not sure, that lein jar doesn't put the manifest in your code that tells it to run the :main ns, and is more commonly used for jar distribution of libs?

10:16 you can unzip the produced jar, noncom|2, and check if there's a manifest

10:16 andyf: Now if we can just get tbaldridge in here, we should have a quorum for the tools.analyzer users club

10:17 ambrosebs: unite!

10:18 everyone is a tools.analyzer user, they just don't know it yet

10:18 andyf: Not quite everyone that uses Clojure/JVM?

10:18 Bronsa: time to add a hidden backdoor

10:19 ambrosebs: everyone who uses the hot new shiz

10:19 :)

10:19 andyf: Bronsa?s plans for world domination have been outed here, folks

10:20 ambrosebs: donating to Bronsa may come back to haunt me

10:21 andyf: or .... protect you. bwah hah hah

10:21 ambrosebs: :D

10:57 si14: ambrosebs: I believe you are the right person to ask :) can you please help me to understand how type hints work? It's meta on symbols, right? But how than things like (let [x (into-array ...)] ...) can help to avoid reflection?

10:58 ambrosebs: si14: they avoid reflection on things like method and field calls

10:58 and constructors

10:59 there's some basic type inference, like if `x`'s rhs knows its type hint, it gets propagated to all occurrences of x in the body

11:01 * si14 ambrosebs: so it's a compiler who propagates the hint? I had an impression that it should come with a binding itself

11:01 si14: (sorry, erroneous /me)

11:02 ambrosebs: the clojure compiler inserts the type hint if it's obvious

11:02 otherwise you can add it manually and it'll just trust you

11:02 not that inferring type hints should be "trusted" in any sense

11:03 they're just unchecked metadata

11:03 ,(read-string "a")

11:03 si14: yeah, I understand, thank you. basically I've tried to see why here https://gist.github.com/si14/c5d584bf622e6de91348 into-array *doesn't* propagate type hint

11:04 clojurebot: a

11:04 ambrosebs: what does *warn-on-reflection* say?

11:04 si14: without that ugly array hint it uses reflection in .set call

11:04 ambrosebs: ah

11:04 Bronsa: si14: into-array can't propagate the type hint

11:05 type-hints are compile-time things, the type returned by into-array is determined at runtime

11:05 ambrosebs: you'd need a macro of some sort

11:05 si14: it's "uknown" type according to reflection warning

11:06 Bronsa: uhm, now I'm confused. I think I saw an occasion when into-array prevented reflection, but maybe I'm just wrong

11:06 ambrosebs: ,(source into-array)

11:06 clojurebot: Source not found\n

11:06 Bronsa: nope that's not possible

11:06 ambrosebs: ,(doc into-array)

11:06 clojurebot: "([aseq] [type aseq]); Returns an array with components set to the values in aseq. The array's component type is type if provided, or the type of the first value in aseq if present, or Object. All values in aseq must be compatible with the component type. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE."

11:06 Bronsa: into-array doesn't have any type hint

11:06 it can't have a type-hint

11:07 si14: Bronsa: ok, I see.

11:07 so everyone resolve to super-ugly string-based array hints for hinting SomeClass[] ?

11:13 ambrosebs: si14: nah, I just don't use methods that require arrays ;)

11:17 si14: ambrosebs: that's a solution, too :)

11:18 anyway, thanks, ambrosebs and Bronsa!

11:18 ambrosebs: :)

13:30 sobel: anyone know how to pass a fully qualified (schema.tablename) table to jdbc?

13:30 postgresql

14:00 n/m, looks like . and _ translate literally from keywords

14:15 noncom|2: is it possible under any circumstances that clojure.core won't be referred to from a newly created namespace?

14:15 justin_smith: noncom|2: yes, if you use in-ns for example

14:16 you can call (clojure.core/refer-clojure) to fix it

14:17 noncom|2: interesting, now testing

14:20 yep! that did it!

14:35 how do i fix Can't change/establish root binding of: *ns* with set ?

14:35 (binding) is not a good variant in the current situation

14:36 justin_smith: noncom|2: this is what in-ns is for

14:36 noncom|2: well, this error happens exactly in the place where i use in-ns :)

14:36 justin_smith: that's because the ns does not exist

14:37 changing the root binding of *ns* without initializing the ns would cause the same problem

14:37 you can use ns (like you would in source files) for switching to an ns and getting default initialization if it is new

14:38 noncom|2: how do i pass a pre-calculated symbol to ns?

14:38 it behaves like a macro

14:39 justin_smith: it is a macro

14:39 noncom|2: so (let [ns-name 'the.good.ns.name] (ns ns-name)) won't work as expected

14:39 justin_smith: you would need to write your own macro

14:39 or use (in-ns ns-name) (clojure.core/refer-clojure)

14:39 noncom|2: the second variant does not work

14:40 idk how to do the first one

14:40 like write a macro wrapper for ns?

14:40 justin_smith: yes

14:40 how does the second variant not work?

14:41 noncom|2: yes, it does not

14:41 with the above error

14:41 macro like this?

14:41 (defmacro my-ns [sym]

14:41 `(ns ~sym))

14:42 justin_smith: right

14:57 noncom|2: justin_smith: i keep getting ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

15:02 justin_smith: here: https://www.refheap.com/99807

15:02 how is that?

15:13 lodin_: noncom|2: I think you end up with (ns 'a), but you want (ns a). You have (ns (quote a)) so ns sees a PersistentList, not a Symbol.

15:15 noncom|2: lodin_: yes, i would think so too, except if (type ~sym) would not return clojure.lang.Symbol ... ?

15:15 lodin_: noncom|2: It would.

15:15 ,(type 'a)

15:16 clojurebot: clojure.lang.Symbol

15:16 noncom|2: oh damn

15:16 lodin_: If you had (type a) then you would look up a and probabaly find that it is undefined.

15:17 noncom|2: Does that make sense?

15:17 noncom|2: probably...

15:17 if i try (second a) since i guess that (second (quote a)) would return a, it does not work too

15:18 since it cannottake second of a symbol

15:18 lodin: noncom|2: No, wait.

15:18 I think you are confusing what ns sees and what type sees.

15:19 AeroNotix_: is there something in core for "return true if there exists only one value in coll which (f element) returns true"

15:19 e.g. (only-ony? pred coll)

15:19 lodin: noncom|2: If you write (ns (second ~sym)) you still pass a list to ns.

15:19 AeroNotix_: e.g. (only-oney? pred coll)

15:19 pfft

15:20 noncom|2: AeroNotix_: yes, tehre is

15:20 AeroNotix_: noncom|2: what's it called?

15:20 noncom|2: => (some even? [1 2 3])

15:20 true

15:20 AeroNotix_: uhm, no

15:21 "there exists _only_one_value_"

15:21 noncom|2: ah

15:21 Bronsa: (comp zero? dec count filter) :P

15:21 noncom|2: lodin: that's sad..

15:21 is there a way around?

15:21 J_Arcane: I wrote an idler 'game' with Hoplon for Ludum Dare: http://ludumdare.com/compo/ludum-dare-32/?action=preview&uid=51484

15:22 ambrosebs: ,*clojure-version*

15:22 clojurebot: {:major 1, :minor 7, :incremental 0, :qualifier "master", :interim true}

15:22 lodin: noncom|2: Yes, take second _before_ you're in `(...).

15:22 ambrosebs: ,(let [x 1] (let [{:keys [a b] :or {a b}} {}] a))

15:22 clojurebot: #error{:cause "Unable to resolve symbol: b in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6543]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: b in this context", :at [clojure.lang.Ut...

15:22 ambrosebs: &*clojure-version*

15:22 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

15:22 ambrosebs: &(let [x 1] (let [{:keys [a b] :or {a b}} {}] a))

15:22 lazybot: ⇒ nil

15:22 lodin: noncom|2: Or do second in the unquote.

15:23 noncom|2: `(ns ~(second quoted-symbol))

15:24 noncom|2: lodin: but hen it comes:

15:24 => (macroexpand-1 (my-ns 'a))

15:24 MY-NS, [A] sym = (quote a)

15:24 CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(D:\temp\form-init5128613490254520947.clj:1:16)

15:26 lodin: noncom|2: (I think you are missing a quote before the form passed to macroexpand-1.)

15:27 Bronsa: ambrosebs: not a bug

15:28 noncom|2: lodin: strange.. can you modify my example on the refheap into a working one?

15:28 ambrosebs: Bronsa: I can believe that

15:28 Bronsa: ambrosebs: e.g. if you write `:or {b a}` it will work on master while it used to fail

15:28 ambrosebs: Bronsa: thought I might help out with a minimal case :)

15:28 yea seems inadvisable

15:29 Bronsa: ambrosebs: something changed the order of something involved in that, but it's unordered so nobody should really rely on that

15:29 ambrosebs: i believe andy posted something about that a bunch of days ago

15:30 lodin: noncom|2: Do you really want to pass 'a to my-ns? Or just a?

15:30 ambrosebs: yea. pretty unintuitive for it to break destructuring.

15:30 or at least change it

15:30 Bronsa: ambrosebs: kinda like the hash change in 1.6 -- broke a bunch of code that relied on order of unordered colls

15:30 noncom|2: lodin: i think it's just a. like it should be

15:31 Bronsa: ambrosebs: unintuitive at first maybe but destructuring doesn't promise you the binding order of destructured locals

15:31 lodin: noncom|2: Then you shouldn't use second.

15:31 noncom|2: (defmacro my-ns [sym] `(ns ~sym))

15:32 noncom|2: lodin: but that's what i have and it causes the error..

15:32 lodin: noncom|2: Because you did (my-ns 'a).

15:33 noncom|2: ah

15:33 lodin: noncom|2: So it because (ns 'a) which is not right.

15:33 ambrosebs: Bronsa: yes. just unfortunate I guess.

15:34 lodin: s/because/becomes/

15:34 noncom|2: lodin: right!

15:34 got it finally

15:34 thank you very much!

15:34 it works

15:34 lodin: noncom|2: No problem.

15:36 ambrosebs: Bronsa: I'm mostly just sad this is a decision you need to make if you want to use {} or #{} in user-level syntax

15:36 Bronsa: ambrosebs: yeah understandable

15:38 ambrosebs: uhm I don't think this particular case has actually nothing to do with {}, probably just an accident of how destructure is implemented

15:39 ambrosebs: ah ok.

15:39 Bronsa: so it might be a bug? depends if core considers binding order to be impl detail or decides to guarantee it I guess

15:41 given that there's also non :keys/:syms destructuring and that definitely is unordered I don't think it will be considered a bug though. dunno.

15:42 noncom|2: lodin: but how would i act if i want to pass 'a, not a ?

15:43 would i use (second) ?

15:46 ambrosebs: Bronsa: it's not entirely clear what the correct semantics are

15:46 Bronsa: what if a :keys variable is shadowing another variable?

15:47 I guess either 1) disallow overlap in :keys and :or 2) consider :keys being bound outside :or

15:48 kwladyka: I have error Use of undefined constant STDIN - assumed 'STDIN' during Artisan::call('migrate'); and Artisan::call('db:seed');

15:48 but only on specyfic server

15:48 oh not this channel, sorry

15:48 ambrosebs: also the case where (let [a 1 {:keys [a] :or {a a}} ...]) is unclear

15:50 lodin: noncom|2: `(ns ~(second quoted-sym))

15:50 Bronsa: ambrosebs: uh, righ

15:50 right

16:05 rombocua: (take 100 (iterate inc 1))

16:06 join #javascript

16:12 iamjarvo: does clojure allow -> in the method names?

16:13 trying to figure out if the -> does something special or part of the string

16:13 oddcully: like in map->Person?

16:14 nuwanda_: iamjarvo: it's part of the name

16:14 iamjarvo: nuwanda_ thank you

16:45 nyomaszto: I get this message when I'm trying to install lein: http://pastebin.com/raw.php?i=JNH1v1Nb

16:49 oddcully: nyomaszto: is it possible that you are behind a firewall?

16:50 nyomaszto: how do I know?

16:50 TimMc: nyomaszto: What happens if you visit that URL in your browser?

16:51 nyomaszto: TimMc: nothing

16:51 TimMc: And are you in a country or using an internet service provider that routinely interferes with web traffic? (e.g. China)

16:52 oddcully: nothing as in an error? white page?

16:52 nyomaszto: it's loadding

16:52 oddcully: could you use the means of your browser to detect, if a proxy is configured with your browser?

16:54 nyomaszto: it's download with wget

16:55 oddcully: if you hold the file you can place it in ~/.lein/self-installs

16:56 this still can indicate, that there is some proxy etc needed to be configured, since other parts will need it configured

16:56 on the other hand it could just have been a hickup with github

16:57 well that rymes

16:57 s/ry/rhy/

16:59 TimMc: nyomaszto: What happens if you try to install lein a second time?

17:00 nyomaszto: TimMc: same problem

17:00 TimMc: can I download the file and place it on that directory?

17:00 TimMc: without the script?

17:01 TimMc: I believe so.

17:01 hmm... that URL says .zip

17:02 You may need to rename the extension to jar

17:02 oddcully: do you have a (systemwide) wgetrc, that holds a http_proxy line?

17:03 nyomaszto: oddcully: no

17:03 oddcully: it was a mistake

17:04 oddcully: wget doesn't download the file, as well.

17:05 oddcully: to bad, because there would a HTTP_CLIENT var that you could set to wget -O

17:10 nyomaszto: AmazonS3 server is forbidden for my ip

17:11 oddcully: but your browser worked, right?

17:11 then move the file to ~/.lein/self-installs/leiningen-2.5.1-standalone.jar

17:12 nyomaszto: then?

17:12 oddcully: then do a `lein repl` and this should download some clojars/maven stuff

17:12 nyomaszto: oddcully: it works

17:13 thanks for your time

17:13 oddcully: yw

17:14 nyomaszto: what is this 'nrepl://127.0.0.1:38425'?

17:16 oddcully: this is the uri you can connect your e.g. editor to

17:16 nyomaszto: could you suggest a reference or a book or whatever

17:17 oddcully: i found this site ok to start: http://www.braveclojure.com/

17:17 ymmv

17:18 nyomaszto: I'm a python programmer

17:19 and I'm very like to learn something new

17:42 snrmwg: i want to create (nested) xml and i woulk like to stream the result. any idea how i can do that in clojure?

17:46 i want to create (nested) xml and i woulk like to stream the result. any idea how i can do that in clojure? i can find a lot about parsing a xml stream, but how can i create one?

18:23 profil: why doesnt this work?

18:23 ,(apply assoc-in [[0 0] [0 0]] [[0 0] 1, [1 1] 1])

18:23 clojurebot: #error{:cause "Wrong number of args (5) passed to: core/assoc-in", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (5) passed to: core/assoc-in", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 48] [clojure.lang.AFn applyToHelper "AFn.java" 171] [clojure.lang.AFn applyTo "AFn.java"...

18:24 profil: ,(apply assoc-in [[0 0] [0 0]] [[0 0] 1])

18:24 clojurebot: [[1 0] [0 0]]

18:24 devn: arrdem: you computing?

18:24 whilst in flight?

18:27 TimMc: profil: Because assoc-in only does one assoc operation.

18:27 ,(doc assoc-in)

18:27 clojurebot: "([m [k & ks] v]); Associates a value in a nested associative structure, where ks is a sequence of keys and v is the new value and returns a new nested structure. If any levels do not exist, hash-maps will be created."

18:27 TimMc: ,(doc assoc)

18:27 clojurebot: "([map key val] [map key val & kvs]); assoc[iate]. When applied to a map, returns a new map of the same (hashed/sorted) type, that contains the mapping of key(s) to val(s). When applied to a vector, returns a new vector that contains val at index. Note - index must be <= (count vector)."

18:28 profil: oh

18:28 TimMc: profil: It doesn't allow you to do a bunch "at once" like assoc does.

18:28 profil: why not :( hmm, and how do I solve it

18:29 TimMc: (Hmm... "only does one assoc operation" is misleading, because it only does one *path* and that may involve multiple assocs.)

18:29 profil: Reduce over your list of key-paths and values.

18:31 ,(reduce (fn [m [ks v]] (assoc-in m ks v)) [[0 0] [0 0]] [[[0 0] 1], [[1 1] 1]])

18:31 clojurebot: [[1 0] [0 1]]

18:32 profil: TimMc: yeah I like that, thanks man

18:33 TimMc: profil: That's essentially what assoc with multiple key/value pairs does anyhow, just more efficiently: https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L177

18:35 profil: TimMc: how is it more efficiently?

18:51 TimMc: profil: reduce has to call assoc-in each time in the example I gave you -- if you implemented the if/recur logic yourself like assoc does, you'd save those fn calls.

18:51 I don't think it's a major performance difference, though. If it mattered, you could benchmark it and see.

18:52 profil: going from [[0 0] 1 [1 1] 1] to [[[0 0] 1] [[1 1] 1]] makes it even longer, so I am thinking about recur instead of reduce

19:02 TimMc: profil: No, that's not a big or (possibly) even a real difference.

19:02 Don't try to optimize perf on this unless or until it is noticeably slow.

19:03 profil: no I am talking about readability, the reduce is getting large and hard to understand

19:37 justin_smith: how could a loop that traverses a sequence in order be more concise than the equivalent reduce? multiple accumulators?

20:23 TimMc: profil: It depends on how you're going to use this. Sure, [[[0 0] 1] [[1 1] 1]] is hard to read, but if you only see one keys/value pair at a time, it's not bad.

20:23 (in the actual code)

21:37 jefelante: might anyone be able to point me towards a github project that utilizes event sourcing? i'm getting jammed up in between simple tutorial and real program

22:12 TimMc: jefelante: I feel like maybe clojars uses it?

22:41 justin_smith: would it be a stretch to call datomic a sort of event sourcing?

22:53 dunderproto: Hi all, I just got a chance to read on Hiccup and thought it was very powerful. Only, I have a question -- how does one incorporate JavaScript into a clojure web app?

22:53 I have heard of clojurescript -- is that what I'm looking for? I don't need the entire web app to compile to javascript, only the client part of the web app

22:54 justin_smith: dunderproto: you have a few options. You can write regular javascript and supply it as a resource, or you can compile clojurescript to js.

22:54 dunderproto: the normal way to use clojurescript is only compile the client part of the app to js

22:54 but clj and cljs are compatible enough that they can share some code as well.

22:55 dunderproto: justin_smith: the rest of the app can then be in regular clojure, correct?

22:55 justin_smith: exactly

22:55 dunderproto: That helps a lot. Thanks very much. I guess I will read up on clojurescript

22:55 justin_smith: you can generate a mixed clojure / clojurescript project using leningen

22:57 for example lein new mies

22:57 https://github.com/swannodette/mies

22:59 dunderproto: thanks! I will check it out

23:00 TimMc: dunderproto: By the way, be careful with hiccup -- it's really, really easy to accidentally render user data as HTML. You might look at ato's fork for a more secure version.

23:05 dunderproto: TimMc: Thanks for the heads up

23:05 I will check that out

23:26 sobel: TimMc: could you nutshell that risk for me? does hiccup destructure for the caller?

23:32 justin_smith: sobel: it doesn't protect from injection of client data into the html

23:43 sobel: i'm not following the problem. client data that would go into the stream as data becomes markup?

23:44 justin_smith: sobel: right. And this is a security problem.

23:45 eg. if they insert js that loads something from a domain they control.

23:45 because given a db, data from one client could be rendered into another client's page (think access logs or comments pages)

23:46 and via this, a client can access another client's data

23:46 or direct them to a phishing site

23:46 or whatever

23:48 sobel: how does misrendered markup turn into cross-session contamination?

23:52 maybe there's some practice i don't do that is assumed because most people do.

23:53 justin_smith: sobel: imagine you have a commenting system, for example

23:53 sobel: ah gotcha

23:54 justin_smith: what TimMc is saying is that hiccup doesn't really prevent data from the user from being interpreted as markup

23:55 nuwanda_: justin_smith: to be fair, it doesn't do it by default, but it provides the functionality for it

23:55 justin_smith: nuwanda_: good to know, I wasn't aware of the details so I was just interpreting what TimMc said

23:56 sobel: hiccup.util/escape-html is apparently the secret sauce

Logging service provided by n01se.net