#clojure log - Mar 18 2016

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

0:00 ajb: and wifi is also perfectly fine, but you do need to be able to use wired internet to install the chipset drivers

0:00 sdegutis: It's literally not seeing it. Why would this be?

0:00 srruby: there is a version of debian with non-free.

0:00 sdegutis: ajb: ahh the dreaded whats-it-called

0:01 ajb: broadcom right?

0:01 ajb: yep :/

0:01 sdegutis: Yeah those drivers.. ugh

0:01 From what I heard they're way crappy and result in very spotty wifi that drops a lot.

0:02 Okay this makes no sense at all.

0:05 Time to google a Clojure Ring tutorial that uses vars.

0:06 ajb: I remember seeing this clojurescript lib that allowed you to see a map in a nice json-like fashion and then expand/compress some of it by clicking on the sub maps, does anyone know what I am talking about?

0:08 parsecChar: what's the state of the art in clojure type checking? I tried type-clojure, but it still seems experimental + slow; is schema the next best thing?

0:08 sdegutis: Sounds neat. But no, I don't know.

0:09 parsecChar: that one big company tried typed-clojure and then gave up on it and wrote a few blogs about it

0:09 parsecChar: I forget who, but google would know

0:09 ajb: here is an image of it, but I don't know what its called https://dsd6xx3mp5v89.cloudfront.net/img/blog/content/sticky-app-state.png

0:09 sdegutis: parsecChar: anyway type checking in Clojure is dead

0:09 ew

0:10 parsecChar: so clojure is still unit testing based ?

0:10 sdegutis: AHA!

0:10 I should have used defonce, not declare.

0:10 Silly me!

0:11 parsecChar: automated testing is frowned upon in Clojure unless its a very few sparse clojure.test-based tests, so yeah

0:14 tolstoy: sdegutis: CircleCI, I think.

0:15 sdegutis: Sounds right.

0:15 ajb: I wish defmulti would somehow be one more character longer

0:15 tolstoy: CircleCI: We're supporting typed Clojure! https://circleci.com/blog/supporting-typed-clojure/

0:15 CircleCI: We're NOT supporting typed Clojure! https://circleci.com/blog/why-were-no-longer-using-core-typed/

0:16 ajb: circleci's entire frontend is built using clojure/script

0:18 sdegutis: ajb: like what?

0:18 ajb: I mean re: defmulti

0:18 ajb: I don't know, just defmethod and defmulti are 1 character different in length

0:19 monospace code doesn't lign up correctly without spaces

0:21 parsecChar: tolstoy: thanks for the links!

0:22 looks like they went for 726 days with typed clojure

0:22 tolstoy: No prob.

0:22 I think most people are either unhappy with lack of types on Clojure, and move on, or use Schema at the edges of their applications.

0:23 sdegutis: ajb: ah right, yeah I know what you mean

0:25 parsecChar: tolstoy: or they stay with haskell and look longingly at the nice tools taht clojure/cljs have

0:26 tolstoy: I used to write apps in which I passed maps from module to module, adding data as I went along (like a job accumulating work), but, somehow, I never do that anymore.

0:26 So, feels like I just have tuples, small "record-like" maps, numbers and strings. Rarely confusing.

0:27 The language teaches you to not need what it can't provide.

0:27 parsecChar: tolstoy: it's possible that type checking has eroded my ability to do simple checks like calcualtors have eliminated my ability to do mental arithmetric

0:28 sdegutis: IT WORKS!

0:28 Btw fwiw I'm strongly opposed to the JS-ification of the web.

0:28 HTML + HTTP + CSS works completely fine, just leave it alone.

0:29 Scrolling doesn't need to be invented in JS, it's a built-in browser feature.

0:29 etc etc

0:29 tolstoy: parsecChar: Yeah, I'd never argue or advise against something like Haskell. My only frustration (and it's just a hurdle to get over) is interacting with stuff like JSON.

0:31 parsecChar: tolstoy: json has not been an issue for me; wanting to do things that I can't easily express in the type system (sql, datomic, etc ...) has been a problem

0:32 tolstoy: Yes, I think that's similar to what I found. For instance, 5 years ago or so all I wanted was a simple XPath util to get data out of XML so that I could then put it into types.

0:33 That sent me down some path toward arrows and/or zippers, an arcane ~> style syntax, etc, etc, and my energy disappeared.

0:34 I'm sure it's better now, but that thin atmosphere between the world of strings and the world of types was filled with ... I don't know. Rich academic discourse? No down-and-dirty grease? Something.

0:36 Alas, I think Lisp &etc are just more aesthetically pleasing according to my minimalist taste. No rationality involved in that at all.

0:37 Speaking of rationality, I really like that ztellman chapter on naming. Quite nice!

0:37 parsecChar: tolstoy: lol, same here: the other day, I wanted typed sql queries -- so I needed row types -- and it was "okay, go read these recent research papers on doing typed row types as an extension of ahskell" -- and after a bit, I just wished I was using an untyped language

0:37 clojurebot: Excuse me?

0:37 tolstoy: parsecChar: Yeah. Let me get the data out as a string->string hash-map, _then_ I'll construct types.

0:38 (Student (get row "name") (get row "age") (get row "year-we'll-fail")), etc.

0:41 slester: Hi there! Is there a nice way of sending something as the initial value of a reduce when threading

0:41 ?

0:41 is ->as the best solution?

0:42 tolstoy: If the initial value isn't computed as a result of a previous step in the thread, you could use partial.

0:42 slester: it is :(

0:45 TEttinger: ,(->> [0 1 2] (mapv inc) (#(reduce conj % [11 12 13])))

0:45 clojurebot: [1 2 3 11 12 ...]

0:46 TEttinger: slester: is that solution not uh clean enough?

0:46 it is pretty janky

0:46 slester: it's a little janky

0:46 I think as-> is more flexible

0:46 in this case

0:46 because I have to do 2-3 update-ins then a reduce

0:47 tolstoy: There's always other options. Split those first update-ins into a separate function, then thread that.

0:49 slester: hmm, okay, thanks for the ideas!

0:49 TEttinger: ha, yeah, I didn't know about as-> . it seems like that's a main use for it, according to clojuredocs http://clojuredocs.org/clojure.core/as-%3E#example-568eeddae4b0f37b65a3c280

0:53 slester: TEttinger, oh, I actually was just going to do the whole thread in as->

0:54 I guess that saves adding some 'x' or whatever everywhere

3:53 jamiei: Morning all, I'm just tying out joplin for migrations and it seems to have run fine for the first 2 migrations that I added, but when I run the command line migrate method, it now fails to detect a third

3:54 Anyone with experience with joplin have any ideas?

3:55 ridcully_: you used the command line for the first two successfully?

3:55 or ran it by some other way?

3:57 jamiei: yes, I think 'lein migrate envname' did the job the first times

3:59 I can see the first 2 migrations in the ragtime_migrations table too

4:01 ridcully_: i asked, since i had fooled around with it and the reset just silently did nothing until i not only told it the env but also the exact db

4:02 jamiei: Interesting

4:02 I'll try that, thanks ridcully_

4:03 ridcully_: e.g. lein reset dev pg-dev vs lein reset dev (later one just does nothing for me - still could be a problem on my end or config)

5:08 Vlat-: hi! i'm new to clojure, playing with it around for a week. Currently I stuck with a problem I don't really understand. Could you, guys please take a quick look at my code (it's only 6 lines), and tell me where I'm wrong? Why 'set' doesn't receive map output as parameter?

5:08 http://pastebin.com/e0tuy5pn

5:10 dysfun: okay, well for a start, i'd write the last one as (into #{} ...) not (set ...)

5:10 have you walked through it in the repl to see what's not working?

5:11 Vlat-: yessir. Every line is working separately. It even work if i replace 'set' with 'println'. But with set/str/vec/etc it just fails

5:12 dysfun: so what is happening? is the input not being given to set or is set not returning what you expect?

5:12 because i suspect what is happening is set isn't behaving as you think it should

5:12 ,(doc set)

5:12 clojurebot: "([coll]); Returns a set of the distinct elements of coll."

5:13 dysfun: and yet the docs say...

5:21 Vlat-: try replacing 'set' with '(into #{})'

5:22 (minus the quotes)

5:22 oh hang on, sorry

5:22 is that meant to be a def, you're not trying to define a function?

5:23 Vlat-: yes, not defn

5:23 constant structure of sentences in a webpage

5:23 dysfun: and if you remove 'set', you see the data you expect, but with duplicates?

5:23 Vlat-: of course, I can make it defn, and it will even work somehow, but I'm trying to figure out what I'm doing wrong in case with def

5:24 dysfun: man, i'm dumb, kill me :)

5:25 dysfun: hey, it's puzzling me too, so don't stress

5:25 Vlat-: i tried to call def, using () :)))))))

5:25 for about a hour

5:25 dysfun: clojure syntax takes a bit of getting used to :)

5:26 anyway. so take out the 'set', does it now almost-work

5:27 Vlat-: dysfun: thx for your help, really appreciate it

5:27 dysfun: np

5:27 Vlat-: i thought i'll go crazy, because my code had to work, bud didn't :)

5:28 dysfun: okay, think i've spotted your error

5:28 i think str/split is wrong

5:28 because it will expect to (str/split ... #"\.")

5:28 expand*

5:28 * dysfun drinks more tea

5:30 dysfun: you have to be careful with arrow macros. if in doubt you can use as->

5:30 Vlat-: well, I definitely have to read more about them

5:31 by the way, can you suggest a good reading on Clojure in generaln?

5:31 dysfun: (doc as->) in the repl is a good start :)

5:31 clojurebot: "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."

5:31 Vlat-: Now I'm learning by trial and error, but it's not always good

5:31 dysfun: what sort of reading do you want? my most rated reading is actually an interactive cheatsheet: http://conj.io

5:32 although arrdem has changed the search so i use cmd-f to search it :)

5:33 Vlat-: maybe not even clojure, but functional programming. I have strong background with imperative languages (used to be C++ coder in gamedev), but don't feel myself home in functional paradigm (which looks promising after years of imperative coding)

5:35 dysfun: heh, well i'm doing a lot of c++ (and clojure!) these days, so i might ask you some c++ questions

5:36 i'm finding it easier to switch between styles than i expected

5:37 do you want a project-based thing or to understand deeply why clojure is how it is?

5:39 it's really a question of practical vs academic

5:41 Vlat-: dysfun: maybe practical is better

5:41 academic style is cool, but I'm afraid, if I start learning academic way - it'll take another half of year

5:42 dysfun: heh

5:42 maybe you could start on youtube, actually

5:42 for functional programming in c++

5:42 to ease you into the idea gradually

5:42 modern c++ gives you quite a lot of room to use functional patterns

5:43 clojure extends that to immutable data structures. i think learning to use those effectively will be a challenge

5:43 and there's going to be a voice in the back of your head worrying about efficiency

5:45 Vlat-: performance efficiency you mean? or programming efficiency

5:45 dysfun: performance

5:45 you'll finally learn what programmer efficiency means haha

6:11 sdegutis: Do I need to be concerned about namespace collisions as I name my root namespace for my project (e.g. "myapp")?

6:13 dysfun: you can think of it as first-come first served, but many of us prefer to use a group name as a prefix

6:14 but bear in mind that if your code is closed source, someone might come along and build an amazing open source library with that name that you then wouldn't be able to use :)

6:14 sdegutis: How would I know if it was already taken like that? Would `lein run` refuse to start or something?

6:15 I mean, let's say I created `myapp.core`, then it would only refuse to work if I loaded up a third party library who also created `myapp.core` right?

6:15 dysfun: i tend to go to clojars.org and search for it

6:15 i believe maven central enforces a group name, so single segment namespaces will not occur there

6:16 sdegutis: Excellent.

6:16 dysfun: there can be odd problems related to single segment namespaces though

6:16 sdegutis: So, what happens if I find one on Clojars that I know I would never ever add to :dependencies. I can use that then, right?

6:17 dysfun: unless it becomes extraordinarily popular and everything else starts using it, yes

6:17 then you have to avoid a lot more software

6:17 sdegutis: And even if I did use it, the only problem would be if any of my fully-qualified namespace names matches any of theirs exactly; sharing a prefix in any namespace isn't a problem, right?

6:18 dysfun: correct

6:18 sdegutis: So for example, my app could be "clojure.core.myapp" and everything would work fine.

6:18 I mean, that would be the prefix of all my namespaces.

6:18 dysfun: yes, though that's definitely not one i'd pick

6:18 sdegutis: Excellent!

6:18 Thanks dysfun you've been a tremendous help this morning.

6:18 dysfun: yw

6:19 sdegutis: I woke up an hour ago (4am) and couldn't sleep, so I got up and opened Clojure.

6:21 BostX: Hi I think I found a bug:

6:21 (def hm (hash-map "a" 1 "b" 2)) ((keyword (second (keys hm))) hm)

6:21 returns nil

6:21 :(

6:21 I'm on 1.8.0

6:21 sdegutis: ,(let [hm (hash-map "a" 1 "b" 2)] ((keyword (second (keys hm))) hm))

6:22 clojurebot: nil

6:22 MJB47: you are looking up a keyword as a key

6:22 when the key is a string

6:23 sdegutis: BostX: your code is literally this:

6:23 ,(:b {"a" 1, "b" 2})

6:23 clojurebot: nil

6:23 sdegutis: BostX: That's not a bug, that's well-defined behavior; there is no :b in that map.

6:23 BostX: sdegutis: so how can I access a value under the key "b"?

6:24 sdegutis: BostX: (get hm "b")

6:24 MJB47: or (hm "b")

6:24 sdegutis: BostX: or, if you're sure the map is not nil, or are okay with NullPointerExceptions if it is, then (hm "b")

6:24 BostX: sdegutis: uhm... I'll try

6:24 sdegutis: BostX: observe:

6:24 ,(= :b "b")

6:24 clojurebot: false

6:24 BostX: sdegutis: basically one never can be sure ... :)

6:24 sdegutis: ,(get {:b 1, "b" 2} :b)

6:24 clojurebot: 1

6:25 sdegutis: ,(get {:b 1, "b" 2} "b")

6:25 clojurebot: 2

6:26 BostX: sdegutis: I like the (get {:b 1, "b" 2} "b")

6:26 sdegutis: that works also if the hash-map is nil

6:26 sdegutis: BostX: correct

6:26 BostX: look up (get) on clojuredocs

6:27 BostX: sdegutis: thanx a lot!

6:29 sdegutis: Any welcome.

6:29 BostX: sdegutis: anyway I don't think that this ,(type (key (second (apply hash-map (.split "a 1 b 2 c 3" " ")))))

6:30 sdegutis: Whoa.

6:30 BostX: sdegutis: is quite correct.

6:30 sdegutis: How are you coming up with this stuff?

6:30 ,str/split

6:30 clojurebot: #error {\n :cause "No such namespace: str"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such namespace: str, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "No such namespace: str"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]\n ...

6:30 BostX: sdegutis: I mean I asked for a key and I got a string back... :(

6:32 sdegutis: Right, you gotta keyword-ize it somehow.

6:33 BostX: also make more use of -> and ->>

6:33 ,(->> (clojure.string/split "a 1 b 2 c 3" #"\s+") (apply hash-map))

6:33 clojurebot: {"a" "1", "b" "2", "c" "3"}

6:34 BostX: sdegutis: I don't like the ->, ->> macros; it's too much to remember. I prefer get-in

6:35 sdegutis: or something more descriptive

7:14 sdegutis: justin_smith: your (routes[this]) idea is turning out significantly more excellent than I could have ever imagined.

7:15 justin_smith: I honestly feel like this may be able to be extracted into a general-purpose library similar to Compojure at some point. Not that I would ever do such a thing, of course.

7:24 J_Arcane: Is there anywhere an actually updated guide and/or lein template for building a cross-platform clj/cljs library? Because I am finding nothing but incomplete information that's almost universally out of date.

7:29 sdegutis: Hmm. I must have forgotten how to make macros. This error surprises me.

7:30 "Unable to resolve symbol: request__14884__auto__ in this context"

7:30 Interesting.

7:31 Oh! Haha, I put request# in there twice.

7:32 Hmm. Yeah, I need to learn macros better.

7:39 Vlat-: could anyone please take look at my code? it's working, but I have a questions about style (i'm newbie to clojure). Are thread macros & functional composition are okay together? :)

7:39 i'm a damned good code maniac. :)

7:40 http://pastebin.com/RMBcidG1

7:41 Glenjamin: Vlat-: seems ok, rather than the comment and the cryptic line, i'd probably extract into a named function

7:44 Vlat-: Glenjamin: thx!

7:52 sdegutis: Vlat-: that doesn't really pack to hash-map

7:52 Vlat-: that turns it into a set it seems

7:52 Vlat-: yep, my bad

7:54 faxmodem: how can I change the log level in repl?

8:03 jweiss: is there a lib that does lightweight persistence (eg, a ref but persisted to a file somewhere)?

8:31 sdegutis: Is there a way to make `lein repl` run the same function that `lein run` would, i.e. the function declared by :main in project.clj?

8:38 Never mind, answered in #leiningen.

8:44 Is it possible to hide the Cider REPL when starting it up?

8:46 Ah, (setq cider-repl-pop-to-buffer-on-connect nil)

9:03 Hmm. Next I need to learn how to use websockets to auto-reload the page if I change something I guess.

9:06 Assoc preserves a record, even when it had no things beforehand, right?

9:07 ,(do (defprotocol IFoo) (defrecord Foo [] IFoo) (let [foo (Foo.)] (assoc foo :foo 'foo)))

9:07 clojurebot: #sandbox.Foo{:foo foo}

9:07 sdegutis: Phew.

10:07 Hi.

10:43 I have successfully created something that is really really really cool and am very excited about it.

10:43 dysfun: congrats

10:44 and yes, assoc preserves the input type, but only since 1.7

10:44 bacon1989: did you make a baby?

10:45 hyPiRion: sdegutis: hurray!

10:46 sdegutis: bacon1989: yes but she's not born yet and that's besides the point

10:46 dysfun: thanks! and we're using 1.8 so it's all good :)

10:46 hyPiRion: :D

10:46 I may even be able to share this code one day if my employer permits! That would be really cool.

10:46 dysfun: yeah, i got bored of employers who didn't like open source, so i decided to do an open source startup

10:47 unfortunately it turns out that i'm still too ashamed of much of it to put it on github...

10:47 bacon1989: sdegutis: congrats on the upcoming baby

10:48 what's this about clojure code in production?

10:48 * dysfun has clojure in production

10:48 bacon1989: I have some clojure code in production

10:48 renl: how do you make a living with an open source startup? *curious*

10:48 bacon1989: I don't think my employer even knows about it

10:49 dysfun: renl: there are actually many ways, not all of them appropriate to all types of business

10:49 bacon1989: renl: by selling the service itself, and not the code

10:49 sdegutis: dysfun: sorry to hear

10:49 bacon1989: thanks!

10:49 dysfun: the easiest way is to do what we do and sell a hosted version

10:49 sdegutis: Okay, going back to working on it now.

10:49 renl: nod

10:49 dysfun: or will be doing when i'm not too ashamed of the code to put it into production

10:49 support contracts are good as well, but it can be very annoying

10:50 bacon1989: in particular, open source pieces of your codebase, like libraries that you deem useful as standalone

10:50 i've wanted to do this

10:50 dysfun: quite a lot of big companies (read: people with lots of money) have very complicated procurement procedures

10:50 be careful with that though, i've got about 10 libraries i'm readying for production because i started factoring things out

10:51 we're self-funding, so we don't have to worry about providing a 1000x return for investors

10:51 renl: im juggling the idea of open sourcing some work at my job given that i suspect no one's gonna get anything done otherwise anyway, but i dont think my employers entertains such ideas

10:52 dysfun: heh. quite often in that case i've gone home and factored out the relevant behaviour into a new library and then rewritten the code to use it

10:52 then you have a legit excuse for working on it in work time

10:52 sdegutis: Wow. I never knew code could be like this.

10:53 dysfun: like what?

10:53 sdegutis: Like.. it makes perfect sense so far and I haven't coded any kind of workarounds that make me sigh yet.

10:53 bbl :)

10:54 dysfun: give it time, you will :)

10:55 bacon1989: my issue with doing a startup, is i'd have to search for talent outside of thunder bay

10:55 my city

10:55 dysfun: ... i don't see a problem

10:56 bacon1989: i do? Who do I hire?

10:56 dysfun: well there are several of us in this channel you could talk to if you wanted work doing

10:57 bacon1989: true, but i'd assume I wouldn't be able to afford most people in this channel

10:58 also, this channel isn't a very big pool of people

10:58 dysfun: how many programmers do you need?

10:58 bacon1989: I don't know, i've never made a startup

10:58 I don't even have a product lol

10:59 dysfun: my startup consists of two people. i write code, the other bofhs

10:59 * justin_smith just bought ztellman's "elements of clojure"

10:59 renl: do companies like to go 4clojure and check out the leaderboard to hire clojure experts?

10:59 bacon1989: I have ideas for projects

10:59 dysfun: renl: 4clojure is just a bit of fun really, i don't think anyone takes it seriously

10:59 renl: heh nod

11:00 justin_smith: it's a great way to get better at clojure, and to see a bunch of different clojure coding styles though.

11:00 dysfun: i tend to hire people i've hacked with before

11:00 when i have the opportunity

11:00 bacon1989: renl: saw a recent article that suggests that people who are good at coding exercises does not correlate with being good at software projects

11:01 renl: nod

11:01 bacon1989: I can attest, given some of the people i've worked with

11:01 ridcully_: justin_smith: the current book is the current free chapter, right?

11:01 justin_smith: ridcully_: yes

11:26 puhrez: Hello!

11:26 x-over from #clojure-beginners

11:27 So I'm having a problem with eastwood complaining about my use of env vars; read the section on their readme and it makes sense. any advice on (proper) ways getting around this?

11:27 i've tried :continue-on-exception true, but it doesn't seem to have taken

11:28 i tried excluding the namespace where the env vars are used (to construct a spark context), but it the spark context is used in the core of my project soo...

11:28 it, the resulting spark context,*

11:28 justin_smith: Bronsa`: I suggested maybe hiding the code that uses &env behind a protocol, and linting the protocol definition but not the implementation (where the thing that used &env actually is), but I was thinking you might have a better idea for this.

11:32 Bronsa`: don't thik that'll work either

11:33 I really don't have a good solution to this other than don't use &env :/

11:35 puhrez: yea, this problem got me to think alot more about the meaning of depending on the environment, and how in general it's probably bad because env is mutable

11:36 Bronsa`: puhrez: I'm curious as to why you need to use the val bit of &env. Depending on the internal compiler representation is not a good idea

11:36 puhrez: but the gains i get with getting to spark-env.sh are good enough for me to put a blanket on it

11:36 " val bit of &env"?

11:36 as in, if i define a env variable, lets say, spark-master-ip, why do i need the value of that?

11:37 (let it be known im using the environ library)

11:37 Bronsa`: oh, there might be a misunderstanding

11:37 me and justin_smith were talking about a different type of env

11:38 Glenjamin: which eastwood warning are you getting?

11:38 Bronsa`: puhrez: what's the actual error?

11:38 puhrez: Exception thrown during phase :analyze+eval of linting namespace client-events.core

11:38 Eastwood cannot analyze code that uses the values of &env in a macro expansion.

11:38 See https://github.com/jonase/eastwood#explicit-use-of-clojure-environment-env

11:38 justin_smith: puhrez: oh, I thought you were getting the error caused by macros using &env

11:38 oh, you were then

11:39 puhrez: well i'm pretty sure the offending code is

11:39 access-key (env :aws-access-key)

11:39 secret-key (env :aws-secret-key)

11:39 spark-master-ip (env :spark-master-ip)

11:39 spark-master-port (env :spark-master-port)

11:39 justin_smith: puhrez: that's not the &env that we or the docs are talking about

11:39 puhrez: where env is [environ.core :refer [env]]

11:40 i assumed (:/) that that was what environ is using under the hood

11:40 justin_smith: that's a normal, safe kind of env, that eastwood doesn't error on

11:40 the &env that the docs are talking about is an implementation detail of the clojure compiler

11:40 puhrez: hmm

11:40 justin_smith: crossed signals here for sure

11:40 Bronsa`: puhrez: are you using the library called useful by any chance?

11:40 puhrez: no

11:40 environ

11:41 justin_smith: puhrez: environ doesn't use &env - I know this because I've read the code, it's a very small project

11:41 Bronsa`: environ isn't the problem here, it must be some other library you're using in your project

11:42 puhrez: i'm using flambo for its spark DSL

11:42 could it be the call to ` f/text-file` which reads a file from some path?

11:42 justin_smith: now *that* might be messing with &env

11:42 puhrez: it would be in the macro magic part, not the paths part

11:43 puhrez: just searched through the repo and found no mention of &env

11:44 yea just looked through my deps' repos for &env and can't find any mention, perhaps looking thru my deps' deps

11:46 (thank you all btw)

11:54 justin_smith: Bronsa`: my thought that was if he hid whatever used &env in the implementation side of some protocol, and the linter was only run against the protocol definition and the things using the supplied implementation, skipping the implementation itself, this could avoid the issue of linting code that uses &env while still being able to lint everything else. This is kind of a big workaround for making a linter work, but I think it would actually do that jo

11:56 Glenjamin: are there any docs on what &env does?

11:56 oh, it *is* googleable

11:56 that's surprising, but handy

11:57 justin_smith: Glenjamin: yeah, first google hit for "clojure macros &env" is decent http://blog.jayfields.com/2011/02/clojure-and.html

11:57 Glenjamin: i assumed the symbol would make it ungooglable

11:57 justin_smith: that's a reasonable expectation, yeah

11:58 Bronsa`: first hit for "clojure macros &env" should be a big "FORGET &ENV EXISTS"

11:58 justin_smith: haha

11:58 ~&env is FORGET &ENV EXISTS

11:58 clojurebot: Alles klar

11:59 Bronsa`: I think the only way to know that &env exists at all is to read the source code for defmacro? Don't think it's actually documented anywhere (thanksfully)

11:59 JK it is

11:59 http://clojure.org/reference/macros#_special_variables

12:00 Glenjamin: website is PRable now, could try and get it removed

12:00 Bronsa`: puredanger: can we add a "Please don't use this, ever" at the end of &env's description? :)

12:01 Glenjamin: nah, I'm ok with it being there. I'm also ok with people using (keys &env), that's just a seq local symbols. Problem is when people start using (vals &env), doing interop with compiler internals

12:34 ilevd: Hello does aleph support ssl for websocket?

12:34 On server side

12:56 WorldsEndless: So, can I make a practical, responding micro-service with nothing but Bidi or Silk? I probably need to have something for servers in there, like Ring? For bare-bones, would I need anything else?

12:57 justin_smith: WorldsEndless: probably some kind of db or http lib for getting / storing your data? that should do it

12:58 WorldsEndless: Is middleware necessary? Or just Ring with a specified :handler ?

12:58 (Thinking just a "hello world" app here, so no data storage necessary)

12:58 tolstoy: ilevd: There was some discussion on the mailing list: https://groups.google.com/forum/#!topic/aleph-lib/g1mbp3ISzkI

13:01 WorldsEndless: If you want to make it stand-alone (not a war), you need an actual server, like jetty, http-kit, aleph, etc.

13:02 WorldsEndless: I use aleph, which doesn't require an adapter or ring (but supports ring).

13:02 WorldsEndless: tolstoy: I've been spoiled by Luminus. Outside Luminus, what's the easiest way to go War?

13:02 tolstoy: I'm trying out Wildfly, and I really like it

13:02 tolstoy: But I'm pretty easy to please. Just let me drop my war in its folder and it's good to go.

13:02 tolstoy: I don't know. Don't use war files.

13:03 I use aleph and: `(http/start-server #(handle %) {:port (:port config)})`

13:04 With `(defn handle [r] (case (:uri r) "/ping" {:status 200 :body "Ok" :headers {"content-type" "text/plain"} not-found))` and so on. I tend to use clout for routing.

13:04 WorldsEndless: But that's just me being minimalist.

13:04 justin_smith: tolstoy: so aleph handles ring response maps without using ring?

13:04 tolstoy: I think so.

13:05 Actually, yes, I'm pretty sure it does.

13:05 justin_smith: tolstoy: odd, because ring is just a protocol, and there isn't much to it beyond extending various kinds of hash-maps to generate http responses, and http requests to generate maps...

13:06 I mean, I believe it does that, but it's also funny

13:06 tolstoy: Well, you have jetty, then the jetty-adapter, then ring. The adapter just reconciles the two. I think ztellman built the adapter into aleph.

13:07 WorldsEndless: You can try this: https://github.com/weavejester/lein-ring

13:08 justin_smith: Yeah, the docs (https://github.com/ztellman/aleph#http) indicate it's a drop-in replacement for any ring compliant server.

13:11 WorldsEndless: So let me make sure I'm scoping the ideas right: Aleph is an alternative to things like Immutant as a way to make your jar self-contained?

13:11 tolstoy: Yeah. I just "java -jar myapp-standalone.jar config.edn" and it starts up a webserver I can put behind a proxy, or access right there.

13:11 WorldsEndless: (looks like its built upon Netty)

13:12 tolstoy: No running inside a container provisioned elsewhere. "Linux is my appserver," etc, etc.

13:12 WorldsEndless: tolstoy: what's yoru solution in the event of a server reboot?

13:12 for restarting your app(s)?

13:13 tolstoy: A shell script that runs "java -jar ..." and the hook that script into whatever the OSs rc.d system is.

13:13 Or use a supervisor. Or use commons.jservice (or whatever it's called).

13:13 WorldsEndless: Okay. Yeah, you utilize your Upstart or Systemd processes. Ok

13:13 tolstoy: In other words, the java web+server+app is just another process running on the OS.

13:14 WorldsEndless: Do you use micro-instances, or do you end up with multiple apps sharing a server?

13:14 justin_smith: WorldsEndless: I use jsvc, which handles things like logging, restarting if it crashes, integrates nicely with server startup scripts, etc.

13:14 tolstoy: Yeah, that thing.

13:14 I've used "monit" actually on Freebsd.

13:14 justin_smith: WorldsEndless: jsvc being the *nix version of commons-daemon

13:15 WorldsEndless: Right now I have NginX proxying to Wildfly, so I can add apps ad nauseum and only need those two things managing them all.

13:15 justin_smith: yeah, one difference with aleph compared to Wildfly is that iirc wildfly can be a container holding various apps inside it, while aleph is an http server that would be inside a self contained app

13:16 it's a question of who wraps who

13:17 i-blis: regarding aleph, anyone knows what is its main value (I've been using immutant/undertow for a year now)

13:17 tolstoy: An advantage of the WAR model is you can configure db connections, or mq, or whatever, in once place and have that app automatically bind to the right things. Nice for dev, staging, prod without having to build those distinctions yourself.

13:17 justin_smith: tolstoy: it has nice abstractions for handling network even streams, managing your server resources, and general piping and queueing of data

13:17 sdegutis: It's.. it's completely done. I can't believe it. The architecture works amazingly perfectly.

13:17 justin_smith: tolstoy: eg you can turn your requests directly into core.async messages on a channel

13:18 tolstoy: justin_smith: I think i-blis was asking about that. I love it for its server AND client websocket stuff. ;)

13:19 justin_smith: tolstoy: oops, reading comprehension fail

13:20 tolstoy: I also like it for its small footprint. I've had issues with the http client, though, in low memory systems.

13:21 WorldsEndless: So, Aleph can replace Ring for a minimal service? Interesting

13:21 i-blis: all these points look like good value, I should probably give it a try at some point ; thanks

13:29 sdegutis: For CSS, do you use reset.css or normalize.css or anything similar? If so, why did you choose it over alternatives? If not, is there any reason?

13:30 MJB47_: i use reset.css because ive used it before

13:30 they should both work

13:30 i didnt really think about it

13:32 sdegutis: Thanks :)

13:46 lellis: Hi all, We got a very wired problem here, this problem we will describe below only happens at amazon ec2 Amazon Linux.

13:46 When we send a request with accented caracters like: João we receive Jo?o. The content-type in the header is correctly set with application/json and charset=utf-8.

13:46 We are packaging the application with lein uberjar and run the application with Jetty embedded. And we start application with parameters -Dfile.encoding=UTF-8 -Dorg.eclipse.jetty.util.UrlEncoding.charset=utf-8.

13:47 But nothing that we had done worked when deployed at ec2 Amazon Linux. anybody could send us a clue?

13:53 spieden: lellis: the characters are in the request body?

14:00 lellis: is your app behind an elastic load balancer? (not sure how that'd matter but would vary from dev/test)

14:05 x-warrior: I'm saving a tree structure inside a map in an atom, it was a part of an interview exercise. I failed on it because of: "One improvement point we have identified is that your code could follow functional programming practices more closely, while being more careful with mutability and side-effects. An example is: the functions that manipulate the tree should be pure functions. You should receive a tree as input, and return a new tree as o

14:05 utput. In your case, you are using the atom in all your code, and it's not a good practice." but then I'm wondering, how could I guarantee that it will work on parallel if I'm not using a structure like an atom?

14:06 spieden: x-warrior: they might mean that you're passing the atom in places where you could pass its values or a subset thereof for manipulation

14:06 justin_smith: x-warrior: by doing what they say, taking a tree as input, and returning a tree as your output

14:07 x-warrior: nb the trees should be immutable and therefore you can't return the same tree

14:07 x-warrior: imagine if you implemented + and instead of returning 4 for (+ 2 2) you modified 2 so it was now equal to 4

14:07 that is what you are doing to trees

14:08 dnolen: ClojureScript 1.8.34 released https://groups.google.com/d/msg/clojure/J2d_WNHrDr4/YPAN4U3VDQAJ

14:09 sdegutis: How would you implement a thing where if you call a Clojure function, it sends a signal to the most recently rendered web page served from an HTTP router within that Clojure process, in order to reload it?

14:11 x-warrior: justin_smith: ok, but as far as I read, clojure is really good for parallelism, so let's say I have an API and a lot of requests changing properties of nodes in the tree. One of this properties, is "points", which is inc on a pyramid way. If your request and mine happen at the same time, and I'm not using something as an atom, you can increase my points from 1 to 2, but I read it as 1 and was increasing to 1.5, so your "+1" got lost

14:12 justin_smith: x-warrior: were they asking you to implement the state management system itself, or the tree updating logic? they shouldn't even have any overlapping code.

14:13 for the former, all the app needs to do is use the tree updater as an argument to swap!, that's not the interesting part of the code, the tree updater should know nothing about how the value is stored

14:14 x-warrior: for example --

14:14 ,(inc 1)

14:14 clojurebot: 2

14:14 justin_smith: ,(swap! (atom 1) inc)

14:14 clojurebot: 2

14:14 justin_smith: inc doesn't need to know about atoms or swap!, and it shouldn't

14:15 sdegutis: Am I looking for "Web Sockets" then? Or is there something else that can do this?

14:15 x-warrior: 23456

14:15 ops, sorry

14:18 justin_smith: they asked me to create a system that keep tracks of customer/invitee and give points like a pyramid as 0.5ˆk. So my direct invitee when he is confirmed (invite someone else) will give me one point... invitee from my invitee 0.5

14:18 I already talked you about this, I showed my solution using a deftype because they said it was too OO

14:19 then I tried this "atom" approach

14:19 I guess I need a lot more study in functional programming :(

14:20 justin_smith: x-warrior: I can't read their minds, but my guess is that they didn't like seeing state management code mixed with value processing code and wanted these to be separate things. That's what I would expect at least.

14:21 x-warrior: lol, I know that I'm just trying to remember you a little bit about the problem...

14:22 https://bitbucket.org/matheusbrat/clojure/src/19380f248d27131209c0573e875a276c777a0471/src/clojure_nubank/treef.clj?at=master&fileviewer=file-view-default

14:24 justin_smith: x-warrior: it should be very easy to replace all your uses of swap! and @ in that code to the functional programming equivalent

14:24 x-warrior: I'm using 2 assoc to add new nodes, 1 update-in to update a property as points and one assoc-in

14:24 justin_smith: then there can be a single call to swap! in the code that uses this namespace

14:24 x-warrior: assoc and update-in do not mutate anything, continue to use those, but don't use an atom

14:25 what you'll likely end up with is let blocks that bind the results of each assoc or update-in call. That's how we normally do it at least.

14:26 ,(let [a {} b (assoc a :foo 42) c (assoc b :bar "OK")] [a c]) ; x-warrior

14:26 clojurebot: [{} {:foo 42, :bar "OK"}]

14:32 x-warrior: always after an update I should update the atom with the new tree, or am I wrong?

14:32 justin_smith: no, don't use an atom

14:32 let someone else use an atom

14:33 that code, in that namespace, should have no atoms and no operations on atoms

14:33 rhg135: Or a ref, or agent. don't choose for them

14:33 justin_smith: exactly

14:34 hell, they can use a database directly if they want

14:37 x-warrior: I think if it has a database directly seems more straightforward to me. I think that I'm missing is, for every request I should "retrieve" the tree operate on it creating a new tree, but that will take some time to execute, if other request happens at the same time, before that is complete, I will have one tree with the node of the first request and another with the node of the second request... but the second request could have influenc

14:37 e on node of the first request

14:41 rhg135: Action at a distance...

14:41 x-warrio_: ops

14:41 my internet connection dropped for a while

14:42 did I miss anything?

14:42 rhg135: Nope

14:45 amalloy: X-warrior: you keep focusing on how to retrieve the tree, but everyone has given you the answer already: don't retrieve it. just take it as an argument to all your functions, and let the caller decide how to retrieve it for you

14:46 one gigantic problem with your tree-in-an-atom solution is it's only possible for you to have one tree at a time. i can't keep track of two separate trees, because all your functions read and write to your designated tree

14:48 gfredericks: so whenever I do tests involving async stuff, I always have to choose a timeout for things, and inevitably no matter what reasonably small value I choose there's always a non-trivial probability that the test will happen to run that slowly (GC pauses?0

14:48 it'd be nice to be able to measure time while accounting for GC pauses

14:48 I had the idea to have a background thread that acts as a clock and just increments a counter periodically

14:49 under the assumption that if the whole process paused then that clock would slow down too

14:49 is this pretty terrible?

14:51 hiredman: have you considered using the g1 collector?

14:54 gfredericks: hiredman nope

14:55 hiredman: my experience is anything involving timeouts in tests are always fragile, so the thing to do is to remove timeouts

14:56 which can be a tall order, but if you really want a repeatable test suite

14:56 gfredericks: hiredman: something like tying the threads together somehow, like catching exceptions on the other thread and throwing them on the main thread or something?

14:56 hiredman: what?

14:56 clojurebot: what is cells

14:57 gfredericks: I've got this thing with a bunch of workers and job queues and stuff

14:57 a timeout often corresponds to a job throwing an exception and languishing

14:58 so to eliminate the timeout I could detect that situation from the main thread somehow

14:58 hiredman: sure, your job queue has an error counter or something, and errors increment it, and you check it

14:58 or something like that

Logging service provided by n01se.net