2014-07-12
| 01:14 | technomancy | kegund: not really |
| 04:01 | latk | I'm working through the om tutorial, could anyone explain what the following code does? (defn handle-change [e owner {:keys [text]}] |
| 04:01 | latk | (om/set-state! owner :text (.. e -target -value))) |
| 04:10 | TEttinger | latk, which part of that is confusing first? |
| 04:10 | latk | I don't understand the .., and why target and value have - prepended |
| 04:11 | TEttinger | [e owner {:keys [text]}] <-- this is argument destructuring |
| 04:11 | TEttinger | ok |
| 04:11 | latk | Actually, I'm only guessing about where -target and -value come from |
| 04:12 | TEttinger | .. 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:12 | TEttinger | it's the same as |
| 04:13 | TEttinger | (. (. e -target) -value)) |
| 04:13 | TEttinger | getting target from e, then value from whatever target is |
| 04:13 | latk | Hm, okay. I'm not that clear on what that . does there. |
| 04:14 | TEttinger | ,(. "hey guys" seq) |
| 04:14 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: seq for class java.lang.String> |
| 04:14 | TEttinger | err |
| 04:14 | TEttinger | ,(. "hey guys" length) |
| 04:14 | clojurebot | 8 |
| 04:15 | latk | Ah, so this is interop then ? |
| 04:15 | clojurebot | excusez-moi |
| 04:15 | TEttinger | .. is especially useful in java, but it is also useful in pure js |
| 04:15 | TEttinger | I'm not entirely sure |
| 04:15 | TEttinger | I haven't used cljs |
| 04:16 | latk | Fair enough |
| 04:16 | latk | How should you google for these kind of things? |
| 04:16 | latk | That was my main issue :P |
| 04:16 | latk | I couldn't find anything in the docs relating to them |
| 04:19 | TEttinger | do you mean this tutorial is the one you used? https://github.com/swannodette/om/wiki/Basic-Tutorial |
| 04:20 | TEttinger | http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/.. |
| 04:27 | latk | TEttinger: Yes |
| 04:27 | latk | Also, thanks for that search tip! |
| 04:28 | TEttinger | well one way is in the repl itself! |
| 04:28 | TEttinger | ,(doc ..) |
| 04:28 | clojurebot | "([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:28 | TEttinger | (doc ..) |
| 04:28 | clojurebot | "([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:28 | TEttinger | (doc .) |
| 04:28 | clojurebot | Gabh mo leithscéal? |
| 04:29 | TEttinger | oh? |
| 04:29 | TEttinger | ##(doc .) |
| 04:29 | lazybot | ⇒ "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:29 | latk | Why did you have to do ##? |
| 04:32 | mbac | Exception in thread "main" java.lang.ClassCastException: clojure.core$byte_array cannot be cast to [B |
| 04:32 | mbac | wat |
| 04:37 | TEttinger | mbac, woah |
| 04:37 | TEttinger | what causes that? |
| 04:40 | mbac | TEttinger, http://pastebin.com/Caevuz8K |
| 04:40 | mbac | TAHT |
| 04:40 | mbac | but only when bundled up into an uberjar |
| 04:40 | mbac | if i lein run it it's fine |
| 04:40 | mbac | ??? |
| 04:40 | lazybot | mbac: How could that be wrong? |
| 04:42 | TEttinger | ,(class (byte-array 0 10)) |
| 04:42 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 04:43 | TEttinger | ,(byte-array 0 10) |
| 04:43 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 04:43 | TEttinger | ,(byte-array 10) |
| 04:43 | clojurebot | #<byte[] [B@16509fe> |
| 04:43 | TEttinger | ,(class (byte-array 10)) |
| 04:43 | clojurebot | [B |
| 04:44 | mbac | (let [num-bytes (.read decoded-stream my-byte-array 0 8192)] |
| 04:44 | mbac | that's the line that raises the classcastexception |
| 04:46 | mi6x3m | hey, any way to sort ns-publics in the way they appear in a source file? |
| 04:50 | mbac | hmm, i upgraded lein in the middle of my project |
| 04:51 | mbac | and now that i did lein clean and deleted the jars it works |
| 04:51 | mbac | and now that i did lein clean and deleted the jars and did lein uberjar from scratch it works |
| 04:52 | mbac | sigh. i mean it works because it moved the .jar location to targets/ |
| 04:52 | mbac | and now i'm running those. i was testing an old version somehow. |
| 05:03 | boxed | I 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:54 | tgoossens | What are some good libs to extract content from an html page? |
| 06:04 | boxed | has 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:08 | zoldar | tgoossens: afaik enlive is a pretty good fit for that - aside from being a template library: https://github.com/cgrand/enlive |
| 06:08 | tgoossens | ty |
| 06:10 | cursork | boxed: 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:12 | boxed | I 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:13 | cursork | That sounds more like something I'd use normal persistent data structures for. |
| 06:13 | boxed | there’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:14 | cursork | boxed: 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:15 | cursork | and that is pretty obvious! Mutation is what confuses after the code has grown. |
| 06:16 | boxed | 2 new buckets and recur or something? |
| 06:18 | cursork | Yeah - 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:20 | cursork | If 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:24 | cursork | boxed: Why would you need the done bucket? I can only think for recording what happened? |
| 06:24 | boxed | well, 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:27 | cursork | Not 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:29 | cursork | If 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:29 | AimHere | Yeah, you could write generators in clojure but it would break the functional idiom, and you'd want to use mutable data structures |
| 06:29 | cursork | ,(reduce + (range 5)) |
| 06:29 | clojurebot | 10 |
| 06:29 | cursork | ,(reductions + (range 5)) |
| 06:29 | clojurebot | (0 1 3 6 10) |
| 06:29 | boxed | a generator is a lazy evaluated possibly infinite series… so I guess it’s pretty similar yea |
| 06:33 | boxed | I 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:35 | cursork | Yeah, 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:35 | AlexCohaniuc | hi |
| 06:35 | cursork | If you can do that, you can reduce it |
| 06:36 | cursork | AlexCohaniuc: hi! |
| 06:38 | AlexCohaniuc | Hey :) 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:38 | boxed | I might give it another go… this is the project I was writing if you’re curious; https://github.com/boxed/Instar |
| 06:38 | cursork | AlexCohaniuc: nope :) |
| 06:39 | cursork | boxed: Ah, I saw that before. Probably a good project to really get to grips with Clojure :) |
| 06:40 | boxed | cursork: or in other words “a good project to slam your head against” :P |
| 06:42 | cursork | Ha. Not at all. reduce would work well there though. |
| 06:42 | boxed | hmm, ok, I’ll give it another shot. In any case I think this lib will be pretty nice :P |
| 06:42 | boxed | or is already rather |
| 06:53 | cursork | I hope this is far enough from your goals but helps anyway (learning is good!) |
| 06:53 | cursork | ,((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:53 | clojurebot | {:bar {:baz 2}, :foo 1, :quux 3} |
| 07:28 | onr | which starter book you recommend? |
| 07:42 | cursork | onr: 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:44 | onr | cursork: oh a free, online book. nice |
| 07:46 | cursork | onr: 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:46 | cursork | onr: Yeah - I say give it a go. It's got a good rep, but never read it through myself |
| 07:47 | boxed | cursork: to use reduce for my problem, do I need to figure out how many state transitions I’m gonna need up front? |
| 07:47 | cursork | boxed: Depends what that question means. Sorry to be awkward |
| 07:48 | cursork | 2 secs |
| 07:49 | cursork | So - 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:49 | cursork | If you need to *re-inject* new operations as you go.... Personally I think loop is a bit nicer and explicit. |
| 07:51 | boxed | check |
| 07:51 | cursork | boxed: If the latter. Make sure you're guaranteed to terminate! |
| 07:55 | cursork | boxed: 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:55 | cursork | Now I just have idioms |
| 07:56 | cursork | boxed: But I think the * and introducing a new mini-language is a nice idea to work with |
| 07:59 | boxed | good thing you don’t think I’m crazy… I asked for a lib like this before and got some pretty snarky comments :P |
| 08:00 | cursork | boxed: Right. Ignore that nonsense. Make something that does what you want! |
| 08:00 | cursork | I hate snarkiness |
| 08:02 | cursork | boxed: 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:05 | boxed | I think this lib would have made my previous pet project a lot easier in one especially fugly place, so I have faith :P |
| 08:09 | cursork | boxed: The function I most wanted and re-implemented a more complex version of in my early days is from clojure.set |
| 08:09 | cursork | ,(clojure.set/rename-keys {:foo 1 :bar 2} {:foo :quux}) |
| 08:10 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set> |
| 08:11 | cursork | Why that's not core, I've no idea. result-seq is core! |
| 08:13 | onr | cursork: thank you! |
| 08:15 | cursork | onr: Brave and True working well? |
| 08:16 | onr | cursork: it seems to be great for starting out |
| 08:17 | boxed | cursork: yea, I found that one… very strange to have it in the “set” namespace when you use it to change maps too ^_- |
| 08:18 | cursork | onr: Thanks. Shall recommend it further then |
| 08:19 | cursork | boxed: Yeah. Clojure has plenty of little... inconsistencies. But overall it is not too shabby |
| 08:19 | onr | cursork: exactly. i'm leaving to focus more on this book, thanks again |
| 11:04 | mping | hi all |
| 11:18 | Shayanjm | So my application has definitely scaled past what my Macbook can offer as far as resources go |
| 11:19 | Shayanjm | I'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:20 | catern | why build+push, why not push+build? |
| 11:21 | arrdem | well in clojure "build" is really a lie for the most time... compilation happens when you boot a JVM not when you package code.* |
| 11:22 | arrdem | so 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:23 | Shayanjm | Sure |
| 11:23 | Shayanjm | Wow scaling is much more simple when 'v1' works on a single machine |
| 11:27 | onr | i can't use Emacs |
| 11:29 | catern | yes you can, believe in yourself! |
| 11:30 | arrdem | M-x try-harder RET |
| 11:30 | catern | the fuck is up with spamming in #clojure, it's weird |
| 11:30 | catern | just got a random pm from |
| 11:30 | catern | kikinii |
| 11:30 | arrdem | tell the ##freenode guys |
| 11:31 | catern | (which appears to be a bot) |
| 11:31 | catern | but there's been spamming here before, why are they targeting #clojure instead of other channels? |
| 11:31 | halogenandtoast | If 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:32 | onr | what about LightTable? |
| 11:43 | dnolen_ | halogenandtoast: what is the purpose of that timeout channel? |
| 11:43 | halogenandtoast | I was attempting to get rid of the error with too many takes, it’s probably not necessary. |
| 11:44 | dnolen_ | halogenandtoast: it's likely to cause problems |
| 11:44 | dnolen_ | halogenandtoast: just convert that into (<! keys-pressed) |
| 11:46 | halogenandtoast | I think my problem is I technically want the go block to be synchronous |
| 11:47 | dnolen_ | halogenandtoast: semantically it is |
| 11:47 | halogenandtoast | I’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:48 | halogenandtoast | And I still have the pending takes problem. |
| 11:48 | dnolen_ | halogenandtoast: you need to rethink the problem if you think you can return the player w/ modifications from key presses. |
| 11:48 | dnolen_ | `update-player` does make sense |
| 11:48 | dnolen_ | it's setting up an event loop |
| 11:48 | dnolen_ | s/does/doesn't |
| 11:48 | dnolen_ | not updating a player |
| 11:49 | halogenandtoast | Yeah my main issue is I don’t think I understand channels, the Rich Hickey talk didn’t help either. |
| 11:50 | halogenandtoast | My 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:50 | halogenandtoast | s/update-user/update-player/ |
| 11:51 | halogenandtoast | Basically have a queue of commands, pull off commands and execute them. |
| 11:53 | halogenandtoast | I’m not sure how to rethink that because it “seems” super straightforward (and obviously isn’t) |
| 11:57 | dnolen_ | halogenandtoast: core.async is not particular obvious if you haven't used a CSP system before |
| 11:58 | halogenandtoast | dnolen_: I definitely have not. |
| 11:59 | halogenandtoast | I think I found an example that might help me which doesn’t use channels. |
| 11:59 | dnolen_ | halogenandtoast: how I would do it is that `update-player` -> `event-handler` |
| 12:00 | dnolen_ | `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:01 | halogenandtoast | How does it get a reference to game state though? |
| 12:02 | halogenandtoast | I saw something like this [document.body EventType/KEYUP (partial input-event input-state-ref) true] so maybe similar by using partial |
| 12:03 | halogenandtoast | Probably cargo-culting too much here, but hoping I’ll have a breakthrough. |
| 12:05 | Phonatacid | Hi. 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:13 | halogenandtoast | dnolen_: Thanks for the suggestions, I’ll play around with some of these ideas. |
| 12:15 | cursork | Phonatacid: 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:16 | kegund | Yes... 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:17 | kegund | I'm starting with quil, I think. |
| 12:19 | Phonatacid | cursork: 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:19 | technomancy | kegund: quil is fun, but working over SSH is a lot easier with textual stuff |
| 12:22 | Phonatacid | to 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:26 | kegund | I do have a GUI view too... but hitting the code without it. Very exciting to start!! |
| 12:36 | cursork | Phonatacid: Sorry - stepped away. But is that not a failure anyway? |
| 12:38 | cursork | i.e. nil is nil. Don't test for absence of existence. Try assuming something exists and if it doesn't return early? |
| 12:40 | cursork | Ah, do you want the information anyway, even if something is nil? |
| 12:41 | cursork | Phonatacid: I find the entity API is far more useful (acts as a graph) in that case |
| 12:41 | Phonatacid | I 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:41 | Phonatacid | second request to get the set of refs it contains. |
| 12:42 | Phonatacid | this is a bit cumbersome |
| 12:42 | cursork | Can 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:43 | cursork | Remember that Datomic does a *lot* in the Peer. It's really not that expensive unless you're trawling some massive DB |
| 12:44 | Phonatacid | thank you, I’ll have a look at this |
| 12:44 | cursork | Not sure I helped, but hope I did! |
| 12:50 | halogenandtoast | When 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:50 | technomancy | halogenandtoast: shared between threads, independent of other atoms. |
| 12:50 | technomancy | that is awfully strange wording though, I agree |
| 12:51 | halogenandtoast | Thanks technomancy |
| 13:11 | kegund | So my emacs-live clojure buffers are acting odd w/ respect to the arrow keys. Tells me 'M-[ a is undefined'??? |
| 13:11 | lazybot | kegund: Oh, absolutely. |
| 13:14 | cursork | (inc lazybot) |
| 13:14 | lazybot | ⇒ 29 |
| 13:18 | cursork | kegund: Escape-[-a *is* one of the arrow keys. It's a bad mapping at some level. |
| 13:18 | kegund | Just a minor annoyance for me... onward! |
| 13:22 | technomancy | kegund: not all combinations of modifiers+keys can be represented over SSH |
| 13:23 | technomancy | that's because modifiers were originally implemented as simply masking some bits of the code |
| 14:07 | kegund | Does anyone have a simple way to merge a good set of clojure emacs settings (like emacs-live) with an existing emacs24-starter-kit? |
| 14:11 | technomancy | I recommend ditching them both |
| 14:12 | technomancy | https://github.com/technomancy/emacs-starter-kit/blob/v3/README.markdown |
| 14:42 | oddtodd | How 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:43 | nathan7 | oddtodd: what function are you looking at? |
| 14:43 | TEttinger | oddtodd, usually if it can take a list it can take a vector, thanks to seqs |
| 14:43 | nathan7 | oddtodd: generally, things take *sequences* |
| 14:43 | nathan7 | oddtodd: which include vectors, lists, various other things |
| 14:44 | oddtodd | just in general. i.e. max |
| 14:44 | TEttinger | (doc max) |
| 14:44 | clojurebot | "([x] [x y] [x y & more]); Returns the greatest of the nums." |
| 14:44 | nathan7 | oddtodd: it takes normal arguments |
| 14:44 | nathan7 | oddtodd: but the & is "and the rest" |
| 14:44 | nathan7 | oddtodd: so you can pass it an infinite amount of arguments |
| 14:45 | nathan7 | ,(apply max (range 9000)) |
| 14:45 | clojurebot | 8999 |
| 14:45 | TEttinger | so that has an arglist [x] [x y] [x y & more]. it can be passed x, as in ##(max 9) |
| 14:45 | lazybot | ⇒ 9 |
| 14:45 | TEttinger | it can be passed x and y, as in ##(max 7 9) |
| 14:45 | lazybot | ⇒ 9 |
| 14:45 | clojurebot | Cool story bro. |
| 14:45 | oddtodd | (what I meant is looking at the doc I can't tell if i should pass a quoted list or a vector o |
| 14:46 | TEttinger | they should be very similar but normally you prefer vectors |
| 14:46 | nathan7 | oddtodd: you pass it regular arguments |
| 14:46 | TEttinger | since the syntax is easier a bit and it separates them visually from lists. also it doesn't quote the stuff inside |
| 14:46 | oddtodd | vectors as function parameters rather than a quoted list |
| 14:46 | nathan7 | oddtodd: the [x] is the function's argument vector |
| 14:46 | nathan7 | (defn identity [x] x) |
| 14:47 | nathan7 | ,(source max) |
| 14:47 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 14:47 | nathan7 | damnit |
| 14:47 | nathan7 | oh wow, max is actually implemented as an RT thing |
| 14:48 | Jaood | oddtodd: when a function takes a collection it will be shown as a collection, [[coll]] vs [x] |
| 14:48 | TEttinger | Jaood, no |
| 14:48 | TEttinger | that's only for destructuring |
| 14:49 | TEttinger | ,(defn coll-ident [[coll]] coll) |
| 14:49 | clojurebot | #'sandbox/coll-ident |
| 14:49 | TEttinger | ,(coll-ident [1]) |
| 14:49 | clojurebot | 1 |
| 14:49 | TEttinger | ,(coll-ident [1 2]) |
| 14:49 | clojurebot | 1 |
| 14:49 | Jaood | TEttinger: oh right, true |
| 14:50 | TEttinger | the extra set of [] there makes it get the sub-element of the arg and call it coll, oddtodd |
| 14:52 | oddtodd | (= [0 1 2 3 4 5 6 7 8 9] (take 10 (range 100))) |
| 14:52 | TEttinger | ,(= [0 1 2 3 4 5 6 7 8 9] (take 10 (range 100))) |
| 14:52 | clojurebot | true |
| 14:52 | oddtodd | why is this statement true when take returns a list |
| 14:52 | TEttinger | because the equality test tests by element I believe |
| 14:53 | TEttinger | there's also other equality checks |
| 14:53 | Jaood | TEttinger: 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:53 | TEttinger | ,(doc ==) |
| 14:53 | clojurebot | "([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false" |
| 14:53 | TEttinger | == is only for numbers |
| 14:53 | TEttinger | ,(doc =) |
| 14:53 | clojurebot | "([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:54 | TEttinger | also, take returns a seq not a list |
| 14:55 | oddtodd | so seq or lazy seq is not a list? |
| 14:55 | TEttinger | they're slightly different, and lazy seqs are quite different |
| 14:56 | TEttinger | they do print as () lists |
| 14:56 | TEttinger | but that's just a limitation of how many kinds of bracket there are.... |
| 14:57 | oddtodd | I guess I have to go back and review seq, lazy seq, and list again. Again thank you. |
| 14:57 | TEttinger | lists are kinda rare in clojue |
| 14:57 | TEttinger | so you can make any collection into a seq by calling seq on it, IIRC |
| 14:57 | TEttinger | ,(seq {:a 1 :b 2}) |
| 14:58 | clojurebot | ([:b 2] [:a 1]) |
| 14:58 | TEttinger | that shows that maps, the {} type, are unsorted, and the key-value pairs print like vectors |
| 14:58 | TEttinger | (they technically aren't but can be treated like them) |
| 14:59 | TEttinger | ,(class (first (seq {:a 1 :b 2}))) |
| 14:59 | clojurebot | clojure.lang.MapEntry |
| 14:59 | TEttinger | ,(second (first (seq {:a 1 :b 2}))) |
| 14:59 | clojurebot | 2 |
| 15:03 | oddtodd | why does (max [2 4 3]) not work but (max 2 4 3) work. |
| 15:04 | oddtodd | this is what I meant about not sure what i should pass as a parameter to a function |
| 15:05 | oddtodd | or (max '(2 4 3)) |
| 15:05 | d0ky | hello 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:06 | seanaway | ,(doc max) |
| 15:06 | clojurebot | "([x] [x y] [x y & more]); Returns the greatest of the nums." |
| 15:07 | seanaway | oddtodd: the docs show max takes one arg or two args or any number - not a collection |
| 15:07 | seanaway | (max [1 2 3]) is a single argument - a collection - (max 1 2 3) is three arguments, numbers |
| 15:07 | oddtodd | so if a function takes a collection it would be like [[coll]] this? |
| 15:07 | seanaway | the docs generally use coll or s or m for collection (or sequence or map) |
| 15:08 | seanaway | ,(doc count) |
| 15:08 | clojurebot | "([coll]); Returns the number of items in the collection. (count nil) returns 0. Also works on strings, arrays, and Java Collections and Maps" |
| 15:08 | seanaway | the ([foo]) means a single argument foo |
| 15:08 | seanaway | ([foo bar]) means two arguments |
| 15:08 | seanaway | ([foo] [foo bar]) means it can take one or two arguments |
| 15:09 | seanaway | doc shows a list of the possible argument lists |
| 15:09 | seanaway | ,(doc doc) |
| 15:09 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 15:09 | seanaway | so doc can take only a single argument: name |
| 15:09 | seanaway | ,(doc map) |
| 15:09 | clojurebot | "([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:10 | seanaway | map takes a function, f, and a collection, coll - or a function, f, and two collections, c1 and c2 - or ... |
| 15:10 | seanaway | does that help? |
| 15:12 | TEttinger | usually 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:13 | TEttinger | if 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:14 | oddtodd | your 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:14 | seanaway | oddtodd: depends on what the function expects |
| 15:15 | seanaway | foo and bar were just names (poor ones) as I was trying to emphasize the arity (number of args), not their types |
| 15:15 | TEttinger | so for a good example... |
| 15:15 | TEttinger | ,(map inc [1 2 3]) |
| 15:15 | clojurebot | (2 3 4) |
| 15:15 | TEttinger | that is map called with 2 args |
| 15:16 | oddtodd | from 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:16 | TEttinger | inc , a function that adds one to its arg, and a vector (which is one arg) of 1 2 3 |
| 15:16 | seanaway | ,(doc max) |
| 15:16 | clojurebot | "([x] [x y] [x y & more]); Returns the greatest of the nums." |
| 15:16 | TEttinger | it can take a single number, 2 numbers, or more than 2 numbers |
| 15:16 | seanaway | that 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:17 | seanaway | in 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:17 | TEttinger | if 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:18 | TEttinger | ,(max [1 2 3 4 5 8]) |
| 15:18 | clojurebot | [1 2 3 4 5 ...] |
| 15:18 | seanaway | ...so for (max 3 4 5), x is 3, y is 4, and more is [5] |
| 15:18 | TEttinger | ,(apply max [1 2 3 4 5 8]) |
| 15:18 | clojurebot | 8 |
| 15:23 | halogenandtoast | If 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:25 | oddtodd | Thank you everyone. I'm going to go and do more studying. |
| 15:25 | halogenandtoast | nevermind I can wrap it in fn |
| 15:26 | Jaood | oddtodd: read about variadic functions to understand that |
| 15:26 | oddtodd | ok |
| 15:27 | mi6x3m | clojure, help! |
| 15:27 | Jaood | oddtodd: is similar to varargs in java methods if you know java |
| 15:28 | mi6x3m | I have a binding x holding a symbol y |
| 15:28 | mi6x3m | I want to get the var of the symbol y through x |
| 15:28 | mi6x3m | something like (var x) |
| 15:28 | mi6x3m | any way to achieve this? |
| 15:29 | jasonjck_ | could reducers library have been implemented in terms of transforming monoid fns? |
| 15:30 | oddtodd | I'm familiar with varargs but will look into it as well just to make sure I'm not missing somethin. |
| 15:30 | jasonjck_ | 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:32 | bbloom | jasonjck_: reducers already do that, in essence |
| 15:33 | jasonjck_ | bbloom: well they're not transforming the "combinef" |
| 15:33 | bbloom | jasonjck_: see "fold" |
| 15:33 | jasonjck_ | bbloom: could you get away with just combinef and not reducef ? |
| 15:33 | bbloom | jasonjck_: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj#L95 |
| 15:34 | bbloom | reuses the same function for both |
| 15:34 | bbloom | jasonjck_: also https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj#L320 |
| 15:34 | bbloom | +, *, etc are already monoids |
| 15:35 | jasonjck_ | interesting |
| 15:36 | jasonjck_ | a + reducing fn transformed by a map would not meet monoid properties of associativity though |
| 15:36 | jasonjck_ | because only the right hand side argument to the binary function is doing the map |
| 15:37 | bbloom | i don't follow |
| 15:39 | jasonjck_ | 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:40 | jasonjck_ | s/12/11/ |
| 15:41 | halogenandtoast | Is there a jsfiddle for clojurescript? |
| 15:41 | halogenandtoast | Nevermind googled myself |
| 15:41 | halogenandtoast | Please forgive me. |
| 15:42 | bbloom | jasonjck_: interesting |
| 15:43 | jasonjck_ | bbloom: obviously it works in practice though :) |
| 15:43 | jasonjck_ | the way it's used |
| 15:43 | bbloom | jasonjck_: it's the combine that must be associative |
| 15:44 | halogenandtoast | If anyone is interested, I wrote a pong implementation in clojurescript http://cljsfiddle.net/fiddle/halogenandtoast.pong.main |
| 15:44 | bbloom | jasonjck_: the reducef is always used left-to-right |
| 15:50 | jasonjck_ | 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:51 | bbloom | jasonjck_: agreed. i nominate you to file a ticket with patch :-P |
| 15:51 | jasonjck_ | ok fine |
| 15:51 | seangrov` | jasonjck_: Don't feel too bad, bbloom's style is to 'file' the patch and refuse the ticket |
| 15:52 | bbloom | seangrov`: huh? |
| 15:52 | seangrov` | 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:52 | bbloom | seangrov`: indeed, grumble grumble |
| 15:59 | kegund | technomancy: Thank you! Stripped out emacs-starter-kit... refactored init.el.. Now I'm running native with emacs-live settings loaded over top!!! sweetness. |
| 16:01 | jasonjck_ | http://dev.clojure.org/jira/browse/CLJ-1464 |
| 16:01 | jasonjck_ | Blkt: |
| 16:01 | jasonjck_ | bbloom: |
| 16:02 | bbloom | jasonjck_: lgtm, now you just wait 1 to 3 years |
| 16:02 | jasonjck_ | haha |
| 17:06 | cespare | What does putting a type hint before a function name do? (defn ^String generate-string ([a] ...) ([a b] ....)) |
| 17:06 | cespare | anything? |
| 17:07 | cespare | (For return vals I thought the type hint was before the args vector) |
| 17:08 | bbloom_ | cespare: it's also return value |
| 17:08 | bbloom_ | seems like the docs don't mention it |
| 17:15 | lodin | cespare: See http://clojure.org/metadata (near the bottom), and the link in that document. |
| 17:17 | amalloy | cespare: 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:17 | amalloy | i can never remember if hinting the arglist works for non-primitives as well; i never use it |
| 17:18 | Bronsa | amalloy: it does |
| 17:24 | cespare | thanks guys |
| 17:26 | cespare | indeed, the docs don't mention it. |
| 18:19 | Glenjamin | are there any cljs api docs around? or is it safe to assume clojure's api is present? |
| 18:39 | gfredericks | definitely not safe |
| 18:40 | Glenjamin | also, i was hoping to be able to figure out how Protocols in cljs work, but i just got a bit lost in macros |
| 18:41 | kristof | That happens. |
| 18:55 | gfredericks | how they're implemented? or the API for defining a protocol? |
| 18:55 | Glenjamin | how they're implemented |
| 18:55 | Glenjamin | i'd like to expose the ability to extend core protocols in mori |
| 18:56 | gfredericks | you might try compiling a simple defprotocol to see what comes out the back |
| 18:57 | Glenjamin | good idea |
| 18:57 | gfredericks | and similar things with defrecord, deftype, & extend wrt your protocol |
| 18:59 | Glenjamin | i shall do this |
| 18:59 | Glenjamin | i feel like i should have thought of that :) |
| 19:09 | nathan7 | Glenjamin: if you find any good cljs docs, do tell |
| 19:10 | mbac | how is (apply + [1 2 3]) different from (reduce + [1 2 3])? |
| 19:10 | mbac | i know they're different things just wondering if one is more efficient than the other |
| 19:11 | mbac | especially if the collection is huge |
| 19:11 | Glenjamin | apply can be lazy |
| 19:12 | Glenjamin | which means depending on what you're doing, each could be more efficient than the other |
| 20:00 | gfredericks | mbac: they're asymptotically the same (O(n)) |
| 20:01 | gfredericks | you can check the source of + to see that in the variadic case it calls reduce anyhow |
| 20:01 | gfredericks | but for other functions the differences can be subtler; concat is a great example |
| 20:07 | Glenjamin | what do you mean by iteration-friendly? |
| 20:08 | randomcharhere | hello |
| 20:12 | gfredericks | Glenjamin: where (reduce concat colls) isn't a stack-threat |
| 20:13 | Glenjamin | ,(doc satisfies?) |
| 20:13 | clojurebot | "([protocol x]); Returns true if x satisfies the protocol" |
| 20:13 | Glenjamin | ,(satisfies? clojure.core.protocols.Reducible (concat '(1) '(2))) |
| 20:13 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: clojure.core.protocols.Reducible, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:14 | Glenjamin | ,(satisfies? clojure.core.protocols/CollReduce (concat '(1) '(2))) |
| 20:14 | clojurebot | true |
| 20:14 | Glenjamin | potentially, LazySeq already does this ^^ |
| 20:16 | gfredericks | it's not the execution of reduce that's a stack threat, it's realizing the return value |
| 20:16 | gfredericks | ,(def my-nums (reduce concat (repeat 5000 [42]))) |
| 20:16 | clojurebot | #'sandbox/my-nums |
| 20:16 | gfredericks | ,(first my-nums) |
| 20:16 | clojurebot | #<StackOverflowError java.lang.StackOverflowError> |
| 20:16 | Glenjamin | oh right |
| 20:20 | gfredericks | only thought so far is what if the LazySeq class had an extra field called tails that was a vector of seqs |
| 20:21 | Glenjamin | ,[*print-length*, *print-level*] |
| 20:21 | clojurebot | [5 10] |
| 20:21 | Glenjamin | ,(apply concat (repeat 5000 [42])) |
| 20:21 | clojurebot | (42 42 42 42 42 ...) |
| 20:21 | Glenjamin | i really don't get why that overflows :s |
| 20:21 | bbloom | gfredericks: tail call elimination would help a great deal ;-) |
| 20:24 | gfredericks | actually it would prollably have to be a persistent queue |
| 20:39 | fifosine | What function am I looking for such that "sux" will not be printed? |
| 20:39 | fifosine | (when [nil] (println "sux")) |
| 20:39 | gfredericks | I can't tell what you're trying to do there |
| 20:39 | Glenjamin | ,(doc with-out-str) |
| 20:39 | clojurebot | "([& 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:40 | Glenjamin | i suspect thats not what you meant |
| 20:41 | fifosine | ,(when [nil] (println "sux")) |
| 20:41 | clojurebot | sux\n |
| 20:41 | fifosine | In 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:42 | gfredericks | ,(when nil (println "sux")) |
| 20:42 | clojurebot | nil |
| 20:42 | Glenjamin | you wrapped it in a vector |
| 20:42 | gfredericks | fifosine: it's a vector with nil in it, not nil |
| 20:42 | fifosine | ... |
| 20:42 | fifosine | dumb |
| 20:42 | Shayanjm | lol |
| 20:42 | Glenjamin | vectors only appear in "syntax" forms when they bind variables |
| 20:43 | fifosine | Glenjamin: I had "when-let" in my head so got confused |
| 20:43 | gfredericks | does eastwood warn about that one? |
| 20:46 | Glenjamin | testing truthiness of a literal seems a sensible warn to have |
| 20:46 | andyf | gfredericks: Eastwood does not warn about that one, but a Github issue suggesting it, with an example, would be welcome. |
| 20:47 | gfredericks | ON IT |
| 20:50 | fifosine | If my function definition has optional keyword arguments, is there a way to require at least 1 be present? |
| 20:52 | gfredericks | not a nice way |
| 20:52 | fifosine | I.e., you can provide 1, 2, or all of A, B, and C but not 0 |
| 20:54 | mikerod | where is the "best" impl of clojure-in-clojure currently to be found at? |
| 20:55 | mikerod | Is 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:56 | mikerod | According to https://github.com/Bronsa/CinC this is just tools.analyzer, tools.analyzer.jvm, tools.emitter.jvm now |
| 20:57 | bbloom | mikerod: you've found it |
| 20:57 | mikerod | bbloom: Wouldn't the idea be to have the core abstractions also defined in clj? |
| 20:58 | mikerod | are those in those projects? |
| 20:58 | bbloom | mikerod: no, that's not on the agenda yet, afaik |
| 20:58 | bbloom | not mentioned is tool.reader too |
| 20:59 | mikerod | bbloom: ah I see. |
| 20:59 | mikerod | so for now everything still interacts via the clojure.lang.RT and all of the java interfaces + impls |
| 20:59 | bbloom | yes |
| 20:59 | bbloom | bootstrapping the data structures is a much harder problem |
| 20:59 | mikerod | ok, that clears that up |
| 20:59 | mikerod | bbloom: I thought so, that's why I wanted to see it :) |
| 20:59 | mikerod | So now I'm sad |
| 21:00 | bbloom | mikerod: you can look at the clojurescript source |
| 21:00 | mikerod | However, I've been looking a bit into the tools.analyzer stuff and I do think it is very cool |
| 21:00 | hiredman | much more tedious problem |
| 21:00 | mikerod | bbloom: yeah, I have briefly glanced at cljs for this sort of thing. I think I'll check it out a bit more. |
| 21:00 | hiredman | ugh, some spam bot is sitting on the channel messaging people who speak again |
| 21:00 | mikerod | hiredman: I think that hit me |
| 21:00 | bbloom | hiredman: it's not just tedium, there's lots of subtleties around initialization order |
| 21:03 | arktvrvs | hmm |
| 21:04 | hiredman | bbloom: I think the problem there is picking a solution from all the possible solutions |
| 21:05 | hiredman | e.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:07 | bbloom | hiredman: yeah, then when you're done you need to make sure none of the loop N-1 structures stuck around :-P |
| 21:07 | hiredman | sure |
| 21:07 | hiredman | have to run lein clean all the time |
| 21:07 | bbloom | having tried bootstrapping various little languages, it's a massive mind bender :-P |
| 21:09 | mikerod | What are "cow versions" |
| 21:09 | hiredman | copy on write |
| 21:09 | mikerod | ah I see |
| 21:09 | bbloom | moo. |
| 21:09 | mikerod | :D |
| 21:09 | hiredman | cowabunga |
| 21:10 | mikerod | I do not know enough about bootstrapping something like this. |
| 21:10 | mikerod | I was hoping I could get a lesson from cinc |
| 21:10 | mikerod | Is cljs a good example? |
| 21:11 | hiredman | not really, clojurescript's compiler is written in clojure, not clojurescript |
| 21:11 | mikerod | hiredman: that's what I thought |
| 21:11 | mikerod | it just "bootstraps" off of clj |
| 21:11 | mikerod | was my thoughts on it |
| 21:11 | mikerod | my thought* |
| 21:12 | hiredman | I 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:12 | hiredman | but I suspect it generates very naive js |
| 21:12 | bbloom | the world could use a really good "here's how you bootstrap a lisp" tutorial |
| 21:12 | mikerod | Hmm I see. |
| 21:12 | mikerod | bbloom: agreed |
| 21:12 | bbloom | would be nice to have a worked example |
| 21:12 | hiredman | *shrug* |
| 21:12 | mikerod | who wants to write it? |
| 21:13 | bbloom | nobody sane, that's for sure :-P |
| 21:13 | mikerod | :P |
| 21:13 | bbloom | it's like monads |
| 21:13 | bbloom | once you get how it works, you're incapable of explaining it |
| 21:13 | bbloom | only w/ monads 379573895793657 people have written a tutorial |
| 21:13 | bbloom | for bootstrappign a lisp, i think there's roughly 0 :-L |
| 21:14 | mikerod | haha |
| 21:20 | nathan7 | bbloom: my favourite is http://mainisusuallyafunction.blogspot.nl/2012/04/scheme-without-special-forms.html |
| 21:20 | nathan7 | bbloom: it describes implementing an F-expression LISP |
| 21:43 | melipone | hi everyone! Where can I find the complete API for clojure.core.matrix? |
| 22:53 | seancorfield | melipone did anyone answer you re: core.matrix? |
| 22:54 | seangrove | What 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:54 | seancorfield | Looks like there's no autodoc-generated page for it (which is what the API docs are for the rest of Clojure & Contrib)... |
| 22:55 | seancorfield | seangrove mixed cljs versions in play? |
| 22:57 | seangrove | seancorfield: Hrm, doesn't seem to be. Seems like all of clojure.core is missing :P |