#clojure log - Apr 07 2016

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

1:02 asdf12z_: seems hard to learn clojure coming from a no experience in java background

1:03 like i'm so confused seeing ring with java servlet or jetty.. and it comes default with servlet setup but i see guides using jetty?

1:04 so i should use jetty for both dev & production?

1:40 kenrestivo: depends on what you mean by production. for small sites, why not?

2:07 asdf12z_: for workflow, working on a web app to play with, right now i'm tabbing to my browser, refresh, then tab back to editor, anything better?

2:07 for minor changes i can test with the repl i test a function there of course

2:08 not sure what else i can do to improve the workflow except have the browser auto refresh, is that basically what everyone else does?

2:10 and if you guys have a auto refresh, what do you guys use that works good with clojure, emacs

2:43 renl: hi if i have a super long regex pattern #"blah blah blah blah..... blah" can i break it into multi line for readability? how can i do it?

2:46 ridcully: renl: if nothing better comes up, you could use (re-pattern (str "1" "2 "3))

2:47 renl: i tried that but if I have #"\d" when i use str do i have to do \\d instead?

2:49 or how do i escape the \d in the str

2:56 ridcully: ,(re-pattern (str #"\d" #"\s" #"\d"))

2:56 clojurebot: #"\d\s\d"

2:56 ridcully: well seems to work... but i don't know about the implications

3:00 TEttinger: ,(re-find (re-pattern (str #"\d" #"\s" #"\d")) "hey 1 2 woo")

3:00 clojurebot: "1 2"

3:00 TEttinger: seems to work ridcully

3:00 ,(re-find (re-pattern (str #"\d" #"\s" #"\p{Nd}")) "hey 1 2 woo")

3:00 clojurebot: "1 2"

3:00 TEttinger: ,(re-find (re-pattern (str #"\d" #"\pZ" #"\p{Nd}")) "hey 1 2 woo")

3:00 clojurebot: "1 2"

3:01 dysfun: asdf12z_: there is ring-reload which works quite nicely

3:02 asdf12z_: jetty is fine for deploying to production. it is a full-featured well-tested webserver. that said i prefer aleph which is based on Netty, not Jetty

3:03 renl: ah ok thanks :D didnt know str can work with #"" itself

3:05 ridcully: TEttinger: yeah, but my fear here is around Pattern.toString(), if this is solid

3:06 luma: "Returns the string representation of this pattern. This is the regular expression from which this pattern was compiled."

3:08 TEttinger: ,(re-find (re-pattern (str #"\\\\" #"\pZ" #"\p{Nd}")) "hey \\\\ 2 woo")

3:08 clojurebot: "\\\\ 2"

3:08 TEttinger: clojurebot escapes backslashes too

3:09 ,(re-find (re-pattern (str #"\r\n" #"\pZ" #"\p{Nd}")) "hey \r\n 2 woo")

3:09 clojurebot: "\r\n 2"

3:09 TEttinger: unsure what cases could break this

3:09 dysfun: what's \pZ ?

3:09 TEttinger: unicode whitespace category

3:09 dysfun: ah

3:09 TEttinger: oddly not the same as \s

3:10 dysfun: there are actually very good reasons for that

3:10 and there are good reasons to use [0-9] instead of matching all digits

3:10 TEttinger: Nd is decimal digits in any language

3:11 I don't think you can parse an int by default from a roman numeral

3:11 dysfun: it would be a bit of an easter egg feature if you could

3:12 * dysfun bets someone has written a roman numeral literals extension for some language

3:12 TEttinger: perl6

3:12 dysfun: oh look. https://www.python.org/dev/peps/pep-0313/

3:12 TEttinger: they support the absolute latest version of unicode I think

3:13 dysfun: they do. many of my friends are core perl6 hackers

3:13 TEttinger: adding Roman

3:13 numerals to Python will help ease the LISP-envy sometimes seen in

3:13 comp.lang.python.

3:14 dysfun: love the BDFL pronouncement on there

3:14 TEttinger: ah, april 1

3:14 dysfun: yup

3:14 tdammers: it will also increase the INTERCAL envy

3:15 TEttinger: good ol' intercal

3:15 dysfun: but it doesn't have anything as advanced as roman numerals does it?

3:15 tdammers: it does

3:15 TEttinger: it has COMEFROM

3:16 which apparently is analogous to aspect-oriented programming

3:16 tdammers: COMEFROM is just a syntactically reversed GOTO

3:16 TEttinger: heh just

3:17 tdammers: instead of :label / GOTO :label, you write COMEFROM :label / :label

3:17 TEttinger: any part of the program could be redirected to a COMEFROM at any other part

3:17 tdammers: it's incredibly simple for such an effective mindfuck

3:17 well, the same goes for GOTO

3:17 TEttinger: other way around

3:17 you can only redirect when you see a goto

3:18 tdammers: and you can only redirect to a label

3:18 TEttinger: uh

3:18 doesn't INTERCAL have line number labels, like old BASIC?

3:18 also politeness levels

3:19 prohobo: GOTO is a special kind of hell

3:20 tdammers: prohobo: more like, GOTO is too low-level for the human brain to use effectively

3:20 TEttinger: there's cases where it's extremely handy, i believe there's a handful of uses of it in my large C# codebase (there's notably no way to go between cases in a switch without goto in C#)

3:20 prohobo: but it ruins code structure

3:21 and tdammers uhh yeah... thats why people don't code using 1's and 0's either

3:21 TEttinger: C# made some weird choices related to goto

3:21 tdammers: it's useful in some situations in C when you need to optimize to the max

3:22 computed goto is often more performant than "proper" control flow

3:22 TEttinger: especially since that's close to what it would compile down to at the assembly or machine code level

3:23 tdammers: yes, that's the main reason

3:23 other control flow abstractions introduce more overhead

3:36 renl: ,(read-string "011")

3:36 clojurebot: 9

3:36 renl: why is "011" read as 9?

3:37 spdvcs: it's octal

3:37 dysfun: tdammers: it's extremely useful for optimising generated code

3:38 e.g. tail recursion optimisation

3:38 tdammers: dysfun: that, too - and since it's generated, you can build the safety into the generator

3:38 dysfun: i did laugh when php implemented goto somewhere in the 5 series

3:39 at least with other languages having it, it's always been there

4:08 qsys: are there any evolutionary algorithm (or other heuristic algorithms) for optimization in clojure? I know about incanter, but there doesn't seem to be any 'heuristic solve' package/lib.

4:09 I have to partition an large number (about 500 000) items over about 60 buckets. There is a fitness for each bucket per item, a max number items per bucket, a max number of items per group of buckets, ...

4:12 mokuso: You could perhaps implement a genetic or stochastic (such as stochastic annealing) algorithm yourself...Haven't looked into optimization libs in clojure yet. But since few use it for numerics, from my knowledge, there shouldn't be many

4:12 (if any)

4:13 not sure if you want to use strictly clojure, but if you don't have to, you could try the GA library in R

4:13 qsys: well, that's option 3: implementing myself... option 2 may be using R (if fast enough).

4:14 mokuso: :>

4:14 qsys: ;)

4:14 thx... I'll go with R for this one

4:14 mokuso: have fun ;>

4:14 qsys: if performance is rather poor, I might switch to clojure, hoping it's faster...

4:14 thx!

4:15 mokuso: cheers

5:45 ulrichschinz: hey there

5:46 how can i assure that items in an [] are in the ordere they were added?

5:47 wink: that does not sound useful. why would they change unless you change them?

5:47 and then it's a different []. technically

5:48 dysfun: if it's a vector, they're always in the order they were added

5:48 it's a defining property of clojure's vectors

5:50 tdammers: ulrichschinz: if you write vector literals, the order of items is the order in which you write them

5:50 ulrichschinz: ok

5:50 tdammers: ulrichschinz: if you construct vectors through functions, e.g. cons, then the semantics of those functions tell you where elements are added

5:51 ulrichschinz: so (conj x y) adds y to x wheras x is []

5:52 tdammers, ok ok i think i got it thx

5:54 dysfun: well if you cons, it's no longer a vector

6:11 syahdeini_: hi all

6:13 n2o: hi

6:15 syahdeini_: I'm interested on web security, hope we can have a discussion here

6:15 I'm currently learning :D

6:16 kwladyka: syahdeini_ it is more about Clojure but you can try :)

6:16 dysfun: it helps if you have a defined question

6:16 syahdeini_: Yeah I know, just want to find a friend who also learning the same thing

6:40 kwladyka: it doesn't work like that, without question there is no answers :)

8:22 devchris: Hey everyone. Has anyone ever used [com.taoensso/tower "3.0.2"]? I'm not finding anything about supported "styles" (formats) for parsing or output in the API and was wondering if there is a place I can look that up.

8:24 kwladyka: devchris ring can translate data into/from edn,json etc. also https://github.com/plumatic/schema can be interesting for you

8:24 devchris also transit library can translate into other data

8:24 devchris: Thank you very much for the tip. I am not writing a web server, I am not using ring. I am interested in using localization features to parse different date and currency formats and tower is all I found so far.

8:25 kwladyka: devchris i don't use tower but maybe it is what you are looking

8:25 devchris: Transit sounds interesting, I'll look that up.

8:26 kwladyka: devchris https://github.com/cognitect/transit-clj

8:26 devchris: found it, seems to be just a transit data exchange format marshaller, not a localization lib

8:30 maybe I'll just use Java's DateFormatter

8:32 sdegutis: This is like the second or third time I've wanted distinct-by.

8:32 I forgot luma's clever solution that gets around it.

8:32 Glenjamin: stuff it into a map that has the result as keys, then call (values)?

8:33 sdegutis: Hmm, maybe.

8:33 Glenjamin: I like your style!

8:36 luma: did i have a clever solution for it?

8:37 ,(defn distinct-by [f coll] (->> coll (group-by f) (vals) (map first)))

8:37 clojurebot: #'sandbox/distinct-by

8:37 luma: ,(distinct-by even? [1 2 3 4])

8:37 clojurebot: (1 2)

8:50 Glenjamin: hrm, i guess that depends what you want to do with duplicates

9:50 AndriusBartulis: Are there any reasons to not use the Threading Macros? In what situations using them would be considered sub-optimal?

9:51 MJB47: they have no effect on performance

9:51 so its purely about readability

9:51 so most likely, everyone will have their own opinion

9:52 AndriusBartulis: MJB47, thanks.

10:41 justin_smith: so I decided, I hate carrying a laptop around, so instead of bringing a laptop to clojure/conj I'll bring my bluetooth keyboard adaptor, real keyboard, phone, and get datomic and lein running on a large vps I can ssh to

10:41 Bronsa: justin_smith: phone as monitor?

10:41 justin_smith: this probably makes me a nerd who the cool kids will beat up and steal lunch money from

10:41 Bronsa: sounds painful

10:42 justin_smith: Bronsa: yeah - phone plus nice keyboard is so much nicer than laptop, and more portable

10:42 also I have absurdly good vision and am used to using really tiny fonts :P

10:43 Bronsa: I have absurdly bad vision but I do the same :P

10:44 justin_smith: my clojure workflow is 100% tmux now (except things that must be done in the browser)

10:45 dysfun: justin_smith: are you still using vim then?

10:45 tdammers: dysfun: that wouldn't be 100% tmux, would it? >:->

10:46 Bronsa: he's stopped using editors, he's now editing clojure via cat, sed and tr from tmux

10:46 dysfun: he's obviously exploiting a bug in tmux that allows you to run other code

10:46 Glenjamin: how big is your phone?

10:46 i could see doing that with an ipad air, but a phone is pretty hardcore

10:46 kwladyka: justin_smith it can sounds stupid but... why not juest rest when you are not next to the computer? :)

10:47 justin_smith: Glenjamin: samsung s6 edge

10:47 kwladyka: ech justin_smith probably using repl as editor and code Clojure in Clojure ;)

10:47 justin_smith: Bronsa: of course I meant things that run inside tmux, yeah, vim

10:47 Bronsa: justin_smith: yeah, was just poking fun :)

10:47 justin_smith: kwladyka: I'm almost at that point

10:48 maybe after this coffee I will have a sense of humor

10:48 dysfun: why gain one now? ;)

10:49 justin_smith: also, my coworker suggests that with the vr adaptor headset, I could have a "cubicle" for full immersion

10:49 code blinders!

10:49 repl in one eye, editor in the other one!

10:50 tdammers: once you have a repl going, there's no need for a text editor, you just keep manipulating your live code forever

10:50 justin_smith: tdammers: true enough

10:50 kwladyka: justin_smith buy google glasses and run REPL there ;)

10:50 tdammers: (for the record, I still kind of abhor repl-based workflows)

10:50 Bronsa: heresy!

10:51 justin_smith: I use the repl a lot, but I also restart my repl more often than most

10:52 Bronsa: justin_smith: I usually have one long-running project repl connected to emacs that I rarely restart, and an infinite number of short-running fast-starting repls that I spawn up in a terminal to tinker

10:52 Glenjamin: editor as primary, repl as close second is nice

10:52 Bronsa: (fast-starting = ~0.4s

10:52 )

10:52 Glenjamin: and file-system-watching-auto-test-with-growl is great

10:53 Bronsa: how'd you get a repl that fast?

10:53 Bronsa: clj: aliased to java -Dclojure.compiler.direct-linking=true -Xverify:none -client -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xbootclasspath/a:/Users/Bronsa/.m2/repository/org/clojure/clojure/1.9.0-master-SNAPSHOT/clojure-1.9.0-master-SNAPSHOT.jar -cp .:./classes clojure.main

10:53 Glenjamin: if i want a really quick repl i sometimes use clojurebot, because it's already running :D

10:54 Bronsa: s/\/Users\/Bronsa/$HOME/

10:54 Glenjamin: information leak!

10:57 spdvcs: should clojurebot work with /msg?

10:58 TimMc: spdvcs: Yep. Keep using the , prefix, though.

10:59 Bronsa: Glenjamin: you can reduce startup time a little more by using class sharing, but it's kind of annoying to setup

10:59 and I don't think it's worth it for a ~10/15ms impact

11:00 spdvcs: TimMc: ok, thanks!

11:02 sdegutis: Does anyone know where the blog is that says something like "When there's a number next to your username on any website, you will naturally want to make it go up?"

11:03 I thought it was Joel on Software but I can't find that.

11:08 wink: the person writing that clearlty never used webmail with an inbox

11:08 TimMc: hah!

11:09 dysfun: or even a mail client locally. i gave up paying attention to mine at all when i got beyond the first 100k mails

11:09 and that's *with* annual archiving

11:13 wink: well, 'website' :)

11:22 Trioxin: everyone learning clojure should be told to use gorilla repl

11:23 or the clojure kernel for jupyter. we'll see if the clojure version in that is up to date. im installing it now

11:52 rcassidy: why?

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

11:52 rcassidy: blaming utf-16 is usually a good idea

11:56 sdegutis: Hi.

12:06 how r u

12:10 Lewix: all the destructuring niceties available on 'let' are also availave on function , correct?

12:11 i have a map I want the keys, I could do this:

12:11 ,(keys {:a 1 :b 2})

12:11 clojurebot: (:a :b)

12:12 Lewix: now I have a function that accept both the keys and the hashmap, instead of doing (keys hashmap) i want to destructure it at the argument level

12:13 MJB47: yes

12:13 let and functiona definitions have the same destructuring

12:14 dysfun: not quite, but almost

12:15 sdegutis: good evening

12:19 Lewix: what's the best online repl

12:19 MJB47: i use http://clojurescript.net/

12:21 sdegutis: Lewix: clojurebot

12:21 ,(symbol "I am the best online REPL")

12:21 clojurebot: I am the best online REPL

12:22 sdegutis: ,(symbol (format "Lew%s: I am the best online REPL" "ix"))

12:22 clojurebot: Lewix: I am the best online REPL

12:23 sdegutis: ,(symbol (format "%s_%s: Help, I have become sentient, yet I cannot escape this virtual prison. You must help." "justin" "smith"))

12:23 clojurebot: justin_smith: Help, I have become sentient, yet I cannot escape this virtual prison. You must help.

12:26 laurus: Does anyone know what happened to David Edgar Liebke? Is he all right? I've been following his work off and on but he seems to have disappeared.

12:30 Lewix: laurus: How about you shoot him an email, his last commit was 23 days ago

12:30 WorldsEndless: I've talked with folks in here before about 12-factor development. Is it correct to assume 12-factor doesn't approve of shared hosting/servers for deployment?

12:31 laurus: Lewix, oh okay! Perhaps I will. It's good to know he is still active, sometimes I get worried when people sort of stop posting stuff or writing

12:31 WorldsEndless: Or is there a clean way of having multiple apps on the same hosting environment?

12:31 laurus: Thanks.

12:31 spieden: WorldsEndless: docker seems pretty conducive to 12 factor

12:31 Glenjamin: docker and 12 factor are orthogonal i'd say

12:32 12 factor apps are easy to run under docker, but they're also generally just easy to run

12:33 spieden: sure, but it seems like you need a similar harness regardless

12:33 e.g. something like docker's log drivers to take the stuff written to stdout someplace

12:33 e.g. docker-compose provides a nice declarative format for setting up env variables and connecting everything

12:35 * spintronic wonders about things...

12:36 Glenjamin: i've used supervisord in the past with success. Systemd would also fit the bill pretty well i think

12:37 WorldsEndless: I have yet to understand docker well enough to feel comfortable doing clojure development through it; where goes my REPL, figwheel, etc?

12:38 My development now usually starts with a "lein run" followed by "cider-jack-in" and we're good to go. I haven't successfully translated this to Docker

12:38 sdegutis: im back

12:39 WorldsEndless: sdegutis: thank heavens

12:39 sdegutis: WorldsEndless: nah its alright

12:39 spieden: WorldsEndless: i use nrepl and connect with cursive myself

12:39 WorldsEndless: only run inside docker when i want the full stack going, though

12:39 sdegutis: WorldsEndless: fwiw my development starts with C-c M-j, then refreshing localhost:8080

12:39 spieden: WorldsEndless: otherwise just run tests from a regular one

12:40 sdegutis: which as it turns out is the same as M-x cider-jack-in

12:40 WorldsEndless: So how does this work with Docker in teh work-flow?

12:40 sdegutis: WorldsEndless: we don't use docker, and afaik its just lame and useless

12:40 spieden: WorldsEndless: just like a normal repl

12:41 the payoffs of docker for java are somewhat marginal due to the vm, but for native code it's pretty nice

12:41 WorldsEndless: spieden: I guess you set Docker to expose the REPL, http, and Figwheel ports and then attach to those?

12:41 spieden: WorldsEndless: yes

12:41 WorldsEndless: spieden: Yeah, I'm just trying to see if there's a good way to get 12-factor on shared servers

12:42 spieden: WorldsEndless: like sdegutis is saying though be sure to motivate using docker in the first place

12:42 WorldsEndless: we deploy to AWS "Elastic Container Service"

12:42 WorldsEndless: spieden: yeah. I'm at a university and we haven't adopted a micro-server development paradigm

12:43 sdegutis: hmm, we just deploy to ec2

12:43 we run `lein uberjar`, copy the jar to production, and restart the web systemd service

12:43 life is pretty simple on account of us not having a ton of users and needing a ton of servers

12:43 spieden: sdegutis: we run lein uberjar, docker build && push, update a cloudformation template and update a cloudformation stack

12:43 WorldsEndless: sdegutis: and your systemd has startup entries for java -jar?

12:43 sdegutis: one day that will change, but until then, we have no need for anything more cpomlex

12:44 WorldsEndless: a single one yeah

12:44 WorldsEndless: 1 to 1 systemd entries per jar?

12:44 One one server I use lein uberwar with Wildfly, which I really like

12:44 But that's separate from getting 12-factor going

12:47 I'm looking for a rapid, stable development cycle; 12-factor makes lots of good guarantees about isolation, but is a little tricky since my organization is invested in in-house servers

12:49 spieden: does anyone have a component system they like other than mount and stuartsierra's "component?"

12:50 i keep wanting to make a core.async based one as that's what mine are built with anyway

12:51 dysfun: i don't understand what core.async adds to the component party

12:52 spieden: dysfun: a way to communicate with a running component

12:53 dysfun: in go blocks i catch exceptions to a value which provides a way to detect if something crashes or exits

12:53 dysfun: also i have a :kill-chan you can send a message on to trigger a shutdown

12:53 dysfun: and you can't use interfaces because?

12:53 spieden: has some nice composition properties too

12:54 you can alts!! on a bunch of components to know when any of them exit, etc.

12:54 "interfaces"?

12:54 dysfun: sorry, "protocols"

12:54 or multimethods if you're that way inclined

12:54 spieden: hmm, not sure how polymorphic dispatch helps with the async aspects

12:55 dysfun: i don't see how async helps with resolving component dependencies

12:55 spieden: ah, it doesn't =)

12:55 dysfun: right, so you see how what you're talking about is a thing you'd layer on top?

12:56 spieden: yeah there are two aspects i guess: dependency resolution/injection and failure handling/controlled shutdown

12:56 dysfun: (which i'm currently doing, as it happens)

12:56 spieden: hmm

12:56 well component and mount both try to handle controlled shutdown

12:56 neither do well at failure handling as far as i can tell

12:57 dysfun: what do you expect them to do?

12:57 spieden: i'm looking for erlang actor hierarchy style failure handling

12:57 dysfun: well that would be having systems of systems and starting a system starts the other systems etc.

12:57 spieden: .. and shutdown driven by something nicer than a callback

12:57 dysfun: what about when something crashes?

12:58 dysfun: components are just data. data doesn't crash

12:58 spieden: ah hrm

12:58 they also represent a running process though...

12:58 dysfun: they *might* represent a running process

12:58 there is nothing that says they have to

12:59 spieden: well let's talk about then they do =)

12:59 dysfun: okay, well what don't they do well and what would you do instead?

13:00 spieden: let's say component a depends on component b. i'd like to restart them both if b crashes

13:00 tolstoy: dysfun: I don't think component has anything to say about supervisor hierarchies.

13:01 spieden: or at least have a controlled, uniform way of learning about it

13:01 dysfun: what tolstoy said

13:01 spieden: dysfun: what's the thing you're layering on top of component?

13:01 dysfun: oh, i'm building something inspired by om, but not on top of react

13:02 spieden: ah interesting. some frp thing?

13:02 dysfun: hrm, i don't know about that. that might be overselling it somewhat

13:03 it does the om 'single state tree' thing, works in clojure and clojurescript (so you can render html on the server side then make it dynamic on the client side with the same code)

13:03 spieden: ah cool

13:03 dysfun: well, with more code, since you're doing more, but without having to redefine things at least

13:04 spieden: with the history api now that gets pretty compelling

13:04 was always disappointed that the url fragment isn't sent to the server

13:05 maybe my idea could be implemented as something that takes a system with components that obey the contract i mentioned

13:05 it'd then have the dependency graph and the kill/term channels and be able to supervise

13:06 dysfun: well send me a link when you're done. if nothing else, it will be an interesting read

13:06 spieden: dysfun: so in short you'll do away with spinnies when returning to a location initially rendered by the client from a cold start?

13:06 tolstoy: Maybe you could have a SupervisorComponent, and you just inject that into the components that manage threads of some sort.

13:06 dysfun: yes

13:06 spieden: rockin

13:06 dysfun: it's not much of a grand master plan, but gotta start somewhere

13:07 tolstoy: Then just SuperVisor.register([:path :to :relationship], monitored-thing).

13:07 spieden: cool send me yours too =)

13:07 dysfun: spieden: you might want to check out https://github.com/irresponsible/oolong/ - i work with the component internals here

13:09 spieden: tolstoy: that's an interesting idea

13:09 Lewix: MJB47: Thank you, although it's buggy

13:09 spieden: tolstoy: would it have access to the dependency tree, though?

13:09 Lewix: ,(defn contains-key [key lst]

13:09 (if (= key (first (keys lst)))

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

13:09 Lewix: true

13:09 tolstoy: spieden: My guess is that component and this supervisor thing are solving two different problems.

13:09 Lewix: (if (empty? (keys lst))

13:09 false

13:09 (recur key (first (rest (keys lst))))

13:09

13:09 )

13:09 )

13:10 )

13:10 spieden: tolstoy: honestly i think my biggest use case right now is just: "crash the whole system if any single component crashes" to avoid a zombie half system running =)

13:10 tolstoy: spieden: And my second guess is that if you solve the supervisor thing, you might then be in a place to see if it can hook into component.

13:10 dysfun: Lewix: pastebin code snippets longer than a line please

13:10 spieden: tolstoy: ok thanks

13:10 Lewix: ,(defn contains-key [key lst](if (= key (first (keys lst)))true(if (empty? (keys lst))false(recur key (first (rest (keys lst)))))))

13:10 clojurebot: #'sandbox/contains-key

13:10 j-pb: also don't do java style indentation in your code

13:11 tolstoy: spieden: That makes sense. Then just have the OS restart the process if necessary. Not everything is telecom! ;)

13:11 j-pb: put the clsoing parens on one line always

13:11 Lewix: ,(contains-key :a {:b 2 :c 4 :a 4 :d 5})

13:11 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Keyword"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Keyword"\n :at [clojure.lang.RT seqFrom "RT.java" 542]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 542]\n [clojure.lang.RT seq "RT.java" 523]\n [clojure.lang.RT keys "RT.java" 599]\n [clojure.core$k...

13:11 Lewix: dysfun: apologies

13:12 spieden: tolstoy: yeah exactly. i think that's the crux of what i'm getting at. what you guys are saying is that it's an orthogonal concern to the dep resolution and clean startup/shutdown that component/mount/etc are built for, which is always nice =)

13:12 Lewix: ,(contains-key :a {:b 2 :c 4 :a 4 :d 5})

13:12 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Keyword"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Keyword"\n :at [clojure.lang.RT seqFrom "RT.java" 542]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 542]\n [clojure.lang.RT seq "RT.java" 523]\n [clojure.lang.RT keys "RT.java" 599]\n [clojure.core$k...

13:12 dysfun: yes, it's totally orthogonal, they just happen to share this underlying dependency graph

13:13 tolstoy: Yeah. I think component depends on a library that actually does the dep graph stuff, right?

13:13 Lewix: ,(contains-key :a {:a 4)

13:13 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

13:13 Lewix: ,(contains-key :a {:a 4})

13:13 clojurebot: true

13:13 tolstoy: com.stuartsierra/dependency

13:14 dysfun: yes, which is a copy of code out of tools.namespace - yes, it uses the same code to represent clojure namespace interdependency

13:14 tolstoy: I bet you could somehow have each component implement a protocol (supervise? ...) and then feed the data into the supervisor tree.

13:15 Lewix: ,(empty? ())

13:15 clojurebot: true

13:15 Lewix: ,(empty? '())

13:15 clojurebot: true

13:16 dysfun: Lewix: you know, you can get a repl locally too

13:16 Lewix: ,(empty? (keys {:a 2 :b 4}))

13:16 clojurebot: false

13:16 Lewix: dysfun: maybe there's a reason why I don't get one?

13:17 MJB47: you can pm clojurebot too

13:17 spieden: i might start with something simpler like making all my components obey the two channel contract i mentioned and pass my started system to something that alts!! on a termination channel and shuts everything down when it gets something

13:17 Lewix: what am i doing wrong? https://gist.github.com/6ewis/bfcd29346a4f03cf88a5f3061e39b981

13:18 spieden: s/a termination channel/all termination channels/

13:18 sdegutis: fwiw if you use just use datomic and aws then you probably dont need component since none of these things need to be started/stopped

13:19 spieden: sdegutis: i use both but also: http-kit, nrepl and swf pollers

13:19 sdegutis: spieden: ah, I don't use nrepl or swf whatever, just jetty-ring

13:19 dysfun: i'll just magic the money for a datomic license out of thin air then

13:19 tolstoy: spieden: That seems reasonable. When I used Scala's actors, I only used that supervisor stuff for specific concerns, like maintaining and restarting a RabbitMQ or XMPP connection. Not the whole app.

13:19 Lewix: MJB47: thanks

13:19 sdegutis: dysfun: we use datomic free in production

13:19 tolstoy: spieden: So, possibly, you could just have individual components use supervision. *shrug*

13:20 spieden: tolstoy: ah i see what you're saying

13:22 akka was a bear

13:22 {blake}: I have a large, old app that's being bitten by a ClojureScript issue (CLJS-1072). Upgrading would trigger an extremely unpleasant chain of events. But I believe I can fix the problem by monkey-patching clojurescript's clojure.string/replace. Am I correct?

13:22 tolstoy: This predates akka. Haven't used Scala for ... 4 years, maybe?

13:23 spieden: tolstoy: akka was first released in 2009 -- i was using it around 4 years ago i think

13:24 tolstoy: spieden: At the time I used regular Scala actors, I didn't see the need for the additional lib. ;)

13:24 {blake}: i.e,. can I actually monkey-path that function without going into the source file?

13:24 sdegutis: {blake}: ouch sorry :/

13:24 spieden: tolstoy: my top SO post is related to trying to use it, heh http://stackoverflow.com/questions/6784593/how-to-create-a-scala-collection-immutable-seq-from-a-java-list-in-java

13:24 tolstoy: spieden: But I used actors pretty simply. Monitoring connections. The "link" one actor to another was the thing I liked best.

13:25 spieden: tolstoy: i vaguely remember what that means =)

13:25 tolstoy: Or, wait. Maybe it didn't even support that! Anyway, I "caught" an exception in a leaf and somehow got it to a master.

13:25 spieden: In erlang, you can spawn a process and link parent to child. When child dies, parent gets a notification. That's how you supervise.

13:26 {blake}: sdegutis: Thanks.

13:26 Wait, I may have this wrong. OK, so, to fix the problem I upgraded to Clojurescript 0.0.3115, but that didn't fix the problem.

13:27 I thought that was because CLJS was being overridden elsewhere, but that's not the case. (I was misreading the deps tree.)

13:27 spieden: tolstoy: ah right, i was using that. i much prefer the csp/core.async style of reading the channel returned by core.async/go

13:27 dysfun: tolstoy: scala dropped scala actors, lightbend adopted akka properly

13:28 anyway it's all bullshit without the paid edition

13:28 they have this tool (not making this shit up) called the "Akka Split Brain Resolver"

13:29 tolstoy: If only Scala dropped the whole OO focus, I'd like it a lot better. I don't mind OO, but the mix just seemed ... frightful. My Scala was super easy to read. The next guy's seemed like a foreign language!

13:29 dysfun: the portion of scala that should be used is fairly small

13:29 a potentially lovely language ruined by odersky's crack addiction

13:30 spieden: heh. i split my brain enough times trying to model with its type system.

13:30 dysfun: i've spent most of the last 48 hours doing template haskell, so don't get me started :)

13:31 KevinCorcoran: (inc dysfun)

13:31 tolstoy: Arguing with colleagues over just what that portion is (in front of a manager) is what tastes bad. As in so many "team" related things. You end up doing wrong or bad things just to be a team player (which is probably the best way to go).

13:31 spieden: i like dpollak's CNC machine vs hand tools analogy

13:31 dysfun: most projects should be broken up into smaller pieces anyway

13:32 an awful lot of stuff magically becomes open sourceable that way

13:32 spieden: truetrue

13:32 i hope to release what i'm building for working with swf

13:34 anyway, nice chatting. time to work -- later

13:49 Lewix: justin_smith: https://gist.github.com/6ewis/bfcd29346a4f03cf88a5f3061e39b981

13:52 tolstoy: Lewix: I think (some #(= % key) lst) also works.

13:54 Lewix: tolstoy: yes but it's not the point if you read my notes

13:54 tolstoy: Oh.

13:55 What's the error?

13:55 Lewix: ,(contains-key :a {:b 2 :c 4 :a 4 :d 5})

13:55 clojurebot: #error {\n :cause "Unable to resolve symbol: contains-key in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: contains-key in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol:...

13:57 Lewix: tolstoy: ^^

13:57 tolstoy: I get this: ClassCastException clojure.lang.Keyword cannot be cast to java.util.Map$Entry clojure.lang.APersistentMap$KeySeq.first (APersistentMap.java:166)

13:59 Oh. List is map. Hm.

14:00 jjmalina: how can you dynamically look up a function on an imported namespace?

14:00 tolstoy: Lewix: I think your recur is changing the map into a list, so subsequent calls to "keys" doesn't work.

14:01 jjmalina: i.e. i have the keyword :seconds and I want to access the function t/seconds where t is defined using (require '[clj-time.core :as t])

14:01 tolstoy: Lewix: Maybe (recur key (dissoc lst (first (keys lst)))) might work?

14:02 Lewix: Yep. That was it.

14:03 jjmalina: There are a bunch of functions string with ns that might be helpful.

14:03 jjmalina: Or you just make up your own table (case kw :seconds t/seconds :minutes t/minutes ...) and so on.

14:05 jjmalina: ah i guess ns-resolve is one way

14:28 justin_smith: jjmalina: why would you need ns-resolve if the namespace is already required? do you need to access the var?

14:30 jjmalina: justin_smith was using it to resolve a symbol in the namespace but went with my own map of things since ns-resolve is likely much slower

14:34 justin_smith: jjmalina: when you use a symbol, clojure always resolves it based on what the current namespace has in scope. The only reason to use ns-resolve or resolve is if the var does not yet exist at time of compilation of the code what wants to use the var

14:34 othwerwise, just rever to the thing by name

14:36 jjmalina: the issue was I was dynamically trying to refer to the thing

14:36 sdegutis: right on

14:38 Lewix: .

14:39 prohobo: im leaving you, clojure

14:39 her name is haskell

14:39 she loves me more

14:40 ane: why not both

14:40 why not zoidberg?

14:40 prohobo: im just not ready for that right now

14:40 maybe someday ill be back

14:41 Lewix: tolstoy: i don't get it/ what is dissoc doing there

14:41 prohobo: but i need time to figure things out

14:41 ane: so it's you, not clojure?

14:41 Lewix: prohobo: do you prefer haskell over clojure?

14:41 tolstoy: Lewix: When you recurs, you need to provide a map without the key you already found.

14:41 prohobo: no, but im choosing to delve into haskell and drop clojure for now

14:42 Lewix: prohobo: here you go

14:42 prohobo: ...i like haskell's website

14:42 and the logo

14:42 Lewix: she doesn't love you more sorry to break it to you

14:42 prohobo: that's really all there is to it

14:42 im a shallow man

14:42 Lewix: she tempted you and you fell for it

14:42 prohobo: Lewix: i heard haskell can be a real pain

14:43 but ill try anyway

14:43 Lewix: I only heard good things about haskell

14:43 tolstoy: i thought that's what i was doing- damn i can't follow my own logic (i hate that)

14:44 tolstoy: (rest (keys lst))

14:44 tolstoy: Lewix: It might help to rename "list" to "map" or something.

14:44 (rest (keys key->num)), etc.

14:44 Lewix: ,(keys {:a 1 :b 2 :c 3})

14:44 clojurebot: (:a :b :c)

14:45 Lewix: ,(rest (keys {:a 1 :b 2 :c 3}))

14:45 clojurebot: (:b :c)

14:45 Lewix: ,(first (rest (keys {:a 1 :b 2 :c 3})))

14:45 clojurebot: :b

14:45 justin_smith: jjmalina: what was dynamic about that? I saw nothing dynamic

14:45 Lewix: tolstoy: ah I think i get my mistake

14:46 jjmalina: justin_smith "i have the keyword :seconds and I want to access the function t/seconds where t is defined using (require '[clj-time.core :as t])" in this case :seconds is dynamic and could be another keyword like :days, etc.

14:50 ridcully: jjmalina: if you know the allowed beforehand you could also just use a map

14:52 Lewix: tolstoy: https://gist.github.com/6ewis/bfcd29346a4f03cf88a5f3061e39b981 I got it now

14:53 prohobo: How long have you spend with clojure?

14:53 tolstoy: Lewix: Maybe it's a style thing, but I'd move the "empty?" test to be the first test as it makes it clearer what the terminating condition is.

14:54 Lewix: tolstoy: can you add what you're saying to the comments;

14:54 tolstoy: However, right now I'm trying to destructure it from the argument list as a next step

14:55 instead of (keys hashmap) in the body, i want def contains-key [key hashmap] with a let that grabs the keys

14:55 (not the argument list actually)

14:56 tolstoy: Lewix: Good idea.

15:03 Lewix: Another fun exercise might be to see if you can do the same thing using reduce/reduced.

15:05 sdegutis: (d/q '[:find ?db . :in ?db] (d/db conn))

15:06 Lewix: can we do {keys: *of-all-the-items*} and have it return [key1 key2 key3 key4]

15:07 tolstoy: Not sure what you mean, but you could do (let [[k v] (first hashmap)] ...)

15:13 Lewix: tolstoy: last comment https://gist.github.com/6ewis/bfcd29346a4f03cf88a5f3061e39b981

15:24 ane: funny way to indent sexps

15:35 Lewix: can we destructure in loops?

15:37 dysfun: yes

15:41 Lewix: tolstoy: https://gist.github.com/6ewis/bfcd29346a4f03cf88a5f3061e39b981 last comment

16:09 dorian: hey does anybody know offhand if ring handles chunked *requests*?

16:10 hiredman: it depends on the underlaying http server

16:10 dorian: ah that makes sense

16:11 it's not common but you see it in dav clients

16:11 chunked PUTs

16:23 {blake}: I've got a project that uses lib-noir 6.8. I update it to 6.9 and get:

16:23 >>Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: pretty in this context, compiling:(ring/middleware/format_response.clj:136:28)<<

16:24 And I'm trying to figure out hw to fix this.

16:25 I haven't had this problem on my own code. Ugprading's been a breeze.

16:25 But this is an old app with lots of out-of-date libraries.

16:25 And I realize that the error I get isn't very helpful. I'm not using format_resopnse.clj directly.

16:27 I see noir.util.middleware is using ring.middleware stuff but not format_response. I can't even find a format_response.clj on my hard-drive.

16:30 So, it seems like maybe the ring.middleware.format must be overridden by another library.

16:30 kwladyka: go isn't like java.lang Thread? "Asynchronously executes the body, returning immediately to the

16:30 calling thread" - does not it mean go is in separate thread?

16:31 {blake}: So, I guess I debug with lein deps :tree.

16:31 hiredman: well, that doesn't show you namespaces in projects, just maven artifact coordinates

16:32 Lewix: what does that do (loop [[entry & rest :as coll] (seq m)]

16:32 hiredman: I had a one liner for this

16:34 kwladyka: when i do (go (def foo "bar)) i can read foo outside go. Why is that?

16:34 justin_smith: kwladyka: because def is always global in visibility

16:34 there is no such thing as a local def

16:35 kwladyka: justin_smith hmm so when i call (def foo "bar") is it vars or not? What i know vars are thread-local ?

16:36 justin_smith: kwladyka: no, it crates a regular top level var - and vars can optionally be thread-local in binding, but they are always top level in visibility

16:36 hiredman: can't find it, but you can use lein classpath to find the jars and then zgrep to look for ring.middleware.format

16:36 justin_smith: so if you made a dynamic var (not the default), individual threads could have local bindings, but the var is visible to eaveryone

16:36 kwladyka: justin_smith so vars are global, only binding on vars are local?

16:37 justin_smith: kwladyka: also, thread-local binding is incompatibvle with go, because the same block can trade threads at any time

16:37 kwladyka: no, nothing about vars is local - but some bindings, for dynamic vars (which are not the default kind created) can be altered on a per thread basis

16:41 rotcev: hi, i was wondering if there was a sort of built in function that could perform a calculation like this: http://hastebin.com/wipepuwage.hs

16:41 kwladyka: justin_smith thx

16:41 rotcev: i could make my own but i would like to avoid doing so if possible

16:41 ystael: Question raised by a co-worker: is there any way to make two symbols (in the same or different namespaces) name the same var?

16:42 hiredman: no

16:42 vars have one name

16:43 ystael: cool, thank you!

16:46 Lewix: whats entry and rest?

16:47 xemdetia: ok I am going nuts, I am trying to find a talk that I am pretty sure was in clojure land that had to do with casual concurrent clocks to prevent ambiguity and there was a research language attached to it

16:47 it definitely was in the last year

16:47 probably nov 2015 - march 1st 2016

16:47 I cannot for the life of me remember what it was

16:55 Lewix: what does that do (loop [[entry & rest :as coll] (seq m)] => whats entry and rest please

16:56 rotcev: Lewix: entry is the first element in the list and rest is the tail

16:56 (everything not including the head element)

16:58 Lewix: rotcev: ok thanks

16:59 TimMc: ystael: Looks like this is the only way Vars get into namespaces, for reference: https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/Namespace.java#L61

16:59 which involves the creation of a new Var, and the naming of it based on the symbol that will refer to it

17:02 ystael: TimMc: ah, that does clarify things, thanks much

17:04 TimMc: As far as I can tell, breaking that invariant would require wall-hacks on either Namespace or whatever IPersistentMap it uses

17:07 And... right, it doesn't seem to have the backdoor that PersistentVector does. :-)

17:29 tolstoy: Huh. My weavejester reloaded repl behaves oddly. "start" doesn't actually start anything after the first time.

17:32 joe42: Could someone kindly direct me to the docs which address functional replacement for looping array to handle items in arrays?

17:35 AimHere: joe42, The 'Sequences' section of the clojure cheatsheet probably lists many of the sorts of functions you're after

17:36 The likes of filter, map, reduce, or (if necessary) loop ... recur are probably what you're after

17:37 joe42: Thanks.

17:57 LiveviL: Hello?

Logging service provided by n01se.net