#clojure logs

2014-07-12

01:14technomancykegund: not really
04:01latkI'm working through the om tutorial, could anyone explain what the following code does? (defn handle-change [e owner {:keys [text]}]
04:01latk (om/set-state! owner :text (.. e -target -value)))
04:10TEttingerlatk, which part of that is confusing first?
04:10latkI don't understand the .., and why target and value have - prepended
04:11TEttinger[e owner {:keys [text]}] <-- this is argument destructuring
04:11TEttingerok
04:11latkActually, I'm only guessing about where -target and -value come from
04:12TEttinger.. is a macro in regular clojure and probably is in cljs too. it takes the first arg (e here), calls a function on it (here, -target, which is a name for a property accessor IIRC in CLJS), then calls another function on the result of that until it runs out of functions
04:12TEttingerit's the same as
04:13TEttinger(. (. e -target) -value))
04:13TEttingergetting target from e, then value from whatever target is
04:13latkHm, okay. I'm not that clear on what that . does there.
04:14TEttinger,(. "hey guys" seq)
04:14clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: seq for class java.lang.String>
04:14TEttingererr
04:14TEttinger,(. "hey guys" length)
04:14clojurebot8
04:15latkAh, so this is interop then ?
04:15clojurebotexcusez-moi
04:15TEttinger.. is especially useful in java, but it is also useful in pure js
04:15TEttingerI'm not entirely sure
04:15TEttingerI haven't used cljs
04:16latkFair enough
04:16latkHow should you google for these kind of things?
04:16latkThat was my main issue :P
04:16latkI couldn't find anything in the docs relating to them
04:19TEttingerdo you mean this tutorial is the one you used? https://github.com/swannodette/om/wiki/Basic-Tutorial
04:20TEttingerhttp://clojure.github.io/clojure/clojure.core-api.html#clojure.core/..
04:27latkTEttinger: Yes
04:27latkAlso, thanks for that search tip!
04:28TEttingerwell one way is in the repl itself!
04:28TEttinger,(doc ..)
04:28clojurebot"([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."
04:28TEttinger(doc ..)
04:28clojurebot"([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."
04:28TEttinger(doc .)
04:28clojurebotGabh mo leithscéal?
04:29TEttingeroh?
04:29TEttinger##(doc .)
04:29lazybot⇒ "Special: .; The instance member form works for both fields and methods.\n They all expand into calls to the dot operator at macroexpansion time."
04:29latkWhy did you have to do ##?
04:32mbacException in thread "main" java.lang.ClassCastException: clojure.core$byte_array cannot be cast to [B
04:32mbacwat
04:37TEttingermbac, woah
04:37TEttingerwhat causes that?
04:40mbacTEttinger, http://pastebin.com/Caevuz8K
04:40mbacTAHT
04:40mbacbut only when bundled up into an uberjar
04:40mbacif i lein run it it's fine
04:40mbac???
04:40lazybotmbac: How could that be wrong?
04:42TEttinger,(class (byte-array 0 10))
04:42clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
04:43TEttinger,(byte-array 0 10)
04:43clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
04:43TEttinger,(byte-array 10)
04:43clojurebot#<byte[] [B@16509fe>
04:43TEttinger,(class (byte-array 10))
04:43clojurebot[B
04:44mbac (let [num-bytes (.read decoded-stream my-byte-array 0 8192)]
04:44mbacthat's the line that raises the classcastexception
04:46mi6x3mhey, any way to sort ns-publics in the way they appear in a source file?
04:50mbachmm, i upgraded lein in the middle of my project
04:51mbacand now that i did lein clean and deleted the jars it works
04:51mbacand now that i did lein clean and deleted the jars and did lein uberjar from scratch it works
04:52mbacsigh. i mean it works because it moved the .jar location to targets/
04:52mbacand now i'm running those. i was testing an old version somehow.
05:03boxedI just pushed a lib to github: https://github.com/boxed/Instar <- it’s the answer to the question I asked two days ago about how to easily modify multiple points in datastructures :P
05:54tgoossensWhat are some good libs to extract content from an html page?
06:04boxedhas anyone used transients? I tried using a transient vector for a problem but it just seems like the API is unusable for anything. pop! returning the collection and there being no peek is pretty annoying for example… how are you supposed to use them?
06:08zoldartgoossens: afaik enlive is a pretty good fit for that - aside from being a template library: https://github.com/cgrand/enlive
06:08tgoossensty
06:10cursorkboxed: What are you trying to do? I use transients, but rarely. They have a specific use-case, and it's not likely you want / need them
06:12boxedI have a list of rules that I process to create new rules and there’s an end condition when the rule is fully evaluated. So I want to have a bucket of things that aren’t done yet, and one with things that are done, and then when the todo-bucket is empty return the result.
06:13cursorkThat sounds more like something I'd use normal persistent data structures for.
06:13boxedthere’s probably a more functional way to do it, but I couldn’t figure it out, and I thought that if I can’t figure it out pretty fast, no one reading the code in the future can figure it out anyway :P
06:14cursorkboxed: You'd be surprised - the Clojure way would be to create 2 new buckets every iteration (unless performance turns out to be a concern *under measurement*)
06:15cursorkand that is pretty obvious! Mutation is what confuses after the code has grown.
06:16boxed2 new buckets and recur or something?
06:18cursorkYeah - so the typical FP way would be tail-recursion using loop-recur. If you don't need the 'done' bucket (i.e. you're not tracking multiple data structures on each iteration), then a seq-based algorithm might be more idiomatic clojure
06:20cursorkIf the list of things to do is fixed, reduce is good. You take your state and pass it through a series of transformations. 'Empty todo-bucket' being the natural termination - empty seq.
06:24cursorkboxed: Why would you need the done bucket? I can only think for recording what happened?
06:24boxedwell, I probably don’t, in python I’d just do “yield foo” and be fine with it, but I couldn’t figure out how to do something like that in clojure :P
06:27cursorkNot familiar with Python (dirty old Perl for me ;) ) but I think yield is for generators. And they can be used in places we'd use lazy sequences?
06:29cursorkIf you're returning an updated state each time, a reduce-like approach could work. There's reductions which will give you the state at each point.
06:29AimHereYeah, you could write generators in clojure but it would break the functional idiom, and you'd want to use mutable data structures
06:29cursork,(reduce + (range 5))
06:29clojurebot10
06:29cursork,(reductions + (range 5))
06:29clojurebot(0 1 3 6 10)
06:29boxeda generator is a lazy evaluated possibly infinite series… so I guess it’s pretty similar yea
06:33boxedI tried using reduce first actually… couldn’t figure it out. The light table instarepl helps a lot, but sometimes it just doesn’t show you what you want to see
06:35cursorkYeah, I think the best way to figure out a reduce based solution (if it is appropriate) is to write a function from state and new value to new state. And just test that.
06:35AlexCohaniuchi
06:35cursorkIf you can do that, you can reduce it
06:36cursorkAlexCohaniuc: hi!
06:38AlexCohaniucHey :) I'm new to IRC. Trying to post a question to #elementary-dev buyt no one seems to answer so I thought maybe there is something wrong with my client
06:38boxedI might give it another go… this is the project I was writing if you’re curious; https://github.com/boxed/Instar
06:38cursorkAlexCohaniuc: nope :)
06:39cursorkboxed: Ah, I saw that before. Probably a good project to really get to grips with Clojure :)
06:40boxedcursork: or in other words “a good project to slam your head against” :P
06:42cursorkHa. Not at all. reduce would work well there though.
06:42boxedhmm, ok, I’ll give it another shot. In any case I think this lib will be pretty nice :P
06:42boxedor is already rather
06:53cursorkI hope this is far enough from your goals but helps anyway (learning is good!)
06:53cursork,((fn transform [m & args] (reduce (fn [m [k-vec v]] (assoc-in m k-vec v)) m (partition 2 args))) {:quux 3} [:foo] 1 [:bar :baz] 2)
06:53clojurebot{:bar {:baz 2}, :foo 1, :quux 3}
07:28onrwhich starter book you recommend?
07:42cursorkonr: Off the wall answer: The Little Schemer (and friends) ;). On Clojure lots of people say good things about Clojure for the Brave and True.
07:44onrcursork: oh a free, online book. nice
07:46cursorkonr: If you're an experienced programmer, I really thought the Joy of Clojure was great (although I read it after already working in Clojure). And don't think it has to be always 'the second book you read about Clojure' (which seems to be the prevailing opinion)
07:46cursorkonr: Yeah - I say give it a go. It's got a good rep, but never read it through myself
07:47boxedcursork: to use reduce for my problem, do I need to figure out how many state transitions I’m gonna need up front?
07:47cursorkboxed: Depends what that question means. Sorry to be awkward
07:48cursork2 secs
07:49cursorkSo - if you have 'some sequence of operations', but that knowledge is outside the reduce then you can create a lazyseq of some description and it'll be fine.
07:49cursorkIf you need to *re-inject* new operations as you go.... Personally I think loop is a bit nicer and explicit.
07:51boxedcheck
07:51cursorkboxed: If the latter. Make sure you're guaranteed to terminate!
07:55cursorkboxed: I once wrote (but never published) a series of data manip libraries doing things on top of Clojure's abstractions. I feel it's a rite of passage to try to bend them to your will
07:55cursorkNow I just have idioms
07:56cursorkboxed: But I think the * and introducing a new mini-language is a nice idea to work with
07:59boxedgood thing you don’t think I’m crazy… I asked for a lib like this before and got some pretty snarky comments :P
08:00cursorkboxed: Right. Ignore that nonsense. Make something that does what you want!
08:00cursorkI hate snarkiness
08:02cursorkboxed: If you feel afterwards you don't need it, that's even better! But I think it's interesting to explore the "instar" problem space. Also much respect for publishing code openly as you learn
08:05boxedI think this lib would have made my previous pet project a lot easier in one especially fugly place, so I have faith :P
08:09cursorkboxed: The function I most wanted and re-implemented a more complex version of in my early days is from clojure.set
08:09cursork,(clojure.set/rename-keys {:foo 1 :bar 2} {:foo :quux})
08:10clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>
08:11cursorkWhy that's not core, I've no idea. result-seq is core!
08:13onrcursork: thank you!
08:15cursorkonr: Brave and True working well?
08:16onrcursork: it seems to be great for starting out
08:17boxedcursork: yea, I found that one… very strange to have it in the “set” namespace when you use it to change maps too ^_-
08:18cursorkonr: Thanks. Shall recommend it further then
08:19cursorkboxed: Yeah. Clojure has plenty of little... inconsistencies. But overall it is not too shabby
08:19onrcursork: exactly. i'm leaving to focus more on this book, thanks again
11:04mpinghi all
11:18ShayanjmSo my application has definitely scaled past what my Macbook can offer as far as resources go
11:19ShayanjmI'll need to start building this on a remote machine. Does anyone have any suggestions on how to set up that environment? nREPL, or build things locally + push and hope they work remotely?
11:20caternwhy build+push, why not push+build?
11:21arrdemwell in clojure "build" is really a lie for the most time... compilation happens when you boot a JVM not when you package code.*
11:22arrdemso to me this means load, lint, test (, typecheck?) as "build", then "push" does a git-push to somewhere with post-recieve hooks that boot and run whatever you're working on.
11:23ShayanjmSure
11:23ShayanjmWow scaling is much more simple when 'v1' works on a single machine
11:27onri can't use Emacs
11:29caternyes you can, believe in yourself!
11:30arrdemM-x try-harder RET
11:30caternthe fuck is up with spamming in #clojure, it's weird
11:30caternjust got a random pm from
11:30caternkikinii
11:30arrdemtell the ##freenode guys
11:31catern(which appears to be a bot)
11:31caternbut there's been spamming here before, why are they targeting #clojure instead of other channels?
11:31halogenandtoastIf anyone is familiar with core.async (and clojurescript) could you help me understand how to make channels work in this case https://gist.github.com/halogenandtoast/6f2f3ac2ed0ba57acfa6 I can’t update the player and I get the error message at the top.
11:32onrwhat about LightTable?
11:43dnolen_halogenandtoast: what is the purpose of that timeout channel?
11:43halogenandtoastI was attempting to get rid of the error with too many takes, it’s probably not necessary.
11:44dnolen_halogenandtoast: it's likely to cause problems
11:44dnolen_halogenandtoast: just convert that into (<! keys-pressed)
11:46halogenandtoast I think my problem is I technically want the go block to be synchronous
11:47dnolen_halogenandtoast: semantically it is
11:47halogenandtoastI’ve update with what you said https://gist.github.com/halogenandtoast/6f2f3ac2ed0ba57acfa6, but the return value for update-player needs to be player (with modifications)
11:48halogenandtoastAnd I still have the pending takes problem.
11:48dnolen_halogenandtoast: you need to rethink the problem if you think you can return the player w/ modifications from key presses.
11:48dnolen_`update-player` does make sense
11:48dnolen_it's setting up an event loop
11:48dnolen_s/does/doesn't
11:48dnolen_not updating a player
11:49halogenandtoastYeah my main issue is I don’t think I understand channels, the Rich Hickey talk didn’t help either.
11:50halogenandtoastMy thought process was to append to a channel in the event, then have an update-user method which would modify the user if any events were present.
11:50halogenandtoasts/update-user/update-player/
11:51halogenandtoastBasically have a queue of commands, pull off commands and execute them.
11:53halogenandtoastI’m not sure how to rethink that because it “seems” super straightforward (and obviously isn’t)
11:57dnolen_halogenandtoast: core.async is not particular obvious if you haven't used a CSP system before
11:58halogenandtoastdnolen_: I definitely have not.
11:59halogenandtoastI think I found an example that might help me which doesn’t use channels.
11:59dnolen_halogenandtoast: how I would do it is that `update-player` -> `event-handler`
12:00dnolen_`event-handler` updates the game state and either puts the updated world on a channel or invokes a render function which re-renders the novelty
12:01halogenandtoastHow does it get a reference to game state though?
12:02halogenandtoastI saw something like this [document.body EventType/KEYUP (partial input-event input-state-ref) true] so maybe similar by using partial
12:03halogenandtoastProbably cargo-culting too much here, but hoping I’ll have a breakthrough.
12:05PhonatacidHi. In datomic, how can I simulate NULL values for cardinality/many refs ? You can do that with datomic’s get-else function, but it only works with cardinality/one attributes.
12:13halogenandtoastdnolen_: Thanks for the suggestions, I’ll play around with some of these ideas.
12:15cursorkPhonatacid: I find it helps to build my Datomic usage around the idea that the DB is a set of 'facts' about unique entities. So I would try to avoid any kind of testing for none on cardinality/many attributes.
12:16kegundYes... I have emacs-live running on a CentOS VM. Connected via ssh & screen. Fresh new .emacs.d too. Suggestions for learning the clojure keys that would be new to me?
12:17kegundI'm starting with quil, I think.
12:19Phonatacidcursork: I’m currently writing two requests because I have two place a test inbetween. It uses data from request 1 to determine if request 2 is runnable. I’m using the missing? function to soften the problem down though
12:19technomancykegund: quil is fun, but working over SSH is a lot easier with textual stuff
12:22Phonatacidto be clearer, my request is runnable only if there is a at least one item in the many-valued ref attribute. If there is none, the unification process fails, and consequently I can’t grab data I fetch in request 1 and which is essential for the next steps in the program.
12:26kegundI do have a GUI view too... but hitting the code without it. Very exciting to start!!
12:36cursorkPhonatacid: Sorry - stepped away. But is that not a failure anyway?
12:38cursorki.e. nil is nil. Don't test for absence of existence. Try assuming something exists and if it doesn't return early?
12:40cursorkAh, do you want the information anyway, even if something is nil?
12:41cursorkPhonatacid: I find the entity API is far more useful (acts as a graph) in that case
12:41PhonatacidI need to get my hand on some entid and do something with it — what I do depends on the presence (either 0 or more) of refs in the many-valued attribute. Unfortunately, due to the way unification works, when there is no refs at all I can’t get the entity id. So what I do is get the entid and what the missing? predicate returns for the attribute in a first request and, if the attribute is not missing, I carry out a
12:41Phonatacidsecond request to get the set of refs it contains.
12:42Phonatacidthis is a bit cumbersome
12:42cursorkCan you get the set of potential entids you're interested in up-front? If so, I'd use datomic.api/entity and use the very natural clojure map-like structure available
12:43cursorkRemember that Datomic does a *lot* in the Peer. It's really not that expensive unless you're trawling some massive DB
12:44Phonatacidthank you, I’ll have a look at this
12:44cursorkNot sure I helped, but hope I did!
12:50halogenandtoastWhen the docs for atoms say “Atoms provide a way to manage shared, synchronous, independent state. “ what do they mean by shared and independent those seem like opposites.
12:50technomancyhalogenandtoast: shared between threads, independent of other atoms.
12:50technomancythat is awfully strange wording though, I agree
12:51halogenandtoastThanks technomancy
13:11kegundSo my emacs-live clojure buffers are acting odd w/ respect to the arrow keys. Tells me 'M-[ a is undefined'???
13:11lazybotkegund: Oh, absolutely.
13:14cursork(inc lazybot)
13:14lazybot⇒ 29
13:18cursorkkegund: Escape-[-a *is* one of the arrow keys. It's a bad mapping at some level.
13:18kegundJust a minor annoyance for me... onward!
13:22technomancykegund: not all combinations of modifiers+keys can be represented over SSH
13:23technomancythat's because modifiers were originally implemented as simply masking some bits of the code
14:07kegundDoes anyone have a simple way to merge a good set of clojure emacs settings (like emacs-live) with an existing emacs24-starter-kit?
14:11technomancyI recommend ditching them both
14:12technomancyhttps://github.com/technomancy/emacs-starter-kit/blob/v3/README.markdown
14:42oddtoddHow can I tell if a function is expecting me to pass a list, a vector, or a single value? Any help would be greatly appreciated. When I read the doc I can't seem to tell.
14:43nathan7oddtodd: what function are you looking at?
14:43TEttingeroddtodd, usually if it can take a list it can take a vector, thanks to seqs
14:43nathan7oddtodd: generally, things take *sequences*
14:43nathan7oddtodd: which include vectors, lists, various other things
14:44oddtoddjust in general. i.e. max
14:44TEttinger(doc max)
14:44clojurebot"([x] [x y] [x y & more]); Returns the greatest of the nums."
14:44nathan7oddtodd: it takes normal arguments
14:44nathan7oddtodd: but the & is "and the rest"
14:44nathan7oddtodd: so you can pass it an infinite amount of arguments
14:45nathan7,(apply max (range 9000))
14:45clojurebot8999
14:45TEttingerso that has an arglist [x] [x y] [x y & more]. it can be passed x, as in ##(max 9)
14:45lazybot⇒ 9
14:45TEttingerit can be passed x and y, as in ##(max 7 9)
14:45lazybot⇒ 9
14:45clojurebotCool story bro.
14:45oddtodd(what I meant is looking at the doc I can't tell if i should pass a quoted list or a vector o
14:46TEttingerthey should be very similar but normally you prefer vectors
14:46nathan7oddtodd: you pass it regular arguments
14:46TEttingersince the syntax is easier a bit and it separates them visually from lists. also it doesn't quote the stuff inside
14:46oddtoddvectors as function parameters rather than a quoted list
14:46nathan7oddtodd: the [x] is the function's argument vector
14:46nathan7(defn identity [x] x)
14:47nathan7,(source max)
14:47clojurebot#<SecurityException java.lang.SecurityException: denied>
14:47nathan7damnit
14:47nathan7oh wow, max is actually implemented as an RT thing
14:48Jaoododdtodd: when a function takes a collection it will be shown as a collection, [[coll]] vs [x]
14:48TEttingerJaood, no
14:48TEttingerthat's only for destructuring
14:49TEttinger,(defn coll-ident [[coll]] coll)
14:49clojurebot#'sandbox/coll-ident
14:49TEttinger,(coll-ident [1])
14:49clojurebot1
14:49TEttinger,(coll-ident [1 2])
14:49clojurebot1
14:49JaoodTEttinger: oh right, true
14:50TEttingerthe extra set of [] there makes it get the sub-element of the arg and call it coll, oddtodd
14:52oddtodd(= [0 1 2 3 4 5 6 7 8 9] (take 10 (range 100)))
14:52TEttinger,(= [0 1 2 3 4 5 6 7 8 9] (take 10 (range 100)))
14:52clojurebottrue
14:52oddtoddwhy is this statement true when take returns a list
14:52TEttingerbecause the equality test tests by element I believe
14:53TEttingerthere's also other equality checks
14:53JaoodTEttinger: I guess the answer to him would be that is hard to know if don't read the source or doc of the function since clojure is not statically typed
14:53TEttinger,(doc ==)
14:53clojurebot"([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false"
14:53TEttinger== is only for numbers
14:53TEttinger,(doc =)
14:53clojurebot"([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison."
14:54TEttingeralso, take returns a seq not a list
14:55oddtoddso seq or lazy seq is not a list?
14:55TEttingerthey're slightly different, and lazy seqs are quite different
14:56TEttingerthey do print as () lists
14:56TEttingerbut that's just a limitation of how many kinds of bracket there are....
14:57oddtoddI guess I have to go back and review seq, lazy seq, and list again. Again thank you.
14:57TEttingerlists are kinda rare in clojue
14:57TEttingerso you can make any collection into a seq by calling seq on it, IIRC
14:57TEttinger,(seq {:a 1 :b 2})
14:58clojurebot([:b 2] [:a 1])
14:58TEttingerthat shows that maps, the {} type, are unsorted, and the key-value pairs print like vectors
14:58TEttinger(they technically aren't but can be treated like them)
14:59TEttinger,(class (first (seq {:a 1 :b 2})))
14:59clojurebotclojure.lang.MapEntry
14:59TEttinger,(second (first (seq {:a 1 :b 2})))
14:59clojurebot2
15:03oddtoddwhy does (max [2 4 3]) not work but (max 2 4 3) work.
15:04oddtoddthis is what I meant about not sure what i should pass as a parameter to a function
15:05oddtoddor (max '(2 4 3))
15:05d0kyhello assume this pseudo code https://www.refheap.com/88125 what is the best way to achieve that goal i wrote that some questions can anybody help me with it im not very familiar with expert system or rare algorithm or if it fits to that problem
15:06seanaway,(doc max)
15:06clojurebot"([x] [x y] [x y & more]); Returns the greatest of the nums."
15:07seanawayoddtodd: the docs show max takes one arg or two args or any number - not a collection
15:07seanaway(max [1 2 3]) is a single argument - a collection - (max 1 2 3) is three arguments, numbers
15:07oddtoddso if a function takes a collection it would be like [[coll]] this?
15:07seanawaythe docs generally use coll or s or m for collection (or sequence or map)
15:08seanaway,(doc count)
15:08clojurebot"([coll]); Returns the number of items in the collection. (count nil) returns 0. Also works on strings, arrays, and Java Collections and Maps"
15:08seanawaythe ([foo]) means a single argument foo
15:08seanaway([foo bar]) means two arguments
15:08seanaway([foo] [foo bar]) means it can take one or two arguments
15:09seanawaydoc shows a list of the possible argument lists
15:09seanaway,(doc doc)
15:09clojurebot"([name]); Prints documentation for a var or special form given its name"
15:09seanawayso doc can take only a single argument: name
15:09seanaway,(doc map)
15:09clojurebot"([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."
15:10seanawaymap takes a function, f, and a collection, coll - or a function, f, and two collections, c1 and c2 - or ...
15:10seanawaydoes that help?
15:12TEttingerusually it refers to collections (anything that can be seq'd and most java collections) as an arg called coll, or if it takes more c1 and c2 etc.
15:13TEttingerif there's extra [[]] then that's destructuring, which can be tricky and isn't common in the standard lib (though it is very common in clojure in-the-wild)
15:14oddtoddyour example [foo bar] means foo and bar cannot be referenced to a list or vector. if I were to assign bar to a vector of integers, (max foo bar) would not work.
15:14seanawayoddtodd: depends on what the function expects
15:15seanawayfoo and bar were just names (poor ones) as I was trying to emphasize the arity (number of args), not their types
15:15TEttingerso for a good example...
15:15TEttinger,(map inc [1 2 3])
15:15clojurebot(2 3 4)
15:15TEttingerthat is map called with 2 args
15:16oddtoddfrom the doc max takes [x y] and i don't know if this means a single variable or a vector or a list or any of these possible variation.
15:16TEttingerinc , a function that adds one to its arg, and a vector (which is one arg) of 1 2 3
15:16seanaway,(doc max)
15:16clojurebot"([x] [x y] [x y & more]); Returns the greatest of the nums."
15:16TEttingerit can take a single number, 2 numbers, or more than 2 numbers
15:16seanawaythat says it can take one argument, x, or two arguments, x and y, or any number of arguments, x and y and the rest of the arguments
15:17seanawayin the x y & more case, internally it gets bindings for x, y, and more where x is the first arg, y is the second arg, and more is a sequence of all the rest...
15:17TEttingerif you want to change it to work on a collection, you can make a collection into more-than-x arguments and pass them to a function with apply
15:18TEttinger,(max [1 2 3 4 5 8])
15:18clojurebot[1 2 3 4 5 ...]
15:18seanaway...so for (max 3 4 5), x is 3, y is 4, and more is [5]
15:18TEttinger,(apply max [1 2 3 4 5 8])
15:18clojurebot8
15:23halogenandtoastIf you use the thread first macro is there any reference to the value passed in if I want to use it later in the call?
15:25oddtoddThank you everyone. I'm going to go and do more studying.
15:25halogenandtoastnevermind I can wrap it in fn
15:26Jaoododdtodd: read about variadic functions to understand that
15:26oddtoddok
15:27mi6x3mclojure, help!
15:27Jaoododdtodd: is similar to varargs in java methods if you know java
15:28mi6x3mI have a binding x holding a symbol y
15:28mi6x3mI want to get the var of the symbol y through x
15:28mi6x3msomething like (var x)
15:28mi6x3many way to achieve this?
15:29jasonjck_could reducers library have been implemented in terms of transforming monoid fns?
15:30oddtoddI'm familiar with varargs but will look into it as well just to make sure I'm not missing somethin.
15:30jasonjck_if you did parallel subdivisions in forkjoin all the way down to segments of size 1, then you're using the monoid to reduce from top to bottom
15:32bbloomjasonjck_: reducers already do that, in essence
15:33jasonjck_bbloom: well they're not transforming the "combinef"
15:33bbloomjasonjck_: see "fold"
15:33jasonjck_bbloom: could you get away with just combinef and not reducef ?
15:33bbloomjasonjck_: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj#L95
15:34bbloomreuses the same function for both
15:34bbloomjasonjck_: also https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj#L320
15:34bbloom+, *, etc are already monoids
15:35jasonjck_interesting
15:36jasonjck_a + reducing fn transformed by a map would not meet monoid properties of associativity though
15:36jasonjck_because only the right hand side argument to the binary function is doing the map
15:37bbloomi don't follow
15:39jasonjck_1 + 10 = 10 + 1 = 11; but if you transform reducing function + with a filter such as <5 (specifically the reducer transformation used in reducers.clj for filter), then it's not associative anymore 1 + 10 = 1 since 10 is not <5, but 10 + 1 = 12
15:40jasonjck_s/12/11/
15:41halogenandtoastIs there a jsfiddle for clojurescript?
15:41halogenandtoastNevermind googled myself
15:41halogenandtoastPlease forgive me.
15:42bbloomjasonjck_: interesting
15:43jasonjck_bbloom: obviously it works in practice though :)
15:43jasonjck_the way it's used
15:43bbloomjasonjck_: it's the combine that must be associative
15:44halogenandtoastIf anyone is interested, I wrote a pong implementation in clojurescript http://cljsfiddle.net/fiddle/halogenandtoast.pong.main
15:44bbloomjasonjck_: the reducef is always used left-to-right
15:50jasonjck_bbloom: it should actually be "([combinef coll] (fold combinef combinef coll))" as every combine fn is a reducer fn, but not every reducer fn is a combine fn
15:51bbloomjasonjck_: agreed. i nominate you to file a ticket with patch :-P
15:51jasonjck_ok fine
15:51seangrov`jasonjck_: Don't feel too bad, bbloom's style is to 'file' the patch and refuse the ticket
15:52bbloomseangrov`: huh?
15:52seangrov`bbloom: You generally complain about the JIRA workflow and filing tickets that are going to be ignored, but that doesn't stop you making patches ;)
15:52bbloomseangrov`: indeed, grumble grumble
15:59kegundtechnomancy: Thank you! Stripped out emacs-starter-kit... refactored init.el.. Now I'm running native with emacs-live settings loaded over top!!! sweetness.
16:01jasonjck_http://dev.clojure.org/jira/browse/CLJ-1464
16:01jasonjck_Blkt:
16:01jasonjck_bbloom:
16:02bbloomjasonjck_: lgtm, now you just wait 1 to 3 years
16:02jasonjck_haha
17:06cespareWhat does putting a type hint before a function name do? (defn ^String generate-string ([a] ...) ([a b] ....))
17:06cespareanything?
17:07cespare(For return vals I thought the type hint was before the args vector)
17:08bbloom_cespare: it's also return value
17:08bbloom_seems like the docs don't mention it
17:15lodincespare: See http://clojure.org/metadata (near the bottom), and the link in that document.
17:17amalloycespare: for functions which don't return primitives, hinting the function name works; that's the only syntax that existed, before the ebility to return primitives by hinting the arglist was added in 1.3
17:17amalloyi can never remember if hinting the arglist works for non-primitives as well; i never use it
17:18Bronsaamalloy: it does
17:24cesparethanks guys
17:26cespareindeed, the docs don't mention it.
18:19Glenjaminare there any cljs api docs around? or is it safe to assume clojure's api is present?
18:39gfredericksdefinitely not safe
18:40Glenjaminalso, i was hoping to be able to figure out how Protocols in cljs work, but i just got a bit lost in macros
18:41kristofThat happens.
18:55gfrederickshow they're implemented? or the API for defining a protocol?
18:55Glenjaminhow they're implemented
18:55Glenjamini'd like to expose the ability to extend core protocols in mori
18:56gfredericksyou might try compiling a simple defprotocol to see what comes out the back
18:57Glenjamingood idea
18:57gfredericksand similar things with defrecord, deftype, & extend wrt your protocol
18:59Glenjamini shall do this
18:59Glenjamini feel like i should have thought of that :)
19:09nathan7Glenjamin: if you find any good cljs docs, do tell
19:10mbachow is (apply + [1 2 3]) different from (reduce + [1 2 3])?
19:10mbaci know they're different things just wondering if one is more efficient than the other
19:11mbacespecially if the collection is huge
19:11Glenjaminapply can be lazy
19:12Glenjaminwhich means depending on what you're doing, each could be more efficient than the other
20:00gfredericksmbac: they're asymptotically the same (O(n))
20:01gfredericksyou can check the source of + to see that in the variadic case it calls reduce anyhow
20:01gfredericksbut for other functions the differences can be subtler; concat is a great example
20:07Glenjaminwhat do you mean by iteration-friendly?
20:08randomcharherehello
20:12gfredericksGlenjamin: where (reduce concat colls) isn't a stack-threat
20:13Glenjamin,(doc satisfies?)
20:13clojurebot"([protocol x]); Returns true if x satisfies the protocol"
20:13Glenjamin,(satisfies? clojure.core.protocols.Reducible (concat '(1) '(2)))
20:13clojurebot#<CompilerException java.lang.ClassNotFoundException: clojure.core.protocols.Reducible, compiling:(NO_SOURCE_PATH:0:0)>
20:14Glenjamin,(satisfies? clojure.core.protocols/CollReduce (concat '(1) '(2)))
20:14clojurebottrue
20:14Glenjaminpotentially, LazySeq already does this ^^
20:16gfredericksit's not the execution of reduce that's a stack threat, it's realizing the return value
20:16gfredericks,(def my-nums (reduce concat (repeat 5000 [42])))
20:16clojurebot#'sandbox/my-nums
20:16gfredericks,(first my-nums)
20:16clojurebot#<StackOverflowError java.lang.StackOverflowError>
20:16Glenjaminoh right
20:20gfredericksonly thought so far is what if the LazySeq class had an extra field called tails that was a vector of seqs
20:21Glenjamin,[*print-length*, *print-level*]
20:21clojurebot[5 10]
20:21Glenjamin,(apply concat (repeat 5000 [42]))
20:21clojurebot(42 42 42 42 42 ...)
20:21Glenjamini really don't get why that overflows :s
20:21bbloomgfredericks: tail call elimination would help a great deal ;-)
20:24gfredericksactually it would prollably have to be a persistent queue
20:39fifosineWhat function am I looking for such that "sux" will not be printed?
20:39fifosine(when [nil] (println "sux"))
20:39gfredericksI can't tell what you're trying to do there
20:39Glenjamin,(doc with-out-str)
20:39clojurebot"([& body]); Evaluates exprs in a context in which *out* is bound to a fresh StringWriter. Returns the string created by any nested printing calls."
20:40Glenjamini suspect thats not what you meant
20:41fifosine,(when [nil] (println "sux"))
20:41clojurebotsux\n
20:41fifosineIn my head, that shouldn't've happened because nil should evaluate false, but clearly I'm wrong, so I'm looking for another function that sees nil as false
20:42gfredericks,(when nil (println "sux"))
20:42clojurebotnil
20:42Glenjaminyou wrapped it in a vector
20:42gfredericksfifosine: it's a vector with nil in it, not nil
20:42fifosine...
20:42fifosinedumb
20:42Shayanjmlol
20:42Glenjaminvectors only appear in "syntax" forms when they bind variables
20:43fifosineGlenjamin: I had "when-let" in my head so got confused
20:43gfredericksdoes eastwood warn about that one?
20:46Glenjamintesting truthiness of a literal seems a sensible warn to have
20:46andyfgfredericks: Eastwood does not warn about that one, but a Github issue suggesting it, with an example, would be welcome.
20:47gfredericksON IT
20:50fifosineIf my function definition has optional keyword arguments, is there a way to require at least 1 be present?
20:52gfredericksnot a nice way
20:52fifosineI.e., you can provide 1, 2, or all of A, B, and C but not 0
20:54mikerodwhere is the "best" impl of clojure-in-clojure currently to be found at?
20:55mikerodIs there any definitive location of this yet? I believe that there is some "serious" plans out there for attempting this that I've heard about.
20:56mikerodAccording to https://github.com/Bronsa/CinC this is just tools.analyzer, tools.analyzer.jvm, tools.emitter.jvm now
20:57bbloommikerod: you've found it
20:57mikerodbbloom: Wouldn't the idea be to have the core abstractions also defined in clj?
20:58mikerodare those in those projects?
20:58bbloommikerod: no, that's not on the agenda yet, afaik
20:58bbloomnot mentioned is tool.reader too
20:59mikerodbbloom: ah I see.
20:59mikerodso for now everything still interacts via the clojure.lang.RT and all of the java interfaces + impls
20:59bbloomyes
20:59bbloombootstrapping the data structures is a much harder problem
20:59mikerodok, that clears that up
20:59mikerodbbloom: I thought so, that's why I wanted to see it :)
20:59mikerodSo now I'm sad
21:00bbloommikerod: you can look at the clojurescript source
21:00mikerodHowever, I've been looking a bit into the tools.analyzer stuff and I do think it is very cool
21:00hiredmanmuch more tedious problem
21:00mikerodbbloom: yeah, I have briefly glanced at cljs for this sort of thing. I think I'll check it out a bit more.
21:00hiredmanugh, some spam bot is sitting on the channel messaging people who speak again
21:00mikerodhiredman: I think that hit me
21:00bbloomhiredman: it's not just tedium, there's lots of subtleties around initialization order
21:03arktvrvshmm
21:04hiredmanbbloom: I think the problem there is picking a solution from all the possible solutions
21:05hiredmane.g. bootstrap using an earlier version of clojure, via some kind of fallback to java structures, boostrap via simple cow versions of the structures, etc
21:07bbloomhiredman: yeah, then when you're done you need to make sure none of the loop N-1 structures stuck around :-P
21:07hiredmansure
21:07hiredmanhave to run lein clean all the time
21:07bbloomhaving tried bootstrapping various little languages, it's a massive mind bender :-P
21:09mikerodWhat are "cow versions"
21:09hiredmancopy on write
21:09mikerodah I see
21:09bbloommoo.
21:09mikerod:D
21:09hiredmancowabunga
21:10mikerodI do not know enough about bootstrapping something like this.
21:10mikerodI was hoping I could get a lesson from cinc
21:10mikerodIs cljs a good example?
21:11hiredmannot really, clojurescript's compiler is written in clojure, not clojurescript
21:11mikerodhiredman: that's what I thought
21:11mikerodit just "bootstraps" off of clj
21:11mikerodwas my thoughts on it
21:11mikerodmy thought*
21:12hiredmanI think there are some unofficial ports of the clojurescript compiler to clojurescript, so you can run the compiler in the browser without needing a jvm
21:12hiredmanbut I suspect it generates very naive js
21:12bbloomthe world could use a really good "here's how you bootstrap a lisp" tutorial
21:12mikerodHmm I see.
21:12mikerodbbloom: agreed
21:12bbloomwould be nice to have a worked example
21:12hiredman*shrug*
21:12mikerodwho wants to write it?
21:13bbloomnobody sane, that's for sure :-P
21:13mikerod:P
21:13bbloomit's like monads
21:13bbloomonce you get how it works, you're incapable of explaining it
21:13bbloomonly w/ monads 379573895793657 people have written a tutorial
21:13bbloomfor bootstrappign a lisp, i think there's roughly 0 :-L
21:14mikerodhaha
21:20nathan7bbloom: my favourite is http://mainisusuallyafunction.blogspot.nl/2012/04/scheme-without-special-forms.html
21:20nathan7bbloom: it describes implementing an F-expression LISP
21:43meliponehi everyone! Where can I find the complete API for clojure.core.matrix?
22:53seancorfieldmelipone did anyone answer you re: core.matrix?
22:54seangroveWhat am I missing if I have a bunch of warnings along the lines of WARNING: Use of undeclared Var clojure.string/reduce at line 16 file:/Users/sgrove/.m2/repository/org/clojure/clojurescript/0.0-2197/clojurescript-0.0-2197.jar!/clojure/string.cljs ?
22:54seancorfieldLooks like there's no autodoc-generated page for it (which is what the API docs are for the rest of Clojure & Contrib)...
22:55seancorfieldseangrove mixed cljs versions in play?
22:57seangroveseancorfield: Hrm, doesn't seem to be. Seems like all of clojure.core is missing :P