#clojure log - Jan 30 2015

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

1:59 irctc: Hello everyone

1:59 rhg135: Hi

2:00 irctc: I'm having an issue with destructuring

2:01 I defn a function with parameter-vector : [[firstPerson secondPerson] peopleVec]

2:01 when I try to pass in the peopleVec vector - REPL tells that I've passed too few parameters?

2:01 amalloy: your function takes two arguments

2:02 the second is called peopleVec, and the second is destructured as [firstPerson secondPerson]

2:02 er, the first is destructured

2:02 irctc: I understood that [firstPerson secondPerson] will be bound to the contents of peopleVec

2:03 therefore [firstPerson secondPerson] does not count as a parameter?

2:04 rhg135: :as

2:07 ianhedoesit: ,(defn foo [[fp sp] pv] (prn fp sp pv))

2:07 clojurebot: #'sandbox/foo

2:07 ianhedoesit: ,(foo [:first :second] :person)

2:07 clojurebot: :first :second :person\n

2:08 amalloy: shredder supply OP

2:09 oops, wrong wnidow

2:09 ianhedoesit: ,(defn bar [[fp sp :as pv]] (prn fp sp pv))

2:09 clojurebot: #'sandbox/bar

2:09 ianhedoesit: ,(bar [:first :second])

2:09 clojurebot: :first :second [:first :second]\n

2:09 amalloy: the dangers of connecting to twitch chat via irc i guess

2:09 ianhedoesit: irctc: does the above help?

2:10 irctc: ianhedoesit: :as binds the entire passed-in vector

2:11 ianhedoesit: yes, in the case of `bar`, `pv` is the name bound to `[fp sp]` (I think I said that correctly)

2:11 irctc: what I was hoping is selective binding like all the examples provide using let eg. (let [x y] [1 2])

2:13 correction: (let [[x y] [1 2]])

2:14 in my case I made the [1 2] vector a parameter of a function - I guess this not be the way function parameters work

2:15 ianhedoesit: I'm not smart enough to see the obvious is there is something obvious I'm missing, so mabe a more specific example would help?

2:15 amalloy: irctc: so, here is the thing. things in clojure which could be names can instead be destructured

2:15 the first half of a let-binding can be a name, so you can destructure it

2:16 each argument to a function could be a name, so you can destructure it

2:16 if you destructure a thing, you don't *also* name it

2:18 irctc: thx amalloy - let me process this for a moment(eg. work through an example)

2:27 got: (defn destruct-this-3 [[fp sp]] (println fp sp)) - my problem was to equate "let" and "defn" destructuring

2:28 In the case of a defn the second vector in let eg. [[x y] [1 2]] -- is implicit in the parameter one passes-in

2:29 amalloy: your statement make perfect sense now - many thanks

2:29 hellofunk: amalloy: you say "if you destructure a thing, you don't *also* name it" but what about :as ?

2:33 amalloy: that's a way to destructure it though

2:33 it's the way of destructuring which says, give this thing a name

2:34 hellofunk: i see, i follow, i understan' my G, i feel you!

2:56 irctc: anyone else using "pidgin" as irc client? what settings are you using, please?- trying to connect to bear.freenode.net is timing out for me

2:58 ianhedoesit: irctc: is there any reason you need to connect to bear.freenode.net? irc.freenode.net is a load balancer and any channel on the freenode network will work when connecting to any specific server, I believe.

2:58 irctc: ianhedoesit: only reason is that I couldn't find #clojure

2:59 will try again...

2:59 ianhedoesit: but you're on #clojure!

2:59 seancorfield: I only connect to irc.freenode.net and I'm here :)

2:59 irctc: ianhedoesit: through the web interface

3:00 ianhedoesit: ah, I see that now. may I ask why you wanted bear.freenode.net specifically?

3:00 irctc: in the web interface it shows me connected to that server

3:01 ianhedoesit: ah

3:02 I can't possibly imagine how this could change anything, but try chat.freenode.net maybe?

3:03 Kir: ianhedoesit: I'm in thanks - it did not show in the list - I had to connect manually

3:04 ianhedoesit: I haven't used Pidgin in years, but I think I know what you mean. it lists a number of networks like EFNet and whatnot but no freenode or something?

3:06 Kir: not quite: once connect to irc.freenote.net one get pull a list of all available rooms - searching for clojure in this list did not find this room

3:06 correction:..one can*

3:07 ianhedoesit: thanks all the same :)

3:07 ianhedoesit: oh, okay. well I don't know what I did but I'm glad you're not using an awful web interface anymore.

3:07 still, you could do better than pidgin.

3:07 :)

3:08 Kir: I'm open to suggestion?

3:09 ianhedoesit: Kir: *nix or Windows?

3:10 Kir: I use both

3:10 currently on windows

3:12 ianhedoesit: it seems like a lot of people are rather fond of Hexchat, especially those who use both Windows and some flavor of Linux since it's cross-platform

3:12 fairuz: I use pidgin both in windows and linux

3:12 quite happy with it

3:12 ianhedoesit: it's also open source, which is nice.

3:13 * Kir go to test Hexchat

3:13 ianhedoesit: Kir: listen to fairuz if you wish! I cannot speak for the usability of Pidgin today - like I said it's been years since I've used it.

3:14 if you want to make your friends think you're a hacker, use irssi like me! people will think you know far more than you actually do!

3:14 fairuz: :)

3:14 agree ^

3:15 rhg135: Telnet ftw

3:15 Kir: lol

3:16 daniel__: ianhedoesit: i use irssi tooo

3:17 and i3 window manager

3:17 ianhedoesit: "what are you doing?" "I am establishing an ssh connection to my vps in SF with an attached tmux session to talk to some chans on irc about clj"

3:17 "so you're hacking?"

3:17 fairuz: "of course"

3:17 ianhedoesit: daniel__: I have no wm. I'm so hip and retro.

3:19 daniel__: ianhedoesit: i boot straight into emacs

3:19 ianhedoesit: lol

3:19 rhg135: I flashed it to my bios

3:25 Kir: ianhedoesit: hexchat is looking like it will replace pidgin - only think I'm missing is the ability to stop logging when users login/logoff?

3:25 thing*

3:28 ianhedoesit: Kir: in irssi I just /ignore #clojure: JOINS PARTS QUITS MODES TOPICS

3:28 well, /ignore #clojure JOINS PARTS QUITS MODES TOPICS

3:28 without the :

3:28 but that might not work in hexchat, I don't know

3:28 Kir: Oh, pardon, didn't notice your not using it

3:28 rhg135: Right click the channel in the menu

3:29 Kir: you're*

3:30 ianhedoesit: Kir: http://wiki.xkcd.com/irc/Hide_join_part_messages#HexChat

3:31 * Kir face-palm

3:31 Kir: thx ianhedoesit

3:32 ianhedoesit: :)

3:36 daniel__: i do /ignore ianhedoesit

3:48 ianhedoesit: daniel__ no

3:48 why me

3:48 daniel__: just kidding ianhedoesit :)

3:49 ianhedoesit: how can I know you're actually replying to me if you ignored me!

3:51 daniel__: ianhedoesit: yes, i hacked irssi to reply on my behalf

3:51 to trick you

3:52 ianhedoesit: you did say you boot straight into emacs, so I'm inclined to believe you.

3:53 daniel__: you're talking to ELIZA

3:55 ianhedoesit: I feel much more at home knowing that.

4:16 sm0ke: hello i want to ^:replace a bool property in lein. but meta cant be applied to bools i think

4:16 ,^:replace true

4:16 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

4:16 ianhedoesit: ,^:replace [true]

4:16 clojurebot: [true]

4:17 sm0ke: ianhedoesit: what about false?

4:17 ianhedoesit: sm0ke: I was just dealing with that for something. it's not a very elegant solution since you need to mess with how you deal with it, but until someone gives a better answer that seems okay?

4:18 sm0ke: what do you mean? the point is that all the containers can have metadata (I think?)

4:18 sm0ke: ianhedoesit: no, its just not about having metadata somehow

4:18 ianhedoesit: so just wrapping anything in a vector or list or whatever will allow it to have metadata

4:19 I must be misunderstanding what you're asking

4:19 sm0ke: ianhedoesit: the problem is ^:replace false is like saying ovrrite this property value with a false

4:19 so i can just say ^:replace [false] because ##(true? [false])

4:19 lazybot: ⇒ false

4:20 sm0ke: lol what

4:20 ,(doc true?)

4:20 clojurebot: "([x]); Returns true if x is the value true, false otherwise."

4:20 ianhedoesit: sm0ke: any vector is truthy

4:20 only nil and false are falsy

4:20 ,(true? 0)

4:20 clojurebot: false

4:20 ianhedoesit: oh

4:20 and 0

4:20 sm0ke: ah

4:20 ianhedoesit: yes exactly my point

4:20 ianhedoesit: ,(true? [])

4:20 clojurebot: false

4:20 ianhedoesit: oh

4:20 wow

4:20 I was wrong

4:20 sm0ke: ianhedoesit: no it just checks for `true` literally

4:20 ianhedoesit: oh

4:20 sm0ke: not logically

4:21 ianhedoesit: :D

4:21 well I don't know much of anything about nothing so I'm just gonna be quiet about what you're doing so as to not make things worse.

4:21 sm0ke: ,(when [false] "This cant be true!")

4:21 clojurebot: "This cant be true!"

4:22 sm0ke: its always nice to get another set of eyes though

4:22 ianhedoesit: Raynes: I'm making something similar to tentacles but for something other than the GitHub API - I've been using some of tentacles.core as a learning tool for a great way of doing api calls and I hope you don't mind me using a couple functions as starting points. obviously not just copying it, but I've been learning a lot from your api-call and related functions and can't imagine any better sort of structure for something like that.

4:22 TEttinger: ,(when 0 "this can't be true!")

4:22 clojurebot: "this can't be true!"

4:22 ianhedoesit: TEttinger: this is the place where I think I was right (only false and nil are falsy)

4:23 TEttinger: yes

4:23 ianhedoesit: ,(if [] true false)

4:23 clojurebot: true

4:24 sm0ke: this is very basic there must be some trick for this

4:24 many lein properties are boolean

4:24 and they heavily use metadata too

4:25 ianhedoesit: sm0ke: because I don't fully understand but I want to, what exactly are you talking about? I don't have a very good understanding of how lein works.

4:27 sm0ke: ianhedoesit: you can have lein profiles with confilicting data e.g. profile1 says :aot true while profile2 says :aot false, now i want to give one profile precendence for replacing the others

4:28 so if you are doing lein with-profile +pf1,+pf2 what would :aot be?

4:29 ianhedoesit: I have no idea. I didn't know you could target multiple profiles at the same time like that. I've only done like `lein with-profile test`

4:31 is the project.clj file read just like any other clojure file? as in can you have arbitrary evaluations in the file? or is there a bit of magic done by lein?

4:32 sm0ke: i dont know internals of lein, but i guess it would be a `read-string`, defproject is a macro afterwall

4:32 its a regular clojure file

4:33 ianhedoesit: hm, right.

4:33 sm0ke: you can actually put (println "hello") before (defproject..) and it would be printed for every lein task

4:33 you do pretty fancy things with it

4:33 you can*

4:34 its kind of awesome to have a programmable build file :D

4:35 ianhedoesit: have you tried boot?

4:36 sm0ke: no, i am kind of very amazed with lein itself

4:37 its too overwhelming for me

4:37 ianhedoesit: I haven't tried Boot, and I'm obviously a novice lein user, but the people who say anything about boot tend to make it seem magical.

4:38 sm0ke: magic is good but stability and features are biggest factors imo

4:38 i will read the rationale behind boot some day though

4:40 nacon: Anyone having experience with clojure.java.jdbc and postgres' new json/jsonb types? Especially the writing/reading in combination with clojure.data.json. It seems I have to create a PGobject myself and set the type and value..

4:40 ianhedoesit: I was trying to think of a word better than magical. I wasn't trying to say it did a bunch of non-obvious magic or anything - from my understanding it's the opposite, which I enjoy.

4:44 mavbozo: nacon: have you tried https://github.com/remodoy/clj-postgresql ? it seems like they have automatic json conversion

4:45 nacon: mavbozo: no I'm using the clojure.java.jdbc api right now -- but might give this a try, thanks!

4:54 slipset: I'm just starting out with https://github.com/krisajenkins/yesql

4:54 so you can write the sql queries as select foo from bar where qux = :qix

4:55 but when calling the query, I haven't found a way to pass the params to the query in a named fashion.

4:55 eg, I'd like to do (query-quxes db {:qix "lols"})

4:55 is that possible?

4:56 for this example it's not so important, but when having multiple params, I'd rather not remember their order.

4:57 https://github.com/krisajenkins/yesql/issues/8

4:57 ianhedoesit: slipset: what do you mean remember there order?

4:58 slipset: well, if I have a query like "select * from foo where bar = :bar and qix = :qix"

4:58 I need to pass the arguments in order when I issue the query

4:59 (foos-and-bars db "value for bar" "value for qix")

5:01 ianhedoesit: slipset: it looks like that's been fixed since September, though?

5:01 https://github.com/krisajenkins/yesql/releases/tag/v0.5.0-beta1

5:01 slipset: Yeps, but not in the non-beta version I guess which is 0.4.0

5:02 ianhedoesit: I was confused because I've used yesql for a couple things and I pass around maps just fine.

5:02 I'm using 0.5.0-rc1

5:02 slipset: but yes, I'll just upgrade to 0.5.0-rc1 and check it out

5:02 ianhedoesit: there's also rc2 as of a week ago, I didn't realize.

5:06 slipset: ianhedoesit: it worked, thanks!

5:06 ianhedoesit: slipset: yup, no problem.

5:06 slipset: ianhedoesit: so if I have a query "select foo from bar" and issue it using yesql, I'll receive something like this:

5:07 [{:foo "value1"} {:foo "value2"}]

5:08 * slipset is writing queries quicker than he can get access to the db

5:08 ianhedoesit: I believe so, yes.

5:09 I mean I don't know if it's a vector or what container it is, but that shouldn't really matter.

5:09 slipset: (inc ianhedoesit)

5:09 lazybot: ⇒ 1

5:10 ianhedoesit: but for example, (first (query/select-all)) => {:id 1 :foo "bar"}

5:11 that is a working test.

5:11 slipset: thanks

5:11 ianhedoesit: also, hey thanks! :) my first inc, whatever that means.

5:12 slipset: I have no idea, I just see that people get inc'ed whenever they seem to deserve it :)

5:12 (karma ianhedoesit)

5:13 https://github.com/Raynes/lazybot/wiki/Commands

5:13 lazybot doesn't seem to respond well to karma queries

5:16 ianhedoesit: yeah, I was just looking at the source.

5:21 skratl0x1C: is it possible to model an undirected immutable graph, without duplicating the data? ie. without having each vertex in the structure more than once?

5:24 clgv: skratl0x1C: depends what you do not want to replicate. you can identify the vertex via an integer id and then use either an adjacency matrix or an edge list to represent existing edges

5:24 skratl0x1C: then you'd keep the data separate so that you can look up the data via the id

5:25 skratl0x1C: clgv: aha, so I should give them IDs and store the adjacency data separate from the vertex/edge data?

5:26 ianhedoesit: (identity slipset)

5:26 lazybot: slipset has karma 0.

5:26 ianhedoesit: (identity ianhedoesit)

5:26 lazybot: ianhedoesit has karma 1.

5:26 slipset: :)

5:26 was just RTFS'ing myself :)

5:27 ianhedoesit: (inc slipset)

5:27 lazybot: ⇒ 1

5:27 slipset: :)

5:27 ianhedoesit: for reading source!

5:27 slipset: everybody lies, except the source

5:28 given, of course, that the source is not self-modifying

5:28 clgv: skratl0x1C: yes, that's the common way in most graph algorithms

5:29 ianhedoesit: I'm curious as to why the README points to the wiki on the flatland fork when that one isn't being updated or mirroring Raynes' repository

5:29 sm0ke: clgv: hello, :classifiers may be of interest to you

5:30 slipset: ianhedoesit: at least now the documentation is more correct

5:30 https://github.com/Raynes/lazybot/wiki/Commands

5:30 clgv: sm0ke: what?

5:31 sm0ke: clgv: about the test thing which i was asking yesterday

5:31 ianhedoesit: slipset: neat! :)

5:31 sm0ke: i though it might be of interest

5:31 clgv: sm0ke: ah ok

5:32 sm0ke: clgv: you can have a :classifiers {:tests {:source ^:replace []}}

5:32 in lein and it will install the test sources with `tests` classifier in maven

5:32 :D win win!

5:32 its pretty cryptic there are no docs for it

5:33 hyPiRion: sm0ke: oh dang, really? We should fix that

5:33 sm0ke: i am thinking of sending a pr to lein for this

5:33 hyPiRion: i have a issue for it

5:33 https://github.com/technomancy/leiningen/issues/1589

5:33 hyPiRion: oh

5:33 sm0ke: will send a PR, you can also do :classifiers {:foo :foo}

5:34 and it will pick up the :foo profile

5:34 slipset: hyPiRion: http://2015.flatmap.no/

5:34 sm0ke: its pretty neat hugo duncan guy committed this

5:34 slipset: ;)

5:34 hyPiRion: sm0ke: I'd totally send out stickers for that PR

5:34 sm0ke: :D i want i want

5:35 ianhedoesit: hyPiRion: you have stickers?

5:35 sm0ke: hyPiRion: you will send me a sticker for a doc pr ?

5:35 wow let me add that right now

5:35 hyPiRion: ianhedoesit: yeah

5:35 ianhedoesit: :O

5:36 I've never had more incentive to learn a tool and contribute to it than right now.

5:36 hyPiRion: sm0ke: of course, any accepted PR gives you rights to a sticker

5:37 sm0ke: nice

5:37 hyPiRion: ianhedoesit: haha, we should probably emphasize it a bit more

5:37 for some reason many people still doesn't know about the stickers

5:38 ianhedoesit: I do remember seeing it when I first read the leiningen page I think. to be fair, it is the very last sentence on the page apart from the footer.

5:39 Glenjamin: hrm, damn - i could have sworn i had a leiningen commit

5:39 hyPiRion: slipset: I want to wait a tiny bit before submitting, as I believe I have a new persistent data structure brewing. (But I need to prove some property first)

5:40 I think that might be interesting to speak about, along with the pvec.

5:41 ianhedoesit: https://twitter.com/technomancy/status/21632759649

5:42 "10 months old and 41 contributors"

5:44 tomjack: pvec?

5:44 hyPiRion: tomjack: persistent vector

5:44 It's so long to write

5:45 tomjack: ah

5:45 ianhedoesit: hypirion.com/musings/understanding-persistent-vector-pt-1

5:45 hyPiRion: that?

5:45 hyPiRion: ianhedoesit: yup

6:16 hellofunk: anyone in here got an emacs erc setup that only shows direct mentions in the mode line, and not all other channel activity? i've been trying to figure this out for days. #emacs guys haven't had much to offer

6:19 dysfun_: emacs fanboy as i am, i use irssi

6:51 luxbock: ,(let [[:a :b & :rest] [1 2 3 4]] [a b rest])

6:51 clojurebot: [1 2 (3 4)]

6:52 luxbock: o_O

6:52 is there a use case for this?

6:54 Glenjamin: well, that's odd

6:55 Bronsa: it works as an accident since 1.6

6:59 luxbock: Bronsa: do you know why the (keyword? b) clause is needed in the 1.6+ clojure.core/destructuring?

6:59 I'm working on something destructuring related and was puzzled by it when reading the source

7:00 Bronsa: ,(let [{:keys [::foo]} {::foo 1}] foo)

7:00 clojurebot: 1

7:00 Bronsa: luxbock: ^ to allow support for destructuring namespaced keywords

7:00 luxbock: oh

7:01 (inc Bronsa)

7:01 lazybot: ⇒ 89

7:02 hellofunk: (set! Bronsa (* Bronsa Bronsa))

7:08 RoccoD: Hi, is this also the channel to ask about clojurescript ?

7:10 hipsterslapfight: RoccoD: #clojurescript

7:10 RoccoD: oeps. sorry, thanks

7:16 kitallis: what would be the easiest way to search within a list of vectors like (["a" "val"] ["b" "val"]) for the value of a specific key like "b"?

7:17 Bronsa: ,((into {} '(["a" "val"] ["b" "val"])) "b")

7:17 clojurebot: "val"

7:19 hyPiRion: ,(first (for [[k v] '(["a" "val"] ["b" "val"]) :where (= k "b")] v))

7:19 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Invalid 'for' keyword :where, compiling:(NO_SOURCE_FILE:0:0)>

7:19 Bronsa: s/where/when

7:19 hyPiRion: yesh

7:19 kitallis: cool

7:19 hyPiRion: I do that mistake all the time :(

7:20 expez: does `lein capsule` work or is it extremely alpha?

8:27 justin_smith: expez: funny, it looks like new code got pushed to that repo about 30 minutes after you asked that. Not that this is an answer to your question :)

8:27 expez: justin_smith: yeah I submitted a minor bugfix

8:27 justin_smith: ahh, OK

8:28 expez: justin_smith: I'm trying to get it to package it refactor-nrepl so we don't pollute the user's classpath with tooling related dependencies.

8:28 I think the generated capsule is OK now, but it fails to register the middleware

8:37 justin_smith: interesting

8:42 jlamain: if i have a defrecord "rec" and I do an assoc on it (assoc rec :x 0) i get a new record. But if i have records containing records, if i change the inner record, does the outer record change ? or does it contain the old value ? I have a bit of a hard time coming from a c++/javascript background ;-)

8:43 justin_smith: jlamain: records do not change

8:43 jlamain: assoc creates a new record

8:44 jlamain: so to update a record inside a record, you are creating new versions of both

8:44 jlamain: update-in makes this easy

8:44 ,(update-in {:a {:b 1}} [:a :b] inc)

8:44 clojurebot: {:a {:b 2}}

8:44 justin_smith: jlamain: note how really we only updated the inner hash-map

8:45 jlamain: but technically two new hash-maps were created

8:46 and yes, the original {:a {:b 1}}, if we still had it around, is unmodified (in this case it was garbage collected because we have no pointer to it)

8:46 jlamain: thanks justin. But now the question. If i have a record implementing a protocol. A function in this protocol needs to add something to the record. Can the function add something to "this" ? if so how is this working for the upper records. if not, what is the clojure way to do suys things?

8:47 justin_smith: jlamain: the protocol method would be able to return a modified version of "this", it is up to the caller to use it or not, the original is unmodified

8:48 jlamain: the behavior of records is identical to the behavior of hash-maps in most ways, including this one

8:49 jlamain: in fact, I would use update-in in order to update the record via its protocol method, if the record were inside another one

8:52 jlamain: justin_smith: thx. Then i'm completely out of ideas how to complete implementing somethink like a UI dsl like in my gist: https://gist.github.com/jlamain/478c6978816b71257930. basically I have functions creating records. (layer, rectangle). But if some aotm changes i need to update some internal fields in a record. This means i should update all higher records also ? Please do not laugh too hard about my first clojure(script)

8:53 justin_smith: jlamain: the key is that anything modified needs to be passed into the modifying function, and also returned from it

8:54 if you need to do a series of updates, you likely will end up doing a chain of update-in operations, inside a swap! call if it must be an atom

8:54 Glenjamin: i quite like using (->) for DLS

8:54 DSLs even

8:54 justin_smith: Glenjamin: yes, -> / ->> are definitely called for when doing multiple updates within one nested data structure

8:56 jlamain: you could simplify the code to render-translated as follows: new-translate (-> translate (update-in [:x] + x) (update-in [:y] + y))

8:57 that chains both the updates into one logical operation, without needing to bind the individual new values

8:57 SagiCZ: jlamain: do you really need that protocol? maybe you could just use hash-maps?

8:57 justin_smith: jlamain: also, do blocks are not needed in let bodies

8:59 perplexa: what would i do if i have [1 2 3 4 0 5 6] and want [1 2 3 4 5 6]? ie. drop the 5th item from the vector

8:59 octatone: Hello

8:59 I am a clojure noob, is there an easy way to log to repo from Midgje auto test in my tests?

8:59 SagiCZ: perplexa: you could join two subvectors.. but no there is no core function that does that

8:59 justin_smith: perplexa: create a new vector, if you need to do this alot, don't use a vector, dropping from the middle is not efficient

8:59 octatone: ^repl

9:00 perplexa: nah, i'm just doing this to modify values for the tests ;x

9:00 i reuse intermediate results

9:00 but i need to drop a row

9:00 octatone: midje seems to just pr-str

9:00 jackhill: justin_smith: what would you use if you needed to do it a lot?

9:01 Glenjamin: a hash-map

9:01 justin_smith: jackhill: finger-tree

9:01 octatone: seems to just eat it

9:01 jlamain: SagiCZ: you mean operating over hash maps using functions ? No records anymore ?

9:01 justin_smith: jackhill: or rrb

9:01 * Glenjamin googles finger tree

9:01 hyPiRion: jackhill: RRB-tree. core.rrb-vector. But it sort of depends on how large they are

9:01 for less than 1000 elts it's probably not worth the effort.

9:01 SagiCZ: jlamain: yeah.. but maybe this is easier.. in similar code of mine i used regular hash-maps with :type keyword and multimethods that dispatch on the :type.. very powerful and easy to extend

9:01 jlamain: justin_smith: thanks for the improvements

9:02 jackhill: justin_smith, hyPiRion: awesome, thanks. I was just curious what was out there

9:02 justin_smith: jlamain: records and hash-maps are behaviorally identical, except with records you have optimized default field lookup, and the possibility of protocols instead of functions (also potentially an optimization)

9:05 octatone: I just want to log to repl from midje autotest ... is this possible? It seems that pr-str is just eaten

9:05 justin_smith: octatone: what do you think pr-str does?

9:05 octatone: prints ?

9:05 justin_smith: no, it creates the string that would be printed if you had printed

9:06 you just want println

9:06 ,(pr-str :a)

9:06 clojurebot: ":a"

9:06 justin_smith: ,(do (pr-str :a) nil)

9:06 clojurebot: nil

9:06 justin_smith: no printing

9:06 hyPiRion: ,(prn pr)

9:06 clojurebot: #<core$pr clojure.core$pr@38950703>\n

9:06 hyPiRion: yayy

9:06 octatone: thanks

9:07 jlamain: oke. thx. i'll try to do with multimethod than. But i'm still confused about the propagation of updated records/hashmaps to upper values. So the multimethod returns a new hashmap when updated and the the upper hashmap does an assoc. hmm. Quite hard embedded engineer normally doing c/c++/javascript ;-) haha

9:09 justin_smith: jlamain: but the update/assoc can be a single operation thanks to update-in - the thing to remember is that you can't update something if you don't return it to your caller

9:10 jlamain: and what eventually becomes clear is that this restriction elimanates many points of failure - you know that any part of your code without mutation can only update what it returns

9:14 perplexa: justin_smith: using (vec (map #(vec (concat (subvec % 0 7) (subvec % 8 11))) aqft/expected-views)) but it is very ugly ;D

9:14 it gets rid of the 8th item, tho. so it's ok ;p

9:15 justin_smith: (vec (map ...)) is (mapv ...)

9:15 perplexa: oh right :) thanks!

9:16 hyPiRion: also, do #(into (subvec % 0 7) (subvec % 8 11)) instead

9:16 more efficient

9:16 justin_smith: (inc hyPiRion)

9:16 lazybot: ⇒ 61

9:18 jlamain: justin_smith: so if i do a (update-in map [:l1 :l2 :l3 :l4 :x] 500) everything is updated updated "four levels" deep.

9:18 justin_smith: well 500 isn't a valid arg to update-in, and that's 5 levels :)

9:18 update-in needs an updating function, maybe that should be assoc-in if you want to set the thing to 500

9:19 but yes, that's the general concept

9:20 jlamain: ok. thanks!

9:20 perplexa: hyPiRion: oh!

9:28 jlamain: justin_smith: I'm now googling and see http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples/Advanced_Data_Structures. If i have a deep tree of maps and one of the deeper subtrees is a complex ui component it might not be handy to every time give the full "path" to the assoc-in/update-in functions. Is it possible to give the "component" a shortcut to its own part of the tree ? How ? Is that were zippers are for, s

9:28 its zipper and say "update yourself!" ?

9:37 justin_smith: jlamain: the answer may be related to the answer to the quesiton "why do you have a deep tree?" - if each subtree is self contained, perhaps it should have its own implementation of update, such that it updates each of its own contents, recursively

9:37 jlamain: in which case you would call some update function on the top item (passing parameters) and it passes the parameters to an update call to each of its branches, etc.

9:38 I've never actually found zippers especially useful

9:40 jlamain: oke. thanks. Indeed thats also a simple/good solution

9:43 zacts: hi #clojure

9:49 justin_smith: code that uses zippers reads like konami cheat codes

9:51 Glenjamin: the xml-zip stuff seems to work pretty well, but i've never traversed up the tree with it

9:52 justin_smith: Glenjamin: (-> (xml-zip form) zip/up zip/down zip/up zip/down zip/left zip/right zip/left zip/right :a :b :start)

9:52 sorry

9:53 chouser: I still like it with data.zip

9:53 justin_smith: maybe I need to give them a second chance

9:54 hyPiRion: You usually make general functions on top of zippers. Like recursion schemes

9:57 It's possible to use them yourself too, but I've felt it's only "viable" after a bit practise.

9:59 hellofunk: zacts: that SICM book is what exactly, a clever analysis of basic physics?

10:03 SagiCZ: would you consider Clojure a good scripting language? like perl or python?

10:04 justin_smith: SagiCZ: there's a few limitations - the lack of access to the PID of a child process, the relatively long startup time

10:04 SagiCZ: though I think cljs/node would address both of those

10:04 SagiCZ: i see

10:06 chouser: (def pid (Long/parseLong (str (Files/readSymbolicLink (to-path "/proc/self"))))) ;; probably only Linux

10:06 stuartsierra: Most "scripting" languages are implemented in C, putting them closer to POSIX-style system calls that are important for scripting.

10:06 justin_smith: chouser: I mean the PID of a child process

10:06 chouser: which amazingly, is not provided by Process

10:07 chouser: justin_smith: *sigh* That JVM. *smh*

10:08 even clojurescript is a bit clumsy for scripting type tasks though because of JVM-based compilation.

10:08 justin_smith: SagiCZ: also, pixie is very similar to clojure in a lot of great ways, and has decent scripting support I think (or at least has that as a goal)

10:08 chouser: I had imagined using the compiled output for scripting

10:09 SagiCZ: justin_smith: who makes pixie?

10:10 justin_smith: SagiCZ: it's a collaboration, but tbaldridge is the biggest contributor

10:10 SagiCZ: justin_smith: oh. nevermind then

10:10 justin_smith: SagiCZ: ?

10:10 $last tbaldridge

10:10 lazybot: Couldn't find that user.

10:11 tbaldridge: lol, I'm here

10:11 justin_smith: haha

10:11 tbaldridge: regardless of what lazybot thinks

10:11 SagiCZ: heh

10:11 justin_smith: I hope that isn't something I broke in the lazybot codebase...

10:11 $last tbaldridge

10:11 lazybot: Couldn't find that user.

10:11 justin_smith: so weird...

10:11 hyPiRion: $last justin_smith

10:11 lazybot: justin_smith last listened to: Jean-Baptiste Lully - Ouverture [LULLY: Ballet Music for the Sun King]

10:12 justin_smith: haha

10:12 of course

10:12 SagiCZ: wait what

10:12 justin_smith: $seen tbaldridge

10:12 lazybot: tbaldridge was last seen talking on #clojure 1 minute and 1 second ago.

10:12 hyPiRion: last.fm

10:12 SagiCZ: oh there we go

10:12 justin_smith: I was using the wrong command, my bad

10:13 SagiCZ: anyway, pixie has better access to the kind of stuff you would want for scripting, I think

10:13 SagiCZ: i see.. well i might as well learn perl since i know nothing about pixie

10:13 justin_smith: SagiCZ: like I said, pixie is very similar to clojure

10:13 intentionally so

10:14 tbaldridge: someone should package up node/cljs somehow so that it's easy to compile scripts from lein

10:14 justin_smith: tbaldridge: agreed

10:14 hyPiRion: That plugin must surely be called inlein

10:14 Glenjamin: as in "script.cljs" -> lein compile script.cljs -> ./script

10:14 zacts: hellofunk: it's a book on classical mechanics

10:15 justin_smith: Glenjamin: exactly, that would be great

10:15 Glenjamin: should be pretty doable

10:15 hellofunk: zacts: right, meaning, basic physics?

10:15 zacts: hellofunk: http://en.wikipedia.org/wiki/Classical_mechanics

10:15 Glenjamin: they're quite chunky though, a small app like that will be 80k of JS

10:15 there's no nice way to share libs or a runtime between compiled cljs afaik

10:16 zacts: advanced newtonian physics

10:16 hellofunk: zacts: i know what mechanics is, but i'm wondering if that book has much incommon with SICP or if it's just cashing in on the name

10:16 zacts: yes it has *much* in common with SICP

10:16 it uses scheme to teach classical mechanics

10:16 justin_smith: hellofunk: I think that it is just using the house naming style for the curriculum

10:16 SagiCZ: hellofunk: what is SICP? i see that thrown areound here a lot

10:16 zacts: then the math notation afterwards

10:16 hellofunk: SagiCZ: Sussman's ouvre

10:17 zacts: so you get an intuitive sense of how classical mechanics work

10:17 justin_smith: SagiCZ: SICP is a free online book, with accompanying free online lecture videos, that introduce programming via scheme

10:17 SagiCZ: very good course

10:17 zacts: I have yet to read SICM, and much of SICP

10:17 SagiCZ: this? http://mitpress.mit.edu/sicp/

10:17 zacts: yes SagiCZ

10:17 justin_smith: SagiCZ: yeah - it was my CS 101 and served me very well

10:17 zacts: I'm wondering if Sussman and Aebelson are planning to update SICP to a 3rd edition, I don't know though

10:18 SagiCZ: i see.. thanks

10:18 zacts: justin_smith: MIT or Berkeley?

10:18 justin_smith: SagiCZ: see also these lectures by the author https://www.youtube.com/playlist?list=PLB63C06FAF154F047

10:18 zacts: MIT

10:18 zacts: ah nice

10:18 justin_smith: zacts: that youtube link is video of the MIT lectures

10:18 zacts: yes

10:18 Glenjamin: how about "lein backer script.cljs"

10:18 zacts: I've watched some of those

10:18 jackhill: zacts: MIT changed the CS curriculum, so probably not.

10:18 zacts: jackhill: well it's nice that justin_smith studied SICP when they used that

10:19 justin_smith: jackhill: much the worse for all of us, that

10:19 zacts: well, I did it on my own - it's been a free book for a long time now

10:19 zacts: oh I see

10:19 jackhill: There is also How To Design Programs which takes a different tact for how a first CS course should be structured (and uses racket)

10:19 zacts: I couldn't personally get into HTDP

10:19 justin_smith: I meant "101" in the general sense, I just read it and did the exercises independently

10:19 zacts: I much prefer the tone of SICP for my taste

10:20 although, to be fair I couldn't get myself to get past the first couple of ch's of HTDP

10:20 perhaps it gets better

10:20 jackhill: zacts: Different things work for different people. Maybe SICPs better for you.

10:21 zacts: ah yeah

10:21 jackhill: I've spend more time with SICP than HTDP, but I appreciate that the HTDP people have articulated why they wrote the book the way they did.

10:21 If nothing else, it help me think of how best to explain things to others.

10:22 (their critique of SICP is Structure and Interpretation of Computer Science Curricula)

10:23 Anyways, I came here to get a critique of some of my early days in clojure code:

10:24 I've written a function, http://paste.ubuntu.com/9957756/ , that returns a sequence of ratios. Is there a "better" (more clear/less repetitive/more efficient) way I could have done it?

10:27 justin_smith: jackhill: you could easily make that function lazy if you used lazy-seq in the tail call

10:27 s/tail-call/self-call

10:28 jackhill: added benefit of lazyness would be not blowing up the stack with large sequences

10:29 jackhill: justin_smith: where would I insert lazy-seq?

10:29 justin_smith: jackhill: one moment, I'll paste my version

10:30 hyPiRion: ,(let [nums [1 2 3]] (map (fn [[f s]] (/ s f)) (partition 2 1 nums)))

10:30 clojurebot: (2 3/2)

10:31 hyPiRion: Knowing that you can make pairs with (partition 2 1 ...) is really useful

10:31 jackhill: hyPiRion: thanks!

10:31 justin_smith: jackhill: https://www.refheap.com/96695

10:32 (inc hyPiRion)

10:32 lazybot: ⇒ 62

10:32 justin_smith: once again, his version is better

10:33 hyPiRion: jackhill: also take a look at justin_smith's one. It's good to know how the base mechanics of laziness works (where to put lazy-seq etc)

10:33 jackhill: justin_smith, hyPiRion: thanks. I just have to read them a couple time to make sure I understand

10:34 justin_smith: jackhill: I may have obfuscated my point by doing some DRY / extending the destructuring a bit

10:34 hyPiRion: jackhill: I can refactor my version to this (->> nums (partition 2 1) (map (fn [[f s]] (/ s f))))

10:35 jackhill: justin_smith: perhaps. Although I suspected I wanted to use a let, so that's great. I also hadn't seen the multi-level destructuring before, so that great too

10:35 chouser: justin_smith: I think that's less lazy than it could be. Is that intentional?

10:35 or perhaps just not important.

10:35 justin_smith: chouser: not intentional, I'd be glad for a tip to make it lazier

10:36 chouser: for maximum laziness, you generally want the lazy-seq form as close to the outside as possible. Alas this often means you don't destructure in the fn args.

10:36 hyPiRion: jackhill: (partition 2 1 [1 2 3 4]) => ((1 2) (2 3) (3 4)), and (fn [[f s]] (/ s f)) is just a fancy way to say "take a seq of two elements, and return the second divided by the first"

10:37 justin_smith: (fn [[f s]] (/ s f)) can also be "cleverly" expressed as (comp (partial apply /) reverse)

10:37 jackhill: hyPiRion: ah, and both partition an map return lazy-seq's?

10:37 justin_smith: (for two element list input)

10:38 chouser: As you've got it, calling empty? on remains means that remains will be forced immediately on calling rolling-ratio, which I think means it will immediately force 3 steps when called.

10:38 If you put lazy-seq just inside the defn, you can reduce that to 0.

10:38 justin_smith: chouser: oh, wow, yeah - the deep digging kills the laziness of course

10:38 hyPiRion: jackhill: yes

10:39 chouser: justin_smith: you got it.

10:39 hyPiRion: jackhill: most functions that work on seqs are lazy (map, filter, take, drop, etc)

10:40 So it's very common to just use them than to use lazy-seq yourself, as you can often compose those into the desired output

10:40 to make the desired output, rather

10:41 jackhill: Indeed. And map alrady knows to stop at the end, so I don't need to explicitly check for it.

10:42 hyPiRion: yup

10:43 jackhill: Yay, thanks everyone this really helped.

10:43 justin_smith: chouser: jackhill: my version more lazy https://www.refheap.com/96696

10:45 I just edited to add a version with a let binding, but I am not sure that is any better in this case

10:46 (if only we had a when-let that tested/required multiple bindings in core)

10:59 chouser: justin_smith: looks good to me

11:00 justin_smith: so now I've identified two corners of clojure I could brush up on today, laziness and zippers

11:09 ragge: I'm contemplating trying to implement something that would allow you to use maven packages JARs with nix. Does anyone know if something like this has been done/tried?

11:09 Ideally, I'd like to express JAR deps using nix, and stick JAR + all deps into nix store

11:10 justin_smith: ragge: what would this do that current usage of maven dependencies / uberjar would not?

11:12 ragge: justin_smith: short answer is that I'd like something that plays well with nix ecosystem

11:13 allowing things like nix-copy-closure

11:14 justin_smith: ragge: typically my clojure deploys consist of creating an uberjar and a shell script that runs it, and putting those two files on a server

11:14 TimMc: Same here.

11:14 justin_smith: ragge: I like the modularity of nix, but when a deploy has so few pieces, I don't really see what is being gained I guess

11:15 ragge: justin_smith: mine too, but there's alot of stuff that's not captured by that

11:15 justin_smith: ragge: OK

11:15 ragge: what about using nix to abstract the rest of the stuff, and using the maven stuff as usual? I don't see what's gained by wrapping up the maven part too

11:15 ragge: like which JVM, which native deps

11:16 justin_smith: ragge: ahh, native deps are another story

11:17 ragge: but still, I feel like wrapping the maven dependency management in nix feels like a pointless layering. my approach would be to wrap everything maven doesn't do well / can't do with the nix abstractions, and then instead of abstracting over maven, just generate the uberjar and treat that as a single atomic artifact

11:18 ragge: justin_smith: this is really just an exercise for me to try something a bit different

11:18 idea is to not really use maven or leiningen, or create uberjar

11:18 just express jar dependencies

11:19 TimMc: You're gonna have to reinvent a lot of stuff.

11:19 ragge: make nix download them, and provide them as needed for compilation/runtime

11:19 then use plain old java -jar clojure.jar:... clojure.main

11:19 or clojure.compile

11:19 TimMc: thats possible

11:20 and even likely

11:20 TimMc: How will you set the JVM args necessary for the app?

11:20 for example heap size, system properties...

11:20 justin_smith: if you're exercising, as long as you're having fun I guess. But it will be a lot of work for little pragmatic end.

11:20 ragge: would be part of your package

11:20 what you execute is up to you

11:20 nix can help provide dependencies

11:21 construct classpath with appropriate JARs (and native deps) stuff from nix store

11:21 TimMc: I see, the command would have to be provided elsewhere, possibly from a shell script anyhow.

12:12 gfredericks: anybody did done made a library for deffing things with HOFs?

12:13 defpartial, defcomp, at least

12:13 not sure if anything else would fit in that group

12:14 chouser: defmap, defreduce?

12:14 gfredericks: the point would be to have better reloadability (by using vars) and better arglist metadata (by stealing it from the original)

12:14 justin_smith: defdef

12:15 (higher order macro for creating def-like forms)

12:15 gfredericks: I feel like I threatened to make a def-oriented library at one point I can't remember what happened

12:15 tcrayford____: gfredericks: free name "defning"

12:15 justin_smith: at least we would never need defdefdef

12:15 gfredericks: tcrayford____: that was suggested for another library already :P

12:16 tcrayford____: dammette

12:16 chouser: justin_smith: probably not, but I could find a use for defdefmacrodef

12:16 justin_smith: haha

12:16 gfredericks: one name I would consider is defdefdefdefdefdefdef

12:16 tcrayford____: gfredericks: "defntlynot"

12:17 hiredman: stick a random f in there

12:17 defdefdeffdefdefdefdef

12:17 gfredericks: hiredman: I'm not opposed to this

12:17 justin_smith: defdefdefdefdefdefdefdef-mushroom-mushroom

12:18 chouser: ,((get get get get) (get get get) ('get get) 'get)

12:18 clojurebot: get

12:18 chouser: who did I steal that joke from?

12:18 stuartsierra: deffr, rhymes with zephyr

12:19 justin_smith: chouser: (get get get get) was my "discovery" I think, but I like that variation

12:19 tbaldridge: obligatory Monty Python vid: https://www.youtube.com/watch?v=anwy2MPT5RE

12:20 chouser: justin_smith: thought it might have been you. It's a wonderful theme, full of potential variations.

12:20 justin_smith: semantic saturation for fun and profit

12:22 gfredericks: ,(defn get-it [] (repeatedly (inc (rand-int 4)) #(case (rand-int 5) (0 1) 'get (2 3) ''get 4 (get-it))))

12:22 clojurebot: #'sandbox/get-it

12:22 gfredericks: ,(get-it)

12:22 clojurebot: ((quote get) (quote get) (get get) (get (quote get)))

12:23 gfredericks: ,((quote get) (quote get) (get get) (get (quote get)))

12:23 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core/get>

12:23 gfredericks: :/ I guess it's not likely to evaluate

12:24 chouser: ,(map map (meta meta))

12:24 clojurebot: ()

12:24 justin_smith: nice

12:24 tcrayford____: (:or :or :or)

12:24 ,(:or :or :or)

12:24 clojurebot: :or

12:25 justin_smith: someone is totally new to clojure and wondering what the fuck they just got into

12:25 (also all of this is totally hilarious)

12:26 TimMc: oh, if we're doing this...

12:26 ,((((comp comp) (comp comp)) ((comp comp) (comp comp))))

12:26 clojurebot: #<core$identity clojure.core$identity@320baa47>

12:27 chouser: nice!

12:27 justin_smith: NICE

12:28 nic77: <justin_smith> someone is totally new to clojure and wondering what the fuck they just got into

12:28 yes thats me

12:29 yall set me back 10 years just now

12:29 justin_smith: nic77: we don't do this in real code, I hope you realize :)

12:30 nic77: though there may be some benefit to realizing why these silly things work

12:30 even if you would never do them on purpose

12:32 TimMc: ,(eval (nth (iterate #(list % %) comp) 5))

12:32 clojurebot: #<ExceptionInInitializerError java.lang.ExceptionInInitializerError>

12:32 TimMc: ?

12:33 justin_smith: TimMc: weird, that works locally

12:33 &(eval (nth (iterate #(list % %) comp) 5))

12:33 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

12:33 justin_smith: maybe the eval is the issue? does clojurebot usually allow it?

12:34 TimMc: ,(eval 5)

12:34 clojurebot: 5

12:34 TimMc: *shrug*

12:34 ,(eval (nth (iterate #(list % %) comp) 5))

12:34 clojurebot: #<ExceptionInInitializerError java.lang.ExceptionInInitializerError>

12:38 TimMc: We should be able to do eval in lazybot, right? As long as we can resolve vars.

12:38 justin_smith: TimMc: I think it is an arbitrary sandboxing constraint, I don't know what the reasoning was.

12:39 TimMc: Challenge: Build a fn that allows you to do this: &(let [ev (fn ...)] (ev (list + 2 3))) ;; 5

12:39 and have it fit in an IRC message, obviously.

12:39 ... = 5 is cheating

12:39 or [] 5 in this case

12:41 justin_smith: &(let [ev (fn [f & args] (apply f args))] (ev (list + 2 3)))

12:41 lazybot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

12:41 justin_smith: hrmph

12:41 oh, duh

12:41 &(let [ev (fn [& [f & args]] (apply f args))] (ev (list + 2 3)))

12:41 lazybot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

12:41 justin_smith: OK, back to my own repl, sorry

12:42 Bronsa: justin_smith: remove the &

12:42 justin_smith: (let [ev (fn [[f & args]] (apply f args))] (ev (list + 2 3)))

12:42 &(let [ev (fn [[f & args]] (apply f args))] (ev (list + 2 3)))

12:42 lazybot: ⇒ 5

13:00 justin_smith: TimMc: '(+ 2 3) would have made me use resolve

13:01 TimMc: &(letfn [(ev [s] (if (list? s) (apply (first s) (map ev (rest s))) s))] (ev (list + (list * 2 3) 5)))

13:01 lazybot: ⇒ 11

13:01 TimMc: recursive!

13:02 justin_smith: I think that's really close to one of the 4clojure problems actually

13:05 mearnsh: this one? https://www.4clojure.com/problem/121

13:05 4clojure forbids resolve though

13:05 justin_smith: yeah, that's the one I was thinking of

13:06 benmoss: does anyone have any advice for how to serialize a byte buffer/byte array in order to write decoding tests against it?

13:06 i’m up against the limits of my knowledge here

13:07 justin_smith: benmoss: I use base64 to turn it into a string that I put as a literal or into a resource file, then bas64decode to turn it into a byte array again for testing

13:07 TimMc: You could turn it into a seq of bytes or maybe produce a base64 string.

13:07 justin_smith: https://github.com/clojure/data.codec data.codec does base64

13:07 TimMc: Seq of bytes is dumb but easy (unless you'll be interacting with resource files.)

13:07 Then it's just dumb.

13:08 justin_smith: yeah, for a smaller one at least seq of bytes would be fine too

13:08 TimMc: Oh, I guess with a seq of bytes you have to deal with the fact that they're signed... :-(

13:09 justin_smith: TimMc: well, it's a transperent thing when you go both ways with it

13:09 it's not like the double conversion would lose anything

13:09 benmoss: hmm how do you turn it into a seq of bytes? i assume we are talking about a byte array here

13:10 justin_smith: ,(seq (byte-array (map byte [1 2 3 4]))

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

13:10 justin_smith: oops

13:10 ,(seq (byte-array (map byte [1 2 3 4])))

13:10 benmoss: groovy

13:10 clojurebot: (1 2 3 4)

13:10 Bronsa: justin_smith: is the map byte really necessary?

13:11 justin_smith: or to construct a vector literal (into [] (.getBytes "hello"))

13:11 benmoss: that is perfect for my needs

13:11 justin_smith: Bronsa: I recall byte-array complaining

13:11 ,(byte-array [1 2 3 4])

13:11 clojurebot: #<byte[] [B@385fbfa0>

13:11 justin_smith: Bronsa: I was wrong

13:11 ,(into [] (.getBytes "hello"))

13:11 clojurebot: [104 101 108 108 111]

13:15 justin_smith: maybe I was thinking of something like (into-array Byte [1 2 3])

13:15 Bronsa: ,(into-array Byte [1 2 3])

13:15 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: array element type mismatch>

13:15 Bronsa: uh

13:15 ,(into-array Byte/TYPE [1 2 3])

13:15 clojurebot: #<byte[] [B@4cef0f23>

13:16 Bronsa: cool

13:16 justin_smith: that's where (map byte ...) is needed, but now I struggle to recall why I would make an array of Byte instead of Byte/TYPE

13:16 stuartsierra: ,(byte-array [1 2 3])

13:16 clojurebot: #<byte[] [B@1eb9de7e>

13:17 Bronsa: stuartsierra: yeah we were just wondering when (map byte [1 2 3]) is necessary and when [1 2 3] is ok

13:22 stuartsierra: ah

13:22 byte coercions are odd. Just the other day I had to write (.byteValue (Long. 0xFF))

13:24 hiredman: (doc unchecked-byte)

13:24 clojurebot: "([x]); Coerce to byte. Subject to rounding or truncation."

13:24 justin_smith: cool

13:24 ,(unchecked-byte 1000)

13:24 clojurebot: -24

13:47 Bronsa: justin_smith: who needs unchecked-byte when you can do ##(first (byte-array [1000]))

13:47 lazybot: ⇒ -24

13:47 TimMc: This seems sensible.

13:48 justin_smith: TimMc: after all, it is 24 short of a value that should map to 0

14:07 gfredericks: thinking of adding a test.chuck namespace for making assertions about generators & their distribution

14:07 and am trying to name the namespace

14:11 hiredman: test.check.gauss

14:11 gfredericks: it would be structured a lot like such-that

14:11 you give it a predicate and it checks that the generator generates something satisfying the predicate before too long

14:12 probably by increasing the size the same way such-that does

14:16 {blake}: Is it true that I need a Clojure library (like "classpath") in order to figure out what the classpath is? (I would've thought it was a built-in.)

14:17 hiredman: the classpath is a static thing handed to the jvm at start up, why would you need to know what it is?

14:17 {blake}: hiredman: I'm trying to use yesql, which requires the sql to be put on the classpath.

14:18 hiredman: {blake}: at run time the classpath is whatever you tell the jvm, at dev time it is the same, but generally people let lein manage launching jvms at dev time, and lein has a classpath command which prints out the classpath it is using

14:19 gfredericks: {blake}: the /resources directory is the normal place to put non-code on the classpath

14:19 hiredman: {blake}: but generally you would put things like the files yesql uses in a directory called resources/

14:20 {blake}: hiredman, gfredericks: Thanks. Does it search subdirs?

14:20 justin_smith: {blake}: provide a path that is relative to that directory

14:20 {blake}: I guess not.

14:20 justin_smith: ie resources/sql/my-query.sql

14:21 then ask for "sql/my-query.sql"

14:21 {blake}: Oh, right. Duh. That's what I started with but off the root.

14:21 Points party!

14:21 (inc hiredman)

14:21 lazybot: ⇒ 69

14:21 {blake}: (inc gfredericks)

14:21 lazybot: ⇒ 114

14:21 {blake}: (inc justin_smith)

14:21 lazybot: ⇒ 178

14:27 benmoss: hmm, anyone familiar with ztellman’s byte-streams/manifold?

14:28 i am trying to emulate the incoming tcp stream from aleph for a test, but can’t wrap my head around how to do it

14:29 i have the byte array i was talking about earlier, but not sure how to turn it into a stream of bytes consumable by gloss

14:29 stuck in ztellman hell

14:40 tcrayford____: benmoss: well, I tooted it at ztellman. Iirc he's on freenode, maybe you could just private message him on here?

14:41 benmoss: hah i just saw that

14:41 tcrayford____: (I use other parts of the ztellman kingdom, but not manifold or gloss or manifold)

14:41 ztellman: benmoss: hey, sorry for the troubles

14:41 if you just use decode-stream on the aleph gives you, it should work

14:42 benmoss: no no its just my relative newbishness

14:42 ztellman: on the stream aleph gives you*

14:42 benmoss: yeah that works fine, i’m trying to diagnose a problem in my codec and thus trying to recreate the TCP stream in a test

14:42 ztellman: then you can just create a sequence of bytes, or a byte array, or whatever

14:42 and (->source bytes)

14:43 benmoss: yeah, i have that much, i get “cannot convert byte[] to source”

14:43 cemerick: stuartsierra: you want (unchecked-byte 0xff)

14:44 ztellman: benmoss it has to be a sequence

14:44 cemerick: meh, should've kept reading the scrollback :-P

14:44 ztellman: (->source [bytes])

14:44 if it's just a byte-array

14:44 I've got to run, unfortunately

14:44 send me an email if you keep having trouble

14:44 benmoss: no worries, thanks though

14:45 your libs are a joy to work with as soon as i can wrap my head around them :)

14:45 ztellman: as a rule of thumb: you can convert streamy and sequencey things to Manifold streams, so you'll need to coerce it at least that ar

14:45 far*

14:45 you can also just call gloss.io/decode on the byte-array

14:45 as an alternative

14:45 anyway, best of luck

14:52 stuartsierra: cemerick: ah, thanks

14:54 cemerick: stuartsierra: sure; ironically, working with bytes in javascript is actually more pleasant than on the JVM because of the signededness

14:59 sdegutis: What majestic technique would you use to return all the non-alphanumeric characters in a string (duplicates found in the string are allowed but not required in the result)?

15:01 amalloy: (.replaceAll s "[a-zA-z0-9]" "")

15:02 or use clojure.string/replace, whatever suits your fancy

15:04 edw: ,(inc 41)

15:04 clojurebot: 42

15:04 benmoss: ,(re-seq #”\W” “foo@bar.com”)

15:04 clojurebot: #<ArrayIndexOutOfBoundsException java.lang.ArrayIndexOutOfBoundsException: 8221>

15:05 sdegutis: amalloy: thanks

15:05 amalloy: benmoss: close, except that removes _ as well

15:05 sdegutis: ,(re-seq #"\W" "foo@bar.com")

15:05 clojurebot: ("@" ".")

15:05 sdegutis: excellent thanks benmoss

15:05 benmoss: ah, don’t listen to me :)

15:05 sdegutis: why?

15:05 clojurebot: why is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone

15:05 sdegutis: it was a legitimate solution benmoss

15:05 edw: Also, benmoss, you has some weird cury quotes in there.

15:05 sdegutis: ,(.replaceAll "foo@bar.com" "[a-zA-z0-9]" "")

15:05 clojurebot: "@."

15:05 amalloy: ,(re-seq #"\W" "foo_bar.com")

15:05 clojurebot: (".")

15:05 benmoss: yeah not sure where that crap is coming from

15:06 sdegutis: oh

15:06 llasram: ,(into #{} (remove #(or (Character/isAlphabetic (int %)) (Character/isDigit %))) "What's this `*` doing in my code?")

15:06 clojurebot: #{\space \` \' \* \?}

15:08 sdegutis: What's a consummate way of removing all duplicate characters from a string?

15:08 TimMc: benmoss: oh ess ex

15:08 llasram: ,(Character/getNumericValue \Ⅼ)

15:08 clojurebot: 50

15:08 benmoss: TimMC: yep just figured out how to disable that :)

15:08 TimMc: llasram: ooooh

15:09 llasram: ,(Character/getNumericValue \L)

15:09 clojurebot: 21

15:09 * llasram sits back, his work for the day done

15:09 TimMc: ,(.getPort (java.net.URL. "http://www.example.com:Ⅼ/&quot;)) ;; just checking

15:09 clojurebot: #<MalformedURLException java.net.MalformedURLException: denied>

15:10 TimMc: ,(.getPort (java.net.URL. "http://www.example.com:८५/&quot;)) ;; for comparison

15:10 clojurebot: #<MalformedURLException java.net.MalformedURLException: denied>

15:10 hellofunk: sdegutis: duplicates in succession, or duplicates anywhere?

15:10 TimMc: uh

15:10 &(.getPort (java.net.URL. "http://www.example.com:८५/&quot;))

15:10 lazybot: ⇒ 85

15:10 amalloy: nice

15:11 sdegutis: hellofunk: anywhere

15:11 TimMc: &(.getPort (java.net.URL. "http://www.example.com:Ⅼ/&quot;))

15:11 lazybot: java.lang.NumberFormatException: For input string: "Ⅼ"

15:12 hellofunk: sdegutis: probably many ways but you could just reduce over the string and add each char to a set which automatically removes duplicates, check for set inclusion in your reduce fn.

15:12 sdegutis: hellofunk: nice

15:12 llasram: ,(into #{} "um, like this?")

15:12 hellofunk: sdegutis: i'm sure there are other oways

15:12 sdegutis: oh wait

15:12 this

15:12 clojurebot: #{\space \e \h \i \k ...}

15:12 sdegutis: ,(= (set "foo") #{\f \o})

15:12 clojurebot: true

15:13 sdegutis: duh lol

15:13 llasram: haha

15:13 Even better

15:13 sdegutis: thanks everyoen for your help

15:13 ,#{#{\@ \% \- \.} #{\@ \.} #{\@ \% \.} #{\@ \- \.}}

15:13 clojurebot: #{#{\@ \.} #{\@ \% \.} #{\@ \% \- \.} #{\@ \- \.}}

15:27 gfredericks: just made an alternative to test.check's prop/for-all that handles the bindings differently: https://github.com/gfredericks/test.chuck#properties

15:28 tomjack: looks like it exposes the generator monad?

15:29 brilliant

15:29 I wrote something like that which didn't handle :let and :when. thank you!!!

15:29 gfredericks: basically; it's based on another macro that does that as a generator rather than a property

15:29 slipset: Burrito!

15:29 gfredericks: tomjack: see this for the generator variant: https://github.com/gfredericks/test.chuck#for

15:30 tomjack: it also has :parallel for doing gen/tuple

15:30 tomjack: pretty awkward to deal with generators which take generated values as parameters without something like that, I think

15:30 gfredericks: yeah I've used it pretty heavily

15:36 tomjack: I've wondered if maybe the generator monad should be made a bit more like core.logic's monad?

15:36 e.g. (gen/sample (gen/bind gen/nat #(gen/such-that even? (gen/return %))))

15:36 should that fail..?

15:37 gfredericks: I don't think so...does it?

15:37 or wait

15:37 is this a such-that thing?

15:37 gotcha

15:37 tomjack: yeah, isn't that how your :when works?

15:37 basically I want fair conjunction I think

15:38 gfredericks: yeah, if you went out of your way to write it that way

15:38 I've pondered an extra feature that would let you group things for applying the :when more selectively

15:39 I haven't actually needed different :when granularity very much

15:39 tomjack: I was trying stuff like "generate an active domain, then bind and generate some stuff from the domain such that certain conditions hold"

15:40 but if the conditions can't be satisfied for any active domain, it breaks

15:40 I mean, if for some active domain, the conditions can't be satisfied at all

15:40 gfredericks: right

15:40 so the question is if you can recognize those kind of domains

15:40 and filter early with that

15:40 if not, then yeah you need different granularity

15:41 I was thinking the syntax could be (for [:group [domain gen-domain, stuff (gen-stuff domain)] :when (...)] ...)

15:41 but couldn't decide what the keyword should be called. :group? something else?

15:42 there might have been some trickier aspect that I can't even remember at the moment

15:42 hellofunk: anyone know where the term "list comprehension" came from? it seems like an odd term. is it from lisp heritage?

15:43 tomjack: I think it's from http://en.wikipedia.org/wiki/Axiom_schema_of_specification

15:43 hiredman: http://en.wikipedia.org/wiki/Set-builder_notation

15:43 amalloy: http://en.wikipedia.org/wiki/List_comprehension#History

15:43 justin_smith: http://en.wikipedia.org/wiki/List_comprehension#History

15:43 haha

15:43 hellofunk: holy wow

15:43 you guys are on top of it!

15:43 amalloy: so uh, tldr the internet is not a hard place to find things

15:43 hellofunk: sigh.

15:44 gfredericks: :group seems like a decent name now that I think about it

15:45 tomjack: that means (for-all [[domain stuff] (for-all [domain gen-domain, stuff (gen-stuff domain)] [domain stuff]) :when (...)] ...) ?

15:46 gfredericks: s/for-all/for/ but yeah

15:51 mspo: hey can someone show me how to configure connection pooling with mysql on org.clojure/java.jdbc?

15:52 justin_smith: the mysql part isn't relevant btw - it's the same for any jdbc driver - one minute, there's a good example out there I can dig up

15:53 mspo: https://github.com/niwibe/clojure.jdbc-c3p0 this lib makes it very easy

15:54 mspo: this shows how to do it via interop http://clojure-doc.org/articles/ecosystem/java_jdbc/connection_pooling.html which is not super hard either

15:57 mspo: thanks

15:58 hellofunk: anyone used Julia?

16:01 cddr: I want to process a map recursively, collecting the values into a flattened sequence after running each one through a fn. Is that something I could/should use clojure.walk/walk for?

16:02 amalloy: probably not. just mapcat+recursion

16:08 justin_smith: tree-seq could be an option if you filtered out the leaves ##(remove coll? (tree-seq coll? seq {:a 0 :b [1 2 3 [4 5 [6]]]}))

16:08 lazybot: ⇒ (:b 1 2 3 4 5 6 :a 0)

16:08 zacts: is there a way I can reload a core.clj within a lein repl, without actually killing and restarting the repl?

16:08 amalloy: justin_smith: that's just flatten

16:08 zacts: (require 'my.ns :reload)

16:08 justin_smith: amalloy: nope ##(flatten {:a 0 :b [1 2 3 [4 5 [6]]]})

16:08 lazybot: ⇒ ()

16:09 justin_smith: maybe flatten + seq?

16:09 amalloy: justin_smith: yes, yes, a slightly improved version of flatten in that you use coll? instead of sequential?

16:10 mgaare: zacts: also can look at clojure.tools.namespace for the Big Guns (reloads all namespaces that have changed and their dependencies in the right order)

16:13 zacts: oh thanks!

16:13 justin_smith: amalloy: now I must take a hard look in the mirror and accept the fact that I have written a slightly improved version of flatten

16:13 noonian: zacts: also (require 'my.ns :reload-all) if code changed in a file required by my.ns

16:13 amalloy: justin_smith: or just break the mirror. some things are worse than seven years' bad luck

16:13 justin_smith: haha

16:15 zacts: oh is it a single quote?

16:15 not 'my.ns', but 'my.ns ?

16:15 I'm getting an error

16:16 amalloy: zacts: 'foo' is pretty much always wrong in clojure

16:16 noonian: yes, the single quote in clojure is used to suppress evaluation, and is syntactic sugar for (quote my.ns). You don't need it if you are doing this from inside the ns form

16:17 hellofunk: what's an approach to a functional lens in clojure? how would one do that?

16:17 noonian: ,foo

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

16:17 noonian: ,'foo

16:17 clojurebot: foo

16:18 amalloy: hellofunk: for simple lenses, update-in and get-in basically handle it all; for complex lenses nobody really bothers

16:18 BobSchack: hellofunk: Here's an article about strongly typed lenses http://blog.podsnap.com/tinhole.html

16:18 hellofunk: amalloy: cool i follow you

16:21 {blake}: Is there a string formatting utility such that "The :speed :color :animal jumps!" would come out as "The quick brown fox jumps!" when passed a map of {:speed "quick" :color "brown" :animal "fox"}?

16:21 hellofunk: amalloy: http://stackoverflow.com/a/21293171/3758484

16:22 stuartsierra: {blake}: yes, string-interpolation in core.incubator

16:23 {blake}: stuartsierra: Thank you!

16:23 (inc stuartsierra)

16:23 lazybot: ⇒ 18

16:23 hellofunk: amalloy: most interesting quote: "Importantly that means that we can be sure when we have a true lens that datatype descent cannot fail—that kind of guarantee is impossible to make in Clojure."

16:25 amalloy: so you've been reading about haskell like you planned, hellofunk?

16:25 hellofunk: amalloy: i have. but mostly going above languages in general to read more about functional theory

17:28 {blake}: ,(let [f0 "C:\\long\\fn.ext" f1 (apply str (take (.lastIndexOf f0 ".") f0))] (apply str (drop (inc (.lastIndexOf f1 "\\")) f1)))

17:28 clojurebot: "fn"

17:28 {blake}: Seems cumbersome.

17:30 Mr0rris0: what is it

17:31 {blake}: Strips a (Windows-style) path of all but the filename.

17:32 You start with a string, which gets turned into an array as you use take, which you turn into a string again, and then turn back into an array with drop, then turn back into a string.

17:39 TMA: ,(defn foobar [f0] (let [f1 (apply str (take (.lastIndexOf f0 ".") f0))] (apply str (drop (inc (.lastIndexOf f1 "\\")) f1))))

17:39 clojurebot: #'sandbox/foobar

17:39 TMA: ,(foobar "c:\\long.ext\\extensionlessfilename")

17:39 clojurebot: "long"

17:40 TMA: ,(foobar "c:\\long\\extensionlessfilename")

17:40 clojurebot: ""

17:40 chouser: ,(let [f0 "C:\\long\\fn.ext"] (second (re-find #"([^\\]*)\.[^.]*$" f0)))

17:40 clojurebot: "fn"

17:41 amalloy: {blake}: why are you doing this with strnigs at all?

17:41 chouser: ,(let [f0 "C:\\long\\noext"] (second (re-find #"([^\\]*)\.[^.]*$" f0)))

17:41 clojurebot: nil

17:41 {blake}: I think I have a line (lein?) on what might be causing my Compojure access errors: When I run "lein new compojure app" and then "lein ring server" on the result in a HEADLESS enviornment, I get an X11 error...like it's trying to open a display.

17:41 amalloy: 'cause that's what comes to me? A filename string?

17:41 amalloy: make a java.io.File, ask it for the filename-part

17:41 kodumulo: Looking for a streaming http client library. I'm looking at a chunked request. I tried http-kit and clj-http and they both seem to block rather than returning some sort of stream

17:42 chunked response*

17:42 dakrone: kodumulo: clj-http will return a stream if you use {:as :stream} with it, then you can read as you need

17:42 amalloy: ,(.getName (java.io.File. "/foo/bar/baz.txt"))

17:42 clojurebot: "baz.txt"

17:42 kodumulo: dakrone: (def foo (client/get "http://localhost:9090" {:as :stream})) is blocking my repl

17:43 amalloy: will do the same thing on windows, for windows-style paths

17:43 {blake}: ,(.getName (java.io.File "C:\whatever\what\os.txt"))

17:43 clojurebot: #<RuntimeException java.lang.RuntimeException: Unsupported escape character: \w>

17:43 chouser: ,(.getName (java.io.File. "c:\\foo\\bar\\baz.txt"))

17:43 clojurebot: "c:\\foo\\bar\\baz.txt"

17:43 {blake}: amalloy: If I'm running on Linux and getting a Windows path?

17:43 amalloy: (I mean, I didn't think of it. But wondering it hat would cause trouble.)

17:43 er, if that

17:44 amalloy: well it won't do anything very useful then

17:44 kodumulo: dakrone: might be the servers fault though, thanks

17:44 {blake}: amalloy: Because it's assuming the path is going to be native?

17:45 amalloy: yeah more or less

17:45 {blake}: (And why wouldn't it. I only have to do this because, apparently, IE gives the whole path where other browsers just give the filename.)

17:45 So, yeah, last segment between \ and . (Extensions required.)

17:46 kodumulo: Ah its working now

17:59 {blake}: So, why would a brand new compojure app generate this? "No X11 DISPLAY variable was set, but this program performed an operation which requires it".

18:00 hiredman: you are loading some java library that is trying to do gui stuff

18:00 amalloy: because lein ring server attempts to open a browser window and navigate to your server, for some misguided reason

18:00 Mr0rris0: is that just another name for clojure?

18:00 hiredman: lein ring has some really terribel stuff :/

18:01 {blake}: amalloy: Oh, sure. It does that locally, but it can't do that on my remote headless server.

18:01 amalloy: mhm

18:01 {blake}: Dammit, I thought I was on to something.

18:01 amalloy: onto something?

18:01 {blake}: Yeah, because I get access errors when I run locally.

18:01 hiredman: don't use lein ring to run your app

18:02 {blake}: hiredman: Locally? Why not?

18:02 hiredman: when doing dev, sure

18:02 {blake}: And it's not my app, per se, it's any Compojure app.

18:02 hiredman: I mean, it is kind of terrible still

18:02 it adds all kinds of middleware and behaviour that will trip you up when it is different without it

18:02 {blake}: hiredman: Using Wildfly in production.

18:03 hiredman: ok, no worries then

18:03 {blake}: Well, different worries, anyway.

18:03 hiredman: well, it is almost certainly lein ring trying and failing to open a browser

18:04 so just do lein ring server-headless or whatever it is and you'll be fine

18:04 {blake}: hiredman: Yeah, and that might be why I get local errors, too. For some reason, lein does not have permission to do that all of a sudden.

18:04 hiredman: but in theory, it could be some other random code loading java.awt or something

18:05 {blake}: Bingo!!

18:05 hiredman: which, well, I think incanter might do that

18:05 TEttinger: yeah

18:05 {blake}: Well, that's a relief.

18:05 hiredman: (for the graphing stuff)

18:05 {blake}: I was getting it with a compojure starting template.

18:05 So it's just a weird Windows thing. I no longer care. =P

18:05 hiredman: there is a command line option you can pass to java to use the headless version of the gui toolkit too

18:06 I forget what it is

18:06 amalloy: it varies by OS i think, hiredman

18:06 oh or i think i'm thinking of something else

18:06 hiredman: http://stackoverflow.com/questions/2552371/setting-java-awt-headless-true-programmatically

18:08 {blake}: Good to know.

18:51 justin_smith: {blake}: yeah, compojure uses awt to use the desktop stuff to make the browser open a page on startup

18:52 {blake}: oh, and I see someone already said that

18:56 Lewix: In terms of trend Go is pulverizing clojure

18:56 Mr0rris0: ya?

18:56 Lewix: yup

18:56 Mr0rris0: whats go

18:57 Lewix: more people use it , and it's growing faster

18:57 Mr0rris0: the new google language

18:57 Mr0rris0: oh

18:57 im just starting to learn something, anything really

18:57 tbaldridge: well shoot, I guess I'll just stop programming clojure then...gotta go with the trends

18:58 Lewix: Mr0rris0: are you new to the world of programming

18:58 Mr0rris0: yes

18:58 Lewix: tbaldridge: yea do that

18:58 hellofunk: wise man once said somewhere that a language's popularity can be approximated by its number of starts on github. in which case Go is about tied with Julia, which I'd never heard of before this evening, both of which are significantly more starred than clojure

18:58 *stars

18:58 Mr0rris0: im trying to understand what these vecters are about with the graph theory, not sure why though

18:59 Lewix: hellofunk: i wonder what attracks people to Go as opposed to clojure and vice versa

18:59 justin_smith: Lewix: the languages have very little in common

18:59 metellus: I'm not sure it's fair to assume that all languages will have github representation proportional to popularity

18:59 tbaldridge: Lewix: could be nothing more than PR. Google is a tad bigger than Rich's team

18:59 Lewix: Mr0rris0: graph theory? why did you choose clojure to start with in the world of programming

19:00 hellofunk: Lewix: a significant part of Go was simply added to Clojure as a single library, so that breaks down the power of the languages pretty clearly

19:00 tbaldridge: same with Rust, the language isn't even finished, but Mozilla keeps hyping it so much it's gaining traction

19:00 Mr0rris0: its just something a guy un here mentioned having to do with a game

19:00 Lewix: hellofunk: well , do you know go at all?

19:01 hellofunk: Lewix: never used it, just going off others' remarks and articles

19:01 amalloy: black plays first, you want to surround territory and capture stones

19:01 Lewix: I stumbled across a few block of people moving from clojure to goland

19:01 Mr0rris0: well i was looking for places like this one and found it

19:01 justin_smith: (inc amalloy)

19:01 lazybot: ⇒ 219

19:01 tbaldridge: I've played around with it a bit, it's cool and all, but not even close to the reach that a JVM based language gets.

19:01 Mr0rris0: clojure was just a chat when i looked at the more than 15,000 freenode channels

19:01 its alphabetical so thats prett much why

19:01 Lewix: aha

19:01 Mr0rris0: :D

19:01 Lewix: nice

19:02 Mr0rris0: yup

19:02 amalloy: we'd get more uptake if rich had had the foresight to name this language Aardvark

19:02 Mr0rris0: there was a room and it was named something closer to A than Z

19:02 yup

19:02 hellofunk: am i imagining it or is there a proliferation of new programming langauges these last few years, coming into the scene at a faster clip than previous decades

19:02 Mr0rris0: Aardvark++

19:03 tbaldridge: forget it, I'm going to program in APL

19:03 Mr0rris0: probably not imagining it

19:03 Lewix: I think it's all about easy and simple

19:03 Golang is both

19:04 Mr0rris0: if it works it works

19:04 Lewix: clojure might be simple but it's not easy

19:04 Mr0rris0: that may be an asset in the long run

19:04 tbaldridge: I'd debate the whole "go is simple" thing. It has mutability through the entire thing

19:04 OOP languages are not simple, let alone those that embrace CSP

19:04 Lewix: tbaldridgei won't listen if you never played with go

19:05 justin_smith: Lewix: few of my criteria that led to choosing Clojure apply to golang. It isn't a lisp, it isn't designed to make functional programming easy to do, it doesn't support programming against interfaces. The only things it has going for it is not being heavily OO and having a smart setup for concurrency, as far as I am concerned.

19:06 Lewix: and for people who don't like java like me it takes a lot to convince us to learn clojure - so far so good , i enjoy it

19:06 Mr0rris0: if its easy everyone does it depends on what side of the racket your on as to that being good or bad

19:06 Lewix: justin_smith: what do you mean by programming against interfaces?

19:07 hellofunk: justin_smith: just started watching this. first big point he makes is about how important interfaces are in Go: https://www.youtube.com/watch?v=ytEkHepK08c#t=73 though i'll have more idea what he's talking about in a few minutes

19:07 justin_smith: Lewix: code where concrete types rarely matter, and instead you can code in terms of an interface any type could implement.

19:07 hellofunk: interesting, I could be wrong on that point then

19:07 {blake}: Lewix: If you don't like Java, there's always ClojureScript and ClojureCLR.

19:08 Lewix: justin_smith: yes you're wrong about that

19:09 {blake}: well I'm currently learning clojure, and I like it with the very basics stuff I learned so far - it's just at some point when ill be more fluent im pretty certain ill encouter java code while debugging

19:09 hellofunk: Lewix: {blake}: i don't think liking/knowing or not-liking/not-knowing Java has much relevance to whether one should/could use/love/learn Clojure. I've never used Java in my life and continue to avoid it despite working in Clojure all day

19:10 Lewix: hellofunk: I think it depends on the type of work you do

19:10 justin_smith: Lewix: java code never shows up in debugging. Java stacktraces sure, but not java code.

19:10 {blake}: Lewix: I've encountered Java code but never while debugging. Just put up a big project using POI.

19:10 Which was awesome, because I got to leverage Java without having to use it.

19:10 Lewix: hey guys im not arguing against clojure

19:10 justin_smith: Lewix: but the code and documentation is good enough in quality generally that you don't need to read java to fix your bug, unless you were writing java.

19:10 {blake}: hellofunk: I agree. I leveraged it. Was happy to have it.

19:10 Lewix: just saying try Go you'll also love it

19:11 {blake}: Lewix: Oh, I didn't think you were. A lot of newcomers seem to have that reservation, vis a vis Java, is all. And it's only as relevant as you want it to be.

19:12 Lewix: Blake1: most libraries use java , the whole point of being on the jvm is to take advantage of it

19:12 {blake}: Just saying: I had a major win here by implementing an Excel/Java thing without having to use either Excel or Java.

19:12 amalloy: well if i use clojure i might encounter java code, but if i use go i will definitely encounter go code

19:12 Lewix: if you're the kind of programmer that tweek libraries, doesn't it make sense you'd encouter java

19:13 {blake}: Lewix: Sure. But it's not necessary. The other big project I manage goes nowhere near Java.

19:13 amalloy: BaZING!

19:13 Lewix: I didn't say it was. I said in my use case it matters

19:13 so I had to suck it up

19:14 hellofunk: man this Go syntax is looking a lot like C. i think lisp has really spoiled me.

19:14 Lewix: amalloy: are you a go dude

19:14 dnolen: Lewix: people here are familiar with Go especially its concurrency model and we love that part, but given its unquestionably weak support for functional programming I don't think you're going to find many converts in #clojure

19:14 Lewix: hellofunk: it sure does

19:14 aha

19:15 dnolen: well if you're closed minded that is

19:15 hellofunk: lol

19:15 clojurebot: Gabh mo leithscéal?

19:15 {blake}: But will Go be as successful as Dart?

19:15 Lewix: dnolen: i came across great blog post about people who are very active with clojure who love go and vice versa

19:15 hellofunk: if dnolen is close minded then i'm an elephant taking a massive shit on the moon

19:15 {blake}: lol

19:16 Lewix: I don't understand how people can argue or pretend to when they never used what they're aguing against

19:16 I fail to understand that

19:16 justin_smith: Lewix: there are thousands of languages I could go learn. I'm here because I use Clojure.

19:16 Lewix: exactly

19:16 hellofunk: Lewix: Go's async abilities are very well understood in the clojure community because of core.async, so it's not total ignorance

19:17 dnolen: Lewix: I've used Go, just never in anger, and I tried it enough to respect it but have zero desire to use it in anger

19:17 hiredman: I started writing a lisp to go transpiler, and wrote a minikanren port to go, I hated it

19:17 Lewix: hellofunk: well it doesn't represent the whole language, so criticizing or assuming you won't like it because you're a "functional guy" is closed minded IMO

19:17 hellofunk: Lewix: i never said anything like that

19:18 Lewix: hiredman: I see. your opinion count then =)

19:18 hiredman: at least you know both

19:18 justin_smith: Lewix: I've done imperitive code, rejecting it again isn't close minded.

19:19 Lewix: justin_smith: it is, the fact that people don't wanna try functional programming is because they think about lips and close their mind to other options such as scala or #f, or clojure

19:19 hiredman: I started the lisp transpiler precisely because I was interested in go's concurrency, but the runtime was/isn't dynamic enough

19:20 hellofunk: Lewix: i will say this, i've rarely encountered someone anywhere who has used a lisp for a long time who didn't want to stick with it after seeing how it works, because other languages just don't quite feel the same to a lisper

19:20 hiredman: I did the minikanren port, because part of the justification for the lisp to go compiler was "oh, maybe I can make this lisp stuff more available to go", but then I thought "I could just do it in go" so I did

19:20 the datastructure related work for minikanren was really painful

19:20 imanc: why would someone define a function like this? (defn foo [& [a b c]]... )

19:20 hiredman: I imeplemented a redblack tree for a persistent map

19:21 justin_smith: imanc: if they don't actually care about the argument count

19:21 imanc: and will just fill in unsupplied args with nils

19:21 hiredman: go is not a great language for custom data structures

19:21 (fighting or ignoring the type system)

19:23 imanc: justin_smith: so presumably a, b, c will be assigned the first 3 params, anything else will get discarded?

19:23 Lewix: hiredman: I see. I give myself a few weeks with clojure - I was attracted to it mainly because of machine learning

19:23 hiredman: have fun, it is a blast

19:23 Lewix: hiredman: go lack the ecosystem / the libraries etc

19:24 thanks

19:24 noonian: I don't agree with the premise that functional programming with immutable values and imperative programming with mutation is merely a matter of taste. I believe there are real technical advantages to avoiding mutation.

19:24 imanc: yep, exactly

19:25 {blake}: Lewix: What's kind of cool about Clojure is that people will wrap up other language libraries and make them better.

19:26 (Or at least arguably so.)

19:26 Lewix: {blake}: really? good to know

19:26 imanc: so why not just do (defn foo [a b c & _] .... )

19:26 Lewix: {blake}: it reminds me of ruby

19:26 {blake}: Lewix: Yeah. So you may find, if you dig around in libraries, you're more inclined to stay out of the host environment.

19:26 justin_smith: imanc: that would not accept (foo a)

19:26 imanc: the other def will

19:27 noonian: imanc: the original one allows you to call it like (foo a) without throwing an exception as long as the body can deal with nil arguments gracefully

19:27 justin_smith: imanc: in fact, it would even work as (foo)

19:27 imanc: ahhh.. .awesome!

19:28 {blake}: Lewix: I came from Ruby (i.e., that was the language I was using professionally) and while Ruby was easier to get started in, Clojure has been easier to get to the details of.

19:28 Lewix: {blake}: im gonna use it then if i like it convince my team to use it for our next service

19:28 {blake}: Lewix: Go for it. It's worth it just for the discipline and the mindset.

19:28 Lewix: {blake}: i'll have to fight someone else who's learning go (and people in the office who like go including me)

19:29 {blake}: oh great - i also started with ruby, and use it mostly

19:29 {blake}: I think I listed a dozen languages yesterday I'd programmed in, and I liked most of them. It's okay to like multiple things. Just ask yourself: What choice makes you a better programmer?

19:29 Lewix: ruby gets messy

19:29 ^^

19:30 (rails)

19:30 ok guys enough talking clojure time

19:30 thanks for the useless chitchat

19:30 always good for relaxing :)

19:31 {blake}: Lewix: Good luck.

19:32 kir: "Clojure Is the New C" - interesting take on why Clojure

19:37 justin_smith: kir: link?

19:38 hellofunk: kir: i wonder if that article suggests that like C, Clojure is a good tool to build other tools (i.e. languages) with

19:39 amalloy: justin_smith: it looked to me like another talk by bob martin based on wholly unsubstantiated claims

19:43 hiredman: amalloy: no different then many other claims made every day about programming here and elsewhere

19:43 than

19:43 then?

19:43 justin_smith: than is the comparitive

19:43 hiredman: but new c seems really weird

19:44 amalloy: hiredman: i dunno about "no different than". bob reaches for some grander claims than most

19:44 justin_smith: oh that one

19:44 haha

19:44 hiredman: I do want a c to jvm compiler

19:44 amalloy: anyone remember "the last programming language"?

19:44 hiredman: vaguely

19:45 amalloy: in which he claims that clojure is so perfect it could realistically be the last programming language anyone ever invents

19:45 or uh something like that. it's been a while since i listened to it

19:45 hiredman: well, I mean, that is pretty spot on, no?

19:45 :P

19:46 hellofunk: amalloy: someone needs to show him the Sussman lecture about how all programming langauges we have are already obsolete

19:47 noonian: I find him fun to listen to even if I don't always agree with him

19:52 {blake}: The last programming language was COBOL.

19:53 So easy, even your secretary could write programs.

19:53 justin_smith: s/secretary/boss

19:54 a big motivation was the theory that management would actually be able to read the code

19:54 hellofunk: i still remember my elementary school librarian telling me about her Cobol work history

19:55 {blake}: My dad told me one of his clients gleefully told him how COBOL would make his services unnecessary.

20:15 hellofunk: what would it entail to lauch a local web server like normal from the REPL and have other computers in the same home/office network have access to what it serves

20:15 justin_smith: hellofunk: give them a URL with your port number in it, and be sure your firewall settings leave that port open

20:16 hellofunk: we would do that a lot at the web shop I used to work at

20:16 hellofunk: also, with linux and OSX at least, the machine will set it up so other people can navigate to http://your-host-name.local

20:16 for whatever the name of your machine is

20:16 hellofunk: you make it sound pretty simple

20:17 justin_smith: it is!

20:17 hellofunk: cool

20:17 justin_smith: IDK about windows though

20:17 I think windows makes these things harder

20:17 hellofunk: on OSX i wouldn't think the default is to just let any other machine access what you serve, is it?

20:17 justin_smith: but linux / osx, very simple

20:17 amalloy: hellofunk: just depends what interface you bind your server to

20:18 if you bind to localhost, then no; a public ip, then yes

20:18 justin_smith: hellofunk: on the contrary, if you don't make some effort to run a network service local only, other machines on your local network can access it

20:18 hellofunk: interesting.

20:18 justin_smith: though yeah, for example nrepl binds to localhost, for good reason

20:22 kir: justin_smith : pardon the late reply(phone) : the link : http://www.infoq.com/presentations/clojure-c

20:23 justin_smith: kir: yeah, found it in the meantime, thanks

20:26 kir: my take: clojure is more complex then C/Go(feature wise - has much wider abstraction); much of what exists in Clojure can be and inevitabily will be duplicated in those langauges(as can be said for assembler vs C)

20:28 ... clojure provides feature and implements them in a highly consistant and integrated manner - far better then those languages could; accept the initial conceptual learning curve, become a better programmer, use Clojure

20:29 features*

20:30 AeroNotix: what's that library for converting between naming styles?

20:30 like fooBar -> foo-bar

20:30 justin_smith: AeroNotix: camel-snake-kebab

20:30 AeroNotix: justin_smith: thanks!

20:30 justin_smith: or was it camelSnake_ke-bab

20:30 something like that :)

20:31 AeroNotix: :)

20:32 zacts: kir: key point asm > clojure :-D

20:32 (joking)

20:34 kir: zacts

20:34 asm?

20:34 justin_smith: I think we should bring back the old rule about Haskell, but for evangelism in general

20:34 kir: assembler macros for generating machine code

20:35 zacts: sorry kir I misread your post, I was trying to make a joke off of it

20:35 tomjack: wonder why they didn't use Guava

20:35 zacts: It was to say that I thought the post was putting down clojure

20:35 so I said, oh well that proves asm > clojure as a joke

20:35 kir: zacts: k

20:35 zacts: but I had the post all wrong anyway

20:36 * zacts is multitasking too much

20:36 kir: zacts : yep :)

20:41 Wanted to add before I go: I'm comming from C++ and recently Go - learning Clojure makes me a more concise and more thoughtfull programmer in those languages; for what it's worth.

20:43 zacts: indeed

21:14 dnolen: methinks needs Figwheel https://www.dropbox.com/s/0o6pa3jdsueeovc/react-native-editing.mp4?dl=0

21:19 tomjack: huh. I don't think the idea of writing native apps in cljs had occurred to me

21:20 I thought apple required using objc?

21:23 dnolen: tomjack: not since iOS 7, official JavaScriptCore bridge

21:23 also React Native works for Android

21:23 (though that work is still underway)

21:23 tcrayford____: dnolen: isn't official jscore *really* slow?

21:24 (iirc there's still no JIT in the javascriptcore that you can use inside apps)

21:27 dnolen: tcrayford____: not true anymore as far as I know

21:28 tcrayford____: and the JSC fast interpreter was never slow, but anyways JIT is on now from what I've heard

21:28 tcrayford____: FB Groups app is already React Native only

21:28 tcrayford____: damn

21:29 (to be fair, last time I used JSC was in 2011)

21:29 cfleming: dnolen: Unfortunately seems to be confirmed that there's no JIT for standalone JSC - not an issue for 99% of apps though.

21:29 dnolen: tcrayford____: it's a come a very, very, very long way in 4 years

21:29 tcrayford____: on many benchmarks for ClojureScript it is on par or besting V8

21:30 cfleming: dnolen: i.e. FB groups is obviously responsive and does no heavy lifting

21:30 tcrayford____: dnolen: yea, damn

21:31 dnolen: it's used by safari right? guess that's all the impetus they need to sink a tonne of money into it

21:31 dnolen: cfleming: ah K good to now, still I suspect for many applications modern JSC perf even non-JITed is great

21:31 tcrayford____: yeah JSC is the Safari / Mobile Safari engine, they've got some serious compiler heads on it now

21:32 cfleming: dnolen: yeah, no doubt. WKWebView does JIT on iOS 8, it seems: https://twitter.com/awfulben/status/561015998610821120

21:35 dnolen: tcrayford____: https://www.webkit.org/blog/3362/introducing-the-webkit-ftl-jit/

21:36 and SpiderMonkey is finally catching up too now that they have Generational GC

21:36 tcrayford____: dnolen: dope, thanks!

21:36 cfleming: dnolen tcrayford____ : I love that article, one of the most interesting things I've read in ages

21:36 dnolen: on-stack replacement in JS engines is amazing.

21:37 tcrayford____: cfleming / dnolen like 3 (?) years ago I took several months off and studied the luajit source code intensively. Compiler optimization is such a fun topic

21:39 cfleming: tcrayford____: Nice, LuaJIT is an amazing piece of work.

21:40 tcrayford____: yeah, it's super intense. It's also amazingly readable (or was back then) - the whole thing is like 40k lines of C + 8k lines of assembly

21:47 Lewix: I find it quite difficult to get going with clojure - what materials did you use to learn it

21:48 I tried a couple of different books but none of them hold my attention long enough

21:49 justin_smith: Lewix: have you tried 4clojure or the clojure koans at all?

21:49 Lewix: i dont think so

22:09 n0n3such: sometimes the best way to learn a language is to pick a project and dig in

22:09 worked for me with scala

22:09 ready to try clojure now

22:28 danlentz: monotonic timestamps

22:28 https://gist.github.com/danlentz/301a0f056ffd9c6605a9

22:39 gfredericks: danlentz: swap!+constantly = reset!

22:39 danlentz: yup. doh

22:39 gfredericks: thanks

22:41 gfredericks: danlentz: this smells racy

22:41 * gfredericks goes to run it

22:44 TimMc: gfredericks: That's the best way to suss out race conditions. Just run it a few times. :-)

22:45 justin_smith: give it a head start

22:45 danlentz: yes, that is what has been working for me :)

22:45 gfredericks: yep looks like collisions

22:46 any kind of "deref the atom, the swap based on what you see" is racy

22:47 justin_smith: danlentz: either put both stamps-this-tick and last-time inside a single map in an atom, or make them refs and use a transaction

22:47 danlentz: yeah

22:48 sdegutis: Can you do monads in Clojure?

22:48 gfredericks: and if you use a single atom you have to do the logic inside the swap function

22:48 sdegutis: it's less rewarding

22:48 sdegutis: gfredericks: why?

22:48 justin_smith: sdegutis: yes, but it performs poorly and it usually isn't especially useful

22:48 gfredericks: a) no type checker to fit the pieces together for you

22:48 b) the pertinent 0-arg functions don't work

22:48 I forget what they're called

22:49 sdegutis: curry?

22:49 bind or something?

22:49 gfredericks: mzero and something else

22:49 p_l: I'd add reason 0 = You're trying to escape time-travel hell in your code

22:49 sdegutis: justin_smith: why wouldn't it be useful?

22:49 To be fair, I don't understand why monads are useful even in Haskell.

22:50 gfredericks: sdegutis: I think clojure's for syntax is a decent approach for lots of monadic things

22:50 p_l: sdegutis: because they simplify what was previously a rather convoluted mess

22:50 gfredericks: there's just not a once-for-all impl of all the monad infrastructure like in haskell

22:50 p_l: but generally, monads are much less useful if you don't have heavy slant on purity that Haskell has

22:50 sdegutis: p_l: oh

22:51 p_l: sdegutis: Monads in Haskell started out from a certain Glasgow extension for doing IO ;)

22:51 sdegutis: neat

22:51 p_l: which replaced declaring main to be a function that consumes future and spits past, or something like that

22:51 (actually it might have been the other way around)

22:52 sdegutis: weird

22:52 But that's basically what monads seem like to me.

22:52 p_l: sdegutis: generally, Monads in Haskell are kinda a way to make impure seem pure

22:53 gfredericks: it's nice to have that stuff tracked in the type system though; e.g. the java type system has no idea where your side effects are

22:53 justin_smith: p_l: I'm pretty sure consumes past and returns future

22:53 yeah, and clojure monads aren't as useful because they can't segregate side effects really

22:53 p_l: justin_smith: I recall it was a bit non-intuitive

22:54 gfredericks: but this kind of syntax ends up being plenty useful even though it smells like monads: https://github.com/gfredericks/test.chuck#for

22:55 you could make a similar thing for Maybe

22:55 p_l: anyway, pseudo-monads were a patch on ills of Haskell (Most of Haskell monads are not, actually, monads)

23:26 tomjack: doesn't :let implement return?

23:26 and :when is mzero

23:27 but only usable in 'for-notation', hmm

23:29 well

23:29 only need them otherwise if you want to write something monad-polymorphic

23:30 which I guess could be quite useful..

23:37 Mr0rris0: i found an old book on basic

23:37 is that of any use?

23:38 was in the loft in my barn

23:38 it looks pretty old, its just a student handbook thing for learning basic

23:41 whats that long number mean (possibilities) (~possibili@2601:9:280:b6b:5126:6189:b7b2:4

23:41 justin_smith: looks like a truncated ipv6 address

23:42 there should be 3 more hex digits at least

23:42 Mr0rris0: lol no clue what that means

23:42 justin_smith: Mr0rris0: domain names map to ip addresses

23:42 Mr0rris0: ya

23:42 justin_smith: ipv6 uses a different format from ipv4

23:43 Mr0rris0: truncated?

23:43 justin_smith: truncated means the end is cut off

23:43 Mr0rris0: oh

23:44 justin_smith: ~foo@address is shortand for the user foo's home directory when you log into that address

23:44 clojurebot: Roger.

23:44 Mr0rris0: foo?

23:44 justin_smith: ~forget foo@address

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

23:44 foo is learn foo

23:44 Mr0rris0: whats foo

23:44 lol

23:45 justin_smith: foo is the standard metasyntactic variable

23:45 in your example it was possibili

23:45 Mr0rris0: that bit before the @ sign?

23:45 justin_smith: so I was saying for any given name n ~n@address means the home directory of n when you log into address

23:46 yeah

23:48 Mr0rris0: i watched a little bit of that Go video

23:48 that one guy promoting Go alot earlier linked a youtube vid

23:49 i only got to see the first bit of it but it looked cool

23:49 i know so little but it seemed a little like the IRC

23:49 just in how it looked

23:49 rhg135: it's all nice until you call foreign-libs

23:49 Mr0rris0: how to work it ive got no clue but i managed to get little scripts going to run my game from irc

23:50 whats foreign-libs

23:50 whats it for

23:50 rhg135: erm, i meant any code you didn't write

23:50 dmitrig01: hey all! core.typed question. I’m using clojure.tools.logging, and when I do (log/error …), which is a macro that expands into a bunch of calls to other tools.logging functions… I’m fine providing them type annotations, but a bunch of them are methods on a protocol, and I don’t know how to annotate that

23:51 rhg135: mutability + code out of your control is a pain

23:51 Mr0rris0: like cutting stuff out and putting other things in?

23:51 whats mutability, i see that word alot

23:51 rhg135: things that can change basically

23:52 Mr0rris0: right i saw how it was hard to customize or edit things that had been done already

23:52 the stuff that is already in irc looks different than things people make for it

23:52 rhg135: it gets hard once you can call code and be unsure if you're data hasn't been changed

23:53 Mr0rris0: hmm

23:53 whats call code

23:53 remember all the shit and not need copy paste?

23:54 justin_smith: or more generally, to get a big picture view of what the invarients of a given piece of code might be. When things are immutable you know exactly where things propage (arguments and return values)

23:54 Mr0rris0: when you use a function that you already defined, that's calling the function

23:54 rhg135: yes as justin_smith says flow becomes explicit

23:54 justin_smith: s/propage/propagate

23:55 Mr0rris0: this is aggrigatin

23:55 :P

23:56 i need a new dictionary

23:56 or just use the old one

23:56 :D lol

23:56 uncommon words to me

23:56 seems theres a few in everything i read about this stuff

23:59 its bugging me all of the things i dont know

23:59 lol but im happy about it, dunno why

Logging service provided by n01se.net