#clojure log - May 19 2016

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

2:31 expez: Why is target on classpath? I sometimes get weird behavior during development if I've forgot to do lein clean and there's an uberjar of my app lying around in target. Can I remove target from cp, or will everything break then?

2:34 hiredman: on uberjar in target wouldn't do it

2:35 that isn't who the classpath works, only jars directly on the classpath have classes loaded from them, not jars in directories on the classpath

2:36 target is on the classpath because the clojure compiler requires that the directory where compiled class files are being written be on the classpath

2:36 you should just stop aot compiling, your life will instantly be better

2:37 expez: what determines where clojure writes it's compiled classes?

2:38 hiredman: just stop aot compiling

2:38 expez: I'm guessing it's lein/boot. Perhaps I can just change this dir, so the build artifacts and 'working set' are in different dirs?

2:39 hiredman: sure, you can do all kinds of stuff, but most likely if you are having issues it is because of stale class files in target (not from an uberjar in target) and if you don't aot compile you won't have that issue

2:40 generally, if someone is aot compiling, it is because they mistakenly believe a. it is the only way to launch an app b. the generate code has better performance

2:41 neither of those things is true, and the downside of aot compilation is it leaves you open to all kinds of odd issues

2:42 expez: yeah, I got that part. Thanks

2:42 Unfortunately, handing out the source code isn't always an option

2:44 (inc hiredman)

2:44 ,(inc hiredman)

2:44 clojurebot: #error {\n :cause "Unable to resolve symbol: hiredman in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: hiredman 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: hiredma...

2:45 TEttinger: I miss lazybot :|

2:45 hiredman: ah, in that case I recommend creating a build profile in lein that does aot compilation, and use that for doing releases, and using a profile without aot compilation for developement (althought that is not without its dangers)

2:45 expez: that doesn't work anymore?

2:46 TEttinger: clojurebot is a different bot and during the friggin' DDoS storm that hit Freenode a few months back it needed perpetual hand-rebooting

2:46 *lazybot needed

2:46 so the person in charge of lazybot took it down, I can't remember who it... was... Raynes?

2:47 you can still run a lazybot, I run one on quakenet. apparently some plugins have stopped working due to google changing an API

2:49 hiredman: ~google clojure

2:49 clojurebot: First, out of results is:

2:49 null

2:49 null

2:49 hiredman: damn, no kidding

2:49 (shows you how much that gets used)

4:04 ben_vulpes: i have finally lost a finger to aot

4:04 or at least an hour


4:05 whole project is an exaggeration

4:05 but definitely the reset toolchain

8:25 Kneiva: Is there a existing function to map with a function that can return a nil and that returns only non-nil values?

8:25 dysfun: keep

8:29 Kneiva: great, thanks!

8:31 dysfun: yw :)

9:08 ilevd: Is boot-clj good for shell scripting?

9:09 dysfun: how do you mean? as a replacement for bash?

9:10 TMA: is there a way to manhandle clojuredocs.org into a non-mobile view? the blue thingy on the right covers half of the screen at all times and there is no search box in the mobile version

9:13 ilevd: dysfun, yes, something like this. The most important thing is its startup time

9:16 dysfun: startup time is about the same as lein

9:16 if you want a bash script... write a bash script

9:19 ilevd: I want to have an opportunity to run ./hello.clj ilevd and get "Hello, ilevd!" immediately :)

9:19 dysfun: sorry, you're out of luck

9:20 you can sort of fake it by keeping a jvm open

9:20 there are a few tools to help you with that

9:22 ilevd: Yes, I'm looking for them now

9:23 dysfun: https://github.com/technomancy/grenchman

9:27 MasseR: ilevd: however afaik you won't have a proper CWD with them, it's shared with the jvm instance

9:27 dysfun: ah yes, that sounds probable

9:28 yazirian: ilevd: if cljs is acceptable http://planck-repl.org/ is probably what you're looking for

9:28 ilevd: Yeah, I've found it too, what is CWD?

9:29 dysfun: current working directory

9:29 ilevd: Ah

9:37 Yet another reason to buy Mac)

9:37 dysfun: odd you should mention that, i've just jumped from a mac

9:38 ilevd: Why?

9:38 clojurebot: why not?

9:38 dysfun: because reliability is not what it used to be and neither is 'just works'

9:39 MJB47: can confirm that

9:39 dysfun: and because i'm sick of the constant tin-rattling

9:39 MJB47: os x has been increasingly annoying me since lion :(

9:39 dysfun: yes, snow leopard is clearly the best release they ever made

9:40 they keep pestering me to upgrade my laptop (which has been relegated to web browsing device) to el capitan

9:41 and oh wow, i should totally get on that update that improves support for some hardware i don't own

9:41 thanks for telling me several times a day

9:42 ilevd: And what do you use now? Debian?

9:42 dysfun: no, i've been on FreeBSD for a few weeks

9:43 i can honestly say it's a lot lower maintenance than OSX now

9:43 MJB47: im using mint at home

9:43 im happy enough with it

9:43 dysfun: i'm planning to move back to linux, but i hate all linux distributions

9:43 and i really don't like systemd

9:43 that limits my distro choice somewhat

9:43 i wouldn't move except that freebsd is a joke for doing GPU work

9:43 ridcully_: gentoo (or one of the binary-only-offsprings) are quite close to the way at least ports behave

9:44 dysfun: well they called it 'portage' for a reason :)

9:44 ridcully_: isn't there the nvidia blob anymore?

9:44 dysfun: i should note i moved from gentoo to freebsd

9:44 oh i don't any any nvidia. fuck that

9:44 own*

9:44 except my knackered old craptop

9:45 i want to play with the new vulkan stuff which is intel/linux only at the minute

9:45 or windows. yeah no thanks

10:00 iwo: hey, does anyone know why someone would do this in their code: (<!! (go ...)) if there were no operations inside the go-block that could be parked?

10:01 it seems like calling go creates a new channel but <!! immediately causes the thread of execution to block anyway - no different to removing the (<!! (go ...)) wrapping altogether

10:13 justin_smith: iwo: if you want to block on some code that includes various non-blocking channel ops inside it

10:22 iwo: justin_smith: I don't have any non-blocking operations inside the go-block. Maybe they existed at some point but were removed - I think the (<!! (go ...)) was probably useful at some point but is no longer the case

10:22 (in the code I'm looking at)

10:22 dysfun: aww, clojure is old enough to have legacy code

10:23 iwo: without non-blocking operations, this construct effectively pointless, am i right?

10:32 justin_smith: so there are no channel reads or writes? if so, yeah it is pointless

10:35 iwo: only reads and writes inside the go are !!> and <!!

10:36 kwladyka: ,(-> {:1 2 :3 4} (keyword (str 1)))

10:36 clojurebot: #error {\n :cause "clojure.lang.PersistentArrayMap cannot be cast to java.lang.String"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentArrayMap cannot be cast to java.lang.String"\n :at [clojure.core$keyword invokeStatic "core.clj" 595]}]\n :trace\n [[clojure.core$keyword invokeStatic "core.clj" 595]\n [clojure.core$keyword invoke "core.clj" 595]\n [sandbox$e...

10:36 kwladyka: hmm in ClojureScript it does strange thing

10:39 ,(-> (keyword (str 1)) {:1 2 :3 4})

10:39 clojurebot: 2

10:40 justin_smith: ,(macroexpand '(-> {:1 :a} (keyword (str 1))))

10:40 clojurebot: (keyword {:1 :a} (str 1))

10:40 justin_smith: that's why that breaks

10:40 also, :1 is terrible

10:42 kwladyka: anyway it behave different here, http://clojurescript.net/ and in app what i am working on, perhaps different versions

10:42 yes :1 is terrible, but i can do nothing about that

10:43 justin_smith: kwladyka: where does it come from?

10:43 TimMc: This is why it's terrible to keywordize random data.

10:43 kwladyka: justin_smith from other software developer :)

10:43 justin_smith: kwladyka: you should stop using their code

10:44 kwladyka: justin_smith i can't i participate in this project :) it is very chaos project :)

10:45 it is much more complex to explain why that you think in the first moment :)

10:45 *then

10:45 justin_smith: as TimMc mentions, stupid things like that get created all the time when people auot-keywordize. And you shouldn't be auto-keywordizing things for that very reason.

10:46 ,(keyword "\n") could be worse, though

10:46 clojurebot: :\n

10:46 kwladyka: justin_smith i agree, but i can't save the whole world :)

10:46 TimMc: justin_smith: It is my personal crusade.

10:47 kwladyka: ,(keyword " ")

10:47 clojurebot: :

10:47 kwladyka: this one is the worst

10:48 justin_smith: ,(keyword "\ufeff") ; even worse

10:48 clojurebot: :

10:50 TimMc: ,(keyword "\u0000")

10:50 clojurebot: :

10:50 ridcully_: ,(keyword "\u00ad")

10:50 clojurebot:

10:51 TimMc: Let's get more creative.

10:52 justin_smith: ,(keyword "f\ufeffo\ufeffo\ufeff")

10:52 clojurebot: :foo

10:52 TimMc: ,(read-string (pr-str (keyword "abc ;; HELLO")))

10:52 clojurebot: :abc

10:52 ridcully_: if only i was not to lazy to look up the vertical tab

10:53 justin_smith: ,(let [foo (keyword "f\ufeffo\ufeffo\ufeff")] [foo :foo (= foo :foo) {:foo :foo foo foo}])

10:53 clojurebot: [:foo :foo false {:foo :foo, :foo :foo}]

10:53 ridcully_: i pitty the f\u

10:53 kwladyka: Somebody use atom editor with Clojure in everyday work? I found it is very perspective but the part about Clojure is not really mature yet. Some small things have to be improve.

10:54 MJB47: its not as good as cider

10:54 kwladyka: heh i see how you like doing this "kitten butcher" :)

10:54 MJB47: but it works well enough

10:55 yazirian: ,(keyword "🖕")

10:55 clojurebot: :🖕

10:56 kwladyka: MJB47 I have for example bad syntax highlight for #{"one" "two" "three"} and some small other things.

10:57 :require-macros is shown as an error etc.

10:57 MJB47: im not sure what a bad syntax highlight is

10:58 but you can change all the syntax highlighitng really easily

10:58 its just css

10:58 well, LESS (or is it SASS? fuck)

10:58 kwladyka: MJB47 highlight #{...} as #() so the first element in set has one color like a function and other different color

10:58 MJB47: and require-macros is not shown as an error for me

10:58 ilevd: ,(keyword ")")

10:58 clojurebot: :)

10:58 MJB47: my sets dont look like that

10:59 perhaps its just your theme?

10:59 regardless, just fiddle with the css if its an issue

10:59 kwladyka: MJB47 i use the default one for now

11:00 MJB47 do you use linter-clojure? It shows me this error about :require-macros

11:00 MJB47: i dont

11:00 is the linter for clojure only? (and not clojurescript)

11:00 kwladyka: MJB47 can you paste me what packages do you use?

11:01 MJB47: clojure related: proto-repl and lisp-paredit

11:01 kwladyka: MJB47 not sure about that, but it activate in ClojureScrupts file

11:01 MJB47: oh and swackets, but its not great

11:01 i need to make a pr for it at some point

11:02 or do my own

11:02 kwladyka: MJB47 why not great?

11:02 do what?

11:02 MJB47: only works for 1 type of bracket at a time

11:02 sometimes bugs out

11:02 kwladyka: oh

11:02 MJB47: is slow

11:03 do my own rainbow parens thing

11:03 or fork it... idk

11:03 kwladyka: linter-clojure, language-clojure, proto-repl, lisp-paredit, ink <- i use this

11:04 MJB47 ambitious.... i just want use editor, not code it :)

11:04 MJB47: swackets is just rainbow parens, its not that complicated

11:04 or needed

11:04 its just a nice to have

11:05 but if you want a clojure editor that works out the box, i would recommend looking at cursive

11:05 kwladyka: MJB47 do you use default theme?

11:05 MJB47: yes but ive modified it

11:06 enough that i probably shouldnt call it the default theme

11:06 kwladyka: MJB47 i use cursive, looking something else where i don't have to touch mouse, but modern solution, not emacs.

11:07 MJB47: then use atom, but its new and so the tooling around it isnt as mature

11:07 kwladyka: MJB47 atom is the only one i think which can be the closest of my needs

11:07 MJB47: this is to be expected

11:07 kwladyka: yes i see it, i am thinking i should wait or not to use it :)

11:08 testing it

11:08 for now i don't like some shortcuts... but i can set my own

11:09 and i didn't find something like alt+cmd+L in cursive, did you?

11:09 MJB47: idk what that does

11:10 kwladyka: MJB47 reformat the code

11:10 indent

11:10 for selected text or a whole file when nothing selected

11:11 the closest is ctrl+alt+i if i remember in atom

11:11 ilevd: http://spacemacs.org/

11:23 kwladyka: MJB47 ah sorry this problem with syntax higlight apperat with code like that (#{"fds" "fdsa" "fdsf" "fdsf"} "fds")

11:30 TMA: ilevd: i have had some trouble with the key mapping described in the docs not present

11:33 ilevd: TMA, oh, I haven't used it yet, only want to

11:35 TMA: ilevd: maybe it works fine outside of Windows

11:36 ilevd: It would be good

11:37 TMA: ilevd: give it a try, maybe I did something really wrong

11:44 ilevd: ok =)

12:04 sdegutis: While Hiccup is pretty convenient to write literally, it's actually very inconvenient to manipulate raw Hiccup data structures.

12:05 Good luck figuring out whether [:form#quux.bar {:class "foo"}] has a given class.

12:06 Especially considering the {} is optional. And given his other projects, I wouldn't be surprised if the attributes thing is allowed to be a function that returns a map.

12:07 Bronsa: what's wrong with that example? it seems to be obvious what classes and ids it will produces

12:08 dysfun: to a human, not to a machine

12:08 Bronsa: there's no need to diss like that an established community member

12:09 dysfun: luckly neither of us is a machine?

12:09 dysfun: he mentioned manipulating it

12:09 sdegutis: dysfun: I tried writing some helper functions that take a Hiccup thing and add to it, and it's a lot more code than I expected.

12:09 dysfun: yeah, i tried to write a library to ease autogenerating sql and i've realised why all the other aren't great for autogenerating - it's sql's fault

12:10 sdegutis: dysfun: that's where datomic comes in

12:10 Bronsa: doesn't seem to me like it'd take that long to normalize that form

12:10 hiccup really doesn't have a lot of syntax

12:10 sdegutis: dysfun: where does he mention manipulating it? just read through the wiki and it's got nothing

12:10 dysfun: no, you mentioned manipulating it

12:11 sdegutis: oh

12:11 ugh

12:11 dysfun: as it is i've concluded that sql is only manipulable in the sense that as long as you have all the conditions in some sensible form you can turn them into sql. good luck working with an already written query and changing it though

12:12 Bronsa: yeah, transpiling to sql is a nightmare

12:12 dysfun: yes. i have spent many many hours with the postgres manual in the last few weeks

12:13 Bronsa: that doesn't sound like fun at all :)

12:13 dysfun: fun? maybe for five minutes :)

12:13 since then it's been that project that i want to forget about

12:13 Bronsa: haha

12:14 dysfun: have rewritten it once

12:14 it just about generates select queries now but i'm so sick of hacking on it

12:15 CStorm: if i want to write a little commandline interface with clojure, is there any suggestions to good libs?

12:15 dysfun: there's tools.cli, but it's not amazing. the startup time of clojure has meant not many people have done it

12:16 ridcully_: as in parsing args or ncurses style UI?

12:16 CStorm: mostly the last part, ridcully_.

12:17 mostly i want to make a small tool to keep a eye on a few webservices on the server

12:17 are they running, if not restart etc etc.

12:18 its manly just for fun, nothing serious why the startup time does not matter that much

12:47 Bronsa: you can easily get a clojure repl in ~.5s which is not *too* bad

12:48 dysfun: and once you load all your dependencies in, it won't be .5s any more

12:48 not to mention you actually want a repl with readline and such

12:49 i used to put up with 45 second repl startup times on my laptop before i nicked my friend's pc

12:50 Bronsa: there's still tons that can be done to improve startup performances even when loading libraries.

12:51 bare clojure + rlwrap loads in 0.45s on my machine, lein repl takes 6s

12:55 jeaye: lein repl is often over 15s for me

13:07 tolstoy: I created a jar with tons of deps embedded in it and it takes very little time to get to a repl, or run a script.

13:33 bsamorim: guys, I know this i totally off-topic, but I wanted to get opinions from functional-programmers

13:34 has any1 of you ever read "Concepts, Techniques and Models of Computer Programming", by Peter Van Roy?

13:49 amoe: I have a test fixture that needs to set up some state for the test

13:50 Is there any way for the test fixture to pass arguments to the test so that the test can manipulate the state?

13:50 justin_smith: no

13:51 it can use a dynamic binding, or set an atom or var before the test starts

13:51 but not pass args directly

13:51 kwladyka: amoe you should have different fixtures then i guess

13:51 sdegutis: Dynamic binding is probably the safest idea.

13:51 In our case though, we just construct the state we need within each test.

13:52 amoe: sdegutis: Ah, I actually didn't conside that for some reason. I might just do that

13:52 ben_vulpes: arrange->act->assert

13:52 sdegutis: That may be more difficult if a traditional DB is involved (though still possible). But if you use Datomic then a memory-db is a good fit.

13:52 justin_smith: amoe: one thing that can help is you can write a function that calls test/is, and if you call that within a test those is will run as things that belong to that test

13:52 amoe: so instead of test/fixture you have function/test - and the test can pass args to that function

13:53 kwladyka: amoe or maybe write some high order function as fixture function where you can put something and it will return the function

13:54 justin_smith: kwladyka: that doesn't offer data to the test though

13:54 amoe: thanks all

13:54 kwladyka: justin_smith what do you mean? (use-fixtures :once wrap-test) if wrap-test will be high order function it should work to do anything?

13:55 justin_smith: kwladyka: the test is passed to wrap-test, wrap-test cannot pass data to the test

13:56 kwladyka: oh probably i miss the main point of amoe question

13:57 sdegutis: justin_smith: that can get messy quick tho

13:57 kwladyka: it is very strange needs i think

13:57 probably bad design?

13:58 sdegutis: kwladyka: I prefer the phrase lifelong continuous learning, as applied to design

13:58 or rather "lifelong continuous learning as applied to good design"

14:02 amoe: kwladyka: the case is greenmail java lib for integration testing of SMTP things. need to start a fake server and then query that same java object in an assertion

14:10 justin_smith: amoe: sounds like something you could do by calling with-redefs in the fixture

14:11 with-redefs pretty much exists just for setting up tests

14:14 dimon_: Hi. what's an idiomatic location for storing user uploaded images on the same server and if it's not AWS? should it be a separate path from the static images used for css or design?

14:14 dysfun: yes, ideally

14:16 i just have a /static/upload directory that i dump things into as a directory forest

14:17 (based on random uuids)

14:19 dimon_: Hi. what's an idiomatic location for storing user uploaded images on the same server and if it's not AWS? should it be a separate path from the static images used for css or design?

14:19 * dysfun could have sworn he just answered that

14:20 dimon_: I can't see it because I've re-logged in

14:21 dysfun: basically, yes and you should use a directory forest

14:21 dimon_: what's a forest? where should that directory be located? separate from my app?

14:22 dysfun: if you want to serve those images, it'll have to be somewhere the webserver can see

14:22 put them in their own directory subject to that

14:22 dimon_: ok. so doesn't really matter where?

14:23 dysfun: no

14:23 a file forest is a way of organising a directory to get around crap performance when you have a huge number of files in a directory

14:24 essentially you take a name such as 'abcdefghij' and make it 'ab/cd/ef/gh/ij'

14:24 dimon_: ok. how is it recommended to name those images or to which directories to put them? for example, should it be something like /some_folder/{article_id}/1.jpg or what?

14:24 dysfun: you can create whichever directories are necessary at the time of writing

14:24 dimon_: yes, how to better organize them?

14:24 dysfun: use random uuids for names

14:25 as for 'organise', well that's metadata that you should store in your database, surely?

14:25 oh, and don't forget to preserve the filetype suffix (.png, .jpg etc.)

14:26 dimon_: sorry, I didn't get you. I mean, what directory forest should look like? something like /main_img_folder/year/month/day/article_id/img_id.jpg or what?

14:27 dysfun: cc

14:27 dysfun: assign random uuids and store them as a forest

14:28 dimon_: yes, uuids for images file names. what do you mean by forest? it is /dir1/dir2/dir3? if so, how is it recommended to build those names of the directories?

14:28 dysfun: so this is a random uuid that duckduckgo just generated for me: 7C21E258-1DEF-11E6-88F8-F5976FA2A08B

14:29 so let's take the dashes out first

14:29 dimon_: do you mean, I should put them all in the same directory?

14:30 dysfun: well, how many images will you be allowing to be uploaded?

14:30 dimon_: theoretically, a hundred every day

14:31 dysfun: right, so that's 36.5k images a year. after 3 years, you'll find that things start to get slow

14:31 dimon_: ok. and?

14:31 dysfun: and that's because large numbers of files in one directory tank performance

14:31 where 'large' typically ~=100k

14:32 etiago: hey everyone, Clojure beginner here... I have the following code http://pastebin.com/czZ7P0us . :on-receive takes a function which it will call, with one argument, upon receiving a message. However, I wanted to have the 'socket' variable available inside that function (which is called message-received). I thought using a partial would be the solution to my problem but... obviously, socket will only evaluate once ws/connect returns, and

14:32 by the time it does, :on-receive has already been assigned to.

14:32 any clever ideas to solve this without using global scope variables?

14:33 justin_smith: etiago: def inside defn is bad, and do inside defn is redundant

14:33 etiago: justin_smith: noted :)

14:33 dimon_: dysfun: and that leads us to my initial question: how would I organize or name the directories of a forest to avoid having over 100 k in the same directory?

14:34 dysfun: you decide first what your granularity is. if you're using uuids, 2-4 digits is sensible

14:34 then you split the name up into groups of that many digits. each one becomes a directory node

14:34 dimon_: tnx

14:34 dysfun: and the final part of it is the remaining digits plus the file extension

14:35 you create the directories on demand as required

14:36 or you can even hash the file contents and use that as the filename instead

14:36 like git does

14:37 justin_smith: etiago: one option is (let [socket (promise)] (deliver socket (ws/connect ... :on-receive (partial message-received @socket))))

14:38 after that you can put socket in an atom or pass it forward to whoever else needs to use it, or whatever

14:39 etiago: in fact, a def is allowed to access itself, but def inside defn still isn't a good idea

14:39 etiago: justin_smith: alright, I haven't used promises or atoms yet... I'll go read about it then :) thx!

14:39 justin_smith: ,(def recursive (cons 42 recursive))

14:40 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Var$Unbound"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Var$Unbound, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3657]}\n {:type java.lang.IllegalArgumentException\n ...

14:40 justin_smith: ergh

14:40 ,(def recursive (lazy-seq (cons 42 recursive)))

14:40 clojurebot: #'sandbox/recursive

14:40 justin_smith: (nth recursive 1000)

14:40 ,(nth recursive 1000)

14:40 clojurebot: 42

14:41 etiago: hah interesting :)

14:41 justin_smith: etiago: this is how self-calls are possible

14:41 so a function is always allowed to pass itself as an arg to something it calls

14:41 ,(defn narcissus [] narcissus)

14:41 clojurebot: #'sandbox/narcissus

14:42 etiago: justin_smith: but still, in my case it doesn't make much sense right? because I need the defined value for the evaluation of the inner function

14:42 justin_smith: ,(= narcissus (narcissus) ((narcissus)))

14:42 clojurebot: true

14:42 etiago: brb

14:42 justin_smith: etiago: it is defined

14:42 etiago: it's the thing you are defining

14:43 etiago: implementation wise, as soon as (def x ...) exists, x is available - even if (def x ...) is inside a form, even if (def x ...) itself refers to x

14:44 but order of definitions in a file is still important - to preserve file/repl compatibility

14:48 etiago: justin_smith: it exists, but how can it have a value if, e.g., (def x (foo x)) foo hasn't finished evaluating?

14:48 justin_smith: etiago: see my definition of narcissus above

14:48 etiago: by the time you use it it is available

14:51 etiago: let me experiment a bit and see if I can wrap my head around this... :)

14:55 justin_smith: etiago: actually inside the body of the def the thing being defined exists but is still unbound

14:56 but anyway, it's better not to do that with def - counting on runtime def (other than via repl in development) is usually a bad idea

14:56 etiago: justin_smith: a-ha! that's exactly the same conclusion I just reached: #object[clojure.lang.Var$Unbound 0x22553faa Unbound: #'fun-bot.core/v]

14:57 justin_smith: agreed :) I will read up on promises and atoms, that seems to be a better option

14:57 thanks again!

15:01 amalloy: i don't think you need a promise for that

15:02 just use a lambda instead of a partial, and the delayed evaluation of fn will combine with var lookup to solve your problem

15:02 (def socket (ws/connect ... :on-receive (fn [message] (message-received socket message))))

15:03 justin_smith: amalloy: I was suggesting a promise or atom instead of def inside defn

15:03 amalloy: but you don't need any of those things. just an ordinary lambda inside a def is fine

15:03 justin_smith: amalloy: but then you have a def with side effects

15:03 amalloy: well that's certainly true, and a problem. good point

15:04 but your promise/deliver has the same issue

15:04 oh, i guess i didn't read the original code

15:04 all this is happening inside a function already

15:04 i retract my suggestion

15:05 justin_smith: amalloy: I think I might have sketched that too roughly I was imagining (defn -main [] (let [socket (promise)] (ws/connect ....) (foo socket) ...)

15:05 right, now we are on the same page

15:05 amalloy: truly it is the page of champions

15:06 justin_smith: etiago: btw stuartsierra's component library is meant for managing things like this

15:06 etiago: it might seem a bit odd at first but it make a nice foundation for putting together various stateful things sanely - he has some good vids on youtube about using it

15:06 *makes

15:10 dysfun: and while we're at it, https://github.com/irresponsible/oolong wraps component quite nicley </unplug>

15:15 amoe: thanks for that rec dysfun

15:17 dysfun: yw :)

15:23 CStorm: has anyone used spacemacs?

15:27 kungi: CStorm: It looks neat if you like the control scheme

15:27 CStorm: it does looks nice.

15:28 kungi: CStorm: I prefer my emacs config which has been evolving for the last ~7 years :-)

15:28 CStorm: yeah, i guess many will have it that way =)

15:29 i only use emacs for clojure, and clojure is only a spare time project :)

15:29 kungi: CStorm: I think spacemacs is a very nice and probably sane entry point to emacs

15:29 CStorm: What are you using at work?

15:30 CStorm: mobile developer, writing swift, objective-c and java

15:30 so intellijs

15:30 ive used emacs for a little under a year so still tons to learn

15:30 :)

15:30 might give spacemacs a go!

15:30 kungi: CStorm: tons doesn't even describe it properly :-)

15:32 CStorm: the biggest problem is that i have learned most of the shortcut i use etc.

15:32 however depending on mood, interest etc there goes 1-2 weeks in between

15:32 then it get hard to remember again :)

15:32 using emacs at work?

15:32 kungi: CStorm: building muscle memory always is hard

15:32 CStorm: I use clojure at work so I use emacs

15:33 CStorm: I started my personal "living in emacs" project about a year ago

15:33 CStorm: sounds awesome

15:33 kungi: CStorm: It is :-) currently I am using emacs to chat

15:34 CStorm: and cook your meal? ha ha :)

15:34 kungi: CStorm: no! I use my kitchen a stove and a pot for that.

15:34 CStorm: oh... right, silly me. :-)

15:37 kungi: CStorm: I think whether you use spacemacs depends on your opinion on the control scheme.

15:37 So choose one and stick with it

15:37 CStorm: and by control scheme you mean keyboard shortcuts?

15:37 kungi: CStorm: yes

15:37 CStorm: Spacemacs provides a completely different set of shortcuts

15:38 CStorm: already gotten quite use to emacs as i wrote to what i need to use

15:38 might be just yet another hill to climb if i change hehe

15:39 kungi: maybe

17:11 TimMc: This should be enough to make OpenJDK 8 produce a Sun Java 6-compatible jar, yeah? :javac-options ["-target" "1.6" "-source" "1.6"]

17:11 ben_vulpes: is there a...slightly flatten?

17:11 eg just the first level of nesting?

17:11 TimMc: ben_vulpes: mapcat identity

17:12 ben_vulpes: class

17:12 classy*

17:12 thanks TimMc

17:12 TimMc: Ideally you'd avoid producing something like that in the first place, by adding another clause to your #'for or something, but it happens.

17:13 Usually one of those two answers is what people really want when they reach for flatten. :-P

17:14 (Aha, I was including a jar that had been compiled on OpenJDK 8 without those options. I can fix that.)

17:47 sdegutis: I've been toying with the idea of making full-fledged Records for each model, rather than a bunch of helper functions that have the first parameter in common.

17:47 And each presenter, and each view function, etc.

17:47 The reason actually being inspired by stuartsierra's Reloaded Workflow: when you reload a function, it's available right away. But not a record.

17:52 hiredman: source and target tell javac how to interpret java source code, and which bytecodes to emit, but that is not enough to ensure compatibility if you have any kind of reflection happening at compile time (which could be the result of any kind of annotation processing in java, and clojure does a lot of in its compiler)

17:53 amalloy: hiredman: that's why javac wants you to set the bootstrap classpath as well when using -source and -target, right?

17:53 hiredman: yep

17:54 it is, on the whole, a royal pain, although often things will be fine with just source and target

18:15 cfleming: kwladyka: I'm interested - where do you find you have to touch the mouse in Cursive?

18:15 luma: moving focus from editor to repl?

18:16 cfleming: There's now an action for that you can bind keys to.

18:16 Tools->Repl->Jump to REPL editor/output pane

18:16 luma: ooh

18:16 nice

18:17 cfleming: You can jump to the output too and cut and paste from it.

18:18 kwladyka: In general, if there's something in Cursive you can't do without the mouse I consider that a bug, and an issue would be very welcome.

18:20 kwladyka: cfleming hi, not really in curisve, it is more about Intellij Idea. For example i don't think it is possible to jump between REPL window, terminal window and code etc.

18:20 or i am in mistake as i can read :)

18:21 cfleming: Well, in your defence those actions are pretty new :)

18:21 From any toolwindow (including the REPL), ESC will always jump back to your code.

18:22 For the terminal window, check the menu at View->Tool windows->Terminal - that should have a shortcut bound to it (alt-f12 on OSX)

18:22 Again, you can rebind that if you want to.

18:22 whilo_: I have a weird problem with core.async and thread bindings: https://gist.github.com/whilo/4946cb4a018065aafed8a1db8d952407

18:22 kwladyka: i will try it maybe tomorrow. Now it is time to sleep. I see you always watch the topic about editors :)

18:23 cfleming: Yes definitely :)

18:23 kwladyka: cfleming i don't know how you do it but you catch the topic with high precision :)

18:23 whilo_: The main problem is that I am not sure how to best debug it. It only happens when I run the uberjar. lein run or REPL with the same code works fine

18:23 cfleming: But do let me know either here or in an issue if you find there are things that require the mouse.

18:24 kwladyka: It's easy, my IRC client tells me whenever anyone is talking about Cursive

18:24 Like when someone mentions your name

18:25 kwladyka: cfleming oh i didn't realise somebody use cursive. I thought you observe also atom editor and others

18:25 whilo_: Any suggestions of how to debug this, so maybe I could open a ticket. I haven't debugged a jar file app with clojure before.

18:25 clojurebot: Titim gan éirí ort.

18:25 cfleming: Well, I'm generally interested in those discussions too, but I don't get notified of them.

18:25 I follow the editors channel in Slack, for example

18:26 justin_smith: whilo_: do you have defs that do core.async operations in their body? I would expect that to cause an issue like that.

18:26 kwladyka: cfleming i believe atom editor when will became mature can be your big competitor in the future

18:27 whilo_: justin_smith: yes

18:27 justin_smith: whilo_: in general def should not have side effects - because the body gets run at compile time

18:27 I would expect that to screw up core.async's state machine

18:27 whilo_: Hmm, why does it work with lein run then?

18:27 cfleming: kwladyka: Yes, possible, especially for CLJS since web devs are more likely to be familiar with it, and less likely to use IntelliJ/Webstorm

18:27 justin_smith: you can replace it with a defn or (def foo (delay ...)) and force it later

18:28 whilo_: lein run does not run a separate compilation step

18:28 whilo_: clojure always compiles your code as it loads it, but with uberjar it compiles when creating the jar, and then it loads (and often does more compilation) at runtime

18:30 kwladyka: cfleming thx you for your reply and information about shortcut to focus REPL windows.

18:30 goodnight all :)

18:31 cfleming: Goodnight!

18:31 whilo_: justin_smith: ok, yes i know. is it reasonable that the stack trace pops up somewhere else?

18:31 justin_smith: well, it's not neccessarily an error when you build the uberjar - it's a runtime error caused by what you built

18:32 whilo_: for a very silly example, if you had (def bye-bye (System/exit 0)) the uberjar process would exit without finishing creating your jar, but would not show any error

18:33 whilo_: ok, interesting. can you elaborate a bit how aot breaks core.async?

18:33 justin_smith: whilo_: aot runs all your code - there is no "compile only mode" in clojure

18:33 whilo_: ok

18:35 justin_smith: whilo_: so, that means that if your def has side effects, and does things that manipulate the state of core.async, the objects in the uberjar will have dirty state - and like I said, some things get re-evaluated at runtime but it's slightly unpredictable (maybe someone else can elucidate the paths / rules there) - and this leads to the core.async state machine (core.async is a lib that turns go blocks into state machines for cooperative multitasking)

18:35 whilo_: justin_smith: this one i know https://github.com/whilo/full.monty/blob/master/full.async/src/full/async.cljc#L58

18:36 justin_smith: yeah - I would say if it's going to be a dynamic var anyway, create it as nil in the def, then bind it inside main with a function that does that whole let block and starts the go-loops

18:36 bind using the binding macro, of course

18:37 but then anything that uses it needs to be created inside the binding body - which might not make sense with your app design

18:38 another option is to make it a delay that gets forced / derefed (this would mean wrapping the let in (delay ...) and putting an @ before every usage of the var

18:38 )

18:39 ,(def later (delay (do (println "hi") :done)))

18:39 clojurebot: #'sandbox/later

18:39 justin_smith: ,later

18:39 clojurebot: #object[clojure.lang.Delay 0x1f7e25f1 {:status :pending, :val nil}]

18:39 justin_smith: ,@later

18:39 clojurebot: hi\n:done

18:39 justin_smith: ,@later

18:39 clojurebot: :done

18:42 whilo_: hmm, ok. the binding is really painful. i have already hit issues in core.async and cljs. i am wondering whether it is worth the effort. it would make sense for a supervisor thought, i think

18:43 though

18:43 even considering all the arguments of stuart sierras binding warning

18:44 otherwise i have to pass the supervisor argument to all go blocks

18:44 justin_smith: you could also have a component for the supervisor, that provides it to the things that start other go blocks

18:45 or, create channels in defs (which is safe) and just write the code to read/write those channels

18:46 whilo_: hmm, this def doesn't seem to be it.

18:49 justin_smith: thx! this was really helpful, will try to pin it down :)

18:49 justin_smith: whilo_: I forget what it is called, but there's a channel that acts like a delay - it blocks until you write, and after that it returns the same first value that was written every time you read it

18:50 whilo_: a promise channel?

18:50 justin_smith: I bet that's the one, yeah

18:50 so you could make the channel at the top level, and write s to it in -main

18:50 whilo_: promise-chan it is

18:51 justin_smith: then you are safe for aot (for that block of code at least) - just change usages of that s to reads from promise-chan

18:51 might be the simplest thing since you are in async-land already

18:54 whilo_: justin_smith: i'll think about it. but first i'll try to find where the dirty state comes from

19:14 justin_smith: whilo_: the dirty state comes from creating go loops while compiling

20:10 bsamorim: to paraphrase dimitry karamazov : "the path of the non typing nor object-oriented programmer is too wide"

20:13 it's really frustrating to see that something that takes forever in clojure would be nipped in the bud with OOP

20:14 i guess the other way around happens way more often, tho

20:20 jasonmason: bsamorim can you provide more details

20:22 bsamorim: basically I have a pattern that I can't abstract away, and it occurs all along my code

20:24 I am dev'ing a trading app. A lot of functions have a dual where I would exchange some computation happening with the bids list with an almost (and that almost is what fucks me) equal computation with the offers list

20:26 for instance, the set of both lists (the "book") is stored as a hash-map, and when a new order comes, i have to do a bunch of stuff that differ only slightly depending if this new order is a bid or an offer

20:29 it would be super easy to model that with a OO language.....but with clojure it is impossible to find an all-encompassing solution....the best I could come up with was to write a dispatcher that would work kinda like an object...

20:30 eh, i guess no language is perfect....

20:30 sdegutis: bsamorim: what's the problem? I just got here

20:30 bsamorim: i'll resend the message

20:30 I am dev'ing a trading app. A lot of functions have a dual where I would exchange some computation happening with the bids list with an almost (and that almost is what fucks me) equal computation with the offers list

20:30 sdegutis: Btw I'm totally about to use Clojure to duplicate files because Emacs is incapable of such a complex task.

20:31 bsamorim: for instance, the set of both lists (the "book") is stored as a hash-map, and when a new order comes, i have to do a bunch of stuff that differ only slightly depending if this new order is a bid or an offer

20:31 sdegutis: bsamorim: sounds easy

20:32 bsamorim: hmmm...how would you solve it? I mean, i'll give a more rigid context

20:34 write a function (fn [book new-order] ...) that finds the opposing orders list to "new order" (if it's a bid, the offers, and vice versa) and returns a new book, removing the matched orders from the opposing list and inserting the unmatched quantity from new order into its corresponding list

20:36 with no control flow to check the order type....

20:37 ideally, it would be a ( fn [ var-fun_1 var- fun_2...var-fun_k book new-order] ...) where the var-fun's would be encapsulate all order type-dependency

20:38 would encapsulate*

20:42 sdegutis: do you think there's a concise way to do this?

21:03 sdegutis: bsamorim: I don't know the whole context so I can't come up with a solution; and it sounds like it could take a few hours, so you'd have to pay me to come up with it in the first place

21:03 bsamorim: but yeah it doesn't sound very complex

21:06 bsamorim: sdegutis: haha, relax dude, I don't expect you to give me a .clj or anything like that

21:06 sdegutis: of course it isn't very complex, especially if you think specifically about this function...

21:07 sdegutis: the problem is thinking about an _abstraction_, useful for any function that could come up in my app....not just some taylor-made hack

21:08 amalloy: bsamorim: just write a function that takes in a function as an argument

21:08 that's polymorphism

21:08 so then you have like (defn handle-computation [f ...]), and (handle-computation bid-handler ...) ... (handle-computaiton offer-handler ...)

21:09 bsamorim: amalloy: that's what i've been doing so far, higher order functions as "abstract functions" and partials as its implementions

21:09 implementations

21:09 amalloy: well, not necessarily partials, since you can be a lot more general

21:09 but sure

21:10 bsamorim: yeah, one could extend it indefinetely...but it starts to get ugly....and, when you see it, you're writing some totally auxiliary data structures and functions with 5+ arguments

21:11 I mean, I just read SICP....the elegance in it!!!!!!

21:11 i guess that my question, in the end, is this: can one write programs that are 100% elegant?

21:11 amalloy: in any language? no

21:11 bsamorim: not a single stinking function or script

21:12 regardless of the language...i mean, you could pick one

21:12 amalloy: yeah, what i'm saying is, in no language can you do that

21:12 bsamorim: i am just a beginner software dev, but i'm starting to think that this is just not possible

21:13 amalloy: hahah, yeah, that's very frustating!!

21:14 amalloy: in the end, there's no such thing as an "elevated profession"....everything's a trade..we're the same as shoemakers from the middle ages..

21:15 I mean, specially software development...how much creative can it really be?

21:16 you can be proud of some part of your source code....but most of it is very down-to-earth, automatic stuff....

21:17 either that, or I'm just too high hehe

21:21 philwhite: `reduce` isn't a transducer, right? But it seems to me that it could be, and that the only reason it's not a transducer is that it wasn't implemented that way. The reason I ask is that i'm trying to implement a `map-reduce` transducer, but then i thought that if reduce wasn't implemented as a transducer, than maybe i shouldn't be implementing `map-reduce` as a transducer. Am i saying nonsense?

21:22 I think i understand what transducers are (an abstraction for transforming processes, as opposed to sequences), but i think i'm still a little confused about when to implement a new one, or how to piggyback on existing ones

21:23 does `map-reduce` have to be implemented as a transducer?

21:23 amalloy: bsamorim: imo software dev is very creative. it's certainly not science, or engineering, when you compare to how good hose guys are at getting things that work

21:26 namra: are fixtures in other test namespaces evaluated when i refer the tests in another namespace?

21:26 basically i want to run all tests from cores-test

21:26 amalloy: the fixtures are evaluated, but they don't wrap tests in other namespaces

21:27 namra: so: (ns app.core-test (:require [app.other-tests :refer [a-test]])) (deftest test-all (a-test))

21:28 this would also evaluate the fixtures in app.other-tests when (a-test) is evaluated?

21:28 from within app.core-test

21:28 amalloy: i mean, the answer to that is definitely yes, but i am not sure you really know what evaluating fixtures mean

21:29 so yes might not be the answer you want

21:32 hiredman: philwhite: the terminology around transducers is not clear, and that causes trouble with any discussion about them

21:32 philwhite: a transducer is generally a function that takes a step function and returns a new step function

21:33 a step function takes an accumulator and a single item and returns the accumulator

21:33 philwhite: okay, that makes sense. so reduce could easily be implemented as a transducer, right?

21:33 hiredman: reduce folds a collection of values in to a single value, which doesn't fit in to a step function

21:34 philwhite: hmmmm, let me think about this

21:34 turbofail: `reduce' is what will be calling the step function

21:35 philwhite: wait, a transducer returns a new step function?

21:35 turbofail: yep

21:35 hiredman: yeah, it is a function that takes a step function in, and returns a step function

21:35 philwhite: that's a little confusing

21:35 ben_vulpes: what's an expedient way to optimistically do math on a value that might be null without wrapping everything in a try/except?

21:35 hiredman: that is why they compose

21:35 amalloy: ben_vulpes: check whether it's null

21:35 philwhite: oooh, that is a good point

21:35 amalloy: you have literally no other option

21:36 ben_vulpes: i hate programming

21:36 thank you amalloy

21:36 amalloy: i mean, you can use some->, or decide to reimplement the maybe monad in clojure

21:36 ben_vulpes: no i kid programming is fun

21:36 I MIGHT

21:36 amalloy: I JUST MIGHT

21:36 raa

21:37 amalloy: but those are the same as chekcing for null, just more convenient

21:37 ben_vulpes: yeah well i'd need type based polymorphism too i imageine

21:37 in clojure

21:37 amalloy: and really some-> only helps if there's only one of the values that might be null, and the others are known-good

21:37 ben_vulpes: nope we're doing it c-style

21:38 turbofail: philwhite: for example, the map transducer looks basically like (defn map [map-fun] (fn [step-function] (fn [acc value] (step-function (map-fun value)))))

21:38 ben_vulpes: (if (and thinger-wont-break-my-code-this-way thinger-wont-break-my-code-that-way thinger-wont-break-my-code-the-other-way) (stuff-with thinger))

21:38 maybe it's just the internet

21:38 philwhite: hiredman: so i think it's a little clearer now, but i'm still not sure what to do with `map-reduce`

21:38 turbofail: i'm actually literally looking at the map source right now

21:39 i think you just made me more confused :)

21:39 oh, wait, never mind i was looking at ben's code too

21:40 ben_vulpes: philwhite: don't do that

21:40 never a good idea

21:40 philwhite: haha

21:41 turbofail: iir the terminology correctly, the return value from (map -) is the actual transducer, i.e. the function that actually transforms the step function

21:41 hiredman: philwhite: in a reducers model, you use reduce (or something like it) to driver the application of the step function to values

21:42 transducers

21:42 sdegutis: amalloy: its a pretty weak form of polymorphism though, but yeah its technically a kind

21:42 amalloy: "weak" in the sense that it is as powerful as any other, yes

21:42 philwhite: do you understand what map-reduce should do, or should i explain it before i keep going

21:42 hiredman: so turning reduce "in to" a transducer doesn't make sense

21:42 turbofail: brb heading home

21:42 hiredman: I understand map reduce

21:43 philwhite: yeah, i get that now

21:43 hiredman: transducers and reducers get rid of map-reduce and replace it with just reduce

21:43 philwhite: really?

21:43 hiredman: yes

21:43 https://vimeo.com/45561411

21:43 sdegutis: isn't map-reduce a mongodb thing?

21:43 hiredman: rich gave a talk at euroclojure a few years back about reducers, which are sort of a precursor to transducers

21:44 amalloy: i'm gonna go out on a limb and say someone probably thought of map-reduce before mongodb

21:45 philwhite: i'll watch the talk, but one last thing

21:47 i just remembered that map-reduce isn't actually what i'm trying to do...it's just a means to an end. What i'm actually trying to do is a map-while, but i was going to implement it as a map-reduce with a boolean state. Does that change anything. I'm gonna have to think more about this whole subject

21:47 ben_vulpes: sdegutis: nice

21:47 hiredman: uh

21:47 sdegutis: ben_vulpes: erm, wrong username?

21:47 hiredman: map while isn't a thing

21:48 sdegutis: but it /could/ be

21:48 hiredman: filter is a thing, and take-while are things

21:48 sdegutis: ,(defn map-while [f coll] (->> coll (map f) (take-while f)))

21:48 clojurebot: #'sandbox/map-while

21:48 hiredman: both of which have transducer forms which transform a steping function

21:48 philwhite: it would map a sequence until the func returns false, and then it leaves the rest of the sequence alone

21:49 sdegutis: ,(map-while not-empty [[1 2 3] [2] [] [3])

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

21:49 hiredman: that is take-while + map

21:49 sdegutis: ,(map-while not-empty [[1 2 3] [2] [] [3]])

21:49 clojurebot: ([1 2 3] [2])

21:49 sdegutis: woo it works

21:49 hiredman: ok yeah map-while is a thing now

21:49 hiredman: if you can, you should avoid while type constructs, they force a linear run

21:49 philwhite: runtime?

21:49 hiredman: no

21:50 you have to evaluate linearly

21:50 philwhite: what's a linear run?

21:50 what's wrong with that?

21:50 ben_vulpes: sdegutis: oh i thought you were making a good joke about map/reduce being a mongodb thing

21:50 amalloy: your joke is sdegutis's reality

21:50 sdegutis: ben_vulpes: oh no, not at all

21:50 ben_vulpes: i was making a bad joke about that

21:51 ben_vulpes: i found it quite entertaining

21:51 sdegutis: uh oh

21:51 you may wanna get that checked out

21:51 hiredman: philwhite: guy steele has a talk, I forget the actual title, but the subtitle is something like "cons considered harmful"

21:51 which addresses exactly that

21:51 sdegutis: rule #4 of #clojure is that sdegutis's jokes are not to be considered funny by anyone ever

21:52 philwhite: there are just so many hours in the day to watch talks, but whatever, haha

21:52 amalloy: hiredman: https://vimeo.com/6624203

21:52 sdegutis: rule #1 is do not talk about #clojure, rule #2 is okay actually you can talk about #clojure but not too loudly

21:52 amalloy: Organizing Functional Code for Parallel Execution; or, foldl and foldr Considered Slightly Harmful

21:52 hiredman: http://xahlee.info/comp/i/ICFPAugust2009Steele.pdf

21:52 I misremembered

21:52 but that

21:52 sdegutis: nobody's quite sure what rule #3 is but we can't just go and renumber all the rules after it

21:52 (cuz immutability)

21:53 and only ben_vulpes knows what rule #5 is, an he's not allowed to say

21:53 philwhite: hiredman: ahh, slides, thank you

21:53 ben_vulpes: it's trivially deduceable though from that i can't say

21:53 sdegutis: but rule #6 is too well known, no haskell discussions allowed after midnight on the third and first tuesdays of the year

21:53 ben_vulpes: we have a monad for it too!

21:53 sdegutis: related, from corpslack today: http://i.imgur.com/gw7vIml.png

21:54 sdegutis: ahh

21:54 ben_vulpes: acknowledged.

21:54 ben_vulpes: i believe that's spelled 'ack'

21:55 amalloy: dang. @channel. the height of rudeness.

21:55 "i have a question so important and urgent i need everyone's attention right now"

21:56 ben_vulpes: amalloy: manners are contextual




21:56 that's /private/

21:56 sdegutis: ben_vulpes: i actually have no idea how to spell it

21:57 amalloy: what is @channel?

21:57 oh, right, in the screenshot

21:57 it must be some Slack thing, right?

21:57 ben_vulpes: yes

21:57 amalloy: yes

21:57 sdegutis: ben_vulpes: was that slack?

21:57 ben_vulpes: the chat app that takes 4gb of ram

21:57 yes

21:58 sdegutis: #clojure?

21:58 clojurebot: #clojure is a clojure IRC channel for asking python questions

21:58 ben_vulpes: hoho clojurebot

21:58 sdegutis: not anymore

21:58 ben_vulpes: sdegutis: $corpslack

21:58 #clientproj

21:58 sdegutis: oh

21:58 im gonna assume $prefix is some kind of like server-delimiting prefix?

21:59 like $freenode?

21:59 Sadly I have not kept up with Slack or how it works at all.

21:59 ben_vulpes: no it's a bashism

21:59 quit trolling me sdegutis

21:59 sdegutis: Fortunately, my employer's efforts to incorporate Slack into our workflow did not work.

21:59 We still use Skype, yay.

22:00 ben_vulpes: inadequate command and control.

22:01 amalloy: slack is pretty cool

22:02 ben_vulpes: burn the heretic

22:06 sdegutis: ben_vulpes: whats cmd & ctrl

22:06 amalloy: I wouldn't be surprised to find you in #clojure on Clojurians.slack

22:07 You seem like the kind of guy to get behind new tech stacks pretty quick

22:07 ben_vulpes: sdegutis: you know, that thing mgmt does, intimidating dev and imposing flashy new pointless tools

22:08 sdegutis: ben_vulpes: oh right

22:08 TEttinger: mgmt the band or mgmt the management?

22:09 sdegutis: yes

22:09 ben_vulpes: no troll

22:09 plz no trolly

22:19 philwhite: hiredman: literally the first real slide of the Guy Steele talk has the point "MapReduce is good."

22:19 so there

23:04 dimon_: hi, does luminus has helper methods for rendering urls like Rails does: link_to "name", controller: , action: , id: ?

23:30 sdegutis: Welcome to #clojure.

23:40 ben_vulpes: sdegutis: talking to himself again

23:40 sdegutis: ben_vulpes: no he isn't

23:40 ben_vulpes: nobody else is

23:50 sdegutis: ben_vulpes: you are :)

Logging service provided by n01se.net