2016-05-19
| 02: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? |
| 02:34 | hiredman | on uberjar in target wouldn't do it |
| 02:35 | hiredman | 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 |
| 02:36 | hiredman | target is on the classpath because the clojure compiler requires that the directory where compiled class files are being written be on the classpath |
| 02:36 | hiredman | you should just stop aot compiling, your life will instantly be better |
| 02:37 | expez | what determines where clojure writes it's compiled classes? |
| 02:38 | hiredman | just stop aot compiling |
| 02: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? |
| 02: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 |
| 02:40 | hiredman | 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 |
| 02:41 | hiredman | neither of those things is true, and the downside of aot compilation is it leaves you open to all kinds of odd issues |
| 02:42 | expez | yeah, I got that part. Thanks |
| 02:42 | expez | Unfortunately, handing out the source code isn't always an option |
| 02:44 | expez | (inc hiredman) |
| 02:44 | expez | ,(inc hiredman) |
| 02: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... |
| 02:45 | TEttinger | I miss lazybot :| |
| 02: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) |
| 02:45 | expez | that doesn't work anymore? |
| 02: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 |
| 02:46 | TEttinger | *lazybot needed |
| 02:46 | TEttinger | so the person in charge of lazybot took it down, I can't remember who it... was... Raynes? |
| 02:47 | TEttinger | you can still run a lazybot, I run one on quakenet. apparently some plugins have stopped working due to google changing an API |
| 02:49 | hiredman | ~google clojure |
| 02:49 | clojurebot | First, out of results is: |
| 02:49 | clojurebot | null |
| 02:49 | clojurebot | null |
| 02:49 | hiredman | damn, no kidding |
| 02:49 | hiredman | (shows you how much that gets used) |
| 04:04 | ben_vulpes | i have finally lost a finger to aot |
| 04:04 | ben_vulpes | or at least an hour |
| 04:05 | ben_vulpes | but hey at least i REFACTORED THE WHOLE PROJECT and MANUALLY TRAVERSED THE NS GRAPH |
| 04:05 | ben_vulpes | whole project is an exaggeration |
| 04:05 | ben_vulpes | but definitely the reset toolchain |
| 08:25 | Kneiva | Is there a existing function to map with a function that can return a nil and that returns only non-nil values? |
| 08:25 | dysfun | keep |
| 08:29 | Kneiva | great, thanks! |
| 08:31 | dysfun | yw :) |
| 09:08 | ilevd | Is boot-clj good for shell scripting? |
| 09:09 | dysfun | how do you mean? as a replacement for bash? |
| 09: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 |
| 09:13 | ilevd | dysfun, yes, something like this. The most important thing is its startup time |
| 09:16 | dysfun | startup time is about the same as lein |
| 09:16 | dysfun | if you want a bash script... write a bash script |
| 09:19 | ilevd | I want to have an opportunity to run ./hello.clj ilevd and get "Hello, ilevd!" immediately :) |
| 09:19 | dysfun | sorry, you're out of luck |
| 09:20 | dysfun | you can sort of fake it by keeping a jvm open |
| 09:20 | dysfun | there are a few tools to help you with that |
| 09:22 | ilevd | Yes, I'm looking for them now |
| 09:23 | dysfun | https://github.com/technomancy/grenchman |
| 09:27 | MasseR | ilevd: however afaik you won't have a proper CWD with them, it's shared with the jvm instance |
| 09:27 | dysfun | ah yes, that sounds probable |
| 09:28 | yazirian | ilevd: if cljs is acceptable http://planck-repl.org/ is probably what you're looking for |
| 09:28 | ilevd | Yeah, I've found it too, what is CWD? |
| 09:29 | dysfun | current working directory |
| 09:29 | ilevd | Ah |
| 09:37 | ilevd | Yet another reason to buy Mac) |
| 09:37 | dysfun | odd you should mention that, i've just jumped from a mac |
| 09:38 | ilevd | Why? |
| 09:38 | clojurebot | why not? |
| 09:38 | dysfun | because reliability is not what it used to be and neither is 'just works' |
| 09:39 | MJB47 | can confirm that |
| 09:39 | dysfun | and because i'm sick of the constant tin-rattling |
| 09:39 | MJB47 | os x has been increasingly annoying me since lion :( |
| 09:39 | dysfun | yes, snow leopard is clearly the best release they ever made |
| 09:40 | dysfun | they keep pestering me to upgrade my laptop (which has been relegated to web browsing device) to el capitan |
| 09:41 | dysfun | and oh wow, i should totally get on that update that improves support for some hardware i don't own |
| 09:41 | dysfun | thanks for telling me several times a day |
| 09:42 | ilevd | And what do you use now? Debian? |
| 09:42 | dysfun | no, i've been on FreeBSD for a few weeks |
| 09:43 | dysfun | i can honestly say it's a lot lower maintenance than OSX now |
| 09:43 | MJB47 | im using mint at home |
| 09:43 | MJB47 | im happy enough with it |
| 09:43 | dysfun | i'm planning to move back to linux, but i hate all linux distributions |
| 09:43 | dysfun | and i really don't like systemd |
| 09:43 | dysfun | that limits my distro choice somewhat |
| 09:43 | dysfun | i wouldn't move except that freebsd is a joke for doing GPU work |
| 09:43 | ridcully_ | gentoo (or one of the binary-only-offsprings) are quite close to the way at least ports behave |
| 09:44 | dysfun | well they called it 'portage' for a reason :) |
| 09:44 | ridcully_ | isn't there the nvidia blob anymore? |
| 09:44 | dysfun | i should note i moved from gentoo to freebsd |
| 09:44 | dysfun | oh i don't any any nvidia. fuck that |
| 09:44 | dysfun | own* |
| 09:44 | dysfun | except my knackered old craptop |
| 09:45 | dysfun | i want to play with the new vulkan stuff which is intel/linux only at the minute |
| 09:45 | dysfun | 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 | iwo | 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 | iwo | (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 | kwladyka | ,(-> (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 | justin_smith | 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 | kwladyka | 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 | kwladyka | it is much more complex to explain why that you think in the first moment :) |
| 10:45 | kwladyka | *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 | justin_smith | ,(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 | kwladyka | :require-macros is shown as an error etc. |
| 10:57 | MJB47 | im not sure what a bad syntax highlight is |
| 10:58 | MJB47 | but you can change all the syntax highlighitng really easily |
| 10:58 | MJB47 | its just css |
| 10:58 | MJB47 | 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 | MJB47 | perhaps its just your theme? |
| 10:59 | MJB47 | regardless, just fiddle with the css if its an issue |
| 10:59 | kwladyka | MJB47 i use the default one for now |
| 11:00 | kwladyka | MJB47 do you use linter-clojure? It shows me this error about :require-macros |
| 11:00 | MJB47 | i dont |
| 11:00 | MJB47 | 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 | MJB47 | i need to make a pr for it at some point |
| 11:02 | MJB47 | or do my own |
| 11:02 | kwladyka | MJB47 why not great? |
| 11:02 | kwladyka | do what? |
| 11:02 | MJB47 | only works for 1 type of bracket at a time |
| 11:02 | MJB47 | sometimes bugs out |
| 11:02 | kwladyka | oh |
| 11:02 | MJB47 | is slow |
| 11:03 | MJB47 | do my own rainbow parens thing |
| 11:03 | MJB47 | or fork it... idk |
| 11:03 | kwladyka | linter-clojure, language-clojure, proto-repl, lisp-paredit, ink <- i use this |
| 11:04 | kwladyka | MJB47 ambitious.... i just want use editor, not code it :) |
| 11:04 | MJB47 | swackets is just rainbow parens, its not that complicated |
| 11:04 | MJB47 | or needed |
| 11:04 | MJB47 | its just a nice to have |
| 11:05 | MJB47 | 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 | MJB47 | 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 | kwladyka | testing it |
| 11:08 | kwladyka | for now i don't like some shortcuts... but i can set my own |
| 11:09 | kwladyka | 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 | kwladyka | indent |
| 11:10 | kwladyka | for selected text or a whole file when nothing selected |
| 11:11 | kwladyka | 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 | sdegutis | Good luck figuring out whether [:form#quux.bar {:class "foo"}] has a given class. |
| 12:06 | sdegutis | 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 | Bronsa | 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 | Bronsa | 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 | sdegutis | 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 | dysfun | 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 | dysfun | 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 | CStorm | mostly i want to make a small tool to keep a eye on a few webservices on the server |
| 12:17 | CStorm | are they running, if not restart etc etc. |
| 12:18 | CStorm | 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 | dysfun | not to mention you actually want a repl with readline and such |
| 12:49 | dysfun | 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 | Bronsa | 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 | bsamorim | 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 | amoe | 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 | justin_smith | it can use a dynamic binding, or set an atom or var before the test starts |
| 13:51 | justin_smith | 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 | sdegutis | 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 | justin_smith | 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 | kwladyka | probably bad design? |
| 13:58 | sdegutis | kwladyka: I prefer the phrase lifelong continuous learning, as applied to design |
| 13:58 | sdegutis | 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 | justin_smith | 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 | dysfun | i just have a /static/upload directory that i dump things into as a directory forest |
| 14:17 | dysfun | (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: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 | dysfun | 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 | dysfun | 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 | dysfun | 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 | dysfun | as for 'organise', well that's metadata that you should store in your database, surely? |
| 14:25 | dysfun | 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 | dimon_ | 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 | dysfun | 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 | dysfun | 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 | etiago | by the time it does, :on-receive has already been assigned to. |
| 14:32 | etiago | 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 | dysfun | 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 | dysfun | you create the directories on demand as required |
| 14:36 | dysfun | or you can even hash the file contents and use that as the filename instead |
| 14:36 | dysfun | 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 | justin_smith | after that you can put socket in an atom or pass it forward to whoever else needs to use it, or whatever |
| 14:39 | justin_smith | 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 | justin_smith | ,(def recursive (lazy-seq (cons 42 recursive))) |
| 14:40 | clojurebot | #'sandbox/recursive |
| 14:40 | justin_smith | (nth recursive 1000) |
| 14:40 | justin_smith | ,(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 | justin_smith | so a function is always allowed to pass itself as an arg to something it calls |
| 14:41 | justin_smith | ,(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 | justin_smith | etiago: it's the thing you are defining |
| 14:43 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | etiago | justin_smith: agreed :) I will read up on promises and atoms, that seems to be a better option |
| 14:57 | etiago | thanks again! |
| 15:01 | amalloy | i don't think you need a promise for that |
| 15:02 | amalloy | 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 | amalloy | (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 | amalloy | but your promise/deliver has the same issue |
| 15:04 | amalloy | oh, i guess i didn't read the original code |
| 15:04 | amalloy | all this is happening inside a function already |
| 15:04 | amalloy | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | *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 | CStorm | 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 | kungi | CStorm: What are you using at work? |
| 15:30 | CStorm | mobile developer, writing swift, objective-c and java |
| 15:30 | CStorm | so intellijs |
| 15:30 | CStorm | ive used emacs for a little under a year so still tons to learn |
| 15:30 | CStorm | :) |
| 15:30 | CStorm | 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 | CStorm | however depending on mood, interest etc there goes 1-2 weeks in between |
| 15:32 | CStorm | then it get hard to remember again :) |
| 15:32 | CStorm | using emacs at work? |
| 15:32 | kungi | CStorm: building muscle memory always is hard |
| 15:32 | kungi | CStorm: I use clojure at work so I use emacs |
| 15:33 | kungi | 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 | kungi | 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 | kungi | 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 | CStorm | 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 | ben_vulpes | eg just the first level of nesting? |
| 17:11 | TimMc | ben_vulpes: mapcat identity |
| 17:12 | ben_vulpes | class |
| 17:12 | ben_vulpes | classy* |
| 17:12 | ben_vulpes | 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 | TimMc | Usually one of those two answers is what people really want when they reach for flatten. :-P |
| 17:14 | TimMc | (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 | sdegutis | And each presenter, and each view function, etc. |
| 17:47 | sdegutis | 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 | hiredman | 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 | cfleming | Tools->Repl->Jump to REPL editor/output pane |
| 18:16 | luma | ooh |
| 18:16 | luma | nice |
| 18:17 | cfleming | You can jump to the output too and cut and paste from it. |
| 18:18 | cfleming | 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 | kwladyka | or i am in mistake as i can read :) |
| 18:21 | cfleming | Well, in your defence those actions are pretty new :) |
| 18:21 | cfleming | From any toolwindow (including the REPL), ESC will always jump back to your code. |
| 18:22 | cfleming | 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 | cfleming | 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 | cfleming | kwladyka: It's easy, my IRC client tells me whenever anyone is talking about Cursive |
| 18:24 | cfleming | 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 | cfleming | 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 | justin_smith | 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 | justin_smith | whilo_: lein run does not run a separate compilation step |
| 18:28 | justin_smith | 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 | kwladyka | 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 | justin_smith | 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 | justin_smith | bind using the binding macro, of course |
| 18:37 | justin_smith | 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 | justin_smith | 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 | justin_smith | ) |
| 18:39 | justin_smith | ,(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 | whilo_ | though |
| 18:43 | whilo_ | even considering all the arguments of stuart sierras binding warning |
| 18:44 | whilo_ | 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 | justin_smith | 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 | whilo_ | 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 | justin_smith | 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 | justin_smith | 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 | bsamorim | it's really frustrating to see that something that takes forever in clojure would be nipped in the bud with OOP |
| 20:14 | bsamorim | 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 | bsamorim | 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 | 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:29 | bsamorim | 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 | bsamorim | 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 | bsamorim | 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 | bsamorim | 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 | bsamorim | with no control flow to check the order type.... |
| 20:37 | bsamorim | 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 | bsamorim | would encapsulate* |
| 20:42 | bsamorim | 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 | sdegutis | 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 | bsamorim | sdegutis: of course it isn't very complex, especially if you think specifically about this function... |
| 21:07 | bsamorim | 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 | amalloy | that's polymorphism |
| 21:08 | amalloy | 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 | bsamorim | implementations |
| 21:09 | amalloy | well, not necessarily partials, since you can be a lot more general |
| 21:09 | amalloy | 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 | bsamorim | I mean, I just read SICP....the elegance in it!!!!!! |
| 21:11 | bsamorim | 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 | bsamorim | 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 | bsamorim | amalloy: hahah, yeah, that's very frustating!! |
| 21:14 | bsamorim | 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 | bsamorim | I mean, specially software development...how much creative can it really be? |
| 21:16 | bsamorim | you can be proud of some part of your source code....but most of it is very down-to-earth, automatic stuff.... |
| 21:17 | bsamorim | 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 | philwhite | 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 | philwhite | 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 | namra | 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 | namra | this would also evaluate the fixtures in app.other-tests when (a-test) is evaluated? |
| 21:28 | namra | 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 | amalloy | 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 | hiredman | philwhite: a transducer is generally a function that takes a step function and returns a new step function |
| 21:33 | hiredman | 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 | ben_vulpes | 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 | ben_vulpes | I MIGHT |
| 21:36 | ben_vulpes | amalloy: I JUST MIGHT |
| 21:36 | ben_vulpes | 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 | ben_vulpes | 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 | ben_vulpes | 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 | philwhite | turbofail: i'm actually literally looking at the map source right now |
| 21:39 | philwhite | i think you just made me more confused :) |
| 21:39 | philwhite | oh, wait, never mind i was looking at ben's code too |
| 21:40 | ben_vulpes | philwhite: don't do that |
| 21:40 | ben_vulpes | 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 | hiredman | 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 | hiredman | 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 | philwhite | 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 | sdegutis | 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 | hiredman | you have to evaluate linearly |
| 21:50 | philwhite | what's a linear run? |
| 21:50 | philwhite | 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 | sdegutis | 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 | sdegutis | 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 | hiredman | 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 | hiredman | I misremembered |
| 21:52 | hiredman | 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 | sdegutis | (cuz immutability) |
| 21:53 | sdegutis | 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 | ben_vulpes | sdegutis: related, from corpslack today: http://i.imgur.com/gw7vIml.png |
| 21:54 | sdegutis | ahh |
| 21:54 | sdegutis | ben_vulpes: acknowledged. |
| 21:54 | ben_vulpes | i believe that's spelled 'ack' |
| 21:55 | amalloy | dang. @channel. the height of rudeness. |
| 21:55 | amalloy | "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 | ben_vulpes | DON'T TELL ME HOW I FEEL |
| 21:56 | ben_vulpes | DON'T TELL ME HOW I LOOK LIKE I FEEL |
| 21:56 | ben_vulpes | YOU DON'T HAVE GETTERS OR SETTERS FOR MY INTERNAL STATE OKAY |
| 21:56 | ben_vulpes | that's /private/ |
| 21:56 | sdegutis | ben_vulpes: i actually have no idea how to spell it |
| 21:57 | sdegutis | amalloy: what is @channel? |
| 21:57 | sdegutis | oh, right, in the screenshot |
| 21:57 | sdegutis | 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 | ben_vulpes | 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 | ben_vulpes | #clientproj |
| 21:58 | sdegutis | oh |
| 21:58 | sdegutis | im gonna assume $prefix is some kind of like server-delimiting prefix? |
| 21:59 | sdegutis | like $freenode? |
| 21:59 | sdegutis | 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 | ben_vulpes | quit trolling me sdegutis |
| 21:59 | sdegutis | Fortunately, my employer's efforts to incorporate Slack into our workflow did not work. |
| 21:59 | sdegutis | 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 | sdegutis | amalloy: I wouldn't be surprised to find you in #clojure on Clojurians.slack |
| 22:07 | sdegutis | 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 | ben_vulpes | 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 | philwhite | 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 :) |