#clojure logs

2015-12-22

00:29allhailcaesarIs there a way to make lein check already downloaded dependencies? I'm on a bad connection, and am worried I might be seeing some errors in a project due to connection instability.
01:07chomwittgood morning.
01:08chomwitta newbie question. where is ring.core ?
01:13allhailcaesar@chomwitt are you getting an error that you don't have it?
01:15chomwittno. i'm trying to understand some basic things. http://ring-clojure.github.io/ring/ i dont see any ring.core in tha API
01:15allhailcaesaradding [ring/ring-core "1.4.0] to your dependencies will pull it to your classpath
01:16hiredmanthe docs show namespaces, and there is no ring.core namespace, so it is not in the docs
01:17hiredmanbut there is a maven artifact (a jar) with the group-id `ring` and the artifact-id `ring-core`
01:18hiredmannamespaces and maven coordinates are orthogonal, and can be completely different, but many projects have maven coordinates that are similar to their namespaces
01:19chomwittwhat the diff of including in my project.clj [ring "1.4.0"]] and [[ring/ring-core "..."]]
01:19chomwitt?
01:19hiredmanthe ring artifact will bring in ring-core and some other stuff as dependencies
01:19chomwitthiredman: your explanation i think is some levels above me :-)
01:20chomwitti dont have an idea what a maven artifact is
01:20hiredmanwhat goes in your project.clj are maven coordinates for dependencies (lein grabs stuff from maven repos)
01:20hiredmanchomwitt: basically a jar
01:20chomwittbetter :-)
01:20chomwitta jar brings some bells :-)
01:21hiredmana zip file full of code
01:21hiredmanwhen you see `foo/bar` in project.clj `foo` is what maven calls the group id and `bar` is what maven calls the artifact id
01:22chomwittso why some tutorials use ring/ring.core and others just ring ?
01:22hiredmanif you have something like `ring` lein assumes the group id and the artifact id are the same, so `ring` is the same as `ring/ring`
01:22chomwitthiredman: i see. makes sense nwo
01:22chomwittnow
01:23allhailcaesarchomwitt: This might help you with the practical side of your question, http://kendru.github.io/restful-clojure/2014/02/19/getting-a-web-server-up-and-running-with-compojure-restful-clojure-part-2/
01:24hiredmanthe ring project used to be published as a single ring artifact, but it is now published as a finer grained set of libraries, you can still get everything by depending on `ring`, but you can also depend on smaller parts of ring, like `ring/ring-core`
01:24hiredmanso for tutorials they are likely interchangable
02:54keep_learningHello everyone
02:54keep_learningI am trying to extract the information https://www.refheap.com/112992
02:55keep_learningwhen I am using (map (comp :href :attrs) (list-of-element)) then it return all the links
02:55keep_learningbut I want to extract the :content also
02:56keep_learningso I have written (map :content (list-of-element)) gives me list of list of one element
02:56keep_learningI tried to combined it together
02:57keep_learning(map (fn [x] ( (comp :href :attrs) x, :content x)) (list-of-element))
02:57keep_learningbut getting error
03:04Kneivakeep_learning: (Without looking at the paste): That last anonymous function could be something like (juxt (comp :href :attrs) :context)
03:06keep_learningKneiva, Thank you
03:09Kneivauh, :content instead of :context
05:29keep_learninghttps://www.refheap.com/112993
05:29keep_learningHello everyone.
05:29keep_learningI have list of url links
05:30keep_learningand I want to navigate through all these links sequentially
05:30keep_learningso I can't write (map fetch-page-from-link url-links)
05:30keep_learningI want to do it sequential manner
05:34kungikeep_learning: does fetch-page-from-link have sideeffects? If yes then `doseq` is right for you.
05:35keep_learning(defn fetch-page-from-url
05:35keep_learning "fetch page source/html page from given url"
05:35keep_learning [url]
05:35keep_learning (do
05:35keep_learning (t/set-driver! {:browser :firefox}) ;set this for moment
05:35keep_learning (t/get-url url)
05:35keep_learning (t/page-source)))
05:35keep_learningkungi, Yes but it returns page of url
05:35kungireturning something is not a sideeffect. But set-driver! probably is.
05:35keep_learningI have to process that html page
05:36kungikeep_learning: why are you using `do` here?
05:36keep_learningand (t/get-url url) is also a side effect
05:36kungiprobably yes
05:36keep_learningkungi, For sequential execution
05:36kungikeep_learning: defn and fn also do an "implicit do"
05:37keep_learningkungi, Thank you
05:37keep_learningso I can write (map fetch-page-from-url url-link) ?
05:38kungikeep_learning: as far as I see it yes.
05:38keep_learningThank you
05:38kungikeep_learning: hmm ok wait. Maybe lazyness will screw you there
05:38kungikeep_learning: I would use `doseq`
05:51owlbirdhow to generate q SQL according different parameter pairs. for example, parameters name and department both are optional, (department maybe used to join another table), what the best way to handle this? Do I have to write a long long (cond ..) ?
06:03Kneivaowlbird: I'm not sure I understood the question right. But how about giving parameters in a map and render the SQL from its entries?
06:03Kneiva,(clojure.string/join " AND " (map (fn [[k v]] (str (name k) "=" v)) {:id 12 :name "aa"}))
06:03clojurebot"id=12 AND name=aa"
06:05KneivaAnd I would think there is some library that can do this kind of thing for you.
06:10owlbirdselect * from user u (if department != "") join dept d on u.dept = d.dept and d.name=? (if name != "") where u.name=?
06:11owlbirddepartment/name both are optional parameter, which would be treated like a SQL segment switch, to open/close a logical.
06:20Kneivaowlbird: search for sql abstraction here: http://www.clojure-toolbox.com/
06:25ridcullybanging strings together has a good chance to introduce sql injections - so watch out here
06:26keep_learningHello everyone
06:26keep_learningI have clojure file and want to covert it to jar file
06:27keep_learninghttps://www.refheap.com/112994
06:42keep_learningDo I need to add main in clojure file
06:44KneivaIf you want it to be runnable jar.
06:48keep_learningKneiva, I want to call go-to-tripadv from other java file
06:49poweredif you want to use the jar as a library then you don't need a main
06:50keep_learningpowered, Thank you
06:51keep_learningI have run lein uberjar
06:51keep_learningand it generated the jar in target directory
06:53poweredyou can also run lein jar if you don't want to include dependencies
06:58keep_learningI am getting two jar files
06:58keep_learningtripadvisor-0.1.0-SNAPSHOT.jar
06:58keep_learningtripadvisor-0.1.0-SNAPSHOT-standalone.jar
06:59keep_learningWhich one I should add to java project to fetch go-to-tripadv function
06:59keep_learning?
07:06Kneivakeep_learning: standalone has all the dependencies like Clojure, selenium and other things you use in your clojure code. If you do not have them on the classpath otherwise you should use the standalone jar.
07:08keep_learningKneiva, I have added both the jar file
07:09keep_learningbut having problem in calling the function go-to-tripadv
07:14Kneivakeep_learning: Maybe this helps: http://stackoverflow.com/a/23555959
08:57vyHi all! I am looking at TechEmpower web framework benchmarks: https://www.techempower.com/benchmarks/ Can somebody enlighten me how on earth Compojure can beat Java servlets in the very same benchmarks, given the fact that Compojure depends on Ring, which depends on Java servlets. What am I missing?
09:05hiredmanring and servlets are both interfaces, not implementations, so neither of those things can actually be benchmarked
09:06hiredmanthe servlet api specifies how http can be represented as java method calls, ring specifies how http can be represented as clojure data structures
09:07vyhiredman: I agree, but I would expect Compojure to come after vanilla Java Sevlets, assuming that they are compared using identical servlet container configurations.
09:07hiredmanan adapter exists that allows you to turn serlvet apis in to ring apis, but ring is a spec that doesn't depend on servlets
09:10hiredmanthe ring spec can be implemented (and has been) on other things besides servlets
09:10hiredmanand compojure is built on top of ring
09:12ridcullysince #1 and #3 seems to differ in db, i'd like to see, how compojure there would do with postgres
09:12hiredmanso to benchmark "compojure" as a thing, without specificy compojure + what implementation of the ring spec, doesn't make sense
09:13vyhiredman: The code is available: https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Clojure/compojure/hello
09:17hiredmanvy: if you are comparing it to the servlet-raw numbers of techempower, (which is such a meaningless name, there is no such thing, the servlet api is an interface) then it looks like `servelet raw` is using some other servlet implementation, and whatever servlet implementation the compojure benchmark is using happens to be faster
09:17vyhiredman: Hrm... Thanks for the explanations.
09:19hiredmanthe techempower numbers are really neat, but non-trivial to interpret, and some of the ways the results are presented don't make much sense
09:20vyI think it is just yet another page for comparing apples and oranges. But that's my idea...
09:20hiredmanalioth for http
09:21vyAlioth is measuring/benchmarking more comparable things.
09:23hiredmanalioth is measuring performance of c ffi to libgmp
10:57jcrossley3little_lamb: cool nick, bro
10:58little_lambjcrossley3: I did it JUST FOR YOU
10:58jcrossley3:)
12:20aurelianhello
12:20aurelianwhat's a nicer way of doing this: https://www.refheap.com/113004 ?
12:21aurelianI tend to solve most of this kind of problems with reduce/map/filter, but I feel there must be a better way
12:23yendawith specter maybe
12:23yenda(select [ALL :sources ALL] lolz)
12:23ridcullyis the order important?
12:23aureliannope, order is not important
12:24aurelianyenda -- will check that out thanks
12:25ridcully(into #{} (mapcat :sources lolz))
12:26aurelianoh, wow
12:27aurelianthanks
12:32aurelianand to keep it unique and as a vector is it better to apply distinct and use into [] or convert the result to vec?
12:33justin_smithI'd use ((comp vec distinct mapcat) :sources lolz)
12:34aurelianI'm very comfortable using reduce but somehow in clojure there's always a better / nicer way
12:36mavbozo,(doc mapcat)
12:36clojurebot"([f] [f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection. Returns a transducer when no collections are provided"
12:36mavbozo,(doc distinct)
12:36clojurebot"([] [coll]); Returns a lazy sequence of the elements of coll with duplicates removed. Returns a stateful transducer when no collection is provided."
12:36aurelianyup, is exactly what I doing in that reduce
12:36aurelianmapcat I mean
12:36mavbozoah, justin_smith's version uses transducers
12:37mavbozo,(doc vec)
12:37clojurebot"([coll]); Creates a new vector containing the contents of coll. Java arrays will be aliased and should not be modified."
12:38justin_smithmavbozo: it doesn't actually, but it could probably be converted to do so
12:39mavbozojustin_smith, oh, my mistake
12:39aurelian,(doc comp)
12:39clojurebot"([] [f] [f g] [f g & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."
12:40justin_smith,((comp vec distinct mapcat) :foo [{:foo [1 2 3]} {:foo [2 3 4]} {:foo [3 4 5]} {:bar [42]}])
12:40clojurebot[1 2 3 4 5]
12:41aureliansweet, thanks
12:56justin_smith,(into [] (comp (mapcat :foo) (distinct)) [{:foo [1 2 3]} {:foo [2 3 4]} {:foo [3 4 5]} {:bar [42]}]) ; mavbozo - this is the transducing version
12:56clojurebot[1 2 3 4 5]
12:56mavbozo,(into [] (comp (mapcat :foo) (distinct)) [{:foo [1 2 3]} {:foo [2 3 4]} {:foo [3 4 5]} {:bar [42]}])
12:56clojurebot[1 2 3 4 5]
12:56WorldsEndlessWhat is the syntax for :require :only in an ns statement? I don't seem to be having luck with (:require [ring.util.io :only [piped-input-stream]])
12:57justin_smithhaha, mavbozo did you just come up with the same thing right when I did?
12:57mavbozojustin_smith, zing isn't it? LOL
12:57justin_smithWorldsEndless: I thought it was use / only and require / refer
12:58WorldsEndlessjustin_smith: I'm not managing to parse that sentence...
12:58justin_smithmavbozo: especially because I had to help a coworker with a couple of things before coming back and figuring that out, haha
12:58justin_smithWorldsEndless: (:use [foo :only [bar]]) (:require [foo :refer [bar]])
12:59mavbozojustin_smith, jinx
12:59WorldsEndlessOk; so no :only for refer in ns? (unlike refer http://clojuredocs.org/clojure.core/refer)
12:59justin_smithWorldsEndless: (doc use) mentions :only, (doc require) mentions :refer
13:00WorldsEndlessGuess I'm confused by the first example from the refer clojuredoc page
13:00mavbozojustin_smith, hahaha, took me quite some time to realize that the (comp ...) order is reversed
13:00justin_smithOK, but the args of require aren't given directly to refer
13:01WorldsEndlessAh, I see. My mind was transposing "require" and "refer" ...
13:07qsysI get a ClassNotFoundException when I try to (:gen-class :extends [some.class]) using maven. I have something like (ns my.namespace (:import (some class)) (:gen-class :extends [some.class]))
13:08qsysand I'm using the com.theoryinpractis:clojure.maven.plugin:1.7.1 maven plugin
13:09justin_smithqsys: have you verified that the class you are trying to extend is on the classpath?
13:09qsysfor some reason, the sme.class is not found (it is present in the maven depencies)
13:09justin_smithqsys: you shouldn't need to import, btw
13:09qsysso yeah, I would suppose if it's in the maven dependencies, it's in the classpath (but apparently, it's not :p)
13:10justin_smithqsys: I don't know maven so well, but is there a way to make maven dump the classpath it would use for a given command?
13:10qsysyes, I thought it wasn't needed in the import, but due to the class not found exception, I added it... so I'll remove it
13:10qsyshmm, I'll check for maven
13:11justin_smithqsys: import just changes whether package qualifiers are needed, it doesn't do any class loading magic
13:11qsysallright, makes sense...
13:15qsysnot that much logging/debug info with maven. searching for classpath when running plugins.
13:15justin_smithqsys: what about looking at the command line args when starting a repl?
13:16justin_smithvia ps or whatever
13:18qsysnothing much about classpaths - don't like that
13:20justin_smithqsys: what about 'mvn dependency:build-classpath'
13:22justin_smithqsys: when I run "ps x" it shows the full classpath as specified on the command line of any java command I have running
13:22qsysthen I get the right classpaths - when I add some.class from Java, there's no problem.
13:23qsysyeah, but with 'ps -x', well, I'm not fast enough: I run maven and it's 'immediately' done before I can say 'ps -x' :)
13:23justin_smithqsys: which is why I suggested starting a repl (if needed commenting out the gen-class so the repl runs)
13:23devth_afkthere's a problem i've never had: mvn being too fast :)
13:24justin_smiththe repl should stay running until you tell it to stop
13:24justin_smithhaha
13:24qsysok... thx - lol
13:24qsysI'm a slow speaker :)
13:28qsysall mvn jobs from the plugin don't seem to add other mvn dependencies in the classpath... I'll check that plugin config again
13:30slesterI struggled to get Cursive to actually run my Leiningen project. I ended up having to ragequit and just run things from the command line like I always do. :(
13:34justin_smithslester: that seems like it misses out on a bunch of the benefits of using cursive
13:35j-pbslester: resyncing with lein often helps
13:35slesteryeah, I follow the instructions I found to import a project from leiningen but I couldn't figure out how to get Run to work properly
13:35j-pbthe leiningen tab on the right
13:35justin_smithslester: did you see these docs? https://cursive-ide.com/userguide/leiningen.html
13:35j-pband then the sync symbol
13:35slesterjustin_smith: that's the one I followed, yup :(
13:35justin_smithslester: at what step did it fail?
13:35slesterI'll try again later, but whew. IDEA is just huge and complicated.
13:36slesterI just couldn't get clicking Run to work is all
13:36qsyslein is another option... but it does take more steps to build - I'd rather have it done in maven
13:36slestermaybe I didn't go into the right menu like the one j-pb suggested
13:36j-pbslester: to get run working you also need to configure a repl for example
13:36slesterthe REPL worked
13:37justin_smithqsys: lein is friendlier for clojure specific stuff though (like clojure.test / clojure specific linters / other clojure test frameworks / etc.)
13:37j-pbslester: what didn't then :)?
13:38slesterI don't know how many ways I can say "the run button" :( but as I said, one of my first times using IDEA so I probably did something wrong
13:38slesterbut it was a lot less plug-and-play than I had imagined when people are tweeting about the release of the Cursive IDE for Clojure I guess
13:40ridcullyleft of the run/debug/chronos/... buttons is a dropdown. there you can "edit configurations"
13:41j-pbslester: no but what do you expect the run botton to do? for me a repl would be what I need
13:44slesterlein run?
13:45j-pbhrm, tbh I never use that
13:46j-pbslester: you would probably have to set up a clojure application configuration in intellij then
13:46j-pbhowever
13:46j-pbI don't see a reason for running lein run
13:46j-pbin development mode you want a repl
13:46j-pbin deploy you want a jar
13:46ridcullyme neither. but if i extrapolate from the other build tools, you can either run it once from the (right hand side) lein tab (it there is one) or you should be able to add a configuration with that lein <run> task?
13:47slesterwell, I am a newb so it's probable I'm doing it wrong
13:47j-pbslester: generally when developing in clojure you want to use the repl
13:47j-pbbecause it allows you to hotload code into your program while you develop it
13:50slesterit seems like a big pain to get code in there
13:51MJB47most people have a function in their editor to send code to the repl
13:51slesterlike I have no idea how I'd use it effectively. I usually use the REPL to try out code
13:53j-pbslester: yeah but you can also call your main from there
13:54j-pbslester: and then you can reevaluate parts of the code while its running
13:54slesterI guess I need to watch a video or read some more about it, then.
14:12devthanyone using spacemacs for clojure?
14:12devthhttps://github.com/syl20bnr/spacemacs
14:16TimMc"An Emacs distribution"
14:16rhg135how do you deal with state like open sockets in an evented design?
14:16devthi'm a heavy vim user but thinking about seeing if all my workflows could be ported to spacemacs.
14:17rhg135the kind you can't recreate
14:17TimMcOh dear. Soon we will see a rant parallel to GNU+Linux where someone complains that Emacs is really just the kernel and that $FOO is the toolchain that matters.
14:17justin_smithTimMc: most of emacs is just RMS' .emacs
14:17winkTimMc: it's Emacs/Linux, not "Linux"
14:19justin_smithTimMc: oh, someone could pull an ubuntu, and make an "easy to use" emacs which randomly sends you to amazon.com
14:19TimMcjustin_smith: Ha, so it has already happened.
14:20justin_smithTimMc: some of us still remember the huge Lucid/GNU emacs split (I was too young for the gosmacs / gnumacs split though)
14:21TimMcGNU+Emacs
14:21TimMcI didn't start with emacs until maybe 2010.
14:22justin_smithpart of the motivation for inventing the GPL: https://en.wikipedia.org/wiki/Gosling_Emacs
14:23devthi'm of the opinion that something as core as $EDITOR should be used for near-life in order to approach maximum potential proficiency and familiarity. so switching is a big deal :) but i've only used vim since 2009, and this would still be "vim-nature".
14:25justin_smithdevth: I used vi, then vim, then emacs (back when Viper was the best vi emulation mode available), after many years with emacs I started to get wrist pain so switched to evil (the best current vim emulation mode)
14:25justin_smithspacemacs is built on evil mode
14:25devthnice. right
14:26devthlong term i think emacs is positioned to better support lang workflows. scala in emacs is pretty amazing. clojure in vim and emacs are probably nearly on-par.
14:26devthhaskell in emacs is way better than vim from what i've gathered.
14:26BRODUScan anyone recommend a good resource to learn about core.async
14:27justin_smithBRODUS: have you walked through the official intro?
14:27BRODUSno, im reading the section on braveclojure, im finding its explanations lacking
14:27qsysgen-class again... something really weird: when I use (:gen-class :implements [some.Class]), it compiles, however, some.Class is a abstract class... so when I change it to (:gen-class :extends [some.Class])
14:28qsysI get an ClassNotFoundException
14:28qsysit's not a classpath issue, since it does compile with :implements
14:29justin_smithqsys: maybe this is related to how how abstract classes are implemented in the vm - there are a lot of things that are abstracted one way in java and another in the vm, and clojure as a rule uses the vm's version
14:29qsysam I missing something about :extends and abstract classes (clojure 1.7.0, by the way)
14:32slesteris there a good place to learn about using the REPL to its maximum when developing?
14:37devthslester: some good stuff at http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded
14:44spiedenslester: here's my ~/.lein/profiles.clj https://gist.github.com/spieden/5af1b11cadceaeed83b9
14:44spiedenslester: might be old versions -- haven't checked in a while
14:45slesterdevth: thanks!
14:45slesterand spieden!
15:09BRODUSam i understanding this correctly? (doseq [i (range 10 100)] (go (>! c (blocking-io-function i)))) will create 90 blocking processes, each one put on a thread in my thread pool. Since there are only 6 threads(4 core machine), only 6 processes will be able to execute concurrently.
15:10qsysallright, so :extend in :gen-class doesn't expect a vector - makes sense, a class can only extend one other class (in Java/on the JVM). sometimes things can be a little subtle
15:10justin_smithBRODUS: core.async creates 42+(nprocs*2) threads for its pool
15:11justin_smithBRODUS: but yes, this would lock up all 50 threads, then use more as they are available
15:11justin_smithwhich is why clojure.core.async/thread exists - for when you are doing blocking IO in core.async
15:14justin_smithBRODUS: if you use async/thread, it will return a channel that you can consume, and your go block can properly park and not own a thread (go (>! c (<! (thread (blocking-io-function i)))))
15:15justin_smith*not own a core.async pool thread - of course it still owns a (mostly inactive, blocking on io) thread
15:15benjyz1hi. is it possible to name async channels?
15:15benjyz1I want to implement publish-subscribe to topics
15:18justin_smithbenjyz1: core.async/pub takes a "topic function" - you create your value (probably via a hash-map) so that the topic can be looked up in it. core.async/sub takes a topic as an argument.
15:20BRODUSjustin_smith: i get it, but whats the other kind of thread if its not a core.async pool thread
15:20justin_smithBRODUS: a thread
15:21justin_smithyou can make as many as you want, until the OS stops letting java create more
15:22justin_smithBRODUS: thread pools are useful because they let you reuse threads, which is good for performance, but you can always just make a new thread unless the OS tells you otherwise
15:22justin_smithsee also java.lang.Thread
15:23BRODUSjustin_smith: why would you want to reuse a thread?
15:23justin_smithBRODUS: because it is expensive to make new ones
15:24justin_smithBRODUS: core.async/thread actually uses a cached thread pool so even it can reuse threads https://github.com/clojure/core.async/blob/a6dc01d2ebb692a39e923988b0853ff2bd1a431b/src/main/clojure/clojure/core/async.clj#L420 the definition of thread is a couple blocks down from the pool definition there
15:25benjyz1interesting. a bunch of async functions have been moved to transducers
15:26rhg135but still you are bound by how many the hardware can run at a time, no?
15:26justin_smithbenjyz1: I think the experience of designing and implementing core.async was part of the motivation for making transducers - they realized how much work they were redoing in order to map / filter / etc. on channels
15:26justin_smithrhg135: well, in terms of how many can run, sure, but the question started with a thread that would be blocked for a long duration
15:27justin_smithand that's handled with kernel level context switches and interrupts, it doesn't block a hardware thread (or else your computer wouldn't be very usable)
15:27rhg135ah I see
15:27benjyz1what about message durability? for me the problem is that its far from trivial to wrap TCP semantics in several scenarios
15:28benjyz1Peer-to-Peer networks and security is generally hard to do with TCP
15:28justin_smithbenjyz1: yeah, core.async isn't about TCP or durability
15:28justin_smithbenjyz1: I thought you meant pub-sub in core.async
15:28BRODUSjustin_smith: thanks for the help
15:28justin_smithBRODUS: np
15:29benjyz1yes. I mean pub-sub over the internet via async. I assume both sides run the JVM
15:29justin_smithbenjyz1: core.async as part of implementing pub-sub over sockets is a whole other can of worms, and you're probably better off using kafka and maybe tying that to core.async on your end if you want to use core.async
15:29justin_smithbenjyz1: core.async is not a networking tool
15:30benjyz1yes absolutely, it is a can of worms
15:31benjyz1its kind of reason I'm drawn to Clojure in the first place. doing TCP means in a sense each process can use any language
15:32benjyz1Scala has Akka, and there is a wrapper around it called Okku
15:42spiedeni much prefer core.async/CSP over Akka/Actors
16:33pilneok, clojure has me stumped
16:34BRODUSpilne: whatsup?
16:34pilne(for [i (range 1 10)] (print i)) is returnning: 123456789(nil nil nil nil nil nil nil nil nil)
16:34pilnein the REPL
16:34MJB47what do you want it to output?
16:35pilnethe nils confuse me?
16:35MJB47for returns a lazy seq
16:35BRODUSthe list of nils is the output of for
16:35MJB47of all the returned values
16:35MJB47print returns nil
16:35MJB47if you dont care about the return values
16:35MJB47use doseq
16:35MJB47or dotimes
16:35pilneohhhhhhhhhhhhh
16:35BRODUSthe numbers preceding are side effects of the operations within for
16:38pilnewhereas the for literally returns nothing (nil) on its own
16:40cflemingslester: If you're still having problems with a lein project feel free to ping me if you'd like help
16:41BRODUSfor returns a lazy sequence, each item in the sequence is going to the be result of (print i)
16:41BRODUSprint will print a string but it returns nil
16:43pilnebecause every function has to return "something" to be considered a function?
16:43BRODUSno, print is a function
16:44BRODUSit just always returns nil
16:44justin_smithpilne: the only things in clojure that I know of that do not return something are System/exit and throw (for obvious reasons you never get a return value when calling either)
16:45justin_smitheven using interop with java / jvm stuff, if nothing else you'll get a return value of nil
16:45pilnewell, it might be a bit quirky (for someone like me), but at least it is consistent (:
16:46MJB47well
16:46justin_smithpilne: that's how a lot of things in clojure are - not what you might be used to, but probably more consistent than what you are used to
16:46MJB47its the basis of functional programming
16:47pilneclojure is my first real REPL experience other than haskell, which makes it obvious up-front (in all the tutorials i found) that since it the REPL is inside the IOMonad, it will be quirky. So this is a fun new experience overall for me
16:48justin_smithpilne: yeah, the whole lang of clojure is in "io" more or less - which means source files and the repl are more mutually consistent, but we also don't have the benefit of purity
16:48justin_smithwith the exception of the rarely used io! macro
16:49BRODUSpilne, heres a function that will print your string and return the string you passed in (defn print-with-return [s] (do (print s) (identity s)))
16:49justin_smithpilne: but even in haskell print returns - it's just that you are less likely to get a list of units returned by list processing - you'd get a type error instead more likely
16:49MJB47you can use print-str
16:50justin_smithBRODUS: #(doto % print)
16:50MJB47https://clojuredocs.org/clojure.core/print-str
16:50justin_smithMJB47: that's not a printing function though
16:50justin_smiththat's for getting what print would have printed, but as a string
16:50MJB47wut
16:50MJB47oh
16:50MJB47you are correct
16:50MJB47nvm me
16:50ridcullyi like doto too. it injects easily into existing code
16:51amalloyjustin_smith: well, map print xs :: [IO a], so you might well not get a type error until later
16:51BRODUSnice, haven't seen doto yet
16:51amalloyer, IO ()
16:51justin_smithamalloy: yeah, my haskell is still very weak
16:52amalloyi've been doing the advent of code exercises in haskell
16:52amalloyit's good practice
16:52justin_smithcool!
16:52amalloyhttps://github.com/amalloy/advent-of-code if you are interested
16:52justin_smithI'm going through bitemyapp's book (slowly)
16:52justin_smithcool, I'll need to check that out
16:53pilnemy gf bought me bitemyapp's book for xmas, but i don't get the download key until xmas eve >.<
16:54pilnei was smart enough to not argue when she wanted to wear one of the outfits i got her for xmas yesterday though >.<
16:55pilnewhat can i say, i'm a functional programming junkie, i've even taken an interest in factor lol
17:00tem0p(second [123 1001])
17:00tem0p=> 1001
17:00tem0p(second [123 01001])
17:01justin_smithtem0p: 01001 means "1001 in octal"
17:01justin_smith,0xff
17:01clojurebot255
17:01justin_smith,010
17:01clojurebot8
17:01tem0pjustin_smith: so what does that second statement return?
17:01justin_smithtem0p: I forget, but it's 1001 in octal
17:01justin_smith,01001
17:01clojurebot513
17:02justin_smith,8r1001
17:02clojurebot513
17:02tem0pjustin_smith: Urgggh, so I'll have to change it to ["123" "01001"]?
17:02justin_smithtem0p: if you want it to print with a leading 0, use a format string
17:03tem0pjustin_smith: Ahh good idea, thanks!
17:03justin_smith,(format "%05d" 1001)
17:03clojurebot"01001"
17:04tem0pjustin_smith: I was testing with [513000 01001] and getting 513 back lol, so confusing.
17:04justin_smithahh, yeah I can see how that would be confusing
17:07TEttingertem0p: neat the starting zero for octal is an annoyance in many languages. however, clojure adds a new and interesting thing like starting 0 for base 8 or 0x for base 16...
17:08TEttinger,[2r001001]
17:08clojurebot[9]
17:08TEttinger,[3r001001 4r001001 5r001001 6r001001 7r001001]
17:08clojurebot[28 65 126 217 344]
17:08TEttinger,[13r001001 14r001001 15r001001 16r001001 17r001001]
17:08clojurebot[2198 2745 3376 4097 4914]
17:09justin_smith,36rjustinsmith
17:09clojurebot72595113320300741
17:09TEttingerand my absolute favorite is using 36r to encode arbitrary alnum strings as numbers, yes
17:09tem0plol
17:09TEttinger,36rTETTINGER
17:09clojurebot82974197147859
17:10justin_smith,(> 36rjustinsmith 36rtettinger)
17:10clojurebottrue
17:10justin_smith:P
17:10TEttinger,(> 29rjustinsmith 35rTOMMYETTINGER)
17:10clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "justi">
17:11TEttingereh?
17:11TEttinger,(> 30rjustinsmith 35rTOMMYETTINGER)
17:11clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "justi">
17:11TEttinger,(> 30rjustinsmith 35rTOMMYETTINGER)
17:11clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "justi">
17:12TEttingerohhh t
17:12TEttinger,(> 31rjustinsmith 35rTOMMYETTINGER)
17:12clojurebotfalse
17:12TEttingerwonder why it stopped at i not t
17:12TEttingerI thought you stuck a \ufeff in there
17:14justin_smithnah, the number formatter wouldn't even take that
17:15winkdaily wtf
17:18winksuddenly my joke proposal for 0sqprFFXIV for roman numbers sounds sane.
17:18wink(different language though)
17:18winkand it's spqr of course
17:19justin_smith,(clojure.pprint/cl-format "wink: ~@r" 42)
17:19clojurebot#error {\n :cause "clojure.pprint"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.pprint"\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 [java.n...
17:19justin_smith,(require 'clojure.pprint)
17:19clojurebotnil
17:19justin_smith,(clojure.pprint/cl-format "wink: ~@r" 42)
17:19clojurebot#error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.core$seq__4116 invokeStatic "core.clj" 137]\n [clojure.co...
17:20justin_smithergh
17:20justin_smith,(clojure.pprint/cl-format nil "wink: ~@r" 42)
17:20clojurebot"wink: XLII"
17:20justin_smith,(clojure.pprint/cl-format nil "wink: ~r" 42)
17:20clojurebot"wink: forty-two"
17:20winknot half as cool :P
17:20justin_smithhaha
17:21winkstill, wow
17:22winkI'm not sure I'd apply violence to a coworker using that example here though: https://clojuredocs.org/clojure.pprint/cl-format
17:22wink(cl-format true "There ~[are~;is~:;are~]~:* ~d result~:p: ~{~d~^, ~}~%"
17:23wink"oh sorry, my cat walked over the keyboard"
18:18devth,(def a 1)
18:18clojurebot#'sandbox/a
18:19devthwhen you def something in clojurebot how long does it last? does clojurebot auto-reset the sandbox on some interval?
18:19devth,help
18:19clojurebot#error {\n :cause "Unable to resolve symbol: help in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: help 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: help in this co...
18:19justin_smithdevth: yeah, I think it's around 5 minutes
18:19devthinteresting
18:19justin_smithbut it's not 5 minutes from when you made the def, it's just every 5 minutes
18:20devthyeah. so you could get erased mid-experiment :)
18:20amalloywell don't use def then
18:20devthwould be cool if you could snapshot/save sessions
18:20devthmainly curious for my own bot's lang repls :)
18:24justin_smith~help
18:24clojurebotNobody can help with "X doesn't work". Please provide context: what you did, what you hoped would happen, and what happened instead. A stack trace is especially helpful, if applicable.
18:25justin_smithwell there's a nice domain error for me
18:25amalloydang, that might be the most polite factoid i've written
18:30spiedenbah, doesn't work with abstract classes
18:32justin_smithspieden: try proxy
18:32justin_smithunlike reify, proxy can do concrete inheritance
18:34amalloyabstract classes :(
18:34spiedencool thanks
18:34spiedenyeah so gross =\
18:34spiedenit only has one concrete method
19:19devthhm, started using protocols and now i have to `lein clean` all the time
19:20devthlots of weird error messages like "No single method: foo of interface ..."
19:21justin_smithdevth: protocols and cached stuff / reloading don't really play nicely
19:21devthi'd expect a repl restart to fix things though
19:21devthand at first they did
19:21justin_smithdevth: lein caches things
19:22devthk
19:22devthjust can't quite figure out when i would have to clean
19:22justin_smithdevth: iirc target/stale/
19:23devthrm -rf it to clear cache?
19:23devthmine has a single file: extract-native.dependencies
19:24justin_smithI mean this is what lein clean should be cleaning, is the whole target dir
19:24devthah
19:26devthi don't know if my code is actually reloading at all. time for some (log/debug "WTF?")
19:28devthlol it was a shadowing problem
19:28justin_smithoops!
19:29devthwhile trying to debug another problem of a dynamically bound var being unexpectedly nil...
19:31devthhm. so if i pass a fn as a callback using #'myfn syntax, when myfn gets called, bindings are not persisted?
19:32justin_smithCalling #'myfn as a function always looks up the latest value of that var. If you are using something like tools.namespace the var might have been deleted from the namespace instead of mutated, but otherwise, with normal code reloading, the function calling the var should end up invoking the new value.
19:39devthhm. looks you're right.
19:39devthstill i will remove #' and see what happens.
19:42devthdo bindings cross ref boundaries?
19:43devththe irc lib is taking my callbacks and storing them in a ref
19:45tem0pis there a way to add multiple singular elements at once? so something like (<fname> v ({:a a :b b} {:c c :d d})) => [{:a a :b b} {:c c :d d}]
19:47ridcullyapply conj?
19:47justin_smith,(apply conj [] '({:a a :b b} {:c c :d d}))
19:47clojurebot[{:a a, :b b} {:c c, :d d}]
19:47justin_smith,(into [] '({:a a :b b} {:c c :d d}))
19:47clojurebot[{:a a, :b b} {:c c, :d d}]
19:47ridcullythere you have it from authority
19:47justin_smithinto is just a beefed-up apply conj
19:47tem0pAhh perfect, thanks :)
19:56devththis is what's going on: https://gist.github.com/devth/77067d61b7b0922bf6ec (Thread. ...) is being created in the irclj lib https://github.com/Raynes/irclj/blob/master/src/irclj/core.clj#L143
19:56devthbindings don't get copied into new Thread instances
19:57devthhmm. not sure how to fix since it's in the lib.
19:58justin_smithdevth: if you use future instead of Thread it will propagate thread bindings
19:58devthhmm. maybe i will submit a PR
19:58devthRaynes: you around?
20:04devthjustin_smith: yep that fixed it
20:05justin_smithdevth: bonus, it also uses the expandable thread pool instead of one off thread creation
20:05devthah cool
20:05justin_smithagent-send-off-pool is the one iirc
20:06devthhttps://github.com/Raynes/irclj/pull/35
20:06devthgotta go for now. thx for the help (again) justin_smith!
20:08justin_smithdevth_afk: glad I could help
21:26BRODUSthis is a really good video on core async https://www.youtube.com/watch?v=VrmfuuHW_6w
21:29noncom|2i just found a super weird thing that kills (into {})
21:30noncom|2,(into {} (partition 2 [:a 1]))
21:30clojurebot#error {\n :cause "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :at [clojure.lang.ATransientMap conj "ATransientMap.java" 44]}]\n :trace\n [[clojure.lang.ATransientMap conj "ATransientMap.java" 44]\n [clojure.lang.ATransientMap conj "ATransientMap.java" 17]\n ...
21:30noncom|2coz
21:30noncom|2,(into {} '((:a 1)))
21:30clojurebot#error {\n :cause "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :at [clojure.lang.ATransientMap conj "ATransientMap.java" 44]}]\n :trace\n [[clojure.lang.ATransientMap conj "ATransientMap.java" 44]\n [clojure.lang.ATransientMap conj "ATransientMap.java" 17]\n ...
21:30noncom|2but
21:30noncom|2,(into {} [[:a 1]])
21:30clojurebot{:a 1}
21:30noncom|2wtf?
21:33noncom|2is this the intended behavior?
21:35BRODUSlooks like it, from the first example here: https://clojuredocs.org/clojure.core/into
21:35justin_smith,(vec {:a 1})
21:35clojurebot[[:a 1]]
21:35justin_smithnoncom|2: looks good to me!
21:36justin_smith,(into [] {:a 1})
21:36clojurebot[[:a 1]]
21:36turbofail,(conj {} [:a 1])
21:36clojurebot{:a 1}
21:36justin_smith(more direct comparison)
21:36turbofail,(conj {} '(:a 1))
21:36clojurebot#error {\n :cause "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :at [clojure.lang.APersistentMap cons "APersistentMap.java" 42]}]\n :trace\n [[clojure.lang.APersistentMap cons "APersistentMap.java" 42]\n [clojure.lang.RT conj "RT.java" 645]\n [clojure.core$co...
21:36noncom|2umm.. see, i get a list.. i want to (->> list (partition 2) (into {}))
21:37justin_smithnoncom|2: (map vec)
21:37turbofailjust add a (map vec) after the partition
21:37noncom|2oh
21:37turbofailbasically, conj on a map knows what to do when it sees a vector, but not a sequence
21:37noncom|2very strange really
21:38noncom|2it could as well understand a two-element (), just like a two-element []
21:38noncom|2can't imagine why shouldn't it
21:38justin_smithnoncom|2: but you can make a map entry out of a vector directly, you can't make one out of a list directly
21:38noncom|2esp that most functions return ()s
21:38noncom|2justin_smith: yeah, turns out so
21:39noncom|2it's just that that is counter-intuitive
21:39noncom|2is there any real reason for that?
21:39noncom|2some greater good?
21:39justin_smithnoncom|2: I meant that literally - thecode that make a map entry can use a vector to make a map entry, a list would need converting
21:40justin_smithnoncom|2: so nobody made the converting default
21:40noncom|2aha, that's what
21:40noncom|2i see
21:40justin_smithnoncom|2: like it or not, clojure avoids building some conveniences that would have larger hidden costs
21:41justin_smithwhether "larger" follows any reasonable standard of measure is another question :)
21:41noncom|2well, yes, that makes sense. but in this particular case and with this particular error message it just an unexpected startling stumble
21:42noncom|2good that you are here, guys, and can explain
21:42BRODUSis it that getting the two elements from the vector is faster than getting them from a list?
21:42justin_smiththat's true - it's not something that can be caught statically when compiling, and often clojure messages that can't be caught while compiling are very odd
21:42justin_smithBRODUS: I'm not totally certain actually
21:44turbofaili feel like a performance-based reason is unlikely
21:45turbofailbut who knows
21:45justin_smithturbofail: try submitting a patch that checks for non-vector sequentials and makes vectors automatically
21:45justin_smithturbofail: it will be rejected for performance reasons
21:46justin_smithturbofail: they reject patches that do sanity checks at runtime in order to have better failure messages - once again, performance reasons
21:50turbofailperhaps. but i feel like this particular thing could be implemented with basically no performance impact
21:50justin_smithdo tell?
21:54tem0pis there a version of into that doesnt add duplicates for vectors? or do I just run (distinct col) over it after?
21:55justin_smith,(into [] (distinct) [1 2 3 3 4 5 1])
21:55clojurebot[1 2 3 4 5]
21:55tem0pahhh, perfect, you're awesome, thanks
21:56justin_smithtem0p: the only thing is (distinct) won't check for items already in the vector
21:56justin_smith,(into [5] (distinct) [1 2 3 3 4 5 1])
21:56clojurebot[5 1 2 3 4 ...]
21:56justin_smithstupid cut off
21:56justin_smith,(into [2] (distinct) [1 2 3 3 4 5 1])
21:56clojurebot[2 1 2 3 4 ...]
21:56tem0pjustin_smith: Oh right damn
21:57tem0pjustin_smith: If i used a set then I could use union right?
21:57justin_smithtem0p: if you don't care about order
21:57tem0pjustin_smith: yeah I dont mind order, that seems good then :) cheers
21:58turbofailhm, actually i see the real reason, looking at the code - it's because if it's not a vector, it assumes that what's coming in is going to be convertable to a sequence of map entries - e.g. another map
21:59turbofail,(into {} {:a 0 :b 1})
21:59clojurebot{:a 0, :b 1}
21:59turbofailso basically it's to make conj do what might be the right thing for map arguments
22:00turbofailand, i guess, any other sequences of MapEntries
22:01turbofailif it weren't for that you could totally remove the instanceof check for vectors, and just call clojure.lang.RT.nth to get the first and second args, and that'd be plenty fast for vectors
22:01turbofail(it'd still be slow for lists, but it wouldn't slow down the vector case)
22:03turbofailwhoops, messed up my example
22:03turbofail,(conj {} {:a 0 :b 1})
22:03clojurebot{:a 0, :b 1}
22:36justin_smith,(conj :a {:b 2} {:c 3})
22:36justin_smitherm
22:36clojurebot#error {\n :cause "clojure.lang.Keyword cannot be cast to clojure.lang.IPersistentCollection"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to clojure.lang.IPersistentCollection"\n :at [clojure.core$conj__4104 invokeStatic "core.clj" 87]}]\n :trace\n [[clojure.core$conj__4104 invokeStatic "core.clj" 87]\n [clojure.core$conj__4104 doInvoke "core....
22:36justin_smith,(conj {} :a {:b 2} {:c 3})
22:36clojurebot#error {\n :cause "Don't know how to create ISeq from: clojure.lang.Keyword"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Keyword"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.lang.APersistentMap cons "APersistentMap.java"...
22:36justin_smithoh, right
22:36justin_smith,(conj {} [:a {:b 2}] {:c 3})
22:36clojurebot{:a {:b 2}, :c 3}