#clojure log - Aug 13 2011

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

0:00 srid: deleting the first item of a list is surely O(1)

0:00 amalloy: no. vectors don't allow you to delete the first item

0:00 srid: right. immutability.

0:01 so if you poping from seq is O(1) why not just use vectors as queue (instead of using PersistentQueue)?

0:01 amalloy: no, i mean you can't do it and keep it a vector. but it's easy to drop an item from a sequential *view* of a vector

0:01 srid: s/vector/seq of vector/

0:01 lazybot: <srid> so if you poping from seq is O(1) why not just use seq of vectors as queue (instead of using PersistentQueue)?

0:02 amalloy: &(let [v [1 2 3]] (map class [v (rest v)])))

0:02 lazybot: ⇒ (clojure.lang.PersistentVector clojure.lang.PersistentVector$ChunkedSeq)

0:02 srid: ah. I didn't realize lazybot was a bot; though someone was fast enough to correct my question.

0:02 thought*

0:04 ok - so popped items are not garbage collected until the seq expires (and it expires when about half of the queue items are popped)

0:05 say, you have a queue of length 1000 (with 500 items in a list). until the 500th pop, none of the half of the queue's memory won't be freed.

0:05 s/won't/will/

0:05 lazybot: <srid> say, you have a queue of length 1000 (with 500 items in a list). until the 500th pop, none of the half of the queue's memory will be freed.

0:05 amalloy: that's true, but 1/2 is a random guess

0:06 if you conj them all before you consume any of them, the whole thing will be a vector before you seq it, and none will expire until you consume the full thousand

0:07 srid: right

0:10 "[…] subsequent attempts to use conj on [the value of (pop aPersistentQueue)] won’t preserve the speed guarantees of the queue type and the queue functions pop peek and conj won’t behave as expected."

0:14 amalloy: srid: link?

0:15 srid: this is from 'The Joy of Clojure'

0:19 amalloy: misquote

0:20 the part in brackets should read [the value of (rest aPersistentQueue)]

0:21 srid: ah, right. I mistook what the word "former" (in the preceding sentence) referred to.

0:32 dnolen: fun stuff, https://gist.github.com/1143483

4:38 leo2007: does , also mean unquote in clojure?

4:39 seems , means space

4:46 amalloy: you're looking for ~

4:48 leo2007: yeah

4:48 does anyone know if fuzzy completion in swank-clojure works fully? I cannot see any thing started with .

5:32 What does #' do?

5:38 thorwil: ,(macroexpand-1 '(#'x))

5:38 clojurebot: ((var x))

5:38 leo2007: I see. thanks

5:39 thorwil: called var quote on the clojure cheat sheet

5:39 http://clojure.org/cheatsheet

9:33 pyr: hi

9:33 facing a weird problem with swank-clojure

9:33 i have one box where it constitenly fails with:

9:34 Exception in thread "main" java.lang.IllegalArgumentException: No value supplied for key: true

9:34 whether in when calling lein swank or clojure-jack-in from emacs

9:34 the call stack goes up to start-server in swank.clj

9:34 raek: pyr: I think that is caused by having multiple versions of swank-clojure on the classpath at the same time

9:35 pyr: ah

9:35 weird, i killed the previous one i thought, i'll check

9:35 raek: pyr: check for old versions in the project.clj and in .lein/plugins/

9:35 also, does your project use incanter?

9:35 pyr: yes

9:36 raek: good find

9:36 raek: incanter pulls in an old version of swank

9:36 pyr: indeed incanter pulled swank

9:36 raek: :dependencies [[org.clojure/clojure "1.2.1"] [incanter "1.2.3" :exclusions [swank-clojure]]]

9:40 pyr: thx

10:08 wunki: anyone else had the problem that the "_id" field from a mongodb database (congomongo) couldn't be parsed to string?

10:08 pyr: meh, incanter has other problems it seems

10:15 so using leiningen fails but using the repl stuff works

10:36 tufflax: I have 32 bits as an integer, what's the easiest way to cram them into an int? The int will possibly become negative.

10:50 pyr: anyone ever got to the point where they could run incanter from leiningen ?

11:07 wunki: can anyone familiar enough with congomongo see this is intented behaviour: https://gist.github.com/1143937

11:08 sleepynate: wunki: (into [] (fetch ...))

11:13 wunki: sleepynate: then I'm putting a json string inside a list, since :as :json returns a string.

11:14 I want to return it in the body, with jetty, so I need a string

11:16 hiredman: clojurebot: ping

11:16 clojurebot: PONG!

11:16 sleepynate: wunki: erp? perhaps i misread your gist

11:17 oh apparently

11:17 so it's giving you {...}\n{...} as opposed to [ {...}, {...} ]

11:17 wunki: sleepynate: yes, exactly

11:18 and since I just began with Clojure, I don't know how to fix this

11:23 sleepynate: wunki: give me a few minutes and i'll help you investigate further :)

11:23 wunki: sleepynate: that would be awesome, appreciate it

11:24 sleepynate: sadly soldering waits for no man :p

11:25 wunki: well, I'll be waiting, since I'm stuck :)

11:25 sleepynate: watch a video from clojure-conj while you wait! http://clojure.com/blog/2011/03/23/conj-talks-all-up.html

11:34 duck1123: wunki: so your problem is the elements aren't wrapped in a list?

11:34 wunki: duck1123: yes, and comma separated

11:35 duck1123: well, comments are whitespace in clojure, but this is coming back as a json string?

11:35 I haven't used congomongo in a while, I switched to karras

11:36 sleepynate: (in https://github.com/aboekhoff/congomongo/blob/master/src/somnium/congomongo.clj#L229 <-- looks like the json is coming straight from mongo

11:36 duck1123: so you might be better off getting it as clojure and convert it to json when you're done

11:37 sleepynate: wunki: can you gist the minimal amount of code to reproduce your issue?

11:37 duck1123: You could even make a simple middleware to convert to json at the end

11:38 wunki: duck1123: I tried switching to clojure and I was able to replace the _id. But then came the "date" type

11:38 duck1123: ahh, I have the code for that

11:38 one sec

11:39 https://github.com/duck1123/jiksnu/blob/master/src/main/clojure/jiksnu/model.clj

11:39 wunki: sleepynate: I can do that

11:39 duck1123: it's in there

11:40 wunki: duck1123: should I move to karras? Do they do it correctly?

11:40 duck1123: I've never used any as-json option

11:41 I prefer to always have it back as clojure

11:41 wunki: duck1123: yes, but I'm building an API that needs to return a json. That's why I thought :as :json would be handy, since it does all the conversions for me

11:42 duck1123: I can't comment on karras vs congomongo except to say I like karras' concept of entities

11:42 eskatrem: Hello, is someone using incanter with clojureBox?

11:43 duck1123: I've found that I very rarely want to send the results of a mongo request as is

11:44 sleepynate: wunki: with congomongo "0.1.6" mine is coming back separated just fnie

11:45 but you're obviously pruning the id

11:45 wunki: sleepynate: do you get a good output from :as :json?

11:45 duck1123: is that coming back as a seq of strings?

11:46 wunki: I'm also on 0.1.6 btw

11:46 sleepynate: wunki: i do

11:46 duck1123: no, it comes back as properly formatted sjson

11:46 wunki: aren you removing the id yourself?

11:46 eskatrem: sleepynate, i dont know how to set up incanter

11:47 wunki: no, I'm doing nothing. I do use :only though

11:47 sleepynate: (fetch :collection :only [:title] :as :json)

11:47 ahh

11:47 hm

11:48 wunki: sleepynate: this is my gist: https://gist.github.com/2f49b471f21eb341891f

11:48 all json-response-cm does is adding the correct headers

11:49 sleepynate: duck1123: oh yea it is a seq of strings

11:49 wunki: so

11:49 wunki: here's my recommendation

11:50 duck1123: (str "[" (string/join ", " col) "]")

11:50 may have the order of join wrong

11:50 sleepynate: duck1123's suggestion will also work

11:51 i was going to say fetch a native structure and use clj-json

11:52 wunki: sleepynate: I tried doing that. But clj-json cannot handle the _id type

11:52 duck1123: is there much difference between clj-json and c.d.json?

11:52 sleepynate: duck1123: probably not

11:53 leo2007: folks, is fuzzy completion fully implemented in swank-clojure?

11:53 duck1123: if you go with c.d.json, the code at the bottom of the file I linked should sort you

11:53 that's what I use for my site

11:54 wunki: so I would need to use c.d.json and then look at your file for how to replace mongo's native types?

11:56 Hodapp: yup, banned from #java again.

11:56 duck1123: yeah, the last 4 block set handlers for date and ObjectId

11:57 you might need to adjust to fit your needs. Ie. I just print the id field

11:57 and I format the date as close to xsd:dateTime as I've been able to get it

11:57 Hodapp: Anyone here messed with Processing, particularly in its Clojure instantiation as Incanter and clj-processing?

11:58 duck1123: still need to put a colon in the timezone

11:58 wunki: duck1123: thanks, will try to incorporate it in my code

12:00 duck1123: so is #java particularly ban-happy?

12:22 eskatrem: Hello, can anyone help me install Incanter on ClojureBox?

12:24 duck1123: what issue is it giving you? Never used incanter

12:24 eskatrem: It's not even an issue, I cant find at all how to install it

12:25 duck1123: are you trying to use it in your project?

12:25 eskatrem: yes

12:25 (I am a Clojure noob)

12:25 raek: eskatrem: my suggestion is to use a project manager like leiningen and install clojure-mode in a clean emacs install

12:26 clojurebox offers no way to add dependencies, afaik

12:26 eskatrem: http://technomancy.us/149

12:26 duck1123: I suggest emacs-starter-kit

12:26 eskatrem: raek: thanks!!!

12:26 raek: I agree with duck1123 :)

12:27 duck1123: incanter is on clojars http://clojars.org/incanter

12:27 eskatrem: hmm it's kind of frustrating, I thought I would be able to install add any package from clojureBox

12:27 duck1123: so just add the code to whatever build system you use

12:28 raek: eskatrem: you add your dependencies with Leiningen: https://github.com/technomancy/leiningen

12:28 duck1123: clojurebox doesn't have elpa?

12:28 eskatrem: I dont think

12:28 but I can add it I guess

12:28 raek: clojurebox is just emacs with slime and clojure-mode installed and with a script to start a swank server

12:29 duck1123: eh, just get the starter-kit and then install the clojure stuff via packages

12:29 eskatrem: ok

12:29 raek: eskatrem: when you add incanter to your project.clj, you have to do a special thing currently: :dependencies [[org.clojure/clojure "1.2.1"] [incanter "1.2.3" :exclusions [swank-clojure]]]

12:30 eskatrem: so you guys are suggesting to forget clojureBox, install clojure and stuff to a standard emacs,, so that would include leiningen, and then I can add easily incanter and whatever else I want

12:30 raek: yes

12:30 eskatrem: ok

12:30 I gonna try that then

12:31 raek: when you have it set up, it works just like in clojurebox, except that you start the clojure instance in a different way

12:31 eskatrem: hmm sorry for asking another dumb question, but what exactly is the starter kit?

12:31 I can have that from elpa?

12:32 duck1123: https://github.com/technomancy/emacs-starter-kit

12:32 raek: eskatrem: the official docs for https://github.com/technomancy/leiningen and https://github.com/technomancy/swank-clojure are the places to look at. there are a number of other tutorials that are outdated.

12:33 duck1123: check that out as your ~/.emacs.d then M-x package-list-packages

12:33 raek: eskatrem: emacs-starter-kit sets up things like elpa for you and also includes the recent Marmalade repo

12:33 eskatrem: raek and duck: thanks! I will try that

12:33 now

12:33 raek: it's basically a bunch of good defaults for various things

12:35 eskatrem: you need to create a clojure project with "lein new your-project-name". in its project.clj you add incanter as a dependency.

12:35 eskatrem: raek: thank you

12:37 raek: 1) install emacs-starter-kit 2) install clojure-mode with M-x package-list-packages 3) create a new project with lein new 4) add dependencies and run lein deps 5) install the swank-clojure lein plugin 6) visit a file in the project directory and launch clojure with M-x clojure-jack-in

12:38 once you have everything set up, only 6) is required to get to work

13:33 dabd: hen I (spit <lazy-seq>) clojure writes the internal name of the seq instead of the literal representation. How do I

13:33 When I (spit <lazy-seq>) clojure writes the internal name of the seq instead of the literal representation. How do I force it to evaluate the seq?

13:33 AWizzArd: dabd: try (spit "c:/file.txt" (pr-str your-lazy-seq) :encoding "UTF-8")

13:34 dabd: thx

13:34 AWizzArd: If your-lazy-seq is too big you want to doseq through it (or have some comparable mechanism) and spit it out in pieces, where you add :append true

14:00 wunki: where should I look if I want to apply the ``str`` fuction to all "_id" elements in a sequence?

14:01 correction ":_id" elements

14:04 AWizzArd: wunki: what is a ":_id" element?

14:04 wunki: AWizzArd: It's the data I get from a MongoDB request.

14:05 AWizzArd: wunki: is it a sequence of maps?

14:05 wunki: AWizzArd: I think so (forgive me, started Clojure yesterday). This is how it looks: https://gist.github.com/537c470cd7459d036ba7

14:08 AWizzArd: wunki: ah okay, so it is a seq of maps that contain an :_id key.

14:08 You can (map :_id your-seq) and will get a seq of the objects

14:08 wunki: yes, and I want to apply the str function to every :_id

14:09 AWizzArd: Something like (apply str (map :_id your-seq))

14:09 wunki: even those that are nested

14:10 AWizzArd: that leaves only a ""

14:11 duck1123: is this for converting to json?

14:11 wunki: duck1123: yes, still

14:12 AWizzArd: wunki: then the values of those maps have the empty string as string representation.

14:12 duck1123: which json lib are you using now?

14:13 wunki: clj-json, but I was able to make strings from _id's, now I only need to do it recursively

14:16 applying ``str`` to the _id's does return a clean string with the sha

14:16 algernon: wunki: if you're using congomongo, it can do the json conversion automatically (fetch :as :json)

14:16 duck1123: it looks like clj-json has a coersions mechanism. You should be able to coerce ObjectId's into strings

14:17 wunki: algernon: yes, and that works great, but only when you have one objects. A list of objects doesn't work

14:18 duck1123: wunki: are you using 1.3?

14:18 algernon: interesting. it worked for me two weeks ago. (for some value of worked, it spew out a bunch of independent json strings)

14:18 wunki: duck1123: no, clojure 1.2

14:19 duck1123: algernon: that's what he had, it was returning a seq of strings, and he wanted it as a single string

14:19 wunki: duck1123: but only because 1.2 was in homebrew. Could use 1.3, I wouldn't know the difference at this stage

14:19 duck1123: ok, it looks like clj-json may not be 1.3-ready yet

14:20 it suggests binding *coercions*, but it's not marked as dynamic

14:20 I like the official lib's way of doing it better, personally

14:23 you're going to run into issues if you ever decide to store ObjectId's in places other than :_id

14:24 wunki: duck1123: I'm now able to replace the _id's with "test" string: https://gist.github.com/89b06d5d1dcadcc5e3bd

14:26 duck1123: (let [id (:_id s)] (assoc s :_id (str id)))

14:26 wunki: instead of "test" ?

14:26 duck1123: That would set :_id to the string version of :_id

14:27 Is there a fn that applies a fn to the value of a key in a map?

14:28 like alter, but one that just returns

14:28 st3fan: to each value of a key i a map?

14:29 duck1123: something like (alterish m :foo inc)

14:29 wunki: duck1123: that is pretty close now! https://gist.github.com/b63c6e601e074e1c0cf0

14:30 duck1123: it's easy enough to get that effect, just wondering if there's a name for that

14:31 tomoj: there is (update-in m [:foo] inc)

14:31 duck1123: wunki: I'm doing something very similar to yours apparently. http://beta.jiksnu.com/api/statuses/public_timeline.json

14:31 tomoj: nice. I'll have to remember that

14:31 wunki: duck1123: yes, you are right

14:32 only yours works :)

14:33 duck1123: are those dashes in your output, or just from copy/paste

14:33 wunki: no, somethings goes wrong

14:33 the output is nested to much

14:34 I think I didn't implement your code

14:34 at the right place

14:37 duck1123: form that last gist, it looks like you're associng the activity into the id

14:40 wunki: duck1123: omg, I think I did something right: https://gist.github.com/94af2114aa9456d1a280

14:41 creates: https://gist.github.com/47dab998331e446bc6c6

14:45 duck1123: nice

14:51 wunki: duck1123: two negatives, it now creates a :_id for every item in the sequence and it doesn't traverse deeper into the tree. Any pointers where to look?

14:53 duck1123: see, that's why I suggested using c.d.json originally. It would have gotten every objectid

14:53 wunki: duck1123: no, It does return the collection the right way, I just want to apply the "str" function deeper into the tree

14:54 duck1123: you could look into clojure.walk and family

14:55 right, The code I linked you to originally would've formatted every objectid just the way you wanted it

14:55 kjeldahl: Any cljs experts on? I'm struggling with "WARNING: Use of undeclared Var cljs.core/defn" and many similar when trying to get noir-cljs going...

14:56 wunki: duck1123: your code on github?

14:57 duck1123: yeah, the bottom of the model file was the code to add support for serializing ObjectId in json with the official json library

14:58 wunki: duck1123: I tried, but I couldn't get it to work. Sorry. Do you have the URI again? I know more know

14:58 duck1123: https://github.com/duck1123/jiksnu/blob/master/src/main/clojure/jiksnu/model.clj#L146

14:59 I extend the json writer so that it calls write-json-object-id whenever it gets an object id

14:59 but that doesn't work with clj-json

15:00 wunki: duck1123: I will swap my json engine with the one you use

15:01 duck1123: (binding [clj-json.core/*coercions* {ObjectId #(str %)}]

15:01 I beleive that's what you need with clj-json, but I don't use it, so I'm not sure

15:03 Hodapp: duck1123: To answer your question from several hours ago: Yes, #java is very ban-happy.

15:14 wunki: duck1123: where does the output of the json happen in your code?

15:16 duck1123: For jiksnu, that happens in the Ciste framework https://github.com/duck1123/ciste/blob/master/src/main/clojure/ciste/formats/default.clj#L11

15:16 ignore the content-type part. I need to fix that

15:19 wunki: duck1123: I got it working, thank you very, very much for your help

15:19 duck1123: keep an eye out on epis.to, you now have contributed to that :)

15:21 duck1123: glad I could help

17:31 XPherior: I have a vector like the following: [((3) (7 4)) (10 13 15)]. Is there a way that I can take the last element of the vector and merge it into the first one? The result would be [((3) (7 4) (10 13 15))]

17:31 Been having trouble getting cons to work how I want it to.

17:33 arohner: XPherior: I'm not sure what you want to happen. both sides of that look the same to me

17:33 XPherior: The (10 13 15) is inside the first list

17:33 So it becomes a vector of one list.

17:34 Rather than two

17:34 arohner: ah, ok

17:34 XPherior: Yeah, it's mildly confusing. Haha

17:34 arohner: I would use butlast and concat

17:34 XPherior: It's really getting me

17:34 arohner: and update-in

17:34 does the structure need to be that complicated?

17:34 XPherior: Okay. I'll check the docs on all of those. Thanks arohner! :)

17:35 Probably not. I'm just hacking away to pass my test, then I'll refactor.

17:35 Clojure is still a bit confusing for me.

17:35 arohner: yeah, it takes a little while to get used to functional thinking, and understanding what kinds of structures work well

17:36 in general though, cons is a low level operation

17:36 XPherior: I can see the point, though. Functional code is so much cleaner.

17:36 Oh? I wasn't aware of that.

17:38 arohner: cons specifically deals with seqs. many of clojure's data structure operations work against broader interfaces

17:38 i.e. conj

17:38 conj will work on a seq, or a vector or a map, or a set

17:38 XPherior: Short for conjoin?

17:38 arohner: yes

17:38 XPherior: Neat. =o

17:46 ,(concat [(1) (2)] (3))

17:46 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

17:46 XPherior: Why? :(

17:46 Oh wait. Nevermind

17:46 Ah, nevermind. I still dont know.

17:48 duck1123: XPherior: If you do (1) it tries to execute the fn 1 with no args. you want '(1)

17:49 XPherior: Ahhh, that makes sense.

17:49 I get tripped up on things like that so easily.

17:49 duck1123: ,(concat ['(1) '(2)] '(3))

17:49 clojurebot: ((1) (2) 3)

17:50 XPherior: Thanks!

18:11 tomoj: hmm

18:11 (defn foo "bar")

18:11 what is foo's arity??

18:11 it seems to have no arity at all

18:11 it's unarible

18:13 amalloy: tomoj: well, its arglists are (nil)

18:13 tomoj: weird

18:13 amalloy: so you call it with a list of arguments which does not exist, rather than one whose length is zero

18:13 tomoj: I almost didn't notice it compiled

18:14 I guess it will return a non-existent value?

18:14 amalloy: &(macroexpand '(fn))

18:14 lazybot: ⇒ (fn*)

18:14 amalloy: &((fn)

18:14 lazybot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: sandbox7610$eval9966$fn

18:14 tomoj: aha

18:15 (fn boom)

18:15 for quick "where is this called and with how many args"

18:15 amalloy: hah

18:16 ldh: in my webapp i've got a record which implements a data access protocol. what i'd like to do is track how many queries are made against the datastore to fulfill the request, and display that on the page. in javaland i might wrap calls to the query methods with AOP advice which increments a counter. what's the idiomatic clojure way to do this?

18:20 amalloy: oh man, aop. invisible code, for when spaghetti code is too easy to follow. anyway, i'd just wrap it in a function that increments a counter

18:22 (def counter (agent 0)), (defn get-data* [] (whatever)), (defn get-data [] (send counter inc) (get-data*))

18:22 duck1123: I guess the best answer is you would find a way to not have to

18:24 amalloy: duck1123: i disagree. that's a perfectly useful thing to want to do

18:25 and in a webapp using ring, you can just make it a middleware

18:26 duck1123: exactly, wrapping is useful, but you're better off trying to work around redefing fns and whatnot

18:26 ldh: amalloy: okay, thanks. that looks workable. i am using ring, so that's kind of an angle i was hoping to pursue

18:26 duck1123: so what do you propose?

18:27 duck1123: I do something like that in my app actually

18:27 I have the notion of actions, and for every action, you can append triggers that fire in a different thread

18:28 https://github.com/duck1123/ciste

18:28 I make all of these types of changes my actions and then I add triggers to them

18:29 I'm sure there are simpler solutions

18:29 ldh: interesting, thanks. i'll look at that.

18:31 duck1123: oh duh, you're looking for robert hooke

18:31 that'll do exactly what you want, although it stopped working for me

18:32 amalloy: blech. hooke doesn't compose well, and you can't do stuff like add a hook then remove it

18:32 duck1123: yeah, I don't use it anymore

18:33 I've been going between using ciste's triggers and lamina's channels

18:38 kjeldahl: Hard to say why, but I could not get noir-cljs working. However when I included the one source file in my own project instead of pulling it in through project.clj (jar), it works just great. An issue with the jar file perhaps?

18:59 paulK: hey everyone, have you worked with clojurescript?

18:59 I wonder how you got started and what your experience was

19:10 grant_: this must be easy, but i just am having all sorts of bad luck

19:10 in a lein generated project i have /src/myproject and /src/sample, sample being a sample project that uses files from myproject

19:11 how do i get /src/sample/core.clj to include functions from /src/myproject/core.clj?

19:11 i swear i have tried every combination of import and names separated with dots

19:11 from logical to totally nonsensical

19:12 amalloy: (ns sample.core (:use myproject.core))

19:12 grant_: thanks!

19:13 amalloy: i probably shouldn't recommend a wholesale :use. a better practice is (ns sample.core (:use [myproject.core :only [myfn1 myfn2]]))

19:13 grant_: right

19:14 so what does :use do?

19:15 actually i should be able to figure this out myself huh :P

19:15 amalloy: grant_: ns forms are hard to intuit

19:16 grant_: mm.

19:16 amalloy: (ns (:use ...)) really just calls (use), but that's not a very informative answer

19:16 grant_: well, that lets me do (doc use) :)

19:17 amalloy: (use) in turn calls (require), which loads the functions in myproject.core and makes them accessible by their long names, such as myproject.core/myfn; then (use) calls (refer), which gives you aliases to [some of] the functions without the namespace prefix

19:17 grant_: aah, neat, so core is pretty much hardcoded to be the main file of a project?

19:18 amalloy: no

19:18 grant_: why not, if use only loads stuff in core?

19:19 amalloy: (use) loads whatever files you give it as an argument. perhaps it's clearer if i write (use ...)?

19:19 grant_: yes that makes more sense

Logging service provided by n01se.net