2015-12-22
| 00:29 | allhailcaesar | Is 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:07 | chomwitt | good morning. |
| 01:08 | chomwitt | a newbie question. where is ring.core ? |
| 01:13 | allhailcaesar | @chomwitt are you getting an error that you don't have it? |
| 01:15 | chomwitt | no. i'm trying to understand some basic things. http://ring-clojure.github.io/ring/ i dont see any ring.core in tha API |
| 01:15 | allhailcaesar | adding [ring/ring-core "1.4.0] to your dependencies will pull it to your classpath |
| 01:16 | hiredman | the docs show namespaces, and there is no ring.core namespace, so it is not in the docs |
| 01:17 | hiredman | but there is a maven artifact (a jar) with the group-id `ring` and the artifact-id `ring-core` |
| 01:18 | hiredman | namespaces and maven coordinates are orthogonal, and can be completely different, but many projects have maven coordinates that are similar to their namespaces |
| 01:19 | chomwitt | what the diff of including in my project.clj [ring "1.4.0"]] and [[ring/ring-core "..."]] |
| 01:19 | chomwitt | ? |
| 01:19 | hiredman | the ring artifact will bring in ring-core and some other stuff as dependencies |
| 01:19 | chomwitt | hiredman: your explanation i think is some levels above me :-) |
| 01:20 | chomwitt | i dont have an idea what a maven artifact is |
| 01:20 | hiredman | what goes in your project.clj are maven coordinates for dependencies (lein grabs stuff from maven repos) |
| 01:20 | hiredman | chomwitt: basically a jar |
| 01:20 | chomwitt | better :-) |
| 01:20 | chomwitt | a jar brings some bells :-) |
| 01:21 | hiredman | a zip file full of code |
| 01:21 | hiredman | when 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:22 | chomwitt | so why some tutorials use ring/ring.core and others just ring ? |
| 01:22 | hiredman | if 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:22 | chomwitt | hiredman: i see. makes sense nwo |
| 01:22 | chomwitt | now |
| 01:23 | allhailcaesar | chomwitt: 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:24 | hiredman | the 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:24 | hiredman | so for tutorials they are likely interchangable |
| 02:54 | keep_learning | Hello everyone |
| 02:54 | keep_learning | I am trying to extract the information https://www.refheap.com/112992 |
| 02:55 | keep_learning | when I am using (map (comp :href :attrs) (list-of-element)) then it return all the links |
| 02:55 | keep_learning | but I want to extract the :content also |
| 02:56 | keep_learning | so I have written (map :content (list-of-element)) gives me list of list of one element |
| 02:56 | keep_learning | I tried to combined it together |
| 02:57 | keep_learning | (map (fn [x] ( (comp :href :attrs) x, :content x)) (list-of-element)) |
| 02:57 | keep_learning | but getting error |
| 03:04 | Kneiva | keep_learning: (Without looking at the paste): That last anonymous function could be something like (juxt (comp :href :attrs) :context) |
| 03:06 | keep_learning | Kneiva, Thank you |
| 03:09 | Kneiva | uh, :content instead of :context |
| 05:29 | keep_learning | https://www.refheap.com/112993 |
| 05:29 | keep_learning | Hello everyone. |
| 05:29 | keep_learning | I have list of url links |
| 05:30 | keep_learning | and I want to navigate through all these links sequentially |
| 05:30 | keep_learning | so I can't write (map fetch-page-from-link url-links) |
| 05:30 | keep_learning | I want to do it sequential manner |
| 05:34 | kungi | keep_learning: does fetch-page-from-link have sideeffects? If yes then `doseq` is right for you. |
| 05:35 | keep_learning | (defn fetch-page-from-url |
| 05:35 | keep_learning | "fetch page source/html page from given url" |
| 05:35 | keep_learning | [url] |
| 05:35 | keep_learning | (do |
| 05:35 | keep_learning | (t/set-driver! {:browser :firefox}) ;set this for moment |
| 05:35 | keep_learning | (t/get-url url) |
| 05:35 | keep_learning | (t/page-source))) |
| 05:35 | keep_learning | kungi, Yes but it returns page of url |
| 05:35 | kungi | returning something is not a sideeffect. But set-driver! probably is. |
| 05:35 | keep_learning | I have to process that html page |
| 05:36 | kungi | keep_learning: why are you using `do` here? |
| 05:36 | keep_learning | and (t/get-url url) is also a side effect |
| 05:36 | kungi | probably yes |
| 05:36 | keep_learning | kungi, For sequential execution |
| 05:36 | kungi | keep_learning: defn and fn also do an "implicit do" |
| 05:37 | keep_learning | kungi, Thank you |
| 05:37 | keep_learning | so I can write (map fetch-page-from-url url-link) ? |
| 05:38 | kungi | keep_learning: as far as I see it yes. |
| 05:38 | keep_learning | Thank you |
| 05:38 | kungi | keep_learning: hmm ok wait. Maybe lazyness will screw you there |
| 05:38 | kungi | keep_learning: I would use `doseq` |
| 05:51 | owlbird | how 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:03 | Kneiva | owlbird: 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:03 | Kneiva | ,(clojure.string/join " AND " (map (fn [[k v]] (str (name k) "=" v)) {:id 12 :name "aa"})) |
| 06:03 | clojurebot | "id=12 AND name=aa" |
| 06:05 | Kneiva | And I would think there is some library that can do this kind of thing for you. |
| 06:10 | owlbird | select * from user u (if department != "") join dept d on u.dept = d.dept and d.name=? (if name != "") where u.name=? |
| 06:11 | owlbird | department/name both are optional parameter, which would be treated like a SQL segment switch, to open/close a logical. |
| 06:20 | Kneiva | owlbird: search for sql abstraction here: http://www.clojure-toolbox.com/ |
| 06:25 | ridcully | banging strings together has a good chance to introduce sql injections - so watch out here |
| 06:26 | keep_learning | Hello everyone |
| 06:26 | keep_learning | I have clojure file and want to covert it to jar file |
| 06:27 | keep_learning | https://www.refheap.com/112994 |
| 06:42 | keep_learning | Do I need to add main in clojure file |
| 06:44 | Kneiva | If you want it to be runnable jar. |
| 06:48 | keep_learning | Kneiva, I want to call go-to-tripadv from other java file |
| 06:49 | powered | if you want to use the jar as a library then you don't need a main |
| 06:50 | keep_learning | powered, Thank you |
| 06:51 | keep_learning | I have run lein uberjar |
| 06:51 | keep_learning | and it generated the jar in target directory |
| 06:53 | powered | you can also run lein jar if you don't want to include dependencies |
| 06:58 | keep_learning | I am getting two jar files |
| 06:58 | keep_learning | tripadvisor-0.1.0-SNAPSHOT.jar |
| 06:58 | keep_learning | tripadvisor-0.1.0-SNAPSHOT-standalone.jar |
| 06:59 | keep_learning | Which one I should add to java project to fetch go-to-tripadv function |
| 06:59 | keep_learning | ? |
| 07:06 | Kneiva | keep_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:08 | keep_learning | Kneiva, I have added both the jar file |
| 07:09 | keep_learning | but having problem in calling the function go-to-tripadv |
| 07:14 | Kneiva | keep_learning: Maybe this helps: http://stackoverflow.com/a/23555959 |
| 08:57 | vy | Hi 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:05 | hiredman | ring and servlets are both interfaces, not implementations, so neither of those things can actually be benchmarked |
| 09:06 | hiredman | the servlet api specifies how http can be represented as java method calls, ring specifies how http can be represented as clojure data structures |
| 09:07 | vy | hiredman: I agree, but I would expect Compojure to come after vanilla Java Sevlets, assuming that they are compared using identical servlet container configurations. |
| 09:07 | hiredman | an 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:10 | hiredman | the ring spec can be implemented (and has been) on other things besides servlets |
| 09:10 | hiredman | and compojure is built on top of ring |
| 09:12 | ridcully | since #1 and #3 seems to differ in db, i'd like to see, how compojure there would do with postgres |
| 09:12 | hiredman | so to benchmark "compojure" as a thing, without specificy compojure + what implementation of the ring spec, doesn't make sense |
| 09:13 | vy | hiredman: The code is available: https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Clojure/compojure/hello |
| 09:17 | hiredman | vy: 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:17 | vy | hiredman: Hrm... Thanks for the explanations. |
| 09:19 | hiredman | the 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:20 | vy | I think it is just yet another page for comparing apples and oranges. But that's my idea... |
| 09:20 | hiredman | alioth for http |
| 09:21 | vy | Alioth is measuring/benchmarking more comparable things. |
| 09:23 | hiredman | alioth is measuring performance of c ffi to libgmp |
| 10:57 | jcrossley3 | little_lamb: cool nick, bro |
| 10:58 | little_lamb | jcrossley3: I did it JUST FOR YOU |
| 10:58 | jcrossley3 | :) |
| 12:20 | aurelian | hello |
| 12:20 | aurelian | what's a nicer way of doing this: https://www.refheap.com/113004 ? |
| 12:21 | aurelian | I tend to solve most of this kind of problems with reduce/map/filter, but I feel there must be a better way |
| 12:23 | yenda | with specter maybe |
| 12:23 | yenda | (select [ALL :sources ALL] lolz) |
| 12:23 | ridcully | is the order important? |
| 12:23 | aurelian | nope, order is not important |
| 12:24 | aurelian | yenda -- will check that out thanks |
| 12:25 | ridcully | (into #{} (mapcat :sources lolz)) |
| 12:26 | aurelian | oh, wow |
| 12:27 | aurelian | thanks |
| 12:32 | aurelian | and to keep it unique and as a vector is it better to apply distinct and use into [] or convert the result to vec? |
| 12:33 | justin_smith | I'd use ((comp vec distinct mapcat) :sources lolz) |
| 12:34 | aurelian | I'm very comfortable using reduce but somehow in clojure there's always a better / nicer way |
| 12:36 | mavbozo | ,(doc mapcat) |
| 12:36 | clojurebot | "([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:36 | mavbozo | ,(doc distinct) |
| 12:36 | clojurebot | "([] [coll]); Returns a lazy sequence of the elements of coll with duplicates removed. Returns a stateful transducer when no collection is provided." |
| 12:36 | aurelian | yup, is exactly what I doing in that reduce |
| 12:36 | aurelian | mapcat I mean |
| 12:36 | mavbozo | ah, justin_smith's version uses transducers |
| 12:37 | mavbozo | ,(doc vec) |
| 12:37 | clojurebot | "([coll]); Creates a new vector containing the contents of coll. Java arrays will be aliased and should not be modified." |
| 12:38 | justin_smith | mavbozo: it doesn't actually, but it could probably be converted to do so |
| 12:39 | mavbozo | justin_smith, oh, my mistake |
| 12:39 | aurelian | ,(doc comp) |
| 12:39 | clojurebot | "([] [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:40 | justin_smith | ,((comp vec distinct mapcat) :foo [{:foo [1 2 3]} {:foo [2 3 4]} {:foo [3 4 5]} {:bar [42]}]) |
| 12:40 | clojurebot | [1 2 3 4 5] |
| 12:41 | aurelian | sweet, thanks |
| 12:56 | justin_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:56 | clojurebot | [1 2 3 4 5] |
| 12:56 | mavbozo | ,(into [] (comp (mapcat :foo) (distinct)) [{:foo [1 2 3]} {:foo [2 3 4]} {:foo [3 4 5]} {:bar [42]}]) |
| 12:56 | clojurebot | [1 2 3 4 5] |
| 12:56 | WorldsEndless | What 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:57 | justin_smith | haha, mavbozo did you just come up with the same thing right when I did? |
| 12:57 | mavbozo | justin_smith, zing isn't it? LOL |
| 12:57 | justin_smith | WorldsEndless: I thought it was use / only and require / refer |
| 12:58 | WorldsEndless | justin_smith: I'm not managing to parse that sentence... |
| 12:58 | justin_smith | mavbozo: especially because I had to help a coworker with a couple of things before coming back and figuring that out, haha |
| 12:58 | justin_smith | WorldsEndless: (:use [foo :only [bar]]) (:require [foo :refer [bar]]) |
| 12:59 | mavbozo | justin_smith, jinx |
| 12:59 | WorldsEndless | Ok; so no :only for refer in ns? (unlike refer http://clojuredocs.org/clojure.core/refer) |
| 12:59 | justin_smith | WorldsEndless: (doc use) mentions :only, (doc require) mentions :refer |
| 13:00 | WorldsEndless | Guess I'm confused by the first example from the refer clojuredoc page |
| 13:00 | mavbozo | justin_smith, hahaha, took me quite some time to realize that the (comp ...) order is reversed |
| 13:00 | justin_smith | OK, but the args of require aren't given directly to refer |
| 13:01 | WorldsEndless | Ah, I see. My mind was transposing "require" and "refer" ... |
| 13:07 | qsys | I 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:08 | qsys | and I'm using the com.theoryinpractis:clojure.maven.plugin:1.7.1 maven plugin |
| 13:09 | justin_smith | qsys: have you verified that the class you are trying to extend is on the classpath? |
| 13:09 | qsys | for some reason, the sme.class is not found (it is present in the maven depencies) |
| 13:09 | justin_smith | qsys: you shouldn't need to import, btw |
| 13:09 | qsys | so yeah, I would suppose if it's in the maven dependencies, it's in the classpath (but apparently, it's not :p) |
| 13:10 | justin_smith | qsys: 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:10 | qsys | yes, 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:10 | qsys | hmm, I'll check for maven |
| 13:11 | justin_smith | qsys: import just changes whether package qualifiers are needed, it doesn't do any class loading magic |
| 13:11 | qsys | allright, makes sense... |
| 13:15 | qsys | not that much logging/debug info with maven. searching for classpath when running plugins. |
| 13:15 | justin_smith | qsys: what about looking at the command line args when starting a repl? |
| 13:16 | justin_smith | via ps or whatever |
| 13:18 | qsys | nothing much about classpaths - don't like that |
| 13:20 | justin_smith | qsys: what about 'mvn dependency:build-classpath' |
| 13:22 | justin_smith | qsys: when I run "ps x" it shows the full classpath as specified on the command line of any java command I have running |
| 13:22 | qsys | then I get the right classpaths - when I add some.class from Java, there's no problem. |
| 13:23 | qsys | yeah, 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:23 | justin_smith | qsys: which is why I suggested starting a repl (if needed commenting out the gen-class so the repl runs) |
| 13:23 | devth_afk | there's a problem i've never had: mvn being too fast :) |
| 13:24 | justin_smith | the repl should stay running until you tell it to stop |
| 13:24 | justin_smith | haha |
| 13:24 | qsys | ok... thx - lol |
| 13:24 | qsys | I'm a slow speaker :) |
| 13:28 | qsys | all mvn jobs from the plugin don't seem to add other mvn dependencies in the classpath... I'll check that plugin config again |
| 13:30 | slester | I 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:34 | justin_smith | slester: that seems like it misses out on a bunch of the benefits of using cursive |
| 13:35 | j-pb | slester: resyncing with lein often helps |
| 13:35 | slester | yeah, 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:35 | j-pb | the leiningen tab on the right |
| 13:35 | justin_smith | slester: did you see these docs? https://cursive-ide.com/userguide/leiningen.html |
| 13:35 | j-pb | and then the sync symbol |
| 13:35 | slester | justin_smith: that's the one I followed, yup :( |
| 13:35 | justin_smith | slester: at what step did it fail? |
| 13:35 | slester | I'll try again later, but whew. IDEA is just huge and complicated. |
| 13:36 | slester | I just couldn't get clicking Run to work is all |
| 13:36 | qsys | lein is another option... but it does take more steps to build - I'd rather have it done in maven |
| 13:36 | slester | maybe I didn't go into the right menu like the one j-pb suggested |
| 13:36 | j-pb | slester: to get run working you also need to configure a repl for example |
| 13:36 | slester | the REPL worked |
| 13:37 | justin_smith | qsys: lein is friendlier for clojure specific stuff though (like clojure.test / clojure specific linters / other clojure test frameworks / etc.) |
| 13:37 | j-pb | slester: what didn't then :)? |
| 13:38 | slester | I 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:38 | slester | but 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:40 | ridcully | left of the run/debug/chronos/... buttons is a dropdown. there you can "edit configurations" |
| 13:41 | j-pb | slester: no but what do you expect the run botton to do? for me a repl would be what I need |
| 13:44 | slester | lein run? |
| 13:45 | j-pb | hrm, tbh I never use that |
| 13:46 | j-pb | slester: you would probably have to set up a clojure application configuration in intellij then |
| 13:46 | j-pb | however |
| 13:46 | j-pb | I don't see a reason for running lein run |
| 13:46 | j-pb | in development mode you want a repl |
| 13:46 | j-pb | in deploy you want a jar |
| 13:46 | ridcully | me 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:47 | slester | well, I am a newb so it's probable I'm doing it wrong |
| 13:47 | j-pb | slester: generally when developing in clojure you want to use the repl |
| 13:47 | j-pb | because it allows you to hotload code into your program while you develop it |
| 13:50 | slester | it seems like a big pain to get code in there |
| 13:51 | MJB47 | most people have a function in their editor to send code to the repl |
| 13:51 | slester | like I have no idea how I'd use it effectively. I usually use the REPL to try out code |
| 13:53 | j-pb | slester: yeah but you can also call your main from there |
| 13:54 | j-pb | slester: and then you can reevaluate parts of the code while its running |
| 13:54 | slester | I guess I need to watch a video or read some more about it, then. |
| 14:12 | devth | anyone using spacemacs for clojure? |
| 14:12 | devth | https://github.com/syl20bnr/spacemacs |
| 14:16 | TimMc | "An Emacs distribution" |
| 14:16 | rhg135 | how do you deal with state like open sockets in an evented design? |
| 14:16 | devth | i'm a heavy vim user but thinking about seeing if all my workflows could be ported to spacemacs. |
| 14:17 | rhg135 | the kind you can't recreate |
| 14:17 | TimMc | Oh 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:17 | justin_smith | TimMc: most of emacs is just RMS' .emacs |
| 14:17 | wink | TimMc: it's Emacs/Linux, not "Linux" |
| 14:19 | justin_smith | TimMc: oh, someone could pull an ubuntu, and make an "easy to use" emacs which randomly sends you to amazon.com |
| 14:19 | TimMc | justin_smith: Ha, so it has already happened. |
| 14:20 | justin_smith | TimMc: some of us still remember the huge Lucid/GNU emacs split (I was too young for the gosmacs / gnumacs split though) |
| 14:21 | TimMc | GNU+Emacs |
| 14:21 | TimMc | I didn't start with emacs until maybe 2010. |
| 14:22 | justin_smith | part of the motivation for inventing the GPL: https://en.wikipedia.org/wiki/Gosling_Emacs |
| 14:23 | devth | i'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:25 | justin_smith | devth: 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:25 | justin_smith | spacemacs is built on evil mode |
| 14:25 | devth | nice. right |
| 14:26 | devth | long 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:26 | devth | haskell in emacs is way better than vim from what i've gathered. |
| 14:26 | BRODUS | can anyone recommend a good resource to learn about core.async |
| 14:27 | justin_smith | BRODUS: have you walked through the official intro? |
| 14:27 | BRODUS | no, im reading the section on braveclojure, im finding its explanations lacking |
| 14:27 | qsys | gen-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:28 | qsys | I get an ClassNotFoundException |
| 14:28 | qsys | it's not a classpath issue, since it does compile with :implements |
| 14:29 | justin_smith | qsys: 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:29 | qsys | am I missing something about :extends and abstract classes (clojure 1.7.0, by the way) |
| 14:32 | slester | is there a good place to learn about using the REPL to its maximum when developing? |
| 14:37 | devth | slester: some good stuff at http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded |
| 14:44 | spieden | slester: here's my ~/.lein/profiles.clj https://gist.github.com/spieden/5af1b11cadceaeed83b9 |
| 14:44 | spieden | slester: might be old versions -- haven't checked in a while |
| 14:45 | slester | devth: thanks! |
| 14:45 | slester | and spieden! |
| 15:09 | BRODUS | am 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:10 | qsys | allright, 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:10 | justin_smith | BRODUS: core.async creates 42+(nprocs*2) threads for its pool |
| 15:11 | justin_smith | BRODUS: but yes, this would lock up all 50 threads, then use more as they are available |
| 15:11 | justin_smith | which is why clojure.core.async/thread exists - for when you are doing blocking IO in core.async |
| 15:14 | justin_smith | BRODUS: 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:15 | justin_smith | *not own a core.async pool thread - of course it still owns a (mostly inactive, blocking on io) thread |
| 15:15 | benjyz1 | hi. is it possible to name async channels? |
| 15:15 | benjyz1 | I want to implement publish-subscribe to topics |
| 15:18 | justin_smith | benjyz1: 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:20 | BRODUS | justin_smith: i get it, but whats the other kind of thread if its not a core.async pool thread |
| 15:20 | justin_smith | BRODUS: a thread |
| 15:21 | justin_smith | you can make as many as you want, until the OS stops letting java create more |
| 15:22 | justin_smith | BRODUS: 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:22 | justin_smith | see also java.lang.Thread |
| 15:23 | BRODUS | justin_smith: why would you want to reuse a thread? |
| 15:23 | justin_smith | BRODUS: because it is expensive to make new ones |
| 15:24 | justin_smith | BRODUS: 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:25 | benjyz1 | interesting. a bunch of async functions have been moved to transducers |
| 15:26 | rhg135 | but still you are bound by how many the hardware can run at a time, no? |
| 15:26 | justin_smith | benjyz1: 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:26 | justin_smith | rhg135: 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:27 | justin_smith | and 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:27 | rhg135 | ah I see |
| 15:27 | benjyz1 | what about message durability? for me the problem is that its far from trivial to wrap TCP semantics in several scenarios |
| 15:28 | benjyz1 | Peer-to-Peer networks and security is generally hard to do with TCP |
| 15:28 | justin_smith | benjyz1: yeah, core.async isn't about TCP or durability |
| 15:28 | justin_smith | benjyz1: I thought you meant pub-sub in core.async |
| 15:28 | BRODUS | justin_smith: thanks for the help |
| 15:28 | justin_smith | BRODUS: np |
| 15:29 | benjyz1 | yes. I mean pub-sub over the internet via async. I assume both sides run the JVM |
| 15:29 | justin_smith | benjyz1: 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:29 | justin_smith | benjyz1: core.async is not a networking tool |
| 15:30 | benjyz1 | yes absolutely, it is a can of worms |
| 15:31 | benjyz1 | its 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:32 | benjyz1 | Scala has Akka, and there is a wrapper around it called Okku |
| 15:42 | spieden | i much prefer core.async/CSP over Akka/Actors |
| 16:33 | pilne | ok, clojure has me stumped |
| 16:34 | BRODUS | pilne: whatsup? |
| 16:34 | pilne | (for [i (range 1 10)] (print i)) is returnning: 123456789(nil nil nil nil nil nil nil nil nil) |
| 16:34 | pilne | in the REPL |
| 16:34 | MJB47 | what do you want it to output? |
| 16:35 | pilne | the nils confuse me? |
| 16:35 | MJB47 | for returns a lazy seq |
| 16:35 | BRODUS | the list of nils is the output of for |
| 16:35 | MJB47 | of all the returned values |
| 16:35 | MJB47 | print returns nil |
| 16:35 | MJB47 | if you dont care about the return values |
| 16:35 | MJB47 | use doseq |
| 16:35 | MJB47 | or dotimes |
| 16:35 | pilne | ohhhhhhhhhhhhh |
| 16:35 | BRODUS | the numbers preceding are side effects of the operations within for |
| 16:38 | pilne | whereas the for literally returns nothing (nil) on its own |
| 16:40 | cfleming | slester: If you're still having problems with a lein project feel free to ping me if you'd like help |
| 16:41 | BRODUS | for returns a lazy sequence, each item in the sequence is going to the be result of (print i) |
| 16:41 | BRODUS | print will print a string but it returns nil |
| 16:43 | pilne | because every function has to return "something" to be considered a function? |
| 16:43 | BRODUS | no, print is a function |
| 16:44 | BRODUS | it just always returns nil |
| 16:44 | justin_smith | pilne: 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:45 | justin_smith | even using interop with java / jvm stuff, if nothing else you'll get a return value of nil |
| 16:45 | pilne | well, it might be a bit quirky (for someone like me), but at least it is consistent (: |
| 16:46 | MJB47 | well |
| 16:46 | justin_smith | pilne: 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:46 | MJB47 | its the basis of functional programming |
| 16:47 | pilne | clojure 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:48 | justin_smith | pilne: 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:48 | justin_smith | with the exception of the rarely used io! macro |
| 16:49 | BRODUS | pilne, 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:49 | justin_smith | pilne: 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:49 | MJB47 | you can use print-str |
| 16:50 | justin_smith | BRODUS: #(doto % print) |
| 16:50 | MJB47 | https://clojuredocs.org/clojure.core/print-str |
| 16:50 | justin_smith | MJB47: that's not a printing function though |
| 16:50 | justin_smith | that's for getting what print would have printed, but as a string |
| 16:50 | MJB47 | wut |
| 16:50 | MJB47 | oh |
| 16:50 | MJB47 | you are correct |
| 16:50 | MJB47 | nvm me |
| 16:50 | ridcully | i like doto too. it injects easily into existing code |
| 16:51 | amalloy | justin_smith: well, map print xs :: [IO a], so you might well not get a type error until later |
| 16:51 | BRODUS | nice, haven't seen doto yet |
| 16:51 | amalloy | er, IO () |
| 16:51 | justin_smith | amalloy: yeah, my haskell is still very weak |
| 16:52 | amalloy | i've been doing the advent of code exercises in haskell |
| 16:52 | amalloy | it's good practice |
| 16:52 | justin_smith | cool! |
| 16:52 | amalloy | https://github.com/amalloy/advent-of-code if you are interested |
| 16:52 | justin_smith | I'm going through bitemyapp's book (slowly) |
| 16:52 | justin_smith | cool, I'll need to check that out |
| 16:53 | pilne | my gf bought me bitemyapp's book for xmas, but i don't get the download key until xmas eve >.< |
| 16:54 | pilne | i was smart enough to not argue when she wanted to wear one of the outfits i got her for xmas yesterday though >.< |
| 16:55 | pilne | what can i say, i'm a functional programming junkie, i've even taken an interest in factor lol |
| 17:00 | tem0p | (second [123 1001]) |
| 17:00 | tem0p | => 1001 |
| 17:00 | tem0p | (second [123 01001]) |
| 17:01 | justin_smith | tem0p: 01001 means "1001 in octal" |
| 17:01 | justin_smith | ,0xff |
| 17:01 | clojurebot | 255 |
| 17:01 | justin_smith | ,010 |
| 17:01 | clojurebot | 8 |
| 17:01 | tem0p | justin_smith: so what does that second statement return? |
| 17:01 | justin_smith | tem0p: I forget, but it's 1001 in octal |
| 17:01 | justin_smith | ,01001 |
| 17:01 | clojurebot | 513 |
| 17:02 | justin_smith | ,8r1001 |
| 17:02 | clojurebot | 513 |
| 17:02 | tem0p | justin_smith: Urgggh, so I'll have to change it to ["123" "01001"]? |
| 17:02 | justin_smith | tem0p: if you want it to print with a leading 0, use a format string |
| 17:03 | tem0p | justin_smith: Ahh good idea, thanks! |
| 17:03 | justin_smith | ,(format "%05d" 1001) |
| 17:03 | clojurebot | "01001" |
| 17:04 | tem0p | justin_smith: I was testing with [513000 01001] and getting 513 back lol, so confusing. |
| 17:04 | justin_smith | ahh, yeah I can see how that would be confusing |
| 17:07 | TEttinger | tem0p: 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:08 | TEttinger | ,[2r001001] |
| 17:08 | clojurebot | [9] |
| 17:08 | TEttinger | ,[3r001001 4r001001 5r001001 6r001001 7r001001] |
| 17:08 | clojurebot | [28 65 126 217 344] |
| 17:08 | TEttinger | ,[13r001001 14r001001 15r001001 16r001001 17r001001] |
| 17:08 | clojurebot | [2198 2745 3376 4097 4914] |
| 17:09 | justin_smith | ,36rjustinsmith |
| 17:09 | clojurebot | 72595113320300741 |
| 17:09 | TEttinger | and my absolute favorite is using 36r to encode arbitrary alnum strings as numbers, yes |
| 17:09 | tem0p | lol |
| 17:09 | TEttinger | ,36rTETTINGER |
| 17:09 | clojurebot | 82974197147859 |
| 17:10 | justin_smith | ,(> 36rjustinsmith 36rtettinger) |
| 17:10 | clojurebot | true |
| 17:10 | justin_smith | :P |
| 17:10 | TEttinger | ,(> 29rjustinsmith 35rTOMMYETTINGER) |
| 17:10 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "justi"> |
| 17:11 | TEttinger | eh? |
| 17:11 | TEttinger | ,(> 30rjustinsmith 35rTOMMYETTINGER) |
| 17:11 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "justi"> |
| 17:11 | TEttinger | ,(> 30rjustinsmith 35rTOMMYETTINGER) |
| 17:11 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "justi"> |
| 17:12 | TEttinger | ohhh t |
| 17:12 | TEttinger | ,(> 31rjustinsmith 35rTOMMYETTINGER) |
| 17:12 | clojurebot | false |
| 17:12 | TEttinger | wonder why it stopped at i not t |
| 17:12 | TEttinger | I thought you stuck a \ufeff in there |
| 17:14 | justin_smith | nah, the number formatter wouldn't even take that |
| 17:15 | wink | daily wtf |
| 17:18 | wink | suddenly my joke proposal for 0sqprFFXIV for roman numbers sounds sane. |
| 17:18 | wink | (different language though) |
| 17:18 | wink | and it's spqr of course |
| 17:19 | justin_smith | ,(clojure.pprint/cl-format "wink: ~@r" 42) |
| 17:19 | clojurebot | #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:19 | justin_smith | ,(require 'clojure.pprint) |
| 17:19 | clojurebot | nil |
| 17:19 | justin_smith | ,(clojure.pprint/cl-format "wink: ~@r" 42) |
| 17:19 | clojurebot | #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:20 | justin_smith | ergh |
| 17:20 | justin_smith | ,(clojure.pprint/cl-format nil "wink: ~@r" 42) |
| 17:20 | clojurebot | "wink: XLII" |
| 17:20 | justin_smith | ,(clojure.pprint/cl-format nil "wink: ~r" 42) |
| 17:20 | clojurebot | "wink: forty-two" |
| 17:20 | wink | not half as cool :P |
| 17:20 | justin_smith | haha |
| 17:21 | wink | still, wow |
| 17:22 | wink | I'm not sure I'd apply violence to a coworker using that example here though: https://clojuredocs.org/clojure.pprint/cl-format |
| 17:22 | wink | (cl-format true "There ~[are~;is~:;are~]~:* ~d result~:p: ~{~d~^, ~}~%" |
| 17:23 | wink | "oh sorry, my cat walked over the keyboard" |
| 18:18 | devth | ,(def a 1) |
| 18:18 | clojurebot | #'sandbox/a |
| 18:19 | devth | when you def something in clojurebot how long does it last? does clojurebot auto-reset the sandbox on some interval? |
| 18:19 | devth | ,help |
| 18:19 | clojurebot | #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:19 | justin_smith | devth: yeah, I think it's around 5 minutes |
| 18:19 | devth | interesting |
| 18:19 | justin_smith | but it's not 5 minutes from when you made the def, it's just every 5 minutes |
| 18:20 | devth | yeah. so you could get erased mid-experiment :) |
| 18:20 | amalloy | well don't use def then |
| 18:20 | devth | would be cool if you could snapshot/save sessions |
| 18:20 | devth | mainly curious for my own bot's lang repls :) |
| 18:24 | justin_smith | ~help |
| 18:24 | clojurebot | Nobody 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:25 | justin_smith | well there's a nice domain error for me |
| 18:25 | amalloy | dang, that might be the most polite factoid i've written |
| 18:30 | spieden | bah, doesn't work with abstract classes |
| 18:32 | justin_smith | spieden: try proxy |
| 18:32 | justin_smith | unlike reify, proxy can do concrete inheritance |
| 18:34 | amalloy | abstract classes :( |
| 18:34 | spieden | cool thanks |
| 18:34 | spieden | yeah so gross =\ |
| 18:34 | spieden | it only has one concrete method |
| 19:19 | devth | hm, started using protocols and now i have to `lein clean` all the time |
| 19:20 | devth | lots of weird error messages like "No single method: foo of interface ..." |
| 19:21 | justin_smith | devth: protocols and cached stuff / reloading don't really play nicely |
| 19:21 | devth | i'd expect a repl restart to fix things though |
| 19:21 | devth | and at first they did |
| 19:21 | justin_smith | devth: lein caches things |
| 19:22 | devth | k |
| 19:22 | devth | just can't quite figure out when i would have to clean |
| 19:22 | justin_smith | devth: iirc target/stale/ |
| 19:23 | devth | rm -rf it to clear cache? |
| 19:23 | devth | mine has a single file: extract-native.dependencies |
| 19:24 | justin_smith | I mean this is what lein clean should be cleaning, is the whole target dir |
| 19:24 | devth | ah |
| 19:26 | devth | i don't know if my code is actually reloading at all. time for some (log/debug "WTF?") |
| 19:28 | devth | lol it was a shadowing problem |
| 19:28 | justin_smith | oops! |
| 19:29 | devth | while trying to debug another problem of a dynamically bound var being unexpectedly nil... |
| 19:31 | devth | hm. so if i pass a fn as a callback using #'myfn syntax, when myfn gets called, bindings are not persisted? |
| 19:32 | justin_smith | Calling #'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:39 | devth | hm. looks you're right. |
| 19:39 | devth | still i will remove #' and see what happens. |
| 19:42 | devth | do bindings cross ref boundaries? |
| 19:43 | devth | the irc lib is taking my callbacks and storing them in a ref |
| 19:45 | tem0p | is 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:47 | ridcully | apply conj? |
| 19:47 | justin_smith | ,(apply conj [] '({:a a :b b} {:c c :d d})) |
| 19:47 | clojurebot | [{:a a, :b b} {:c c, :d d}] |
| 19:47 | justin_smith | ,(into [] '({:a a :b b} {:c c :d d})) |
| 19:47 | clojurebot | [{:a a, :b b} {:c c, :d d}] |
| 19:47 | ridcully | there you have it from authority |
| 19:47 | justin_smith | into is just a beefed-up apply conj |
| 19:47 | tem0p | Ahh perfect, thanks :) |
| 19:56 | devth | this 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:56 | devth | bindings don't get copied into new Thread instances |
| 19:57 | devth | hmm. not sure how to fix since it's in the lib. |
| 19:58 | justin_smith | devth: if you use future instead of Thread it will propagate thread bindings |
| 19:58 | devth | hmm. maybe i will submit a PR |
| 19:58 | devth | Raynes: you around? |
| 20:04 | devth | justin_smith: yep that fixed it |
| 20:05 | justin_smith | devth: bonus, it also uses the expandable thread pool instead of one off thread creation |
| 20:05 | devth | ah cool |
| 20:05 | justin_smith | agent-send-off-pool is the one iirc |
| 20:06 | devth | https://github.com/Raynes/irclj/pull/35 |
| 20:06 | devth | gotta go for now. thx for the help (again) justin_smith! |
| 20:08 | justin_smith | devth_afk: glad I could help |
| 21:26 | BRODUS | this is a really good video on core async https://www.youtube.com/watch?v=VrmfuuHW_6w |
| 21:29 | noncom|2 | i just found a super weird thing that kills (into {}) |
| 21:30 | noncom|2 | ,(into {} (partition 2 [:a 1])) |
| 21:30 | clojurebot | #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:30 | noncom|2 | coz |
| 21:30 | noncom|2 | ,(into {} '((:a 1))) |
| 21:30 | clojurebot | #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:30 | noncom|2 | but |
| 21:30 | noncom|2 | ,(into {} [[:a 1]]) |
| 21:30 | clojurebot | {:a 1} |
| 21:30 | noncom|2 | wtf? |
| 21:33 | noncom|2 | is this the intended behavior? |
| 21:35 | BRODUS | looks like it, from the first example here: https://clojuredocs.org/clojure.core/into |
| 21:35 | justin_smith | ,(vec {:a 1}) |
| 21:35 | clojurebot | [[:a 1]] |
| 21:35 | justin_smith | noncom|2: looks good to me! |
| 21:36 | justin_smith | ,(into [] {:a 1}) |
| 21:36 | clojurebot | [[:a 1]] |
| 21:36 | turbofail | ,(conj {} [:a 1]) |
| 21:36 | clojurebot | {:a 1} |
| 21:36 | justin_smith | (more direct comparison) |
| 21:36 | turbofail | ,(conj {} '(:a 1)) |
| 21:36 | clojurebot | #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:36 | noncom|2 | umm.. see, i get a list.. i want to (->> list (partition 2) (into {})) |
| 21:37 | justin_smith | noncom|2: (map vec) |
| 21:37 | turbofail | just add a (map vec) after the partition |
| 21:37 | noncom|2 | oh |
| 21:37 | turbofail | basically, conj on a map knows what to do when it sees a vector, but not a sequence |
| 21:37 | noncom|2 | very strange really |
| 21:38 | noncom|2 | it could as well understand a two-element (), just like a two-element [] |
| 21:38 | noncom|2 | can't imagine why shouldn't it |
| 21:38 | justin_smith | noncom|2: but you can make a map entry out of a vector directly, you can't make one out of a list directly |
| 21:38 | noncom|2 | esp that most functions return ()s |
| 21:38 | noncom|2 | justin_smith: yeah, turns out so |
| 21:39 | noncom|2 | it's just that that is counter-intuitive |
| 21:39 | noncom|2 | is there any real reason for that? |
| 21:39 | noncom|2 | some greater good? |
| 21:39 | justin_smith | noncom|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:40 | justin_smith | noncom|2: so nobody made the converting default |
| 21:40 | noncom|2 | aha, that's what |
| 21:40 | noncom|2 | i see |
| 21:40 | justin_smith | noncom|2: like it or not, clojure avoids building some conveniences that would have larger hidden costs |
| 21:41 | justin_smith | whether "larger" follows any reasonable standard of measure is another question :) |
| 21:41 | noncom|2 | well, yes, that makes sense. but in this particular case and with this particular error message it just an unexpected startling stumble |
| 21:42 | noncom|2 | good that you are here, guys, and can explain |
| 21:42 | BRODUS | is it that getting the two elements from the vector is faster than getting them from a list? |
| 21:42 | justin_smith | that'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:42 | justin_smith | BRODUS: I'm not totally certain actually |
| 21:44 | turbofail | i feel like a performance-based reason is unlikely |
| 21:45 | turbofail | but who knows |
| 21:45 | justin_smith | turbofail: try submitting a patch that checks for non-vector sequentials and makes vectors automatically |
| 21:45 | justin_smith | turbofail: it will be rejected for performance reasons |
| 21:46 | justin_smith | turbofail: they reject patches that do sanity checks at runtime in order to have better failure messages - once again, performance reasons |
| 21:50 | turbofail | perhaps. but i feel like this particular thing could be implemented with basically no performance impact |
| 21:50 | justin_smith | do tell? |
| 21:54 | tem0p | is there a version of into that doesnt add duplicates for vectors? or do I just run (distinct col) over it after? |
| 21:55 | justin_smith | ,(into [] (distinct) [1 2 3 3 4 5 1]) |
| 21:55 | clojurebot | [1 2 3 4 5] |
| 21:55 | tem0p | ahhh, perfect, you're awesome, thanks |
| 21:56 | justin_smith | tem0p: the only thing is (distinct) won't check for items already in the vector |
| 21:56 | justin_smith | ,(into [5] (distinct) [1 2 3 3 4 5 1]) |
| 21:56 | clojurebot | [5 1 2 3 4 ...] |
| 21:56 | justin_smith | stupid cut off |
| 21:56 | justin_smith | ,(into [2] (distinct) [1 2 3 3 4 5 1]) |
| 21:56 | clojurebot | [2 1 2 3 4 ...] |
| 21:56 | tem0p | justin_smith: Oh right damn |
| 21:57 | tem0p | justin_smith: If i used a set then I could use union right? |
| 21:57 | justin_smith | tem0p: if you don't care about order |
| 21:57 | tem0p | justin_smith: yeah I dont mind order, that seems good then :) cheers |
| 21:58 | turbofail | hm, 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:59 | turbofail | ,(into {} {:a 0 :b 1}) |
| 21:59 | clojurebot | {:a 0, :b 1} |
| 21:59 | turbofail | so basically it's to make conj do what might be the right thing for map arguments |
| 22:00 | turbofail | and, i guess, any other sequences of MapEntries |
| 22:01 | turbofail | if 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:01 | turbofail | (it'd still be slow for lists, but it wouldn't slow down the vector case) |
| 22:03 | turbofail | whoops, messed up my example |
| 22:03 | turbofail | ,(conj {} {:a 0 :b 1}) |
| 22:03 | clojurebot | {:a 0, :b 1} |
| 22:36 | justin_smith | ,(conj :a {:b 2} {:c 3}) |
| 22:36 | justin_smith | erm |
| 22:36 | clojurebot | #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:36 | justin_smith | ,(conj {} :a {:b 2} {:c 3}) |
| 22:36 | clojurebot | #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:36 | justin_smith | oh, right |
| 22:36 | justin_smith | ,(conj {} [:a {:b 2}] {:c 3}) |
| 22:36 | clojurebot | {:a {:b 2}, :c 3} |