#clojure logs

2015-10-07

00:34Jaood'
00:35wmealing'
00:35wmealingi couldnt let that go unmatched
00:35justin_smith' doesn't need a match in clojure
00:36wmealingoh NOW people talk
00:36wmealing;P
00:36amalloyjustin_smith couldn't bear to see your correction go uncorrected
00:36justin_smiththings have been getting quiet around here
00:36amalloyjustin_smith: is everything in slack now, or what?
00:37justin_smithit's pretty active... but I can't use it like I do IRC
00:37justin_smithtoo much of an "app"
00:37wmealingwhat is slack ?
00:37wmealinghttps://slack.com/?r=1 ?
00:37justin_smithit's an app that's a lot like IRC, and there's a clojurians channel there that a lot of people are using now
00:38justin_smithit even has an IRC gateway that I may eventually set up, my workplace uses slack
00:42justin_smithlast I checked, having an archive / searchable log / on slack cost money, so clojurians doesn't have a searchable backlog
01:13FrozenlockGotta love all those new shiny stuff. Remember when email was broken? Now we have Facebook messages. Wheeeeee
01:16wmealingi didnt think that any of it was broken
01:17FrozenlockIt wasn't, nor is IRC.
01:18TEttingerbeing able to post snippets of code inline with a preview is pretty nice though, on slack
01:18mungojellyi think irc is still awesome but it could also be improved, like why don't we have any irc clients that understand richer text, we wouldn't have to change anything about the infrastructure just put <i> or w/e and parse it on the other side
01:18TEttingerI like Gitter better than Slack, less signing up :P
01:19mungojellysigning up prevents abuse which is why the internet has been such a sparlking fantastic positive place since we started having to sign up everywhere /s
01:19amalloyyeah, i use slack at work, but i am not willing to sign up for slack in order to try the clojure slack
01:42devangshahhow can i use java functions inside the anonymous functions as part of map or filter?
01:42justin_smithdevangshah: by using java methods inside anonymous functions
01:43devangshahi am trying to access them using (doall (filter #(.isDirectory) (file-seq (io/file dirpath))))
01:43justin_smithdevangshah: you need % to indicate the argument
01:43justin_smith#(.isDirectory %)
01:44devangshahsilly me…
01:44devangshahthanks anyway..
01:44devangshahnewbie to clojure
01:45justin_smithdevangshah: #(foo) is a function of no arguments that calls foo, the argument count expected is determined by the usage of %, %2, etc. you can also use %& for varargs
01:46devangshahyes.. i knew it.. even i used it in my project.. but somehow i missed here.. thanks anyway..
02:11sm0ke,(clojure.java.shell/sh "pwd")
02:11clojurebot#error {\n :cause "clojure.java.shell"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.java.shell"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n ...
02:11justin_smith,(System/getenv "PWD")
02:11clojurebot#error {\n :cause "access denied (\"java.lang.RuntimePermission\" \"getenv.PWD\")"\n :via\n [{:type java.security.AccessControlException\n :message "access denied (\"java.lang.RuntimePermission\" \"getenv.PWD\")"\n :at [java.security.AccessControlContext checkPermission "AccessControlContext.java" 372]}]\n :trace\n [[java.security.AccessControlContext checkPermission "AccessControlContext.java...
02:11justin_smith:P
02:12sm0ke,(do (require 'clojure.java.shell) (clojure.java.shell/sh "pwd"))
02:12clojurebot#error {\n :cause "denied"\n :via\n [{:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__883 invoke "sandbox.clj" 69]}]\n :trace\n [[clojurebot.sandbox$enable_security_manager$fn__883 invoke "sandbox.clj" 69]\n [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkExec nil -1]\n [java.lang.ProcessBuilder start "Process...
02:12sm0keok but does (sh/sh "echo foo") works for anyone?
02:13wmealing,(do (require 'clojure.java.shell) (clojure.java.shell/sh "echo $ENV"))
02:13clojurebot#error {\n :cause "denied"\n :via\n [{:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__883 invoke "sandbox.clj" 69]}]\n :trace\n [[clojurebot.sandbox$enable_security_manager$fn__883 invoke "sandbox.clj" 69]\n [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkExec nil -1]\n [java.lang.ProcessBuilder start "Process...
02:13sm0keah its supposed to be used like (sh/sh "echo" "foo")
02:13sm0keweird
02:14justin_smithalso it won't expand globs and doesn't really call sh
02:15sm0ke(sh "echo" "-n foo") (sh "echo" "-n" "foo") are different
02:16sm0keinteresting implementation
02:19opqdonutsm0ke: no, a very standard implementation
02:19opqdonutsm0ke: works just like the C exec
02:19opqdonutthough I have to admit it's a bit weird to call it sh and not do sh-like command handling
02:21sm0kethere is a `sh` in C which is completely different
02:21sm0keso you can compare it to `exec` and call it normal
02:21opqdonutdo you mean `system` in C?
02:22sm0keits like saying my cat is absolutely fine just that it looks like a elephant
02:22opqdonutyeah, I do agre that it is surprising
02:22opqdonut*agree
02:27mungojelly (clojure.java.shell/sh "clojure" :in "(clojure.java.shell/sh \"clojure\" :in \"(print \\\"hi\\\")\")")
03:05nXqdhi guys how can I pass the keys parameter in function call as a variable. For example : (def base-keys [username password]) (defn x [& {:keys base-keys} ())
03:08sm0ke,( (fn [& {:keys [foo]}] (prn foo)) :foo 1)
03:08clojurebot1\n
03:08amalloy~mapply
03:08clojurebotYou have to do something like (defn mapply [f & args] (apply f (apply concat (butlast args) (last args)))), which just goes to show why unrolled keyword args are a bad idea
03:08sm0keis this what you meant?
03:08amalloyoh, that. ignore mapply
03:08amalloyyou can't do that at all
03:08amalloysomewhere i ahve a stackoverflow answer that is semi-relevant
03:09nXqdsm0ke: if i understand correctly, the example you show does show the normal usage of parameter destructuring
03:10amalloybasically you don't want to do that: instead define the function as taking a map, and write a simple macro like (with-user user body) that destructures username and password out of the user map
03:10nXqdwhat I want is to pass the key as variable
03:10sm0ke,(let [key :foo] ( (fn [& {:keys [foo]}] (prn foo)) key 1))
03:10clojurebot1\n
03:10nXqdyeah it would be a better way :P
03:11amalloyyou can't
03:12nXqdamalloy: and btw, how to insert multiple value to a record in datomic. For example : I have email, password, name in the function, then I can insert some how all of the dynamically
03:12nXqdinstead of specify each like :user/email email, :user/password password
03:12amalloybeats me. i can't even insert one anything into datomic
03:13nXqdhmm @(d/transact conn [{:db/id (d/tempid :db.part/user) :user/email email :user/password password}])
04:03FenderHi guys, I want an async web server in clojure (such as httpkit or ring-async), however, most servers are not able to deal with an async channel for the *complete* response (instead, the only the body is an async channel). This means, I cannot set the HTTP status code of the response and I'll probably have to respond with 200 all the time. Then there's jet, that is able to do it but was obviously compiled against Java 8. So - is it usual to
04:05TMAFender: your question was chopped off after "So - is it usual to"
04:06Fenderthx - "So - is it usual to always respond in async servers with HTTP 200, am I missing something or is there no good server for my problem?"
04:41nXqdanyone here using component, please explain me what is map->ComponentName , is map-> a macro or something. how is it defined ? thanks
04:42ianhedoesitmap->* is a constructor created by defrecord
04:44ianhedoesitI suppose factory functions might be easier to distinguish due to the OO hold on the term "constructor"
04:44ianhedoesit->TypeName takes positional parameters to field values and map->TypeName takes a map of keywords to field values
05:02tdammersso I'm having a bit of trouble adjusting to clojure (coming from Haskell)
05:02tdammersmy main gripe is that every fn reads as something like "Anything -> Anything -> ... -> IO (Maybe Anything)
05:03tdammersand the only strategy I've found so far for understanding what it does is reading the code
05:03tdammersincluding all of its dependencies
05:03tdammersbut I can't help but think that there must be a better way
05:05ianhedoesityou mean you don't know how to understand functions in Clojure because there's no type hints or anything?
05:05ianhedoesit(I'm not trying to sound rhetorical or anything, I'm trying to understand your problem)
05:07tdammerspretty much, yes
05:07tdammerssometimes, there's documentation, which helps a lot, but still
05:08nXqdianhedoesit: hey thanks ! I didn't notice Clojure has bunch of -> factory function :)
05:08tdammerse.g., I'm working with kioo here, and there are all these macros that take an optional emit-opts argument
05:08tdammersthere is no documentation on that argument
05:09ianhedoesitnXqd: it actually (I think?) only has the two that are generated from defrecord (->TypeName and map->TypeName)
05:09ianhedoesitthey're pretty handy.
05:09tdammersin order to figure out how to use it, I have to descend about 4 or 5 levels into the call chain
05:09tdammersseveral paths, even, because each call dependency looks at a different key
05:10tdammersthis is really not a complaint, I just want to know where the "easy" button it
05:10tdammers*is
05:12ianhedoesittdammers: I think that's one of the common complaints (and something I worry about with dynamic languages) about all dynamic languages, no?
05:12tdammersianhedoesit: yes
05:12ianhedoesitone of the huge niceties of Haskell, for example, is that you can just look at a function signature and know, at least, exactly what types you need to pass to a function to do _something_
05:13tdammersexactly
05:13ianhedoesitin dynamic languages you don't have that option. however, core.typed and Prismatic/Schema try to help with that.
05:13tdammersalso, even with nothing but type signatures in place, the generated documentation is still useful in that you can easily click through to anything any function references
05:17ianhedoesitwell to attempt an answer of your initial problem/question, you have to rely on good code, for the most part. also making assumptions like (defn foo [m k v] ,,,) probably takes a map, a key, and a value, etc.
05:17ianhedoesitor add type hints and whatnot.
05:17tdammersso it takes a map; but which keys does it expect, which values are allowed for them, etc.
05:21ianhedoesitthat's typically where you need to look at the docstring
05:22ianhedoesitI don't know if that's all that different even for statically typed languages though? just because you have Map -> Key -> Anything -> Map doesn't mean you know what exactly to pass it either
05:23ianhedoesityou can have the same questions ("What key? What Anything? What's the Anything used for?" etc.)
05:25tdammersexcept that typically you wouldn't be using `Map Anything Anything -> Anything -> IO Anything`, but rather something like `Map UserID User -> UserID -> Maybe User`
05:26ianhedoesittrue, but then you need to define all those things, no?
05:26ianhedoesit(I have virtually 0 experience with Haskell, so excuse my ignorance in this situation)
05:27tdammersyou have to do that anyway, either explicitly (through data types) or implicitly (through the code that handles them)
05:27tdammerscan be as simple as newtype UserID = UserID Int, even
05:27tdammersor even just type UserID = Int, which is less useful, but still acts as documentation at least
05:28tdammersbut yes, defining your data types upfront does form a bit of overhead
05:36mungojellycouldn't you also just type a program strongly enough that you don't need anything but types, that the whole flow of the program can only go one way b/c types, has anyone done that yet?
05:36amalloyyes, you can just run your entire program inside the compiler
05:37amalloybut then it's no easier to analyze than a program that runs ar tunrime
05:37tdammersGHC's type checker itself is turing complete, so you can write anything in it, yes
05:37mungojellylike you'd have a function processed-some -> processed-more, and then processed-more -> processed-most, and processed-most -> done, and so it's just in the types how to compute the result
05:38mungojellyturing complete, everything's turing complete. :/ don't we have any better standards
05:39tdammersnot everything is turing complete
05:39tdammersmost of the older SQL dialects aren't
05:39tdammersmany type checkers aren't either
05:39mungojellybut i mean people say something's turing complete like that proves you could do anything useful with it, but what did anyone make with a turing machine lately
05:40tdammersthe thing about TC is that if you can implement an algorithm in one TC language, you can implement it in all of them
05:40tdammerstheoretically speaking at least; practical considerations often make the implementation unfeasible
05:41tdammers(e.g., it'd require way more memory than we can provide, or it would take very long to run)
05:42mungojellyi want to bound my queues but i have unreasonable amounts of data coming into them, what's my problem called
05:42opqdonutsee also "turing tarpit"
05:42emautonOr it'd be a nightmarish inverted tower of Babel spiralling down into the nine hells of computing. ;o)
05:42emautonmungojelly: "overload"
05:43mungojellyi know some strategies like (a) forget oldest unprocessed requests (b) drop new requests (perhaps applying backpressure)
05:44emautonHave a read of chapter 3 of "Erlang in Anger" by Fred Hebert (it's free online).
05:44mungojellyidk i just thought of (c) putting new things into random spots once the queue's full
05:44mungojellyemauton: ok thanks will do :)
05:44opqdonutdropping random stuff is good
05:44opqdonuthas all sorts of nice theoretical properties
05:44tdammers"load shedding"
05:44tdammers^ useful google incantation
05:44mungojellyyeah i felt that as soon as i started running it in my mind, i was like huh well then at least it does its best like *statistically*
05:45tdammersyes
05:45tdammersif you take great care to shed in "atomic" units, then that's probably the best you can get
05:45mungojellyooh, "load shedding" is a good term for it. that's the opposite of the hell of naming i guess, the heaven of beautiful names.
05:54ianhedoesittdammers: I stepped away for a minute, so this is backtracking a couple screens, but that is interesting. however, for complex types I fear the overhead would be much more significant, no? also, it's much less composable, is it not?
05:55ianhedoesitI don't know if I can make a point for the composability of either form, though
05:57tdammersI'd argue that it's *more* composable, because the mental overhead stays constant as your codebase grows
05:57tdammersalso, you usually use type variables and constraints rather than actual types in your signatures, so your code stays generic and composable
05:58ianhedoesitas in Int instead of UserID, but a UserID could still be passed?
05:58ianhedoesitor what do you mean by that?
05:58tdammersno, more like how, for example, fmap can map over any functor, not just lists
05:59tdammersinstead of writing :: (String -> String) -> [String] -> [String]
05:59mungojellydid y'all see that talk from strangeloop this year about chemical computing? that's like there's just types or just types and environments and the program makes the specific connections for you
05:59tdammerswe write it as :: Functor f => (a -> b) -> f a -> f b
05:59tdammersand with that, you can use fmap on lists, vectors, maps, maybes, eithers, etc.
06:00amalloytdammers: it might be easier to start with map instead of fmap, and explain how the types for *that* work, because it's more familiar
06:00tdammersamalloy: yeah, probably
06:00tdammersamalloy: was using fmap because that's more reusable and generic
06:01tdammersmap is kind of inbetween, in that it takes lists of a variable type, but they still have to be lists
06:01tdammers:: (a -> b) -> [a] -> [b]
06:01amalloywell yes, but if you don't understand how map can be typed generically (i didn't, when i was starting to figure out functional programming) thenfmap is hopeless
06:02tdammersI'm assuming an audience that is familiar with generic functions here
06:08dragon-irlIs there a way to get intellij to resolve js calls when using cursive?
06:17mungojellyeverything about backpressure and granting resources says to make a request queue of things that want the resource but what if you get too many *requests* to even handle those, how do i like pass out a finite number of request tickets
06:22ianhedoesittdammers: is `map :: (a -> b) -> [a] -> [b] really more simple than `map ([f coll])`?
06:22tdammersnot by itself
06:23ianhedoesitI realize that since I have very little understanding of Haskell, it's more difficult for me to parse it mentally, but seeing that my parameters are "f" and "coll", I assume it wants a function and a collection
06:23amalloythe point is that you can write (map 5 *) in clojure, and the compiler doesn't know that's wrong
06:23tdammersbut checking whether String -> Text is a valid first argument for (a -> b) -> [a] -> [b] is much easier than judging whether (fn [x]) is a valid first argument for (fn [f c])
06:23ianhedoesitI know what a and b should be in Haskell's map, but if I didn't know what the map function does from an abstract point of view, I would have no idea
06:24amalloywith a static type the compiler can know enough to say "that's not how you use map"
06:24tdammersactually, there's not an awful lot the map function can do, given its type signature
06:24ianhedoesitamalloy: I know, and I agree that it's a valid complaint, and I worry about that too when thinking about committing time to a dynamic language
06:25tdammersit could reverse the list while processing it, or it could completely ignore the function argument and always produce an empty list, or it could stop mapping after reaching a hard-coded limit
06:25tdammersbut if you add the convention that the function does not add any hard-coded information, nor ignore any of its input, then map's behavior is pretty much completely described by its type signature
06:25clojurebotA nod, you know, is as good as a wink to a blind horse.
06:27ianhedoesitI really should try to spend more time with Haskell. but I love my lisps the more I use them.
06:29ianhedoesitTMA: why only in the past?
06:29TMAbut then I got to a point where I realized that it was not the static typing that made me uneasy, it was rather the unexpressiveness and burden thereof (C/C++/Java type systems)
06:30tdammersthose languages have done a lot to set back statically typed languages
06:31TMAianhedoesit: in a sense, dynamic typing is like global mutable state but applied to the metaprogram
06:31ianhedoesitI agree to some degree.
06:32TMAit can bite you if you do not pay attention (like passing a (fn [a b] ...) to first argument of map)
06:32mungojellyevery paradigm has a mixture of typing strategies depending on where you look, you're always dynamically determining the meanings of some things
06:33TMAbut it is hidden (not readily apparent)
06:34TMAI caught myself adding (declaim (ftype (function (...) ...) ...)) in my CL programs as a form of documentation
06:35ianhedoesitTMA: what are your feelings on things like core.typed, Schema, or Typed Racket, for example?
06:38TMAianhedoesit: I think that gradual typing is somehow THE way; however, I have not yet managed to immerse myself in any of those
06:39ianhedoesithm, thanks.
06:39ianhedoesitTMA: what would you say your language of choice is today?
06:39TMAlike: bang together the prototype and then add the type annotations to hunt down some of the bugs
06:39ianhedoesitas far as static typing goes
06:40TMAianhedoesit: it depends on the problem [and the environment]
06:41TMAbut mostly I write my code in any language at hand, while designing (in my head) the thing in lisp code with haskell types
06:41ianhedoesitfair enough
06:42TMAunfortunately I forego most of the benefits of the compiler in this way :(
06:42ianhedoesitI suppose the answer I was hoping for was something like "try Haskell to feel the power of a proper statically typed language"
06:42tdammers"lisp code with haskell types" sounds like a great mode of operation
06:42TMAbut the interoperability is much more importatnt to ship the result
06:43TMAsometimes prolog lends its hand in too :)
06:44TMAianhedoesit: by all means, try it out
06:51TMAyesterday, I was hunting down a persistent NullPointerException in Java code, when I finally found the place that was causing it, I really missed my Maybe monad
06:55spaceplukhi, I need to build a very big JSON string incrementally by appending small pieces very quickly over a period of time. What would be an efficient clojureish solution for this?
06:55spaceplukshould I just use interop with StringBuffer or is there a better way?
06:57tdammersyou could write the JSON to a stream
06:58tdammersthat way you could avoid having it all in RAM at once
06:58clojurebotIt's greek to me.
06:59ianhedoesitTMA: I do really like Maybe (from what I understand of it)
07:00tdammersit's really just null checks lifted to the type level
07:00ianhedoesitright, but that's powerful.
07:00tdammersalthough, because Maybe is also a Monad, you get a bunch of things for free
07:01tdammerssuch as short-circuiting Maybe calculations as soon as one of the operands is Nothing
07:01tdammersdo { x <- Just 1; y <- Just 2; return (x + y) }
07:01tdammersor, in applicative syntax, (+) <$> Just 1 <*> Just 2
07:02ianhedoesitHaskell's syntax also scares me every time I try to get involved with it.
07:02ianhedoesitI also find myself wanting to resort back to simple sexps
07:04tdammersLisp syntax scares me... everything looks the same, even when it's something radically different
07:04tdammers;)
07:07ianhedoesitI have the opposite fear. having (according to you) `do { x <- Just 1; y <- Just 2; return (x + y) }` and `(+) <$> Just 1 <*> Just 2` (I assume the return statement was left out, but would be after `Just 2`) be the same confuses and upsets me.
07:11TMAtdammers: the pointless style scares me; and it even does not solve the problem of getting rid of the parentheses
07:11ianhedoesitI'd rather have everything look alike. I like that def, -> and + are three entirely different things, but (def a) (-> a) and (+ a) are all valid
07:12ianhedoesitTMA: pointless style?
07:12TMAianhedoesit: pointfree
07:12TEttingerianhedoesit: I think you missed a winky emoticon <tdammers> ;)
07:14TMAianhedoesit: let's assume for a while an exotic clojure dialect where there are partial applications
07:14ianhedoesitTEttinger: I saw it but I'm not sure what inflection that's supposed to add
07:14TEttingernot serious?
07:15TEttingerthat inflection
07:16TMAianhedoesit: (f a b c) is just a shorthand for (((f a) b) c)
07:17ianhedoesitTEttinger: oh, I assumed he was serious. I figure it's actually pretty common that people don't like that everything looks the same.
07:19TMAianhedoesit: so instead of (defn x [a b c] (f a a b c)) you write (def x (join f)), never mentioning the arguments at all
07:19tdammersianhedoesit: there is no return statement in Haskell. return is a function that "wraps" a value in a monad. it's not a statement, it doesn't return from a function, it "returns a value into a monad"
07:20tdammersre everything looks the same: I was half serious there, in that I do think having different things look different is good, and in case of doubt, I prefer sacrificing "same things look the same" for that
07:20TMAianhedoesit: "return" is a haskelese for unit :: Monad m => a -> m a
07:21TMAtdammers: in haskell everything (but the type declarations) looks the same
07:21tdammersTMA: I would say in Haskell, you have a lot of room for making things look different
07:21ianhedoesitTMA: so then with x what do you do? how do you use it if it's defined as just (join f)?
07:22tdammersapplicative syntax is done entirely in Haskell itself, no special cases in the compiler are needed
07:22TMAianhedoesit: you call it as usual: (x a b c)
07:23tdammersre point-free style:
07:23tdammersconsider map
07:23tdammers(map f items)
07:23TMApoint-free style is awesome to write, but hell to read :-L
07:23tdammersnow, "map f over something" is very common, it's basically a specialization of map
07:24tdammersyou could wrap that in a function like so:
07:24tdammers(fn [x] (map f x))
07:24tdammersthe "x" in there is often called a "point" in Math textbooks
07:25tdammers"point-free", then, just means that we write the function such that no points appear
07:26tdammerswhich, if clojure functions were automatically curried, would just be (map f)
07:26ianhedoesitoh okay.
07:26tdammersand in Haskell, we can do exactly that: passing too few arguments produces a new function that takes the remaining arguments
07:27ianhedoesitso currying is key
07:27tdammersthat's one way to look at it, yes
07:27ianhedoesitI was mostly just wondering what "(+)", "<$>" and "<*>" were.
07:27tdammersoh, that
07:28tdammers(+) is just the + operator, but the parentheses allow us to use it in prefix notation
07:28TMA"(+) a b" is just another way to write "a + b"
07:28tdammers<$> and <*> are library-defined operators from applicative
07:28tdammers<$> is an alias for fmap
07:29TMAtdammers: like (<$>) = fmap ?
07:29tdammersyes, that's exactly how it's defined
07:30ianhedoesitwhat is <*>?
07:31TMAholy whatever! why? why? why would you take a fine function with established name and rename it to a haphazardly named operator of unknown precedence and associativity?
07:32tdammers(<*>) :: f (a -> b) -> f a -> f b
07:33tdammersi.e., it takes a pure function and converts it into a function that works on the same types wrapped in some applicative
07:33hyPiRionTMA: Because f <$> a <*> b is easier to read sometimes.
07:33ianhedoesitthat's another question. so in the above example of `(+) <$> Just 1 <*> Just 2`, is `(+) fmap Just 1 <*> Just 2`?
07:33ianhedoesitequivalent*
07:33TMAianhedoesit: no
07:34tdammersfmap (+) Just 1 <*> Just 2
07:34ane<$> is defined as an infix operator
07:34TMAyou would need to wrap the fmap in `fmap` backticks
07:34aneif you did (+) `fmap` ... that would work
07:34ianhedoesitoh, I see.
07:34ane(backticks make anything act as infix)
07:34ianhedoesityeah, I remember that now.
07:34tdammersthe reason why applicative syntax is so popular is because of the similarity between pure function application and applicative function application:
07:34tdammersf x y ==> f <$> x <*> y
07:35tdammersthe first calls f on two pure values; the second one calls the same function on two values in some applicative functor and returns the result back into it
07:35tdammersthe function itself is blissfully ignorant of the functor's plumbing
07:36tdammersand you can write the whole thing almost like you would write pure code, except that the functor takes care of handling effects for you
07:36tdammerse.g., I/O, failure, iteration, etc.
07:36tdammersit's kind of like taking function application to a higher abstraction level
07:37tdammers(hence the name "applicative functor")
07:37TMAand then you come across ((.) <*>) and you give up on haskell
07:37tdammerswell, of course all of these features can be abused into academic obscurity
07:37MasseRTMA: you can always overdo stuff, but that syntax isn't really recommended :)
07:41TMAI have learned haskell in 2001 or 2002 IIRC; the simple typing rules have stuck in my head [the not so simple have gone]. I have tried to get back to Haskell since the last year, but I consistently hit the wall
07:42TMAmost of the "new" stuff seems to be heavily fond of avoiding alphabetic characters and parentheses, except to turn the operators into their prefix form
07:44MasseRTMA: Ignore everything about lens and it will be much, much easier
07:44mungojellyyeah i like the ideas about typing but i don't quite understand or even believe that the perl syntax has anything to do with them
07:49MasseRsomeString & allVersions %~ succ
07:49MasseRas an example
07:50MasseRBut really, avoid them :)
07:56ianhedoesitwell I've learned a lot about everything other than Clojure tonight.
07:56ianhedoesitso thanks everyone for that. :)
07:59clgvaleph question: My IdleStateHandler does not fire IdleStateEvents on the client side - but on the server side it does as expected. What might be wrong there? The pipeline is set up the same way on client and server.
08:01clgv$seen ztellman
08:11tdammersanyway
08:11tdammersthe thing I'm missing the most, I think, is the ability to step in at any point in the code and have the compiler figure out the shape of the data I can expect at that point
08:29crocketDoes clojure enable mediocre programmers to maintain programs of 10k lines or even 100k lines?
08:29opqdonutno programming language enables that
08:30opqdonutdevelopment processed do
08:30opqdonut*processes
08:30damethos+1
08:31muhukI'd expect 100 kloc programs written in blub to be 5~10k when written in Clojure
08:32mavbozocan clojure enable mediocre programmers to create programs of 10k lines before they give up?
08:32clgvmavbozo: yeah, copy & paste ;)
08:33clgvthat's language agnostic
08:33crocketWhat is the economic tradeoff?
08:34crocketmuhuk, If you're correct, would a C++ program of 140k lines can be written in 7-14k lines?
08:34crocketouch
08:34mavbozoi assume mediocre programmers just sprinkle defs everywhere even inside function, or even using atoms as plain-old variables
08:34crocketIf you're correct, would a C++ program of 140k lines be written in 7-14k lines?
08:34mavbozoeffectively create imperative programs with clojure
08:35crocketmavbozo, That would be terribly programmers.
08:35crocketI am a mediocre programmer, and I don't write that kind of code.
08:35crocketterrible*
08:36crocketI couldn't have written such a beautiful snippet of code as https://github.com/crocket/clj-ddns-client/blob/master/src/clj_ddns_client/core.clj in java or javascript.
08:36crocketEven, a mediocre programmer can write such beautiful codes in clojure.
08:37muhukcrocket: I'm generalizing. But yes.
08:37crocketmuhuk, If it includes test codes, wouldn't it double?
08:37crocket7-14k -> 14-28k
08:37crocketOr, does it include tests?
08:37muhukpossibly more than double
08:38crocketTest code is code
08:38muhuksometimes my tests are 5 times LOC
08:38muhukI wouldn't included test code when I'm sizing up my codebase.
08:38crocketI could probably get less LOC in haskell or OCaml if you include tests.
08:39crocketYou have to maintain tests as well
08:39crocketSince I'm a mediocre programmer, I don't know what functions I should test in clojure.
08:40xcvI think it's more a matter of the paradigms people are used to. Imperative + OO is pretty complex to wrap your head around, compared to FP.
08:40crocketSome of them just look like internal details
08:40xcvIt's easy to forget what it was like to learn imperative programming.
08:40xcvJust my two cents.
08:40crocketImperative programming is straightforward.
08:40crocketOO isn't.
08:41xcvYeah, it is. And if the approach is "hack at it until it works" instead of writing something you basically understand, it can seem quite a bit easier.
08:43crocket14*5 = 60k
08:43crocketYOu don't save much LOC
08:44crocket30k? maybe
08:44tdammerstest code is code, period.
08:45crocketperiod
08:45tdammersin fact, I believe that to get a fair comparison, one should also include the necessary documentation
08:45crocketIf a C++ program has 140k lines of code, how many LOC would a clojure equivalent including tests have?
08:45crocketoh, documentation
08:46tdammerswhich, granted, would be favorable for underdocumented codebases, so one would have to come up with a metric for "sufficient documentation"
08:46tdammersbut the reason I'd want to include documentation is similar to why I'd include tests
08:47mavbozo"everything is an expression" and immutability effectively forces clojure programmers to write code in less imperative style and more towards functional style
08:47tdammersmavbozo: it's very easy to opt out of either though
08:47spaceplukcrocket: wild guess 1/10th of that if you don't need to call a lot of native code
08:48tdammersmavbozo: clojure has immutable values, but almost all the other side effects are completely uncontrolled
08:48muhukremove the test code and your program works fine. Similar to generated code/files, test code is second class to actual code.
08:48crocketspacepluk, including tests?
08:48spaceplukcrocket: and assuming it's written in a functional way not just copy the c++ code in clojure
08:49spaceplukcrocket: do you need to mock a lot of things?
08:49crocketmock what kind of things?
08:49spaceplukcrocket: servers, databases, etc.
08:49crocketI don't know
08:49crocketyet
08:50jsabeaudryIs there a way to not resolve a symbol in a backquote context?
08:50spaceplukeither way pure functional code is easier to test
08:50muhukoh, wait. I forgot to say "period".
08:50muhukperiod.
08:50crocketSomeone wrote a set-theoretic database in C++ of 140k lines including tests. I was just wondering how many LOC I can save with clojure.
08:51TMAjsabeaudry: `(... ~'a ...)
08:51crocketIt's like NoSQL.
08:51jsabeaudryTMA, oh sweet, thanks!
08:52crocketspacepluk, ^^
08:52mavbozotdammers, what's the state of the art of controlling side effects? static typing?
08:52TMAcrocket: it depends heavily on the style it is written in
08:52spaceplukcrocket: I'm sure it will be shorter and be simpler if done right
08:53crockethmm....
08:53taylanubmavbozo: usually just not using side-effecting operations, I believe. :-) and monads I guess.
08:53spaceplukcrocket: at least you get rid of all the c++ boilerplate, build system etc.
08:53crocketHis code is full of templates which he was proud of because templates fit his needs.
08:54TMAmavbozo: or a pure language like haskell
08:54crocketIs monad common in clojure?
08:56muhuknope
08:56tdammersmavbozo: in clojure? I don't know; "discipline" and "naming conventions", I believe
08:56tdammersmavbozo: Haskell uses the type system... the traditional approach is to use monads (or, as the case may be, functors or applicatives)
08:56spaceplukyou don't really need monads as bad as in haskell
08:56tdammersspacepluk: you do, but you can keep them implicit
08:57crocketSince I don't know monads, I don't know if I need them.
08:57tdammerscrocket: you are already using them, they're just not formalized
08:57spacepluktdammers: yeah, I mean for side-effects and that kind of stuff
08:57tdammersspacepluk: monads and effects are somewhat orthogonal
08:58spacepluktdammers: what I mean is that you don't need monads to wrap side-effects in clojure
08:58tdammershaskell doesn't have side effects at all
08:58spaceplukwhich makes your life easier if you're careful hehe
08:58tdammersjust effects
08:59tdammersbut anyway
08:59crocketHas any of you used typed clojure? How was it?
08:59tdammersyou don't need monads for that in haskell either
08:59tdammersyou do need types that encode effects, though
08:59tdammersand those types almost always happen to be monads
09:00mavbozotdammers, state of the art in programming world. In clojure, I resort to some patterns that is described here http://www.infoq.com/presentations/Clojure-Design-Patterns
09:00crocketOk
09:00tdammersmavbozo: ah, ok... I'm not sure about that, but I believe most approaches treat effects individually, building separate features for each into their languages
09:01spaceplukcrocket: are you familiar with other lisps?
09:01tdammerse.g., exception handling for failures, comprehensions for lists, "something" for I/O, const-ness checks for mutability, thread control for concurrent mutability
09:01crocketspacepluk, no
09:02crocketI know a little of emacs lisp, though
09:02tdammersbut there are a few approaches that try to generalize effects into a uniform pattern
09:02spaceplukcrocket: I would keep it simple and skip types at the beginning
09:02crocketIs there a better way to handle logging than mutating the global logging configuration in a namespaced var?
09:03crocketIt is not pure
09:03crocketI tried to separate logging from business logic, but you can't attach hooks onto protocol methods and multimethods.
09:04spaceplukcrocket: a macro might help there
09:05crockethow
09:05crockethttps://github.com/technomancy/robert-hooke/ doesn't work on protocols
09:05crocketI tried to add logging as a post hook.
09:06crocketspacepluk, Can you show me how macro helps?
09:06spaceplukI'm not familiar with that library
09:07spaceplukbut I guess you can make a macro that calls the logger to define the implementations
09:26crocketOi
09:28dstocktonOi
09:42clgvio
09:45jonathanjis there something like readthedocs.org for Clojure projects?
09:45muhukno. But RTD is language agnostic.
09:53patrkrishi there. is it possible somehow to make leiningen change the settings in logback.xml when building for production?
09:55justin_smithpatrkris: for one thing, you could have a different :resources-paths setting for the build
10:02patrkrisjustin_smith: oh yeah, good idea. how come you always have the time to help? :D
10:08visofhi guys
10:12justin_smithpatrkris: I'd probably find the answer to that question depressing
10:12crocketI realized there are only a few common types to go with in clojure.
10:12crocketMap, list, vector, and set
10:12crocketSo, you don't worry much about types
10:12visofwhat is the best solution for this: i have a record Foo with :x and :y fields, and i want to apply function f on all elements in this Data structure, #Foo{:x (#Foo{:x (p1 p2 ...) :y (p1 p2 p3....)} ...) :y (#Foo{:x (p1 p2 p3...) :y (#Foo{...})})
10:13visof?
10:13crocketTypes generated by defrecord are sort of treated like maps
10:13crocketIf defrecord types are not treated like maps, they are type-checked during compile time.
10:14crocketHow convenient.
10:14visofspecial_map function (special_map function datastructure) ?
10:14crocketPartially typed
10:14justin_smithcrocket: they are maps, as much as any of the other clojure types implementing the interface
10:14crocketDynamic typing is not as painful when all types are map, list, vector, and set.
10:14crocketsort of
10:16taylanubI find dynamic typing never painful. static typing on the other hand...
10:17ToxicFrogcrocket: the problem there is that "map" covers infinity types. If you pass a map that is a lookup table of userIDs to user info structs to a function that expects a map that is a user info struct, you're going to have a bad time.
10:17ToxicFrogBut they're both the same type!
10:18ToxicFrogDynamic typing in and of itself isn't painful, but debugging type mismatch errors that only occur at runtime far from the point of error absolutely is, and if core.typed actually worked I'd be using it for all of my clojure work.
10:18crocketToxicFrog, yes
10:18crocketI guess that's where haskell shines.
10:18crocketor Ocaml
10:23tdammersinteresting... I find dynamic typing painful as soon as the codebase reaches a fairly benign complexity level
10:57skeuomorfDoes core.match allow function applications when matching? e.g. execute `f` if the pattern is "x"?
10:57skeuomorfs/applications/application
10:58clgvskeuomorf: on the selected branch? why not?
10:59skeuomorfclgv: Yeah, on the selected branch, skimming the examples and I didn't see similar usage, so was wondering
11:00clgvskeuomorf: just try it ;)
11:00skeuomorfclgv: can't afford to spawn a repl currently :)
11:00clgvlein try core.match x.y.z
11:19spaceplukis it just me or package management in java is completely broken? :(
11:20spaceplukevery time I add a new dependency I need to track down incompatibilities with joda-time jackson or that kind of libraries
11:20spacepluknpm feels like alien technology compared to this
11:20muhukspacepluk: package management in _ is completely broken
11:20rhg135It's pretty nice compared to say c
11:20spaceplukrhg135: that's true
11:22spaceplukmuhuk: this wouldn't happen in node/npm because each module can depend on a different version of the same library
11:23spaceplukI don't think you can do that in the jvm
11:23rhg135As for npm, try upgrading/downgrading node and watch the native module build failures
11:23muhukspacepluk: I don't think that's a good idea.
11:23spaceplukrhg135: yeah, you need to wipe the cache node_modules in that case, but you don't need to do package manager work yourself, tracking down versions, etc.
11:24rhg135Sometimes they just won't build
11:24spaceplukmuhuk: why not? I'm having this problem because of implementation details of different libraries
11:25spaceplukrhg135: I guess you can't fix c package management hehe
11:25rhg135Sad but true
11:27spaceplukI'm trying to use storm/kinesis-storm-spout/amazonica/monger together, I looked great on paper
11:28skeuomorfspacepluk: oh npm is horrible, maybe not as horrible as Java though, I like nix and guix and in terms of languages, Cargo is great (Rust's de-facto package manager)
11:28muhukspacepluk: because there's no guarantee the effects of having two versions of the same lib will be isolated like that.
11:28spaceplukmuhuk: yeah, but that's a jvm limitation right?
11:28spaceplukskeuomorf: yeah, cargo is very nice
11:30rhg135Aren't classloaders meant to isolate classes?
11:31spaceplukrhg135: I thought about that, but in this case with storm/thrift's serialization I don't think I can
11:32rhg135I've never used either, please explain
11:32spaceplukso I'm trying to find a combination of versions that can work together, hence my frustration
11:33spaceplukstorm is a distributed realtime computation framework
11:33muhukspacepluk: why would you say that?
11:33spaceplukthe computations must be serializable so that storm can send the code through the cluster
11:34spaceplukI don't think I can control how storm loads the classes
11:35spaceplukmuhuk: what? sorry
11:35rhg135Doesn't it use Class/forName?
11:36muhukspacepluk: why do you think it's a jvm limitation?
11:36rhg135Unless it does weird stuff with Unsafe
11:36muhukspacepluk: suppose you call f & g in your code. Both of which in turn calls different versions of h
11:36spaceplukmuhuk: yeah, you're right you can load the same thing in different classloaders, is a limitation of my usecase I guess
11:37muhukspacepluk: how would you compare the results of h?
11:37spaceplukmuhuk: I think that's ok if h-stuff is not exposed through f&g interfaces
11:37muhukspacepluk: yeah, I was speaking in general terms. Having two versions of the same lib is a bad idea.
11:37muhukspacepluk: it's not OK though, if it's exposed.
11:38spaceplukmuhuk: I feels like the simplest solution for this specific case though, I just don't think I can do it
11:38spaceplukmuhuk: agreed
11:39muhukspacepluk: I too wish maintainers would keep releasing with updated deps often. It would make it a lot easier to align such dependencies then. (more options to choose)
11:39spaceplukhow do you deal with this situations? is there any tool I can use to find combinations of versions?
11:40spaceplukmuhuk: yeah, I didn't expect so much pain, I've been away from jvm development for quite a long time, and had high expectations about maven and friends
11:40muhukspacepluk: I exclude the older lib, sacrifice the goat and keep my hands inside the vehicle at all times.
11:40spaceplukhahaha
11:41spaceplukis there something like pactree for maven?
11:45muhukspacepluk: lein deps :tree ?
11:45rhg135https://github.com/flatland/classlojure
11:46spaceplukmuhuk: that's great thanks
11:46muhukyw
11:51spaceplukrhg135: that sounds cool thanks, but first I'm gonna try to avoid messing with the class loaders
11:52spaceplukhopefully there's a combination that can work
11:52rhg135Old versions of software make me cry at night
11:53rhg135It makes me feel if I have a bug people will not upgrade till much later
11:53spacepluksame here :(
11:54spaceplukI'm stuck with clojure 1.6 because of storm ¬¬
11:54rhg135It makes programming harder
11:55rhg135Have to be loose in your input
11:55rhg135Stableish api
11:56spaceplukthere should be a very big "dependencies obsolete" flag in every package manager so that people feel guilty and upgrade
11:56spaceplukit's a lot easier when you do it often
11:56rhg135I agree, but sometimes you can't
11:57muhukspacepluk: lein ancient
11:58spaceplukmuhuk: I tried that with this libs it broke everything hehe
11:58rhg135But that's optional :-P
11:58muhukspacepluk: define broke
11:58spaceplukthe same problem I'm having now basically
11:59spaceplukit just breaks at different points
11:59muhukspacepluk: I don't get it. It just reports libs that has newer versions.
11:59spaceplukI had a working combination, but then added amazonica and started to dance again
12:00spaceplukmuhuk: yes, my problem is that the libs I'm using depend on different incompatible versions of the same thing joda-time, jackson, and utility stuff like that
12:02muhukspacepluk: ok, you've probably already figured this out. But FWIW I set the latest versions, and downgrade one by one until I find a working combination.
12:02spaceplukin the end I might need to fork one, I'm not sure how to do that with lein/maven
12:03spaceplukmuhuk: :_( yes
12:10spaceplukmuhuk: rhg135: thanks for you help, at least now I don't feel stupid
12:10rhg135Np
13:05mavbozoi use mysql db and suppose I want to deliver this request "Give me a list of phone numbers of people who called in the last 4 days, whose call wasn’t answered and had never called us before"
13:05mavbozousually, at first, I just create a function to wrap the query and parametrized the number of days
13:05mavbozo (defn phone_numbers_of_people_who_called_in_the_last_N_days_and_call_not_answered_and_never_called_before [db N] ...)
13:05mavbozois it usual to wrap such query in a function with long name? or are there any other alternative?
13:09sobeltons of alternatives
13:09sobeluse a shorter name
13:10sobelthat is ridiculous. also, hyphenate not underscore, if you want to be fashionable.
13:10sobelthat fn name seems to be the spec of the query
13:11sobelpersonally, if it's that important, i'll make a sql function/procedure and mirror it with a clj fcn of similar name.
13:15mavbozooops, i still use old php, js function naming style. old habits die hard.
13:17sobel- is an operator in most languages. fortunately clojure has not operators.
13:17sobelso lisp(s) are gonna be the odd ones out, using -
13:20mavbozostill, i find it really hard to find shorter-meaningful names for query functions that satisfies many specific criteria
13:20sobelstrict fn naming criteria sounds like like a self-injury to me
13:20sobeli don't seek meaning from fn names. just reference value.
13:27mavbozosobel, how do you name your query functions then? do you have some rule of thumbs based on your experience?
13:28oddcullymavbozo: why don't you name it what biz calls them? these are just the where clauses put togehter. you could as well name it select_star_from_phonenumbers_where_...
13:39spaceplukmavbozo: you can also make a small dsl to build the queries via function composition
13:39spaceplukI'm sure somebody already did that
13:41mavbozooddcully, in most cases the biz has these names, but when they don't have ones, i use long name for the functions
13:41spaceplukmavbozo: maybe name the function after the reason you need to make the query?
13:43spaceplukmavbozo: or use a shorter more general name and put filters as named parameters
13:43spaceplukI would hate running into a name like that hehe
13:48sobelmavbozo: i call them something short but related to their behavior
13:49sobelexample: i had a recursive query that calculated and ordered script dependencies. it did a lot of different things but ultimately, it delivered ordered dependencies. it got named get-ordered-deps.
13:49skeuomorf,(defprotocol MyProtocol (mutate [this]))
13:49clojurebotMyProtocol
13:49sobelit's a workhorse query. i deleted SO much procedural code after that query took over its job.
13:50sobelbut it doesn't need a fancy name.
13:50mungojellyis this shortness fetish really appropriate, code is read a lot more than it's written, i'd rather read code written in whole words instead of using my actual brain guessing what "ch" and "prob" and stuff mean.
13:51skeuomorf,(defrecord MyRecord [mymap] MyProtocol (mutate [this] (set! (. this mymap) (assoc mymap :hello 2))))
13:51clojurebotsandbox.MyRecord
13:51sobelfetish implies that it's an aesthetic (sexual!) preference. it's actually very practical.
13:51skeuomorf(def x (MyRecord-> {:nah 1}))
13:51mungojellypractical how? please don't say efficiency of typing :/
13:51sobelbut it's optional, if you don't like it, go ahead and type those long names you love to read
13:51skeuomorf,(def x (MyRecord-> {:nah 1}))
13:51clojurebot#error {\n :cause "Unable to resolve symbol: MyRecord-> in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: MyRecord-> in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: MyR...
13:51sobelit's quicker to read
13:52skeuomorf,(def x (->MyRecord {:nah 1}))
13:52clojurebot#'sandbox/x
13:52sobelmy editor can autocomplete them but i'll be damned if i want to LOOK at code with over-length identifiers
13:52skeuomorf,(x)
13:52clojurebot#error {\n :cause "sandbox.MyRecord cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "sandbox.MyRecord cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval157 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval157 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval157 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java...
13:52skeuomorf,(mutate x)
13:52clojurebot#error {\n :cause "sandbox.MyRecord cannot be cast to compile__stub.sandbox.MyRecord"\n :via\n [{:type java.lang.ClassCastException\n :message "sandbox.MyRecord cannot be cast to compile__stub.sandbox.MyRecord"\n :at [sandbox.MyRecord mutate "NO_SOURCE_FILE" -1]}]\n :trace\n [[sandbox.MyRecord mutate "NO_SOURCE_FILE" -1]\n [sandbox$eval181 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval181 ...
13:52mungojellyit's quicker to read made up shorthand than actual words? hm kwl id, fn w/lgwg
13:52skeuomorfWhat's going on here? ^
13:52spaceplukI appreciate when code fits in 80chars
13:52sobelmungojelly: if you make up shorthand that lame, you deserve what you get
13:53sobelmungojelly: do you code?
13:53spacepluknames like that make that impossible
13:53sobelyou're always here dumping on traditions evolved by years of practice and preference without any useful suggestions of what would actually be better
13:53sobeleven less evidence of why you think these things
13:53sobelso i wonder
13:54mungojellyit seems to me a lot of these short names are "obvious" once you've simply steeped in this culture for a decade. i can usually guess them. but i use my brain doing that and it excludes newbies.
13:54sobeland making a ridiculous extreme out of a very reasonable idea, just so you can make fun of it, is pathetic and rude.
13:54sobelno one suggested unreadable or "made up" shorthand except you, for the purpose of belittling a reasonable idea of not making identifiers so long
13:55sobelso, i've been using clojure for commercial code less than 6 months, but the nomenclature was pretty obvious from day one. i'm not sure why you think it takes 10 years unless you're unfamiliar with coding.
13:56sobelwhich is ok, i'm just curious
13:56sobelthis is a good place if you code and need a little support on the language or approaches. i come here for that. i don't understand why you're here, though.
13:56mungojellyobviously there's some balance between length and clarity somewhere. of course this level of shortness makes sense to people here, that's why it persists. but it's talking like this in a world of people who'd like to program with us but can't that feels rude to me.
13:56hiredmanskeuomorf: a few things, but regardless of the other things, that will never work because mymap is not mutable so you cannot use set! to change it
13:57sobelmungojelly: it's not a big deal.
13:57sobelmungojelly: as matters of programming goes, this isn't. it's just a social question, unless you're trying to exceed the min or max bounds for identifier length.
13:58skeuomorfhiredman: hmm, I think? I should probably use an atom and swap its value
13:58mungojellysure it's "just" a social question, just a question of how many and which kind of people are able to read the things we write.
13:58sobelmungojelly: bullshit.
13:58skeuomorfhiredman: An atom holding a map and swap that map with the new map
13:59sobelmungojelly: if you write something, you get to determine what the identifiers are. most people like their work product to be commonly acceptable.
13:59sobelmungojelly: let me know how those long ids work out for you when you code with an eye for passing review, peer acceptance, or maintenance by others.
14:00sobeluntil then you just don't get a say because you're proposing telling others how to do things you don't even yourself do
14:00sobelbe done
14:00hiredmanthere is some syntax to mark fields as mutable
14:01hiredmanbut an atom is going to be nicer to use so I would recomend using that
14:02hiredmanthat compiler error isn't actually related to the mutable field thing, but if you solved the compiler error you would hit the mutable field thing, and atom would deal with both
14:04kungiI have the strangest of strange bugs. When I run my web application through the cider emacs repl I get each line of log output exactly once as it should be. When I run it through lein repl on the commandline I get each line exactly three times. The logger currently just uses println. O.o
14:05hiredmankungi: cider opens a few emacs buffers, and while some output gets directed to the repl buffer, other output can end up in other buffers
14:06hiredmanso you maybe printing 3 times in cider too, and the output just ends up in one of the other buffers
14:07mavbozosobel, oddcully spacepluk, mungojelly thank you for the perspectives and insights
14:07kungihiredman: just had a look in every buffer. It doesn't look like there is any stray debug output there.
14:11oddcullymavbozo: naming it get-missed-opportunities-phone-numbers makes it easier to compose it internally and don't have it's name beeing wrong after each change in the underbelly
14:14justin_smith,(defmacro define-function [& body] `(defn ~(symbol (clojure.string/join \- (flatten body))) ~@body))
14:14clojurebot#'sandbox/define-function
14:14justin_smith,(define-function [x] (+ x x))
14:14clojurebot#'sandbox/x-+-x-x
14:15justin_smith,(x-+-x-x 2)
14:15clojurebot4
14:15kungihiredman: https://github.com/clojure-emacs/cider-nrepl/issues/266
14:18mavbozooddcully, that's a good name
14:19mavbozojustin_smith, :-D
14:23skeuomorfhiredman: I see
14:37skeuomorf,(defrecord MyRecord [mymap] MyProtocol (mutate [this] (swap! mymap (assoc @mymap :hello 2))))
14:37clojurebot#error {\n :cause "Unable to resolve symbol: MyProtocol in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: MyProtocol in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: ...
14:38hiredmanthat call to swap is incorrect
14:43skeuomorfhiredman: Yeah, hastiness in editing the weechat buffer :)
15:30zxcHello! How can I change this so it won't give me a lazy seq? I want just a string
15:30zxchttp://lpaste.net/142497
15:32oddcullyzxc: (apply str...) e.g.
15:32zxcoddcully: Thank you!
15:56sagaxhi all!
15:57sagaxi new be in clojure
15:57sagaxbut interesting,
15:57skeuomorfsagax: Hi!
15:57skeuomorfsagax: Welcome :)
18:34trisswhen using ArrayMaps apparently "Subsequent assoc-ing will eventually cause it to 'become' a hash-map."
18:34trissthat kinda sucks doesn't it?
18:34trissI really would like a nice array map...
18:35trissand when i say something's an array-map i want it to stay that way
18:37ianhedoesitI'm confused.
18:38trisshttp://clojure.org/data_structures#Data Structures-ArrayMaps
18:40ianhedoesitright, but it won't actually change the type of whatever collection you have. if you need to ensure it's an ArrayMap you can just do (array-map (assoc initial-array-map :keys [values])), no?
18:41trissum... yeah i think i could. might have to jus for safeties sake in what I'm p to
18:41trissthanks ianhedoesit
18:41ianhedoesityou certainly can.
18:42ianhedoesit(apologies for the long example to follow)
18:42trissmaybe i should just use a vector of key value pairs though
18:42ianhedoesit,(type (assoc {} :a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9 :j 10))
18:42clojurebotclojure.lang.PersistentHashMap
18:42ianhedoesit,(type (assoc {} :a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9))
18:42clojurebotclojure.lang.PersistentArrayMap
18:42ianhedoesit,(type (array-map (assoc {} :a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9)))
18:42clojurebotclojure.lang.PersistentArrayMap
18:43ianhedoesitwoops, the last one should add another kv pair, but either way, the explicit call to array-map will make it an ArrayMap.
18:43ianhedoesita map with more than 10 key value pairs will be a HashMap because it's more efficient than an ArrayMap at that point.
18:44trissyup... i understand why HashMap might be implemented that way behind the scenes
18:45trissbut this is a bit bonkers if you ask me...
18:45trissalso if i cast the hash map i get given back by the assoc i'll have lost the ordering wont i?
18:45trisswhich is what I'm after
18:52rhg135on a tangent, if I wanted to use this logic to build at runtime (ala (apply f ...)) is that possible?
18:53ianhedoesittriss: why do you want a sorted map in the first place?
18:54trissah so I've got these maps... and I want to derive values from other values if they aren't specified...
18:55trissi put functions in these maps to derive them...
18:57trissand some of these values depend on other values that derived via funcions
18:57clojurebotIt's greek to me.
18:57ianhedoesit that sounds complicated and I don't understand why a sorted map is required.
18:57trissit kind of is...
18:57ianhedoesitbut I'm not going to be here long enough to help, unfortunately. good luck.
18:57trissthanks man
18:58trissso am I the only one that thinks this behaviour is potentially confusing?
18:59TEttingertriss: would an ordered map be a better fit?
18:59trissthe array-map becoming a hash-map thing?
18:59TEttingerno
18:59TEttingerhttps://github.com/flatland/ordered
19:00trissTEttinger: BOOM! thanks man
19:01rhg135It's rather nice to have optimized maps
19:01TEttingertriss: if you were relying on either array maps or hash maps having a consistent iteration order, that's probably a bug. I haven't used flatland/ordered yet, but I now strongly prefer using ordered collections in Java
19:02TEttinger(try iterating through a java.util.HashMap in Java 7, and in Java 8. different order just about every time. then try with a LinkedHashMap, same order. the latter is the behavior of ordered maps)
19:02trissno array-maps are documented as having consistent order.
19:02TEttingeryes, but they also have a maximum size, I think
19:02trissyup ten....
19:04trissit seems quite an easy thing to get confused about... I homestly thought an array-map would just stay an array map when i first saw it...
19:04trissAnd stuff changing type based on size seems nuts to me.
19:05trissyes. do it behind scenes for performance....
19:05trissbut just tell me you're a HashMap...
19:06trissdo other types change like that in Clojure?
19:06TEttingersorta. Integer can promote to BigInteger if you use the promoting math fns. * won't promote, but *' will
19:07TEttinger,(reduce * (range 20 200))
19:07clojurebot#error {\n :cause "integer overflow"\n :via\n [{:type java.lang.ArithmeticException\n :message "integer overflow"\n :at [clojure.lang.Numbers throwIntOverflow "Numbers.java" 1501]}]\n :trace\n [[clojure.lang.Numbers throwIntOverflow "Numbers.java" 1501]\n [clojure.lang.Numbers multiply "Numbers.java" 1867]\n [clojure.lang.Numbers$LongOps multiply "Numbers.java" 467]\n [clojure.lang.Numbers ...
19:07TEttinger,(reduce *' (range 20 200))
19:07clojurebot32416343309932862480078063450197751286360345254602064903101245078980649624910495919277583333729267927978044287550245689991180639587939195917412832736019999345923394479196148258074227897996791388337336270220011364475288934580843359607845024722273008686295523615766901687120288519406781073348991324061273932221644800000000000000000000000000000000000000000000N
19:07TEttingernote the N, which is a BigInteger
19:07TEttinger,(reduce *' 1.0 (range 20 200))
19:07clojurebotInfinity
19:07TEttingerha
19:07TEttinger,(reduce * 1N (range 20 200))
19:07clojurebot32416343309932862480078063450197751286360345254602064903101245078980649624910495919277583333729267927978044287550245689991180639587939195917412832736019999345923394479196148258074227897996791388337336270220011364475288934580843359607845024722273008686295523615766901687120288519406781073348991324061273932221644800000000000000000000000000000000000000000000N
19:08TEttingerit doesn't need a promoting fn if it's already a BigInteger
19:08TEttinger,(reduce * 1M (range 20 200))
19:08clojurebot32416343309932862480078063450197751286360345254602064903101245078980649624910495919277583333729267927978044287550245689991180639587939195917412832736019999345923394479196148258074227897996791388337336270220011364475288934580843359607845024722273008686295523615766901687120288519406781073348991324061273932221644800000000000000000000000000000000000000000000M
19:08TEttingerM is BigDecimal
19:08Frozenlo`I'd prefer if * was automatically promoting. (Wasn't it like that before?)
19:08TEttingerit was. it caused performance problems
19:09TEttingerit was changed back in 1.1 or 1.2 or so?
19:09TEttingerthere's also the unchecked-whatever fns, not sure when they were added
19:09TEttingerwhich do the standard java behavior of not throwing exceptions on arithmetic overflow
19:10TEttingerand just doing weird stuff to the bits
19:10Frozenlo`Screw perfomance :-p
19:12TEttingerFrozenlo`: just for you:
19:12TEttinger,(alter-var-root #'* *')
19:12clojurebot#error {\n :cause "Cannot cast clojure.core$_STAR_ to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "Cannot cast clojure.core$_STAR_ to java.lang.Number"\n :at [java.lang.Class cast "Class.java" 3176]}]\n :trace\n [[java.lang.Class cast "Class.java" 3176]\n [clojure.core$cast invokeStatic "core.clj" 338]\n [clojure.core$_STAR__SINGLEQUOTE_ invokeStatic "core.clj"...
19:12TEttinger,(alter-var-root #'* #'*')
19:12clojurebot#error {\n :cause "Cannot cast clojure.core$_STAR_ to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "Cannot cast clojure.core$_STAR_ to java.lang.Number"\n :at [java.lang.Class cast "Class.java" 3176]}]\n :trace\n [[java.lang.Class cast "Class.java" 3176]\n [clojure.core$cast invokeStatic "core.clj" 338]\n [clojure.core$_STAR__SINGLEQUOTE_ invokeStatic "core.clj"...
19:12TEttingersigh
19:12TEttingerI don't remember how it works
19:14Frozenlo`For user-friendliness, I'd argue that * should do the 'obvious' layman stuff, while *' the more machine related perfomant stuff.
19:14TEttinger,(alter-var-root #'* (constantly *'))
19:14clojurebot#object[clojure.core$_STAR__SINGLEQUOTE_ 0x291e9ae9 "clojure.core$_STAR__SINGLEQUOTE_@291e9ae9"]
19:14justin_smithTEttinger: alter-var-root is the same api as swap basically
19:14TEttinger,(reduce * (range 20 200))
19:14clojurebot32416343309932862480078063450197751286360345254602064903101245078980649624910495919277583333729267927978044287550245689991180639587939195917412832736019999345923394479196148258074227897996791388337336270220011364475288934580843359607845024722273008686295523615766901687120288519406781073348991324061273932221644800000000000000000000000000000000000000000000N
19:16TEttingerFrozenlo`: I think also anything that returns different types, with one of them being a primitive or boxed primitive, could be trouble. arraymap and hashmap both implement the same interface, you just return Map or whatever more specific variant they use. I don't think Integer and BigInteger share that?
19:17TEttingerthere's some specialization on certain primitives in a gnarly chunk of clojure's internals
19:36Frozenlo`I have a webserver doing some task each time it receives a POST. Some of them might take some time, and I'd like to organize them in a queue and possibly do some monitoring. Any suggestion for a library?
19:58Frozenlo`To answer my own question (logs), https://github.com/Factual/durable-queue seems to do most of what I asked for.
21:33crocketIf I rewrite a C++ program of 140k LOC, which language between haskell and clojure will result in the least LOC including tests?
21:33crocketOr OCaml
21:34wmealingthis always depends on the task at hand
21:35wmealingyour C++ is likely heavy class oriented, and your clojure application will be data oriented.
21:36wmealingif you're a competent C++ programmer, and a first time other language programmer you likely wont get the advantage of the language unless you know the domain you're writing from very well.
21:37wmealing(trying not to be a downer, just from my personal experience, going from C -> (erlang | clojure | haskell)
21:37wmealing)
21:39wmealingcrocket: what i found as a useful exercise is to find the core of your problem domain, and try to port part of that to your target language and do a comparison on it.
21:39crocketwmealing, Let's assume I have decent expertise in all languages involved.
21:39wmealingok
21:39crocketLet's say I have coded with each of them for 2 years.
21:39wmealingincluding C++ right ?
21:39crocketyes
21:43wmealingi haven't forgotten, just give m e a moment
21:45wmealingok, what i was -planning- to do was take an approach of LOC used in debians benchmark game
21:45wmealinghttp://benchmarksgame.alioth.debian.org/play.html
21:46wmealingi know that doesn't include test cases
21:46wmealingbut it will give an idea of how many LOC for similar problems
21:46wmealingacross multiple problems
21:57wmealingannoyingly there is no single github of source.. they keep it in an issue tracker
21:57wmealinghttps://alioth.debian.org/tracker/?func=browse&amp;group_id=100815&amp;atid=413122
22:22crocketHow do I attach logging to protocol methods and multimethods?
22:39neoncontrailsSay you're using Ring as the HTTP server for a figwheel app.
22:39neoncontrailsDo you boot in figwheel?