2016-03-18
| 00:00 | ajb | and wifi is also perfectly fine, but you do need to be able to use wired internet to install the chipset drivers |
| 00:00 | sdegutis | It's literally not seeing it. Why would this be? |
| 00:00 | srruby | there is a version of debian with non-free. |
| 00:00 | sdegutis | ajb: ahh the dreaded whats-it-called |
| 00:01 | sdegutis | ajb: broadcom right? |
| 00:01 | ajb | yep :/ |
| 00:01 | sdegutis | Yeah those drivers.. ugh |
| 00:01 | sdegutis | From what I heard they're way crappy and result in very spotty wifi that drops a lot. |
| 00:02 | sdegutis | Okay this makes no sense at all. |
| 00:05 | sdegutis | Time to google a Clojure Ring tutorial that uses vars. |
| 00: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? |
| 00: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? |
| 00:08 | sdegutis | Sounds neat. But no, I don't know. |
| 00:09 | sdegutis | parsecChar: that one big company tried typed-clojure and then gave up on it and wrote a few blogs about it |
| 00:09 | sdegutis | parsecChar: I forget who, but google would know |
| 00: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 |
| 00:09 | sdegutis | parsecChar: anyway type checking in Clojure is dead |
| 00:09 | sdegutis | ew |
| 00:10 | parsecChar | so clojure is still unit testing based ? |
| 00:10 | sdegutis | AHA! |
| 00:10 | sdegutis | I should have used defonce, not declare. |
| 00:10 | sdegutis | Silly me! |
| 00:11 | sdegutis | parsecChar: automated testing is frowned upon in Clojure unless its a very few sparse clojure.test-based tests, so yeah |
| 00:14 | tolstoy | sdegutis: CircleCI, I think. |
| 00:15 | sdegutis | Sounds right. |
| 00:15 | ajb | I wish defmulti would somehow be one more character longer |
| 00:15 | tolstoy | CircleCI: We're supporting typed Clojure! https://circleci.com/blog/supporting-typed-clojure/ |
| 00:15 | tolstoy | CircleCI: We're NOT supporting typed Clojure! https://circleci.com/blog/why-were-no-longer-using-core-typed/ |
| 00:16 | ajb | circleci's entire frontend is built using clojure/script |
| 00:18 | sdegutis | ajb: like what? |
| 00:18 | sdegutis | ajb: I mean re: defmulti |
| 00:18 | ajb | I don't know, just defmethod and defmulti are 1 character different in length |
| 00:19 | ajb | monospace code doesn't lign up correctly without spaces |
| 00:21 | parsecChar | tolstoy: thanks for the links! |
| 00:22 | parsecChar | looks like they went for 726 days with typed clojure |
| 00:22 | tolstoy | No prob. |
| 00:22 | tolstoy | 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. |
| 00:23 | sdegutis | ajb: ah right, yeah I know what you mean |
| 00:25 | parsecChar | tolstoy: or they stay with haskell and look longingly at the nice tools taht clojure/cljs have |
| 00: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. |
| 00:26 | tolstoy | So, feels like I just have tuples, small "record-like" maps, numbers and strings. Rarely confusing. |
| 00:27 | tolstoy | The language teaches you to not need what it can't provide. |
| 00: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 |
| 00:28 | sdegutis | IT WORKS! |
| 00:28 | sdegutis | Btw fwiw I'm strongly opposed to the JS-ification of the web. |
| 00:28 | sdegutis | HTML + HTTP + CSS works completely fine, just leave it alone. |
| 00:29 | sdegutis | Scrolling doesn't need to be invented in JS, it's a built-in browser feature. |
| 00:29 | sdegutis | etc etc |
| 00: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. |
| 00: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 |
| 00: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. |
| 00:33 | tolstoy | That sent me down some path toward arrows and/or zippers, an arcane ~> style syntax, etc, etc, and my energy disappeared. |
| 00:34 | tolstoy | 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. |
| 00:36 | tolstoy | Alas, I think Lisp &etc are just more aesthetically pleasing according to my minimalist taste. No rationality involved in that at all. |
| 00:37 | tolstoy | Speaking of rationality, I really like that ztellman chapter on naming. Quite nice! |
| 00: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 |
| 00:37 | clojurebot | Excuse me? |
| 00:37 | tolstoy | parsecChar: Yeah. Let me get the data out as a string->string hash-map, _then_ I'll construct types. |
| 00:38 | tolstoy | (Student (get row "name") (get row "age") (get row "year-we'll-fail")), etc. |
| 00:41 | slester | Hi there! Is there a nice way of sending something as the initial value of a reduce when threading |
| 00:41 | slester | ? |
| 00:41 | slester | is ->as the best solution? |
| 00:42 | tolstoy | If the initial value isn't computed as a result of a previous step in the thread, you could use partial. |
| 00:42 | slester | it is :( |
| 00:45 | TEttinger | ,(->> [0 1 2] (mapv inc) (#(reduce conj % [11 12 13]))) |
| 00:45 | clojurebot | [1 2 3 11 12 ...] |
| 00:46 | TEttinger | slester: is that solution not uh clean enough? |
| 00:46 | TEttinger | it is pretty janky |
| 00:46 | slester | it's a little janky |
| 00:46 | slester | I think as-> is more flexible |
| 00:46 | slester | in this case |
| 00:46 | slester | because I have to do 2-3 update-ins then a reduce |
| 00:47 | tolstoy | There's always other options. Split those first update-ins into a separate function, then thread that. |
| 00:49 | slester | hmm, okay, thanks for the ideas! |
| 00: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 |
| 00:53 | slester | TEttinger, oh, I actually was just going to do the whole thread in as-> |
| 00:54 | slester | I guess that saves adding some 'x' or whatever everywhere |
| 03: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 |
| 03:54 | jamiei | Anyone with experience with joplin have any ideas? |
| 03:55 | ridcully_ | you used the command line for the first two successfully? |
| 03:55 | ridcully_ | or ran it by some other way? |
| 03:57 | jamiei | yes, I think 'lein migrate envname' did the job the first times |
| 03:59 | jamiei | I can see the first 2 migrations in the ragtime_migrations table too |
| 04: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 |
| 04:02 | jamiei | Interesting |
| 04:02 | jamiei | I'll try that, thanks ridcully_ |
| 04: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) |
| 05: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? |
| 05:08 | Vlat- | http://pastebin.com/e0tuy5pn |
| 05:10 | dysfun | okay, well for a start, i'd write the last one as (into #{} ...) not (set ...) |
| 05:10 | dysfun | have you walked through it in the repl to see what's not working? |
| 05: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 |
| 05:12 | dysfun | so what is happening? is the input not being given to set or is set not returning what you expect? |
| 05:12 | dysfun | because i suspect what is happening is set isn't behaving as you think it should |
| 05:12 | dysfun | ,(doc set) |
| 05:12 | clojurebot | "([coll]); Returns a set of the distinct elements of coll." |
| 05:13 | dysfun | and yet the docs say... |
| 05:21 | dysfun | Vlat-: try replacing 'set' with '(into #{})' |
| 05:22 | dysfun | (minus the quotes) |
| 05:22 | dysfun | oh hang on, sorry |
| 05:22 | dysfun | is that meant to be a def, you're not trying to define a function? |
| 05:23 | Vlat- | yes, not defn |
| 05:23 | Vlat- | constant structure of sentences in a webpage |
| 05:23 | dysfun | and if you remove 'set', you see the data you expect, but with duplicates? |
| 05: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 |
| 05:24 | Vlat- | dysfun: man, i'm dumb, kill me :) |
| 05:25 | dysfun | hey, it's puzzling me too, so don't stress |
| 05:25 | Vlat- | i tried to call def, using () :))))))) |
| 05:25 | Vlat- | for about a hour |
| 05:25 | dysfun | clojure syntax takes a bit of getting used to :) |
| 05:26 | dysfun | anyway. so take out the 'set', does it now almost-work |
| 05:27 | Vlat- | dysfun: thx for your help, really appreciate it |
| 05:27 | dysfun | np |
| 05:27 | Vlat- | i thought i'll go crazy, because my code had to work, bud didn't :) |
| 05:28 | dysfun | okay, think i've spotted your error |
| 05:28 | dysfun | i think str/split is wrong |
| 05:28 | dysfun | because it will expect to (str/split ... #"\.") |
| 05:28 | dysfun | expand* |
| 05:30 | dysfun | you have to be careful with arrow macros. if in doubt you can use as-> |
| 05:30 | Vlat- | well, I definitely have to read more about them |
| 05:31 | Vlat- | by the way, can you suggest a good reading on Clojure in generaln? |
| 05:31 | dysfun | (doc as->) in the repl is a good start :) |
| 05: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." |
| 05:31 | Vlat- | Now I'm learning by trial and error, but it's not always good |
| 05:31 | dysfun | what sort of reading do you want? my most rated reading is actually an interactive cheatsheet: http://conj.io |
| 05:32 | dysfun | although arrdem has changed the search so i use cmd-f to search it :) |
| 05: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) |
| 05:35 | dysfun | heh, well i'm doing a lot of c++ (and clojure!) these days, so i might ask you some c++ questions |
| 05:36 | dysfun | i'm finding it easier to switch between styles than i expected |
| 05:37 | dysfun | do you want a project-based thing or to understand deeply why clojure is how it is? |
| 05:39 | dysfun | it's really a question of practical vs academic |
| 05:41 | Vlat- | dysfun: maybe practical is better |
| 05:41 | Vlat- | academic style is cool, but I'm afraid, if I start learning academic way - it'll take another half of year |
| 05:42 | dysfun | heh |
| 05:42 | dysfun | maybe you could start on youtube, actually |
| 05:42 | dysfun | for functional programming in c++ |
| 05:42 | dysfun | to ease you into the idea gradually |
| 05:42 | dysfun | modern c++ gives you quite a lot of room to use functional patterns |
| 05:43 | dysfun | clojure extends that to immutable data structures. i think learning to use those effectively will be a challenge |
| 05:43 | dysfun | and there's going to be a voice in the back of your head worrying about efficiency |
| 05:45 | Vlat- | performance efficiency you mean? or programming efficiency |
| 05:45 | dysfun | performance |
| 05:45 | dysfun | you'll finally learn what programmer efficiency means haha |
| 06:11 | sdegutis | Do I need to be concerned about namespace collisions as I name my root namespace for my project (e.g. "myapp")? |
| 06: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 |
| 06:14 | dysfun | 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 :) |
| 06:14 | sdegutis | How would I know if it was already taken like that? Would `lein run` refuse to start or something? |
| 06:15 | sdegutis | 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? |
| 06:15 | dysfun | i tend to go to clojars.org and search for it |
| 06:15 | dysfun | i believe maven central enforces a group name, so single segment namespaces will not occur there |
| 06:16 | sdegutis | Excellent. |
| 06:16 | dysfun | there can be odd problems related to single segment namespaces though |
| 06: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? |
| 06:17 | dysfun | unless it becomes extraordinarily popular and everything else starts using it, yes |
| 06:17 | dysfun | then you have to avoid a lot more software |
| 06: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? |
| 06:18 | dysfun | correct |
| 06:18 | sdegutis | So for example, my app could be "clojure.core.myapp" and everything would work fine. |
| 06:18 | sdegutis | I mean, that would be the prefix of all my namespaces. |
| 06:18 | dysfun | yes, though that's definitely not one i'd pick |
| 06:18 | sdegutis | Excellent! |
| 06:18 | sdegutis | Thanks dysfun you've been a tremendous help this morning. |
| 06:18 | dysfun | yw |
| 06:19 | sdegutis | I woke up an hour ago (4am) and couldn't sleep, so I got up and opened Clojure. |
| 06:21 | BostX | Hi I think I found a bug: |
| 06:21 | BostX | (def hm (hash-map "a" 1 "b" 2)) ((keyword (second (keys hm))) hm) |
| 06:21 | BostX | returns nil |
| 06:21 | BostX | :( |
| 06:21 | BostX | I'm on 1.8.0 |
| 06:21 | sdegutis | ,(let [hm (hash-map "a" 1 "b" 2)] ((keyword (second (keys hm))) hm)) |
| 06:22 | clojurebot | nil |
| 06:22 | MJB47 | you are looking up a keyword as a key |
| 06:22 | MJB47 | when the key is a string |
| 06:23 | sdegutis | BostX: your code is literally this: |
| 06:23 | sdegutis | ,(:b {"a" 1, "b" 2}) |
| 06:23 | clojurebot | nil |
| 06:23 | sdegutis | BostX: That's not a bug, that's well-defined behavior; there is no :b in that map. |
| 06:23 | BostX | sdegutis: so how can I access a value under the key "b"? |
| 06:24 | sdegutis | BostX: (get hm "b") |
| 06:24 | MJB47 | or (hm "b") |
| 06:24 | sdegutis | BostX: or, if you're sure the map is not nil, or are okay with NullPointerExceptions if it is, then (hm "b") |
| 06:24 | BostX | sdegutis: uhm... I'll try |
| 06:24 | sdegutis | BostX: observe: |
| 06:24 | sdegutis | ,(= :b "b") |
| 06:24 | clojurebot | false |
| 06:24 | BostX | sdegutis: basically one never can be sure ... :) |
| 06:24 | sdegutis | ,(get {:b 1, "b" 2} :b) |
| 06:24 | clojurebot | 1 |
| 06:25 | sdegutis | ,(get {:b 1, "b" 2} "b") |
| 06:25 | clojurebot | 2 |
| 06:26 | BostX | sdegutis: I like the (get {:b 1, "b" 2} "b") |
| 06:26 | BostX | sdegutis: that works also if the hash-map is nil |
| 06:26 | sdegutis | BostX: correct |
| 06:26 | sdegutis | BostX: look up (get) on clojuredocs |
| 06:27 | BostX | sdegutis: thanx a lot! |
| 06:29 | sdegutis | Any welcome. |
| 06:29 | BostX | sdegutis: anyway I don't think that this ,(type (key (second (apply hash-map (.split "a 1 b 2 c 3" " "))))) |
| 06:30 | sdegutis | Whoa. |
| 06:30 | BostX | sdegutis: is quite correct. |
| 06:30 | sdegutis | How are you coming up with this stuff? |
| 06:30 | sdegutis | ,str/split |
| 06: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 ... |
| 06:30 | BostX | sdegutis: I mean I asked for a key and I got a string back... :( |
| 06:32 | sdegutis | Right, you gotta keyword-ize it somehow. |
| 06:33 | sdegutis | BostX: also make more use of -> and ->> |
| 06:33 | sdegutis | ,(->> (clojure.string/split "a 1 b 2 c 3" #"\s+") (apply hash-map)) |
| 06:33 | clojurebot | {"a" "1", "b" "2", "c" "3"} |
| 06:34 | BostX | sdegutis: I don't like the ->, ->> macros; it's too much to remember. I prefer get-in |
| 06:35 | BostX | sdegutis: or something more descriptive |
| 07:14 | sdegutis | justin_smith: your (routes[this]) idea is turning out significantly more excellent than I could have ever imagined. |
| 07:15 | sdegutis | 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. |
| 07: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. |
| 07:29 | sdegutis | Hmm. I must have forgotten how to make macros. This error surprises me. |
| 07:30 | sdegutis | "Unable to resolve symbol: request__14884__auto__ in this context" |
| 07:30 | sdegutis | Interesting. |
| 07:31 | sdegutis | Oh! Haha, I put request# in there twice. |
| 07:32 | sdegutis | Hmm. Yeah, I need to learn macros better. |
| 07: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? :) |
| 07:39 | Vlat- | i'm a damned good code maniac. :) |
| 07:40 | Vlat- | http://pastebin.com/RMBcidG1 |
| 07:41 | Glenjamin | Vlat-: seems ok, rather than the comment and the cryptic line, i'd probably extract into a named function |
| 07:44 | Vlat- | Glenjamin: thx! |
| 07:52 | sdegutis | Vlat-: that doesn't really pack to hash-map |
| 07:52 | sdegutis | Vlat-: that turns it into a set it seems |
| 07:52 | Vlat- | yep, my bad |
| 07:54 | faxmodem | how can I change the log level in repl? |
| 08:03 | jweiss | is there a lib that does lightweight persistence (eg, a ref but persisted to a file somewhere)? |
| 08: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? |
| 08:38 | sdegutis | Never mind, answered in #leiningen. |
| 08:44 | sdegutis | Is it possible to hide the Cider REPL when starting it up? |
| 08:46 | sdegutis | Ah, (setq cider-repl-pop-to-buffer-on-connect nil) |
| 09:03 | sdegutis | Hmm. Next I need to learn how to use websockets to auto-reload the page if I change something I guess. |
| 09:06 | sdegutis | Assoc preserves a record, even when it had no things beforehand, right? |
| 09:07 | sdegutis | ,(do (defprotocol IFoo) (defrecord Foo [] IFoo) (let [foo (Foo.)] (assoc foo :foo 'foo))) |
| 09:07 | clojurebot | #sandbox.Foo{:foo foo} |
| 09:07 | sdegutis | Phew. |
| 10:07 | sdegutis | Hi. |
| 10:43 | sdegutis | I have successfully created something that is really really really cool and am very excited about it. |
| 10:43 | dysfun | congrats |
| 10:44 | dysfun | 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 | sdegutis | dysfun: thanks! and we're using 1.8 so it's all good :) |
| 10:46 | sdegutis | hyPiRion: :D |
| 10:46 | sdegutis | 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 | dysfun | 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 | bacon1989 | what's this about clojure code 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 | sdegutis | 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 | dysfun | 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 | bacon1989 | 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 | dysfun | be careful with that though, i've got about 10 libraries i'm readying for production because i started factoring things out |
| 10:51 | dysfun | 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 | dysfun | 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 | sdegutis | 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 | bacon1989 | 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 | bacon1989 | 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 | bacon1989 | 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 | 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 | dysfun | 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 | puhrez | x-over from #clojure-beginners |
| 11:27 | puhrez | 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 | puhrez | i've tried :continue-on-exception true, but it doesn't seem to have taken |
| 11:28 | puhrez | 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 | puhrez | 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 | Bronsa` | 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 | puhrez | " val bit of &env"? |
| 11:36 | puhrez | as in, if i define a env variable, lets say, spark-master-ip, why do i need the value of that? |
| 11:37 | puhrez | (let it be known im using the environ library) |
| 11:37 | Bronsa` | oh, there might be a misunderstanding |
| 11:37 | Bronsa` | 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 | puhrez | Eastwood cannot analyze code that uses the values of &env in a macro expansion. |
| 11:38 | puhrez | 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 | justin_smith | oh, you were then |
| 11:39 | puhrez | well i'm pretty sure the offending code is |
| 11:39 | puhrez | access-key (env :aws-access-key) |
| 11:39 | puhrez | secret-key (env :aws-secret-key) |
| 11:39 | puhrez | spark-master-ip (env :spark-master-ip) |
| 11:39 | puhrez | 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 | puhrez | 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 | justin_smith | 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 | puhrez | 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 | puhrez | 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 | justin_smith | 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 | puhrez | yea just looked through my deps' repos for &env and can't find any mention, perhaps looking thru my deps' deps |
| 11:46 | puhrez | (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 | Glenjamin | oh, it *is* googleable |
| 11:56 | Glenjamin | 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 | justin_smith | ~&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 | Bronsa` | JK it is |
| 11:59 | Bronsa` | 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 | Bronsa` | 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 | ilevd | 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 | WorldsEndless | (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 | tolstoy | 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 | tolstoy | 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 | WorldsEndless | tolstoy: I'm trying out Wildfly, and I really like it |
| 13:02 | WorldsEndless | 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 | tolstoy | I use aleph and: `(http/start-server #(handle %) {:port (:port config)})` |
| 13:04 | tolstoy | 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 | tolstoy | 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 | tolstoy | 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 | justin_smith | 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 | tolstoy | WorldsEndless: You can try this: https://github.com/weavejester/lein-ring |
| 13:08 | tolstoy | 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 | WorldsEndless | 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 | tolstoy | 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 | tolstoy | 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 | justin_smith | 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 | MJB47_ | they should both work |
| 13:30 | MJB47_ | 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 | lellis | 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 | lellis | 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 | lellis | 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 | spieden | 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 | x-warrior | 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 | justin_smith | x-warrior: nb the trees should be immutable and therefore you can't return the same tree |
| 14:07 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | x-warrior: for example -- |
| 14:14 | justin_smith | ,(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 | x-warrior | ops, sorry |
| 14:18 | x-warrior | 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 | x-warrior | I already talked you about this, I showed my solution using a deftype because they said it was too OO |
| 14:19 | x-warrior | then I tried this "atom" approach |
| 14:19 | x-warrior | 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 | x-warrior | 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 | justin_smith | x-warrior: assoc and update-in do not mutate anything, continue to use those, but don't use an atom |
| 14:25 | justin_smith | 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 | justin_smith | ,(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 | justin_smith | let someone else use an atom |
| 14:33 | justin_smith | 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 | justin_smith | 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 | x-warrior | e on node of the first request |
| 14:41 | rhg135 | Action at a distance... |
| 14:41 | x-warrio_ | ops |
| 14:41 | x-warrio_ | my internet connection dropped for a while |
| 14:42 | x-warrio_ | 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 | amalloy | 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 | gfredericks | it'd be nice to be able to measure time while accounting for GC pauses |
| 14:48 | gfredericks | I had the idea to have a background thread that acts as a clock and just increments a counter periodically |
| 14:49 | gfredericks | under the assumption that if the whole process paused then that clock would slow down too |
| 14:49 | gfredericks | 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 | hiredman | 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 | gfredericks | a timeout often corresponds to a job throwing an exception and languishing |
| 14:58 | gfredericks | 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 | hiredman | or something like that |