2014-06-09
| 00:01 | technomancy | danielcompton: weird, on some machines there is very little difference. thanks for the input. |
| 00:02 | technomancy | seems like this will have to delay the release further =( |
| 00:04 | danielcompton | technomancy some faster, some slower, some the same? |
| 00:04 | technomancy | no, some a handful of ms slower, some ~500ms slower |
| 00:04 | technomancy | none faster |
| 00:04 | technomancy | but I wouldn't block a release over <10ms |
| 00:06 | danielcompton | Isn't https://www.refheap.com/86389 faster on the new version? |
| 00:07 | technomancy | oh crap, yeah |
| 00:08 | technomancy | didn't notice that |
| 00:10 | technomancy | danielcompton: can you move ~/.lein/profiles.clj out of the way and try again? |
| 00:12 | technomancy | oh, I see what the difference is |
| 00:12 | technomancy | 2.2.0 -> 2.4.0 is slower but 2.3.4 -> 2.4.0 isn't |
| 00:13 | technomancy | except for cbp |
| 00:13 | technomancy | he somehow has outrageously fast 2.3.4 invocations?? |
| 00:13 | lazybot | technomancy: Uh, no. Why would you even ask? |
| 00:13 | danielcompton | technomancy https://www.refheap.com/86390 |
| 00:14 | technomancy | curious |
| 00:14 | technomancy | http://p.hagelb.org/mystery.gif |
| 00:15 | technomancy | cbp: teach me your secrets |
| 00:15 | hellofunk | can anyone enlighten me on the difference between (take! ...) and (go (<! ...)) -- both are async takes; assuming you don't have a complex go body that requires continued "parking," is there a difference between these? |
| 00:18 | technomancy | danielcompton: is your `lein` command a symlink to a git checkout of lein? |
| 00:19 | danielcompton | I'm using homebrew, it looks like that I think |
| 00:21 | danielcompton | My /usr/local/bin is a symlink to /usr/local/Cellar/leiningen/2.3.4/bin/lein |
| 00:21 | danielcompton | My /usr/local/bin/lein is a symlink to /usr/local/Cellar/leiningen/2.3.4/bin/lein |
| 00:21 | danielcompton | and that is a git repo |
| 00:21 | technomancy | oh gotcha. would it be too much trouble to try against a manual lein install? |
| 00:22 | justin_smith | I don't think homebrew for lein is a loss, using straight lein is actually simpler and easier to manage versions / upgrade |
| 00:22 | justin_smith | *homebrew for lein is a loss, that is |
| 00:26 | danielcompton | technomancy not at all, I'll do that now |
| 00:29 | danielcompton | justin_smith how is it any different using homebrew? It means I have a consistent way of upgrading packages |
| 00:30 | justin_smith | but lein handles upgrades and versions better than homebrew does - thus homebrew introduces an abstraction layer that in this case improves nothing in its indirection |
| 00:31 | justin_smith | same problem (if not worse) using the linux apt package for lein |
| 00:33 | cbp | technomancy: dat ssd man |
| 00:34 | technomancy | this wouldn't be the first time homebrew screwed up their lein packaging |
| 00:34 | technomancy | wouldn't be the second either |
| 00:34 | hellofunk | three times is a charm |
| 00:36 | technomancy | justin_smith: if it's coming from apt then at least there's a single file on my system I can add it to so that I can bootstrap a fresh machine to have everything I need on it (assuming a relatively recent version) |
| 00:37 | technomancy | but with brew you can't even do that |
| 00:38 | justin_smith | so how is the nixos project coming along anyway? I wonder |
| 00:38 | justin_smith | http://nixos.org/ |
| 00:39 | benkay | in the context of compojure routes, how does one set up a destructuring bind for params while preserving the URL param? (GET "/thinger/:stuff" [{params :params} stuff :as req]) isn't working for me |
| 00:40 | justin_smith | that :as clause is misplaced |
| 00:40 | justin_smith | it uses standard destructuring syntax |
| 00:41 | justin_smith | ,(let [stuff {:a 0 :b 1 :params "ok"} {params :params :as req} stuff] params) |
| 00:42 | clojurebot | "ok" |
| 00:42 | justin_smith | if something works in a let destructure, it should work in a compojure destructure, and visa versa |
| 00:43 | benkay | destructuring is not my strong point. thanks for the tips. |
| 00:43 | justin_smith | benkay: I never made sense of it until I experimented for a while with let in the repl |
| 01:09 | danielcompton | technomancy here's my results with a manual lein install https://www.refheap.com/86391 |
| 01:14 | ddellacosta | did we figure out a way to test code involving core.async? |
| 01:15 | danielcompton | ddellacosta yes but it requires Rich Hickey's toenails and eye of newt |
| 01:15 | ddellacosta | danielcompton: damn, that shit is pricey too |
| 01:16 | ddellacosta | I guess I can probably expense it though |
| 01:17 | danielcompton | ddellacosta stranger things have been put on a company card |
| 01:17 | ddellacosta | danielcompton: not sure I want to know... |
| 01:17 | Hodapp | o_O |
| 01:18 | ddellacosta | huh, I guess one approach is to mock the receiving channel |
| 01:18 | ddellacosta | but does that mean I have to have a test in a go block? blech |
| 01:18 | ddellacosta | "integration tests: yer doing it wrong." *sigh* |
| 01:19 | danielcompton | ddellacosta yo dawg |
| 01:19 | danielcompton | https://groups.google.com/d/msg/clojurescript/OlyylM4LMEk/u3LLyBLLQmQJ |
| 01:20 | ddellacosta | okay, so apparently it's hard in CLJS although I know clojurescript.test supports it now, but apparently using <!! provides an answer? Thanks for the clue danielcompton |
| 01:20 | danielcompton | ddellacosta how do you verb yourself in IRC? |
| 01:21 | ddellacosta | danielcompton: oh, you mean the "ddellacosta goes off to investigate thing?" just type /me and then the thing you want to say |
| 01:22 | tolstoy | I fell for that once. |
| 01:22 | ddellacosta | tolstoy: now I'm scared, what does that do? |
| 01:22 | tolstoy | One Windows (I think), it closes the app. |
| 01:22 | ddellacosta | tolstoy: ah, okay |
| 01:23 | ddellacosta | http://knowyourmeme.com/memes/alt-f4 |
| 01:23 | ddellacosta | gotcha |
| 01:23 | ddellacosta | mean |
| 01:23 | tolstoy | Hah! Wow. |
| 01:23 | ddellacosta | I know, it's amazing what folks will do |
| 01:23 | danielcompton | What are peoples thoughts on (= nil nil) being true |
| 01:24 | danielcompton | Coming from a SQL background where that isn't the case it caught me out a few times |
| 01:24 | ddellacosta | danielcompton: well, it makes sense, why? I mean, nil is equal to nil |
| 01:25 | danielcompton | ddellacosta I guess nil could also mean undefined so two undefined values compared should = ? |
| 01:26 | danielcompton | ddellacosta I think I like it still, though I do ponder it every now and then |
| 01:26 | ddellacosta | danielcompton: well, except it is explicitly not undefined in Clojure, it's nil (is I guess what I would respond with) |
| 01:26 | ddellacosta | heh |
| 01:27 | danielcompton | ddellacosta: you're right, that's why it makes sense |
| 01:27 | ddellacosta | danielcompton: for me this is meaningful useful when I'm using it with multi-methods or protocols, for example--I can define behavior based on nil |
| 01:27 | ddellacosta | *meaningfully useful |
| 01:27 | ddellacosta | ye good olde nil object pattern |
| 01:28 | ddellacosta | er, null rather |
| 01:55 | justin_smith | the sooner everyone upgrades from nil to proper option types the better |
| 01:56 | danielcompton | justin_smith how do you do that in Clojure? |
| 01:56 | danielcompton | *with Clojure |
| 01:58 | justin_smith | with static typing :P |
| 02:00 | danielcompton | justin_smith typed clojure? |
| 02:01 | justin_smith | maybe one can do option types with core.typed, I haven't used it actually |
| 02:02 | justin_smith | I've just been learning some stronger typed languages lately, and enjoy the absence of unexpected nil values (instead getting an error for non-exhaustive value matching) |
| 02:07 | ddellacosta | justin_smith: agreed that ADTs are the way to go here |
| 02:08 | ddellacosta | justin_smith: a Null Object is kind of a poor imitation of doing it properly w/ADTs |
| 02:08 | justin_smith | that is one way to look at it, yeah |
| 02:09 | justin_smith | do adts predate null in plt history? |
| 02:11 | ddellacosta | justin_smith: I can't answer that, good question. I suspect not |
| 02:12 | ddellacosta | ambrosebs: do ADTs predate null in PLT history? I figure you may know. ;-) |
| 02:12 | ddellacosta | d'oh, not around perhaps |
| 02:15 | dbasch | I believe pointers are from the 60s and ADTs were formalized in the 70s |
| 02:16 | justin_smith | ahh and pointers in practice pretty directly lead to a nil / null value |
| 02:16 | ddellacosta | right, makes sense |
| 02:16 | justin_smith | adts are from simula67, according to this paper http://www.cs.utexas.edu/users/wcook/papers/OOPvsADT/CookOOPvsADT90.pdf |
| 02:17 | ddellacosta | was just going to ask, thanks |
| 02:17 | ddellacosta | huh, so ADTs are *post* OOP? interesting |
| 02:17 | justin_smith | well, that description makes them sound parallel |
| 02:17 | ddellacosta | ah |
| 02:17 | justin_smith | (the description in that paper) |
| 02:18 | ddellacosta | justin_smith: right, gotcha. Very interesting, sounds like it's been an ongoing dialogue between the two "camps" if they can be described as such |
| 02:19 | ddellacosta | very nice, thanks for that paper |
| 02:19 | justin_smith | np |
| 02:20 | ddellacosta | I guess the lesson is that these things rarely spring fully formed from someone's mind; they are the result of ongoing discussion and attempts at implementations along the way, as well as new theoretical frameworks that come about |
| 02:20 | dbasch | in the late 90s I was a TA for Jeannette Wing, who liked to rant about how Java was all wrong regarding types |
| 02:21 | ddellacosta | ah, CMU bigshot! |
| 02:21 | ddellacosta | dbasch: wow, that must have been super educational |
| 02:21 | dbasch | yes, she was very sharp |
| 02:21 | ddellacosta | dbasch: huh, she's partially responsible for Liskov substitution principle, didn't realize that |
| 02:22 | justin_smith | I've been learning ats, which is ml-derived and has a type system that a) only exists at compile time, reverting to an untyped runtime fully compatible with c in the compiled code and b) generalizes typing to verification arbitrary static properties (ie. guarantees that the code cannot write off the end of a given array) |
| 02:22 | ddellacosta | justin_smith: so it's kind of like a type-safe C pre-processor? |
| 02:23 | justin_smith | ddellacosta: exactly, while also extending what "type-safe" can mean via proof constructing in the typechecker |
| 02:23 | ddellacosta | interesting, will check it out |
| 02:23 | justin_smith | also it is weird and kind of a pain in the ass and very experimental :) |
| 02:23 | justin_smith | it has its ups and downs to be sure :) |
| 02:23 | ddellacosta | haha...fun. :-) |
| 02:24 | ddellacosta | dbasch: curious what she said about Java though, although I already had a strong intuition that Java's typing was pretty crap |
| 02:24 | justin_smith | the author have very odd naming conventions - ie. a second order function has the type "-<cloref1> a" which is just stupid naming |
| 02:25 | ddellacosta | justin_smith: wat |
| 02:25 | justin_smith | yeah, I know |
| 02:25 | justin_smith | oh, sorry, that's a closed over function, my bad |
| 02:25 | justin_smith | but still, the name doesn't help me remember which is which :) |
| 02:26 | ddellacosta | justin_smith: yeah, it's really not clear what's going on there regardless |
| 02:26 | justin_smith | but on the other hand, ml syntax and semantics compiling to raw c, which is kind of awesome |
| 02:27 | dbasch | ddellacosta: obviously she didn’t like the fact that the Liskov substitution principle didn’t hold in Java |
| 02:27 | justin_smith | and not your typical "my compiler generates a tangle of convoluted inefficient c", but actual like n gc or type tags or size field on the array c code |
| 02:27 | ddellacosta | dbasch: ah, haha |
| 02:29 | justin_smith | reading about liskov substitution, it seems like hoare logic (from which that is derived) also informs the kind of theorem proving type system ats uses |
| 02:30 | justin_smith | many times ats types will actually look like an argument, plus a type, plus arbitrary pre-conditions like you would see in a clojure :pre block |
| 02:32 | hellofunk | pilates? good for the muscles |
| 02:35 | justin_smith | I read "java concurrency in practice" recently, and one thing I noticed was how often they talked about things that must be invariant but could not be expressed directly in the language |
| 02:35 | justin_smith | which smells funny, to be sure |
| 02:37 | gws | if i'd like to call a method in one namespace on something created via deftype in another namespace, is the idiomatic way to do that just dot-notation?\ |
| 02:39 | justin_smith | gws: yeah, and use import in the other namespace |
| 02:40 | justin_smith | gws: the exception being if you implement a protocol, then you should use require to bring the protocol functions into scope, and use those |
| 02:40 | justin_smith | but for regular methods just use dot notation |
| 02:43 | gws | justin_smith: ah, thanks! i am implementing a protocol, actually... though simply requiring the type's constructor (e.g. ->MyType) without the imports (which works). when i try to require the protocol functions into scope, i get "no such var" |
| 02:43 | gws | however dot-notation works |
| 02:44 | justin_smith | how are you doing the require? |
| 02:45 | gws | [myns.mail :as mail] in an ns form, then mail/mymethod - is it necessary to :refer? |
| 02:46 | justin_smith | no, that should all work |
| 02:47 | justin_smith | myns.mail is where you define the protocol, correct? |
| 02:47 | gws | alright, thanks. let me check again. if i can't make it work, i'll reduce it and put the code up somewhere |
| 02:47 | justin_smith | the protocol functions need to be pulled in from the ns that defines the protocol, not the one where you define the type implementing the protocol |
| 02:48 | gws | this is code that I haven't refactored properly so they are not yet separate namespaces. is that my problem? |
| 02:49 | gws | in other words, deftype and defprotocol are in the same ns |
| 02:49 | justin_smith | nope, that would even prvent this problem |
| 02:50 | justin_smith | one moment, let me try to find a place on github in one of my projects that demonstrates this stuff |
| 02:51 | gws | sorry i missed it - yes, myns.mail is where both defprotocol and deftype are |
| 02:52 | justin_smith | https://github.com/caribou/caribou-c3p0-plugin/blob/master/src/caribou/plugin/c3p0.clj here is an ns implementing a protocol (using a defrecord) |
| 02:52 | justin_smith | https://github.com/caribou/caribou-plugin/blob/master/src/caribou/plugin/protocol.clj here is where the protocol and the convenience function that implements it for that record are defined |
| 02:53 | justin_smith | both quite small namespaces, so it should be pretty straightforward to see what is being done |
| 02:53 | ddellacosta | a macro that defines helper functions and an instance of a type in a namespace: ugly? Is there a better strategy for configuring a set of easy-of-use helper functions? |
| 02:53 | ddellacosta | *ease-of-use |
| 02:54 | justin_smith | ddellacosta: the annoying part is when I try and use that namespace, and look for the definitions of said instance and convenience functions |
| 02:55 | ddellacosta | justin_smith: yeah, that's my reservation too. But I should be more clear--this would be something the user of the lib would call in their own application |
| 02:55 | ddellacosta | justin_smith: so they'd do something in my.ns like (init-lib! arg1 arg2 arg3 arg4) |
| 02:55 | ddellacosta | justin_smith: and then they'd be able to call my.ns/helper1, my.ns/helper2 |
| 02:55 | justin_smith | hmm |
| 02:56 | justin_smith | seems like it is just passing the buck, because their code ends of having said problem |
| 02:56 | ddellacosta | justin_smith: to give a bit more explanation, what I'm trying to avoid is that the user calls the lower-level fns every time with four args |
| 02:56 | ddellacosta | two or three of which may never change during the lifetime of that lib user's application |
| 02:57 | ddellacosta | justin_smith: it's passing the buck in one sense, but it's also try to avoid them typing redundant crap all the time |
| 02:57 | ddellacosta | justin_smith: I'm just really not sure how to structure this so that the user can set up these defaults in a clean way, and have them available consistently |
| 02:57 | justin_smith | what about making the functions so that they return the params as an options map, such that they can be chained? |
| 02:58 | ddellacosta | justin_smith: sorry, I don't follow--how would that avoid having the user have to call the functions with those args every time? |
| 02:59 | justin_smith | oh, I misunderstood, sorry |
| 02:59 | justin_smith | I thought you meant multiple functions taking the same args |
| 02:59 | justin_smith | but you mean multiple calls with the same args |
| 02:59 | ddellacosta | justin_smith: oh, yeah, exactly |
| 03:00 | amalloy | ddellacosta: instead of passing the same four args to N functions, they could pass one map to the N functions, i think is what justin_smith was suggesting |
| 03:00 | justin_smith | well, then in that case you can have them use a configuration map - see how the connection data is in a map as the first arg to just about every clojure.java.jdbc function |
| 03:00 | justin_smith | yeah, pretty much |
| 03:00 | ddellacosta | amalloy, justin_smith: yeah, maybe a config/option map is really the right way to do this |
| 03:01 | ddellacosta | it seems a bit uglier, but I'm wary of macro magic |
| 03:01 | justin_smith | an options map is easy for a user to wrap if they find it cumbersome |
| 03:01 | justin_smith | by defining a partial for example |
| 03:02 | ddellacosta | justin_smith: yeah |
| 03:02 | justin_smith | but better that than scratch my head over where something is even defined, IMHO |
| 03:02 | ddellacosta | agreed |
| 03:02 | ddellacosta | okay, thanks! |
| 03:09 | gws | justin_smith: thanks for the code. i reduced it to an example which is very similar to mine, and it does work as I expected - so I've got bigger problems |
| 03:09 | gws | http://pastebin.com/e1Npfhtt |
| 03:09 | gws | justin_smith: i'll dig in to this, but good to know it works as I originally thought :) |
| 03:10 | justin_smith | so is the pasted one the one that works? |
| 03:10 | gws | yep |
| 03:11 | gws | which is how i expect it to work |
| 03:15 | gws | i think your point about needing to pull in the ns in which the protocol is originally defined was my problem |
| 03:15 | gws | I've got a second deftype in there which implements a protocol from a different ns |
| 03:15 | gws | ugh |
| 03:15 | gws | so that's the issue |
| 03:15 | gws | got it now, thanks |
| 03:16 | justin_smith | np |
| 03:24 | dfg888 | selling intim |
| 03:41 | allenj12 | has anyone compared hoplon vs reagent vs om? |
| 03:46 | allenj12 | it seems hoplon is much more mature than om |
| 03:46 | allenj12 | and reagent to for that matter |
| 03:46 | michaniskin | allenj12: i can answer any questions you have about hoplon |
| 03:48 | allenj12 | michaniskin: ok well let me put it like this i was going through the om tutorials, and to be honest they kinda sucked it was hard to tell what om was doing alot of the time. i guess my questons are is hoplon mature? does hoplon have better docs than om? and is hoplon easy? |
| 03:49 | allenj12 | michaniskin: like literally oms advance tutorial was a blank page, it was quite sad |
| 03:49 | michaniskin | allenj12: you should look at http://hoplon.io/#/getting-started/ |
| 03:50 | michaniskin | that will give you an idea of what it's like |
| 03:50 | allenj12 | michaniskin: just am now it looks way better already, im assuming its more popular than om? |
| 03:50 | michaniskin | i don't know if it's exactly "easy", but i think it's pretty simple |
| 03:51 | michaniskin | there aren't a lot of things to know about it, really, but it is kind of weird |
| 03:51 | michaniskin | once you get over how weird it is i think it's pretty straightforward |
| 03:52 | michaniskin | i think it's a lot less popular, but it's hard to tell |
| 03:53 | allenj12 | michaniskin: o really? im assuming you prefer it tho? and theres good reason to? |
| 03:53 | justin_smith | allenj12: om is a specific lib for optimizing re-rendering of dynamic changes to pages, I think it can be used inside hoplon even |
| 03:53 | michaniskin | i'm one of the guys working on it :) |
| 03:53 | kzar | allenj12: There definitely was quite a bit of coverage of Om on hacker news a while back and I've heard less hype about hoplon. But more hype does not better technology make. (I regretfully still haven't tried either in earnest.) |
| 03:53 | kzar | I think both are worth giving a try |
| 03:53 | justin_smith | allenj12: you will probably figure things out faster if you start without om and then start using it if you need its features |
| 03:54 | michaniskin | allenj12: you might want to look at the demos: https://github.com/tailrecursion/hoplon-demos |
| 03:54 | allenj12 | hmm alright it seems so far html files arent rly used here? interesting |
| 03:54 | michaniskin | we're adding things all the time (whenever i do something new for work and i can open source it i throw up a demo there) |
| 03:55 | allenj12 | michaniskin: oo cool |
| 03:55 | michaniskin | allenj12: we have a contrib library now, with some libraries you can use: https://github.com/tailrecursion/hoplon/tree/master/contrib |
| 04:00 | allenj12 | michaniskin: boot development dosnt work for me, is there a way to fix that? |
| 04:00 | michaniskin | allenj12: what happens? exception? |
| 04:01 | allenj12 | no its just not a command... |
| 04:01 | kzar | Is there a good static site generator like Jekyll written in Clojure? |
| 04:01 | allenj12 | michaniskin: does it matter im in windows now? |
| 04:02 | michaniskin | allenj12: ah, windows. did you try this: https://github.com/tailrecursion/boot#windows ? |
| 04:03 | michaniskin | we need to work on windows support for boot, it's on the list |
| 04:03 | allenj12 | michaniskin: hate windows :p cant wait till i re image my slackware, yea im trying it now |
| 04:04 | michaniskin | allenj12: you may need to do `java -jar boot.jar ...` |
| 04:04 | michaniskin | it's executable in unix or if you have cygwin |
| 04:04 | michaniskin | are you using cygwin? |
| 04:06 | allenj12 | michaniskin: its pretty much a fresh windows now. had to re image |
| 04:07 | allenj12 | michaniskin: i think its working tho :p |
| 04:08 | michaniskin | allenj12: awesome |
| 04:11 | allenj12 | michaniskin: dam how long is it suppose to take tho |
| 04:13 | michaniskin | allenj12: how long to do what? it should take maybe 20 sec to compile the first time |
| 04:13 | allenj12 | michaniskin: im at 5 min |
| 04:13 | michaniskin | then after that if you're using the watch task it'll be fast |
| 04:14 | michaniskin | do you see like a stopwatch with elapsed time ticking? |
| 04:14 | allenj12 | michaniskin: well its just printing the time like ever so sub seconds |
| 04:15 | michaniskin | i think it's done :) |
| 04:15 | michaniskin | when it finishes compiling it prints the elapsed time since the last compile |
| 04:15 | michaniskin | i sometimes don't trust it that it really recompiled my application, so i like being able to see when the last time it compiled was |
| 04:15 | allenj12 | michaniskin: oooo hahahha im silly :) |
| 04:16 | michaniskin | belt and suspenders |
| 04:16 | michaniskin | lol |
| 04:16 | allenj12 | so the last thing i should see before all those prints is compiling clojurescript.... |
| 04:16 | michaniskin | right |
| 04:17 | allenj12 | gotcha |
| 04:17 | michaniskin | if you are using the local jetty server you will see some stuff about it starting that |
| 04:28 | allenj12 | michaniskin: do you know how to add highlighting to lighttable for hoplon? i tried http://stackoverflow.com/questions/21793023/clojure-how-to-associate-hl-files-to-clojure-syntax-highlighting-in-light-tabl and a solution on the group but neither worked for me |
| 04:29 | michaniskin | allenj12: hm, i dunno, i think that worked for me, but it was a little while ago |
| 04:30 | allenj12 | michaniskin: hmm alright |
| 05:13 | allenj12 | michaniskin: hey i just wanted to let you know the tutorial was great! im pretty brand new to web dev (mostly just an ai guy) and this actually taught me alot other libraries didnt but had included. |
| 05:14 | michaniskin | allenj12: thanks :) what kind of ai? |
| 05:15 | allenj12 | michaniskin: well im doing my masters in cognitive science right now and do alot of social modeling using cognitive architectures, in almost all other times when im not working on that, im doing machine learning of some kind. i also hope to move into the field of AGI and research generalizid systems |
| 05:16 | allenj12 | machuga: althought AGI is kinda a joke right now :) |
| 05:18 | allenj12 | btw out of curiosity no one here would happen to be a lawyer right? |
| 05:23 | mi6x3m | allenj12: do you need one? |
| 05:24 | allenj12 | mi6x3m: well eventually i just have some questions about what defines gambling. its related to what im working on right now and picking up web dev :) |
| 05:24 | allenj12 | mi6x3m: i did some research and i think im in the clear but i just wanted to make sure |
| 05:25 | michaniskin | allenj12: that sounds exciting and mysterious |
| 05:25 | mi6x3m | allenj12: which jurisdiction? |
| 05:26 | allenj12 | new jersey. |
| 05:27 | allenj12 | michaniskin: haha i yea im pretty much chose the path of acadamia forever, so i wanted to start this company while i did my masters etc... im pretty excited for it :) |
| 05:28 | mi6x3m | allenj12: oh, that's quite far |
| 05:28 | allenj12 | mi6x3m: far from where? |
| 05:28 | mi6x3m | europe |
| 05:28 | allenj12 | mi6x3m: o lol |
| 05:28 | mi6x3m | aren't there some official guidelines of what to be aware? |
| 05:29 | allenj12 | mi6x3m: ehh i mean we would just kinda be in a grey area it seems, its hard to tell from what we read so far |
| 05:52 | mping_ | hi |
| 06:11 | ddellacosta | mping_: hi |
| 06:16 | mping_ | can you guys help me out? I'm trying to debug a ring app with cursive clojure |
| 06:16 | mping_ | (ddellacosta: it's funny I'm using your lib for oauth2) |
| 06:17 | cfleming | mping_: what's happening? |
| 06:17 | mping_ | I would like to debug a running ring app with step by step debugging (a la java et al) |
| 06:17 | cfleming | Ok |
| 06:17 | mping_ | I'm still quite new in clojure land |
| 06:17 | mping_ | I configured ring to start an nrepl server |
| 06:17 | cfleming | No worries :-) |
| 06:17 | ddellacosta | mping_: cool. :-) |
| 06:18 | mping_ | and I've managed to connect cursive clojure to it |
| 06:18 | mping_ | I'd like to set up a breakpoint in the ide |
| 06:18 | mping_ | and hit an url, and debug from there |
| 06:18 | mping_ | but I guess that's not the way things work hehehe |
| 06:18 | cfleming | Hehe |
| 06:19 | cfleming | So you're starting the REPL outside of Cursive, and then connecting to it using a remote run configuration for your REPL? |
| 06:19 | mping_ | yep |
| 06:19 | mping_ | i've got this in a lein profile: |
| 06:19 | mping_ | :dropbox {:ring {:handler friend-oauth2-examples.dropbox-handler/app :nrepl {:start? true :port 3333}}} |
| 06:20 | cfleming | Ok, so Cursive normally assumes that you're starting the REPL within Cursive itself, then if you start it in a debug config it can start the JVM in debug mode |
| 06:20 | cfleming | To debug the JVM you need some system properties at startup |
| 06:20 | cfleming | So you should be able to add those properties manually and connect a remote debugger to it |
| 06:20 | cfleming | Try this: |
| 06:21 | cfleming | Run->Edit configurations |
| 06:21 | cfleming | Create a Remote debug configuration |
| 06:22 | mping_ | ok |
| 06:22 | cfleming | Under Command line arguments for running remote JVM it gives you some system properties to copy and paste |
| 06:22 | cfleming | You'll need to add those to lein, so the JVM gets started in debuggee mode |
| 06:22 | cfleming | The next step is to cross your fingers :-) |
| 06:22 | mping_ | *fingers crossed* |
| 06:23 | mping_ | duh! I tried this before but tried to connect as lein remote app |
| 06:23 | mping_ | its working :) |
| 06:23 | cfleming | Nice :-) |
| 06:23 | mping_ | thanks! |
| 06:23 | cfleming | The debugger is still a little flakey from time to time |
| 06:24 | cfleming | I need to fix it up |
| 06:24 | cfleming | (Cursive dev here, BTW) |
| 06:25 | mping_ | hey, since you are a cursive dev: what's with the backspace key? it doesn't normally delete things... |
| 06:25 | john2x | does (.method instance "foo") return the instance if the method returns void? |
| 06:25 | cfleming | That'll be the structural editing (like paredit) mode. |
| 06:25 | mping_ | I must have configured it badly. it seems like I'm using vim or something |
| 06:25 | mping_ | aah.... |
| 06:25 | danielcompton | cfleming is the debugger specific to cursive or can it be used elsewhere too? |
| 06:26 | cfleming | mping_: check https://cursiveclojure.com/userguide/paredit.html |
| 06:26 | cfleming | You can turn it off if it annoys you, but it's worth getting used to it |
| 06:26 | cfleming | danielcompton: it's mostly just the built-in IntelliJ debugger. |
| 06:26 | danielcompton | cfleming I suspected as much |
| 06:27 | cfleming | It has some customisations for Cursive, but not many at the moment. I'm planning to add a lot more. |
| 06:27 | cfleming | Instead of the Java-style expression evaluation I'm going to add a debug REPL |
| 06:28 | danielcompton | cfleming: so you could pause and expect the environment at any point? |
| 06:28 | danielcompton | cfleming: and execute arbitrary clojure code? |
| 06:29 | cfleming | Yeah |
| 06:29 | cfleming | You can already do that, but the evaluation is flakey right now |
| 06:29 | cfleming | I need to fix the symbol resolution there. |
| 06:30 | cfleming | I'm still not sure how customisable the debugger is, I think it's pretty flexible. |
| 06:30 | cfleming | Currently you can't access closed-over locals, which is a pain |
| 06:31 | cfleming | For some reason the debugger is incredibly slow with Clojure too, I don't know why |
| 06:31 | danielcompton | cfleming, that's where it would be most handy too |
| 06:32 | cfleming | danielcompton: yeah, it's still really useful though. I couldn't get through the day without it. |
| 06:32 | cfleming | Since I'm essentially working with a huge ball of someone else's code. |
| 06:33 | danielcompton | cfleming do you use tools.trace? |
| 06:33 | danielcompton | cfleming: I tend to use that for my debugging/reasoning about a program most of the time |
| 06:33 | cfleming | danielcompton: No, I haven't. |
| 06:34 | danielcompton | cfleming: but I haven't learnt how to use the debugger so I don't know what I'm missing on that side |
| 06:34 | cfleming | My problem is generally that the code that I don't understand isn't mine, and is Java |
| 06:34 | cfleming | (the IntelliJ platform) |
| 06:36 | danielcompton | cfleming mmm, I'll bet your java interop skills are pretty good! |
| 06:37 | danielcompton | cfleming: how much of cursive is clojure vs java code (that you've written)? |
| 06:37 | cfleming | danielcompton: Yeah, sadly |
| 06:37 | cfleming | danielcompton: nearly all of what I write is Clojure now, unless I'm taking + customising code from IntelliJ |
| 06:38 | cfleming | danielcompton: but Clojure's interop is lacking some features I need, so I still write a lot of Java shims then call into Clojure |
| 06:39 | danielcompton | hahaha I just wrote defn- main, instead of defn -main |
| 06:39 | danielcompton | that was a headscratcher |
| 06:39 | danielcompton | cfleming: did you come from a java background? |
| 06:40 | cfleming | danielcompton: Yeah, I worked with Java (and IntelliJ) for about 10 years or so |
| 06:41 | danielcompton | cfleming were you developing plugins for intellij or using it as your IDE? |
| 06:41 | cfleming | danielcompton: using it as my IDE, and I wrote a few small plugins |
| 06:41 | cfleming | danielcompton: I started one for Scheme, and a few smaller things |
| 06:42 | danielcompton | cfleming neat! |
| 06:44 | mping_ | do you guys recommend any ring app for me to study? I've dabbled in clj but still don't have a solid idea on how things should look |
| 06:44 | mping_ | things like validation, etc |
| 06:47 | mi6x3m | is there a variant of defmulti allowing you to specify multiple dispatch values? |
| 06:50 | cfleming | mping_: No sorry, I've never done any web dev in Clojure. I think clojars might be open source. |
| 06:50 | cfleming | mi6x3m: I've never tried it, but I think you could dispatch on a vector of values |
| 06:52 | kzar | :o just had a phone interview for a clojure job *waits of an email*! |
| 06:53 | mi6x3m | kzar: grats :) |
| 06:53 | kzar | for* |
| 06:53 | kzar | Thank |
| 06:53 | mi6x3m | what kid of job / location / specifics? |
| 06:53 | kzar | mi6x3m: Arg can't type this morning, I meant to say "Thanks, but let's see!" |
| 06:54 | kzar | Feel shy to talk specifics to be honest |
| 06:55 | kzar | Has anyone used the stasis static site generator library here? (Is it any good?) |
| 06:57 | mi6x3m | is there a clojure function consuming arguments and doing nothing? |
| 06:58 | kzar | mi6x3m: identity? |
| 06:58 | kzar | ,(identity 2) |
| 06:58 | clojurebot | 2 |
| 06:58 | mi6x3m | ,(identity 2 3 4) |
| 06:58 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/identity> |
| 06:58 | mi6x3m | nope |
| 06:58 | kzar | ,(apply identity [2 3 4]) |
| 06:58 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/identity> |
| 06:59 | kzar | whoops sorry, dumb idea |
| 06:59 | CookedGryphon | ,((constantly nil) 1 2 3) |
| 06:59 | clojurebot | nil |
| 06:59 | kzar | mi6x3m: When you say "doing nothing" do you mean returning what you've passed in as a sequence? |
| 06:59 | mi6x3m | no, returning nil |
| 06:59 | kzar | oh |
| 07:00 | mi6x3m | just a black hole for stuff |
| 07:00 | mi6x3m | tnx CookedGryphon |
| 07:00 | kzar | mi6x3m: Something like (fn [& args]) ? |
| 07:01 | kzar | ,((fn [& args]) 1 2 3 4) |
| 07:01 | clojurebot | nil |
| 07:01 | mi6x3m | yes |
| 07:01 | kzar | (May I ask, why yo would want such a thing?) |
| 07:01 | kzar | you* |
| 07:02 | mi6x3m | I am writing a library extending seesaw with some exotic components |
| 07:02 | mi6x3m | so I need all types of weird gizmos :) |
| 07:02 | kzar | OK |
| 07:02 | kzar | say no more heh |
| 07:05 | gfredericks | mi6x3m: (constantly nil) |
| 07:06 | gfredericks | unless by "consuming arguments" you mean something related to laziness |
| 07:06 | mi6x3m | gfredericks: yes this is what I was needing :) |
| 07:06 | mi6x3m | cfleming: so about this vector thing for multimethods |
| 07:07 | mi6x3m | (defmethod mymethod [[dispatcher-1] [dispatcher-2]] .... |
| 07:07 | mi6x3m | i was imagining something like that |
| 07:09 | cfleming | I think you can only have one dispatcher, but it can be (fn [x] [(dispatcher-1 x) (dispatcher-2 x)]) |
| 07:10 | cfleming | Again, I think - I've never tried this |
| 07:10 | cfleming | Don't see why it wouldn't work though. |
| 07:10 | mi6x3m | ah |
| 07:10 | mi6x3m | a function dispatcher |
| 07:10 | mi6x3m | i see |
| 07:11 | cfleming | Sorry, I meant that would have to be the dispatcher function that you would use with defmulti |
| 07:11 | mi6x3m | yeah, I understand |
| 07:11 | cfleming | In fact, the example here is what you want, right? http://clojuredocs.org/clojure_core/clojure.core/defmethod |
| 07:12 | cfleming | I guess it does work :-) |
| 08:45 | jcidaho | hi - some macro magic needed. Is it possible to get the name of a surrounding fn? |
| 08:51 | TimMc | jcidaho: Hmm, I remember a conversation about this last week. |
| 08:51 | Bronsa | jcidaho http://sprunge.us/RgMd |
| 08:52 | jcidaho | nice :-) Good hackery, thanks |
| 08:52 | Bronsa | jcidaho needles to say, don't use this in Real Code™ |
| 08:52 | jcidaho | yeah right ;-) |
| 08:53 | mi6x3m | hey, what is a way to stop the namespace expansion in syntax quote? |
| 08:53 | mi6x3m | for instance to avoid arguments being expanded |
| 08:53 | mi6x3m | or is it safe to expand arguments? |
| 08:53 | Bronsa | '`~'a |
| 08:53 | Bronsa | ,`~'a |
| 08:53 | clojurebot | a |
| 08:54 | Bronsa | mi6x3m: though you porbably want to use the auto-gensym feature |
| 08:54 | Bronsa | ,`(do a# a#) |
| 08:54 | clojurebot | (do a__49__auto__ a__49__auto__) |
| 08:56 | mi6x3m | Bronsa: here's my code for clarity http://pastebin.com/zdpGC5Me |
| 08:57 | mi6x3m | it generates a native java Adapter instance from a set of requested events |
| 08:57 | Bronsa | mi6x3m: yeah, relace ~' with e# |
| 08:57 | mi6x3m | event-fn should have ~' though, no? |
| 08:57 | mi6x3m | only e should be # |
| 08:58 | Bronsa | mi6x3m: it looks like event-fn should be unquoted though, I don't see how that'd work otherwise |
| 08:59 | TimMc | Bronsa: Man, where were you last week? THat's a much better solution. (The thisName thing.) |
| 09:04 | no7hing | does anybody know of a vector math library for clojurescript ? |
| 09:06 | mi6x3m | Bronsa: yeah well technically 'e' doesn't need the gensym, but it doesn't hurt having it |
| 09:06 | mi6x3m | since e is an indepedent parameter name, but i see your point |
| 09:06 | mi6x3m | thanks works nicely :) |
| 09:11 | Bronsa | TimMc: it will work only for (fn name [] ..) though, I don't think it will for (defn name [] ..) |
| 09:11 | Bronsa | even though there should be a way to make that work too |
| 09:13 | TimMc | Bronsa: I don't see why it wouldn't work. |
| 09:13 | Bronsa | TimMc: defn expands to (def x (fn [] ..)) |
| 09:14 | TimMc | Huh, I would have expected it to fill in the function name. |
| 09:16 | Bronsa | looks like if you want it to work with defn yoo you have to use .name and do some unmunging |
| 09:16 | hyPiRion | TimMc: That would've destroyed all the (alter-var-root #'foo memoize) calls out there |
| 09:18 | hyPiRion | ,(defn fib [n] (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))) |
| 09:18 | clojurebot | #'sandbox/fib |
| 09:18 | hyPiRion | ,(alter-var-root #'fib memoize) |
| 09:18 | clojurebot | #<core$memoize$fn__5097 clojure.core$memoize$fn__5097@1ab7a89> |
| 09:18 | hyPiRion | ,(fib 70) |
| 09:18 | clojurebot | 308061521170129 |
| 09:23 | TimMc | hyPiRion: Ah, interesting point! |
| 09:27 | hyPiRion | yeah, I found it out when I tried to memoize a recursive anonymous function =( |
| 09:30 | roppongininja | Hello! Can someone help me me out? |
| 09:30 | roppongininja | (ns miw-projekt-2.core |
| 09:30 | roppongininja | (:require [clojure.java.io :as io])) |
| 09:30 | roppongininja | (def data-file (io/file |
| 09:30 | roppongininja | (io/resource |
| 09:30 | roppongininja | "dane1.txt"))) |
| 09:30 | roppongininja | (defn -main [] |
| 09:30 | roppongininja | (println (slurp data-file))) |
| 09:30 | roppongininja | Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil |
| 09:32 | bcarrell | you don't need io/file, io/resource gives you an instance of java.io.File, which you can slurp |
| 09:35 | roppongininja | I still get Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil |
| 09:37 | Glenjamin | what does (io/resource "dane1.txt") give you? |
| 09:39 | TimMc | roppongininja: Please use a pastebin next time you want to share code. (e.g. refheap.com) |
| 09:41 | mdrogalis | TimMc: I kind of wish we had one named ParenBin |
| 09:43 | TimMc | mdrogalis: Buy the domain and fork refheap. :-P |
| 09:45 | mdrogalis | TimMc: ParenPool. Oh, I'm full of it today. |
| 10:28 | ddellacosta | can someone tell me what is going on here? |
| 10:28 | ddellacosta | ,(map repeat (repeat 3) [1 2]) |
| 10:28 | clojurebot | ((1 1 1) (2 2 2)) |
| 10:29 | ddellacosta | if map applies f (repeat in this case) to each value of each collection in turn, what is it taking from the infinite sequence produced by (repeat 3) ? |
| 10:29 | ddellacosta | and how does that produce two instances of the values from the last collection [1 2] ? |
| 10:33 | roppongininja | does anyone here have a few minutes (more like 10-20) for a total noob? |
| 10:34 | ddellacosta | roppongininja: if you have some questions just put 'em out there |
| 10:34 | ddellacosta | are you actually in Roppongi, btw? |
| 10:34 | roppongininja | nope |
| 10:34 | roppongininja | unfortunately no |
| 10:35 | roppongininja | are you? ;) |
| 10:35 | ddellacosta | roppongininja: coincidentally, I may go there tomorrow to work. :-) |
| 10:35 | ddellacosta | roppongininja: this is an awesome workspace, on the 49th floor of Mori tower: http://www.academyhills.com |
| 10:35 | ddellacosta | roppongininja: but I digress |
| 10:35 | roppongininja | ddellacosta: nice man! I'm happy for you. |
| 10:35 | ddellacosta | roppongininja: what was your question? |
| 10:36 | ddellacosta | roppongininja: yeah, I have no complaints. :-) |
| 10:36 | roppongininja | Would you mind talking via private messages because those are some real dumb ass questions |
| 10:36 | ddellacosta | roppongininja: well, that's totally cool but you shouldn't feel embarrassed, and others may benefit from your questions |
| 10:36 | roppongininja | that I have for you :P |
| 10:36 | ddellacosta | but sure. :-) |
| 10:36 | mping_ | roppongininja: that way the rest of us won't learn |
| 10:37 | ddellacosta | roppongininja: see, what did I say? ^ |
| 10:37 | ddellacosta | ;-) |
| 10:37 | mping_ | ddellacosta: any suggestion on how to use multiple oauth2 providers with friend-oauth2? |
| 10:37 | roppongininja | mping_: I assure you that you won't learn anything from me! |
| 10:37 | ddellacosta | mping_: er, I'm working on it. :-( |
| 10:37 | mping_ | eheheh :) |
| 10:37 | ddellacosta | mping_: so unfortunately not as of yet... |
| 10:38 | roppongininja | I was given this assignment "For the data in the file it daneXX.txt 1 Suggest a linear parametric model and then specify the parameters of the model using the least squares method." |
| 10:38 | roppongininja | I know how to do it in java, but I want to learn clojure so I thought that I'll just do it in clojure |
| 10:38 | ddellacosta | roppongininja: dude, I thought you were going to ask a Clojure question...haha |
| 10:38 | mping_ | haha |
| 10:38 | mping_ | ddellacosta: oh well, I may give this a go: https://github.com/oauth-io/oauthd |
| 10:39 | mping_ | keep up the good work though |
| 10:39 | roppongininja | I basiclly skimmed a book on clojure in 3-4 hours and now have little to no idea how to start actually xD |
| 10:39 | ddellacosta | mping_: let me know how it goes! |
| 10:39 | ddellacosta | mping_: I need to make this work with multiple providers...*sigh*...soon |
| 10:40 | ddellacosta | roppongininja: well, unfortunately my math is a bit crap so I may not be able to help too much with the specifics |
| 10:40 | roppongininja | I know the math |
| 10:41 | ddellacosta | roppongininja: so, that's good. Then I guess the question is, what is the first thing you know you need to do? |
| 10:41 | roppongininja | wow sorry freenode kicked me out for some reason |
| 10:41 | ddellacosta | d'oh, dunno if you saw my last message: |
| 10:41 | ddellacosta | "so, that's good. Then I guess the question is, what is the first thing you know you need to do?" |
| 10:42 | roppongininja | anyway I know the math and I have already implemented this program in java, now I just want to translate it to clojure (thats not required by my course) in hopes of learning something |
| 10:42 | roppongininja | maybe not something, but clojure :D |
| 10:42 | ddellacosta | roppongininja: oh, okay. So, are you familiar at all with Java interop stuff? http://clojure.org/java_interop |
| 10:43 | ddellacosta | roppongininja: one approach I can suggest would be to do the "naive" translation from Java to Clojure using interop |
| 10:43 | ddellacosta | roppongininja: and then you can throw it in a gist/refheap or what not and let folks on IRC take a look |
| 10:43 | roppongininja | ddellacosta: familiar is not the right word, but I have skimmed through that |
| 10:44 | roppongininja | ddellacosta: I don't want to translate anything from java and I want to use as little java as possible |
| 10:44 | ddellacosta | roppongininja: I mean, unfortunately I think it's actually rather hard to learn Clojure the way you're proposing--it's actually easier to start out by writing "Clojure-esque" Clojure, if you know what I mean |
| 10:44 | ddellacosta | roppongininja: yeah, I think that's probably a good idea |
| 10:44 | ddellacosta | roppongininja: are you using a lot of 3rd-party libs in your Java code? |
| 10:45 | roppongininja | ddellacosta: the idea is not to do this assignment but to actualy learn something by doing it, because I just can't stand reading books, even on my ADD medication |
| 10:45 | ddellacosta | ha |
| 10:46 | ddellacosta | so, re: 3rd-party libs ^ ? |
| 10:46 | roppongininja | ddellacosta: I am not using any |
| 10:46 | ddellacosta | roppongininja: okay, that should make it simpler. Do you want to put the Java in a gist or something so we can take a look? |
| 10:47 | roppongininja | ddellacosta: sure I can but I don't want you to write a solution if you know what I mean :P I'm not asking for doing my homework |
| 10:47 | ddellacosta | roppongininja: no, not at all! It's more that, I'm having a hard time figuring out how to suggest you should try things in Clojure without having a sense of what you're working on |
| 10:48 | ddellacosta | roppongininja: I mean, I can give you some general tips, like--think about the data structures you're using and restructure them as Clojure immutable data structures. That's probably the big one. |
| 10:49 | roppongininja | ddellacosta: ok just a second I'm changing the variable names to english :P |
| 10:49 | ddellacosta | ahaha, okay |
| 10:49 | ddellacosta | what language were they in originally, if you don't mind me asking? |
| 10:50 | roppongininja | polish |
| 10:50 | roppongininja | aka russian with latin letters |
| 10:51 | ddellacosta | roppongininja: haha, okay. Yeah, I would have been useless with that. :-) |
| 10:52 | gavilancomun | ,(map #(list %1 %2) (repeat 3) [1 2]) |
| 10:52 | clojurebot | ((3 1) (3 2)) |
| 10:53 | ddellacosta | gavilancomun: is that based on what I posted above, perchance? |
| 10:53 | gavilancomun | sure |
| 10:53 | ddellacosta | gavilancomun: do you know what is going on with the (repeat 3) there? I'm a bit stumped |
| 10:54 | gavilancomun | map is taking the first element of each coll, then the second of each coll |
| 10:55 | gavilancomun | Those pairs are then fed to the first repeat in your example |
| 10:55 | ddellacosta | oh, I see, in that case repeat is just producing an infinite sequence of 3s, huh |
| 10:55 | ddellacosta | I guess then what I don't understand is what the first repeat is doing here: |
| 10:55 | ddellacosta | ,(map repeat (repeat 2) [1 2 3]) |
| 10:55 | clojurebot | ((1 1) (2 2) (3 3)) |
| 10:55 | gavilancomun | Yes, the (repeat 3) is lazy, so as there are only 2 elements in the vector [1 2] it only contributes two 3s |
| 10:56 | ddellacosta | gavilancomun: ah, so, I guess the infinite sequence of 2s that (repeat 2) produces becomes the first argument to repeat, which generates a partial, which then gets applied to the values in the [1 2 3] ? |
| 10:57 | gavilancomun | ,(doc map) |
| 10:57 | 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." |
| 10:58 | gavilancomun | Not sure you need to involve the notion of a partial... |
| 10:59 | gavilancomun | ,(map #(list %1 %2) (repeat 2) [1 2 3]) |
| 10:59 | clojurebot | ((2 1) (2 2) (2 3)) |
| 11:00 | gavilancomun | map makes the pairs which then get fed to repeat |
| 11:01 | ddellacosta | gavilancomun: right, I see, I was misreading it. Thanks! |
| 11:01 | gavilancomun | np :-) |
| 11:02 | gavilancomun | ,(map list (repeat 2) [1 2 3]) |
| 11:02 | clojurebot | ((2 1) (2 2) (2 3)) |
| 11:02 | gavilancomun | There you go, no need for the % |
| 11:37 | agarman | anyone have an opinion on congomongo v. monger? |
| 11:41 | roppongininja | why does clojure.java.io/reader work and (:require clojure.java.io)) with just reader doesnt |
| 11:42 | cbp` | roppongininja: those are two different things. Can you explain better what's not working? |
| 11:43 | roppongininja | something like this works http://pastebin.com/qUmgkWsG |
| 11:44 | justin_smith | roppongininja: require does not bring symbols into scope, use or :as do |
| 11:44 | roppongininja | something like this doesnt |
| 11:44 | roppongininja | http://pastebin.com/fcYinAGp |
| 11:44 | roppongininja | (sorry for flooding : /) |
| 11:44 | justin_smith | (:require [clojure.java.io :as io]) ... (io/reader ...) |
| 11:45 | cbp` | roppongininja: the first one working is a fluke |
| 11:46 | cbp` | roppongininja: you want what justin_smith wrote or (:require [clojure.java.io :refer [reader]]) |
| 11:49 | roppongininja | Ok thanks guys :) |
| 11:52 | justin_smith | csound devs are working on Clojure integration http://csound.github.io/site/news/2014/06/09/score_library_clojure.html |
| 11:59 | deathknight | Is there a zero-to-hero guide regarding clj-http (or its alternatives) and making API calls with google apps? |
| 12:02 | roppongininja | I have a file, which in each line has 2 doubles (2 values). How do I read that file and write first values in each line into one map and second values in each line into another map? |
| 12:03 | cbp` | roppongininja: how big is the file? |
| 12:03 | roppongininja | small |
| 12:04 | roppongininja | 4kb |
| 12:04 | deathknight | I'm interested in the answer to this also *_* |
| 12:06 | dbasch | roppongininja: what are the keys and values of each map? |
| 12:07 | roppongininja | it should be the row number (line number) but insted of a map you can use a list as well |
| 12:07 | roppongininja | if that'll be easier |
| 12:08 | dbasch | 1) slurp the file (because it’s small) |
| 12:08 | dbasch | 2) split it by \n |
| 12:09 | dbasch | 3) map split by space to each line |
| 12:09 | dbasch | that will give you a 2 x n matrix of strings representing doubles |
| 12:10 | CookedGryphon | or get an io/reader on the file and use line-seq rather than slurp and split by \n |
| 12:10 | dbasch | yes, it makes no difference for a 4k file though |
| 12:11 | dbasch | then you can do apply map vector to the result, and now you have an n x 2 matrix |
| 12:11 | justin_smith | https://www.refheap.com/86402 alternately, line-seq |
| 12:12 | dbasch | justin_smith: faster to write than to explain :P |
| 12:13 | dbasch | although that’s not what he wanted |
| 12:13 | deathknight | I can't wait until that refheap is like english |
| 12:14 | justin_smith | https://www.refheap.com/86402 updated to key in the maps by line number |
| 12:15 | justin_smith | dbasch: I think that's what he wanted now, I just went ahead before the spec was fully described knowing it would be easy to adapt |
| 12:28 | roppongininja | how do I split a string containing two doubles into two doubles? :))) |
| 12:29 | gfredericks | the haxy way is |
| 12:29 | gfredericks | ,(def s "3.14 6.28") |
| 12:29 | clojurebot | #'sandbox/s |
| 12:29 | justin_smith | roppongininja: see my paste, it is in there (map (partial read-string) ... |
| 12:29 | gfredericks | ,(read-string (str \[ s \])) |
| 12:29 | clojurebot | [3.14 6.28] |
| 12:30 | justin_smith | ,(map (comp (partial map read-string) #(string/split % #" ")) "1 2") |
| 12:30 | clojurebot | #<CompilerException java.lang.RuntimeException: No such namespace: string, compiling:(NO_SOURCE_PATH:0:0)> |
| 12:30 | justin_smith | ,(map (comp (partial map read-string) #(clojure.string/split % #" ")) "1 2") |
| 12:30 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.CharSequence> |
| 12:30 | justin_smith | ergh |
| 12:30 | dbasch | roppongininja: https://www.refheap.com/86405 |
| 12:30 | justin_smith | ,((comp (partial map read-string) #(clojure.string/split % #" ")) "1 2") |
| 12:30 | clojurebot | (1 2) |
| 12:30 | justin_smith | there we go |
| 12:31 | mindbender11 | justin_smith: those are not doubles |
| 12:35 | dbasch | https://www.refheap.com/86406 |
| 12:36 | justin_smith | mindbender11: fair point |
| 12:36 | justin_smith | ,((comp (partial map read-string) #(clojure.string/split % #" ")) "1e0 2e0") |
| 12:36 | clojurebot | (1.0 2.0) |
| 12:36 | mindbender11 | ,((comp (partial map read-string) #(clojure.string/split % #" ")) "1.0 2.0") |
| 12:36 | clojurebot | (1.0 2.0) |
| 12:37 | dbasch | I’m sure it could be prettier, but my paste does what roppongininja asked |
| 12:38 | justin_smith | dbasch: definitely prettier than the piece of shit I pasted :) |
| 12:40 | dbasch | justin_smith: still my last line is pretty ugly |
| 12:57 | TimMc | justin_smith: Now do that to "NaN Infinity" |
| 12:58 | justin_smith | ,((comp (partial map read-string) #(clojure.string/split % #" ")) "NaN Infinity") |
| 12:58 | clojurebot | (NaN Infinity) |
| 12:58 | justin_smith | OK |
| 12:58 | justin_smith | that's cheating, those are symbols :) |
| 12:58 | TimMc | &(-> "NaN" read-string class) |
| 12:58 | lazybot | ⇒ clojure.lang.Symbol |
| 12:59 | TimMc | &(-> "NaN" (Double/parseDouble) class) |
| 12:59 | lazybot | ⇒ java.lang.Double |
| 12:59 | justin_smith | right |
| 12:59 | justin_smith | if you really know it is all doubles parseDouble is clearly better |
| 13:00 | TimMc | That means EDN is not good for round-tripping floats. :-( |
| 13:01 | Bronsa | TimMc: just use tools.reader and that should work :D |
| 13:06 | ticking_ | am I missing something or is there no good way to get a predicate matching element from a sequence and have the item and rest of the sequence returned? |
| 13:06 | cieloesazul | hi, how can I run all of the tests in the clojure repo? |
| 13:06 | justin_smith | ,(group-by even? (range 10)) ticking_: |
| 13:06 | clojurebot | {true [0 2 4 6 8], false [1 3 5 7 9]} |
| 13:07 | justin_smith | cieloesazul: if it is set up properly, lein test should do it |
| 13:08 | justin_smith | ,(group-by #(= % 1) (range 5)) ticking_: if you only expect one match, it would look like this |
| 13:08 | clojurebot | {false [0 2 3 4], true [1]} |
| 13:09 | ticking_ | justin_smith: yeah but I want only one element aka `some` like behaviour similar to ,(let [{t true f false} (group-by even? (range 10))] [(first t) (concat (rest t) f)) |
| 13:10 | ticking_ | sorry, ,(let [{t true f false} (group-by even? (range 10))] [(first t) (concat (rest t) f)]) |
| 13:11 | tbaldridge | cool news - https://twitter.com/richhickey/status/476048628289925121 |
| 13:11 | Bronsa | wooo! |
| 13:12 | cieloesazul | justin_smith: to be clear, I'm asking about the clojure source code, not a lein project. btw, I tried lein test and it complained there was no project.clj. |
| 13:12 | justin_smith | ,((juxt #(first (filter even? %)) identity) (range 4)) |
| 13:12 | clojurebot | [0 (0 1 2 3)] |
| 13:12 | ticking_ | ,(let [{t true f false} (group-by even? (range 10))] [(first t) (concat (rest t) f)]) |
| 13:12 | clojurebot | [0 (2 4 6 8 1 ...)] |
| 13:12 | justin_smith | cieloesazul: then you need to set up your classpath properly, load all the namespaces manually, and then call clojure.test/run-tests |
| 13:12 | ticking_ | tbaldridge: wow awesome |
| 13:12 | justin_smith | cieloesazul: setting up a lein project is easier |
| 13:14 | ticking_ | cieloesazul: clojure without lein = madness unless you have a really really really good reason |
| 13:14 | justin_smith | tbaldridge: wow, that is huge |
| 13:14 | bbloom | tbaldridge: haha awesome |
| 13:17 | ticking_ | am I the only one for whom the name field does not work -.- |
| 13:18 | hyPiRion | oh man, awesome that you now can sign the CA online |
| 13:18 | Raynes | You can? |
| 13:18 | Raynes | Dear God |
| 13:18 | Raynes | The 21st century |
| 13:18 | Raynes | Feels good |
| 13:19 | cieloesazul | ticking_: looks like you have to fill in the signature first and it autofills the name |
| 13:20 | bbloom | i like the official legal term "Rich Hickey Contributor Agreement" |
| 13:20 | ticking_ | cieloesazul: seems so, feels still broken to me ^^ |
| 13:20 | bbloom | like we're contributing to the six million dollar man or something |
| 13:21 | justin_smith | he should offer hickey-bonds |
| 13:21 | danneu | i've been using the RHCA on my own projects |
| 13:22 | pjstadig | the RHCA is just the Sun CA with some names changed |
| 13:22 | danneu | it's a nice rate limiter for the hordes of contributers my projects attract |
| 13:22 | pjstadig | (which was the intent with the Sun CA) |
| 13:29 | cieloesazul | ticking_, justin_smith, I should have looked at the dev.clojure.org site before asking. I did `mvn test` and it worked. thanks |
| 13:29 | justin_smith | cieloesazul: do you have a pom.xml then? |
| 13:29 | silasdavis | I'm using a zipper, I need an efficient way to go from a zipper location of a node (say loc(node)) to (loc(child)) given that I have the child |
| 13:30 | silasdavis | I could (-> node-loc zip/down zip/right ...) |
| 13:30 | silasdavis | where zip/right gets me to the appropriate child |
| 13:33 | cieloesazul | justin_smith: yes. it's the clojure language source code from github. it contains a pom.xlm file |
| 13:33 | justin_smith | ahh, OK |
| 14:27 | amalloy | ticking_: i think you want drop-while: (let [[first-matching & more] (drop-while (complement pred) coll)] ...) |
| 14:30 | amalloy | reading the scrollback more carefully, it looks like you don't want to drop the non-matching items, but rather surgically remove the first matching item from the middle of the sequence and keep all the rest? that's not a very good access pattern for sequences; maybe you can use a set or a multimap or something that supports efficient removal from the midd |
| 14:30 | ticking_ | amalloy: not quite, other should contain everything that came before the match as well but you just gave me an idea |
| 14:33 | ticking_ | amalloy: yeah, that is the thing I'm looking for, you're probably right as for the access pattern :) |
| 14:34 | ticking_ | I thought I could do this with split-with but that wouldn't work either |
| 14:40 | dbasch | ticking_: why won’t split-with work? |
| 14:43 | ticking_ | dbasch: you would need to inverse the predicate for the take and drop wait a sec I'll write it down |
| 14:45 | ticking_ | dbasch: hm yeah I think you're right |
| 14:46 | silasdavis | is this a strange/bad thing to do: https://www.refheap.com/86413 |
| 14:47 | silasdavis | as in I just want to use Java's binary search, but have it compare using a particular function, but Java comparator expects a comparator to act between the same type |
| 14:47 | silasdavis | I'm assuming that java.util.Collections/binarySearch is a fair bit faster than a pure clojure implementation |
| 14:48 | ticking_ | dbasch: yeah you are right :) , I got mixed up in the negation |
| 14:48 | ticking_ | ,(let [coll (range 5) pred #(= 2 %) [t d] (split-with (complement pred) coll) other (concat t (rest d)) match (first d)] [match other ]) |
| 14:48 | clojurebot | [2 (0 1 3 4)] |
| 14:49 | llasram | silasdavis: That is totally the way to go |
| 14:50 | S11001001 | silasdavis: there exists a type containing all values |
| 14:52 | amalloy | silasdavis: you might also benefit from putting this into a sorted data structure to begin with, instead of doing binary search on a vector |
| 14:53 | silasdavis | I'd put in in a BST |
| 14:53 | silasdavis | but i'm using it with a zipper |
| 14:53 | silasdavis | and I have written a down function that zips down to the nth child |
| 14:54 | silasdavis | and that implementation wants a vector or equivalent |
| 14:54 | silasdavis | actually I'd use a sorted-map |
| 14:54 | ticking_ | amalloy: I just realized that "have you tried a different datastructure" is clojures equivalent to "have you tried to turn it off and on again" ^^ thanks for the reminder :D |
| 14:55 | justin_smith | silasdavis: what about something like a sorted-set or sorted-set-by that maintains its own tree and sorts on insertion? |
| 14:55 | p_l | ticking_: well... it *IS* the basic thing to consider, IMO :P |
| 14:55 | silasdavis | perhaps I should reverse a bit: from a node in zipper, I need to jump to a child of that zipper without scanning all the children |
| 14:55 | silasdavis | and get the child loc |
| 14:56 | silasdavis | I need a way of looking up the child quickly by a key, which is easy enough, but then I need a way to jump directly to the appropriate child |
| 14:56 | ticking_ | p_l: yeah I completely agree, clojures seq concept is bot a gift and a curse, because most operations will leave you with it, and one is tempted to keep using it |
| 14:56 | amalloy | have you uh...considered whether you need a zipper? it's vanishingly rare to have a good reason to use zippers |
| 14:56 | silasdavis | I was able to modify zip/down to jump to the nth child |
| 14:57 | silasdavis | well it makes my implementation of trie fairly nice |
| 14:57 | justin_smith | (inc amalloy) - unless this is just a "how do I use a zipper" exercise |
| 14:57 | amalloy | the fact that you're modifying zip/down to go to some nth child, rather than the first one, screams that you don't really want zippers |
| 14:57 | p_l | ticking_: One thing I was taught in general is that one should always first look at data, then at algorithm, then think about implementation :P |
| 14:58 | silasdavis | hm |
| 14:58 | amalloy | you certainly don't need zippers to implement a prefix trie. they'll just get in the way |
| 14:58 | amalloy | nested maps, update-in, get-in, are all you need |
| 14:58 | ticking_ | p_l: yeah, but you don't really want `into`s all over the place either |
| 15:00 | ticking_ | p_l: I feel that clojure.core shouldn't contain all the seq stuff, there should be clojure.core clojure.seq and clojure.reducers, so that you don'h, always go to seqs as the default |
| 15:00 | ticking_ | p_l with reducers the `into`s wouldn't be that bad |
| 15:01 | ticking_ | p_l: well everything is a seq |
| 15:02 | ticking_ | p_l: ah no keywords arent ^^ |
| 15:02 | justin_smith | ,(seq? 'everything) |
| 15:02 | clojurebot | false |
| 15:02 | justin_smith | :) |
| 15:02 | ticking_ | touche |
| 15:02 | ticking_ | ^^ |
| 15:02 | p_l | ticking_: a friend of mine had "lisp" class in uni. We told him to bring a banner saying "you're wrong" :D |
| 15:03 | ticking_ | lol |
| 15:03 | justin_smith | ,(map seq? [:everything 'everything "everything" ::everything]) |
| 15:03 | clojurebot | (false false false false) |
| 15:04 | ticking_ | ,(seq "everything") |
| 15:04 | clojurebot | (\e \v \e \r \y ...) |
| 15:04 | ticking_ | though ^^ |
| 15:04 | silasdavis | amalloy, hm yeah I might have a rethink, thanks |
| 15:04 | justin_smith | ,,(map (comp seq? seq name) ["everything" :everything ::everything 'everything]) |
| 15:05 | clojurebot | (true true true true) |
| 15:05 | ticking_ | justin_smith: yeah I feared that name gets called automatically on keywords and symbols ^^ |
| 15:05 | ticking_ | thus my inital statement ^^ |
| 15:08 | amalloy | i don't think it conveys anything to put ^^ after every sentence ^^ |
| 15:11 | exobyte | Any resources for Java programmers leanring Clojure other than Rich Kickey's videos? |
| 15:11 | technomancy | amalloy: I know, right. (PLEASE RT) |
| 15:11 | SegFaultAX | exobyte: http://www.clojurebook.com/ and Joy of Clojure are excellent. |
| 15:12 | ticking_ | amalloy technomancy: doesn't harm either, and it has proven to lessen the cance of the convesation partner feeling offended (some sentences sound harsher without facial expression) by a significant margin |
| 15:12 | SegFaultAX | And they're agnostic of your background. |
| 15:12 | SegFaultAX | exobyte: My advice to you is to learn Clojure /the Clojure Way/, as opposed to trying to fit Clojure into your existing Java mental model. |
| 15:13 | exobyte | SegFaultAX: fair enough |
| 15:13 | numberten | is there a strict version of repeatedly? |
| 15:14 | justin_smith | exobyte: my small nugget of wisdom: information hiding doesn't buy you much when everything is immutible, the "final" status of the datastructures is usually all the encapsulation you need |
| 15:14 | SegFaultAX | numberten: (repeatedly n fn) |
| 15:14 | amalloy | SegFaultAX: he said strict |
| 15:14 | amalloy | numberten: no |
| 15:14 | exobyte | SegFaultAX: I also know C, JS, and python; my issue, and this was with learning python, is lots of resources spend too much time trying to teach me to program. |
| 15:14 | numberten | alright thanks |
| 15:15 | amalloy | generally "the strict version of X" is not included, because you can easily make anything strict if you want, with doall or dorun or whatever |
| 15:15 | justin_smith | exobyte: joy of clojure if anything assumes you are too competent, it is not a book that talks down to the reader or assumes you are not a programmer |
| 15:15 | exobyte | justin_smith: well that's amost like my java code! |
| 15:15 | justin_smith | exobyte: well that's a great start then :) |
| 15:15 | justin_smith | clojure just makes that approach easier, more default |
| 15:15 | SegFaultAX | But doall on repeatedly without a size is a bad idea. |
| 15:15 | exobyte | justin_smith: I'd rather have *too* competent. |
| 15:16 | justin_smith | exobyte: many clojure newcomers find joy of clojure baffling, but it is a good book, and if you don't want your hands held do check it out |
| 15:16 | SegFaultAX | exobyte: In some sense you're going to have to re-learn how to program. Or at least, you're going to have to re-learn certains ways of modeling problems in your head. |
| 15:16 | exobyte | justin_smith: the author of a python book I read said he never found regexes or composite dict keys to be worth learning. cringes. |
| 15:16 | justin_smith | wow |
| 15:16 | SegFaultAX | exobyte: :( What book was this? |
| 15:17 | gtrak | no composite keys, omfg. |
| 15:17 | justin_smith | exobyte: python culture can be pretty aggressively mediocre sometimes |
| 15:17 | exobyte | SegFaultAX: checking... Idomatic Python, was really good, though |
| 15:17 | numberten | amalloy: if i understand correctly, the only difference between dorun and doall is that the former doesn't retain the head? |
| 15:18 | SegFaultAX | How good can it be if the author doesn't see value in something as basic as composite dict keys? |
| 15:18 | gtrak | admittedly, I'm pretty bad at regexes, saying they aren't worth learning is like saying compilers shouldn't exist. |
| 15:18 | exobyte | SegFaultAX: "Learning to Program Using Python." I should have paid more attention to the title |
| 15:18 | mdeboard | everyone's so crusty in here today |
| 15:18 | cbp` | hrm sorted-set doesn't print in sorted order in clojurescript |
| 15:18 | mdeboard | grizzled vets everywhere |
| 15:19 | danielcompton | cbp` in clojurescript set sorts you |
| 15:19 | justin_smith | cbp`: wow, that is weird |
| 15:19 | justin_smith | sounds like a bug |
| 15:20 | cbp` | ,(sorted-set 6 92 1 2 3 4 5 1 0 2 39 4) |
| 15:20 | clojurebot | #{0 1 2 3 4 ...} |
| 15:20 | exobyte | justin_smith: I saw that mediocrity at a former job, too. a lead dev on a major website didn't like decorators because he couldn't figure out the stact traces. |
| 15:20 | cbp` | #{0 1 39 4 92 6 3 2 5} in cljs |
| 15:20 | SegFaultAX | exobyte: ... what does that have to do with decorators? |
| 15:21 | justin_smith | SegFaultAX: decorators can lead to stack traces that don't look like your code, I guess |
| 15:21 | justin_smith | not nearly as bad as what laziness does to stack traces though... |
| 15:21 | exobyte | SegFaultAX: it was like he said "decorators are too hard" |
| 15:22 | SegFaultAX | justin_smith: Decorators are just syntactic sugar. @foo def bar(): ... == def bar(): ... bar = foo(bar) |
| 15:22 | justin_smith | see also the official reasons for not supporting the elimination of the GIL back when that was done, and for not having real lambdas |
| 15:22 | exobyte | justin_smith: it's too hard(tm) |
| 15:23 | SegFaultAX | Removing the GIL /is/ too hard, though. |
| 15:23 | technomancy | ticking: oh, I read it as "see the above line" |
| 15:23 | exobyte | justin_smith: coming from java, python's VM is a joke. |
| 15:23 | exobyte | SegFaultAX: when you don't have a proper concurrency or memory model, yes. |
| 15:23 | SegFaultAX | Considering just about every library (including the standard library) is not built to be thread-safe, the rammifications of removing the GIL would be dire. |
| 15:23 | justin_smith | SegFaultAX: they did it once, and nobody supported that branch of the code |
| 15:23 | justin_smith | well yeah, there is that |
| 15:24 | SegFaultAX | justin_smith: It has been done mulitple times by multiple people. |
| 15:24 | justin_smith | but hell, they can't even update libs to version 3 |
| 15:24 | justin_smith | SegFaultAX: interesting, I had no idea |
| 15:24 | SegFaultAX | Yea, much less make them thread safe. |
| 15:24 | SegFaultAX | justin_smith: If you're interested in learning more about the Python GIL: https://www.youtube.com/watch?v=Obt-vMVdM8s |
| 15:25 | justin_smith | I think with its culture, python is stuck with "intuitive" as a hard constraint, which pretty much rules out doing concurrency right |
| 15:25 | exobyte | What was funny was because of the GIL, we couldn't run the webapp as a single process, so the local in-memory cache got cloned. |
| 15:25 | cbp` | guido is still crusty about being forced to put lispy things inside python |
| 15:25 | justin_smith | cool, thanks SegFaultAX |
| 15:26 | SegFaultAX | justin_smith: Great talk in general, even if you never use Python IRL. |
| 15:26 | cbp` | like anonymous functions |
| 15:26 | SegFaultAX | cbp`: And map, filter, reduce. |
| 15:26 | amalloy | it's funny because of all the things that are in python *anyway* that were pioneered by lisp |
| 15:27 | exobyte | amalloy: all the cool parts that people like |
| 15:27 | justin_smith | SegFaultAX: clearly because these fp concepts are not accessible |
| 15:27 | exobyte | amalloy: the class system was bolted on |
| 15:27 | justin_smith | not *intuitive* |
| 15:27 | SegFaultAX | If we played "remove all the things lisp invented from Python", Python would cease to exist as a language. |
| 15:28 | SegFaultAX | justin_smith: I think GvR drinks from the same koolaid bowl as the Pike et al. |
| 15:28 | SegFaultAX | (The golang team, that is) |
| 15:28 | exobyte | Python people do love Go |
| 15:29 | cbp` | It's nice that it makes async things possible i guess |
| 15:29 | SegFaultAX | Well I just mean in terms of language design. Pervasive mutability, imperativeness, etc. |
| 15:29 | SegFaultAX | I'm not making a value judgement about whether that's good or bad. Just pointing out that the languages are similar in that respect. |
| 15:32 | SegFaultAX | If and when Go ever gets parametric polymorphism, I'll give it a more serious look. |
| 15:33 | SegFaultAX | But for me personally, for the style of programming I enjoy doing and the types of applications I tend to write, lack of PP and other FP-enabling tools makes it a non-starter. |
| 15:33 | justin_smith | I have hella respect for pike, he is a very smart man, even if he is often wrong |
| 15:33 | amalloy | cbp`: are you sure about that sorted-set? the sorted-set code looked fine to me in cljs source, so i tried running your example, and it prints ordered for me with latest cljs |
| 15:35 | amalloy | oh, actually, i bet i'm not in a cljs repl. it's been ages since i tried to use that project |
| 15:36 | amalloy | okay, whew. even in a cljs repl: https://www.refheap.com/86415 |
| 15:37 | cbp` | amalloy: I guess I should update first.. |
| 15:40 | amalloy | jesus, does repljs still require you to type :cljs/quit to quit? i'm certain i sent a patch that lets C-d exit |
| 15:40 | deathknight | :O |
| 15:41 | amalloy | http://dev.clojure.org/jira/browse/CLJS-167 |
| 15:43 | wei | is there a way to write a middleware handler that knows whether its inner routes matched or not? |
| 15:44 | wei | use case: I must return 401 for routes that matched, but nil otherwise so the matcher can fall through |
| 15:46 | justin_smith | (fn [handler] (fn [request] (if (should-401 request) (assoc request :status 401) (handler request)))) something like this, if you want to short circuit all previous handlers to be preempted |
| 15:47 | cbp` | amalloy: no clue https://www.refheap.com/86416 |
| 15:47 | cbp` | going out to eat for an hour though |
| 16:40 | expez | Any good places to read about error handling in clojure? |
| 16:40 | joegallo | well, what do you want to know? |
| 16:40 | joegallo | and how well do you already understand java exceptions? |
| 16:40 | expez | I write Java profesionally :( |
| 16:41 | expez | Java forces you to think about every exception, so the first question is how do I even find out what can go wrong when I'm calling a clojure function? |
| 16:41 | bbloom | expez: javadoc |
| 16:41 | joegallo | ah, simple |
| 16:41 | joegallo | anything can go wrong |
| 16:42 | expez | Reading through source of the entire stack beneath me doesn't seem like a good idea |
| 16:42 | joegallo | basically forget about checked exceptions, they're all just runtime exceptions now |
| 16:42 | stuartsierra | As some well-known JVM designer once put it, checked exceptions are a fiction of javac. |
| 16:42 | joegallo | stuartsierra: well quoted |
| 16:43 | TimMc | And they're typed wrong. |
| 16:43 | TimMc | They're not even a *consistent* fiction. |
| 16:43 | TimMc | http://james-iry.blogspot.com/2010/08/on-removing-java-checked-exceptions-by.html |
| 16:44 | expez | The clojure books I've read only deal with exceptions in terms of java interop, but I'm sure some of the clojure functions people write can fail too :) |
| 16:44 | justin_smith | expez: many things in clojure are very easy going, and just return nil. If you want to enforce some invarients check out :pre and :post conditions |
| 16:44 | bbloom | TimMc: the clojure internals call that "sneaky throw" |
| 16:44 | TimMc | expez: You get (try ... (catch ...)) and so forth if you need it. |
| 16:45 | TimMc | And slingshot can be a nice library to use if you want a bunch of exception types without creating classes for all of them. |
| 16:45 | bbloom | expez: if you're calling java code that expects you to catch exceptions, that sucks... but it works the same as in java |
| 16:45 | technomancy | expez: the only clojure-specific thing about exceptions is ex-info/ex-data |
| 16:45 | bbloom | expez: otherwise, just avoid throwing/catching exceptions unless you expect to crash |
| 16:46 | bbloom | by that i mean, crashing is a fine thing to do if you get an unexpected exception |
| 16:46 | expez | absolutely |
| 16:48 | expez | Has anyone written a library for modularizing a system into components that can crash on their own and then be restarted? |
| 16:48 | gfredericks | java.lang.JVMNotAvailableException |
| 16:48 | sjl | expez: if you want a common-lisp-condition-system-like lib check out http://docs.caudate.me/ribol/ |
| 16:49 | gfredericks | expez: I've played around with different approaches to stapling that kind of stuff onto stuartsierra/component, but I didn't feel good about any of them |
| 16:49 | TimMc | gfredericks: You twerp, you made me go look that up. |
| 16:49 | gfredericks | (inc java.lang.JVMNotAvailableException) |
| 16:49 | lazybot | ⇒ 1 |
| 16:49 | bbloom | all: please don't suggest random libs to new comers who have foundational questions |
| 16:50 | gfredericks | I am a newcomer to this conversation and don't know who is a newcomer :P |
| 16:50 | stuartsierra | bbloom: amen |
| 16:50 | expez | gfredericks: in terms of building it on top of component or the actual approach of restartable / isolated components? |
| 16:50 | gfredericks | expez: the former I think |
| 16:51 | TimMc | bbloom: Probably a good idea if those situations can be identified. |
| 16:51 | gfredericks | coordinating failure in general has been hard; erlang has this nice feature of forcing a group of processes to crash together |
| 16:51 | expez | mhmm |
| 16:52 | stuartsierra | I've been thinking about ways to make 'component' support error handling and restarts. But it's very hard. |
| 16:52 | bbloom | expez: the short answer is: avoid exceptions unless java forces them on you. then pretend it's just like java. get a baseline of experience w/ clojure |
| 16:52 | gfredericks | stuartsierra: I've ended up implementing error channels and similar things a few times |
| 16:52 | gfredericks | for batch jobs: a promise that gets delivered with nil on success or a throwable on error |
| 16:53 | expez | bbloom: thanks, that sounds like good advice. Errors and function composition go poorly together :p |
| 17:26 | Glenjamin | i've been playing around with a component-like system that attempts to minimise closures - in theory this would make it more resiliant to errors |
| 17:28 | Glenjamin | although that wasnt my goal when building it |
| 17:28 | bbloom | Glenjamin: by minimize closures, you mean avoids capturing mutable state in closures? |
| 17:28 | Glenjamin | or any state really, yeah |
| 17:29 | bbloom | well i guess there really isn't any other kind of state, besides mutable |
| 17:29 | Glenjamin | i was annoying at having to rebuild all app state when changing a function |
| 17:29 | Glenjamin | *annoyed even |
| 17:29 | Glenjamin | especially when my app took ~10s to load up its state |
| 17:29 | Glenjamin | so i'm trying to use vars in a way that doesn't break tools.namespace/refresh |
| 17:30 | Glenjamin | which basically means my ring handler is a very small clojure that calls find-var |
| 17:31 | Glenjamin | closure even |
| 17:31 | Glenjamin | it's really hard to type closure in this channel |
| 17:38 | justin_smith | Glenjamin: isn't this what passing #'handler to ring already does? |
| 17:38 | Glenjamin | yes, but i had an additional constraint |
| 17:39 | justin_smith | oh, ok |
| 17:39 | Glenjamin | in order to inject the other bits of my system into the ring handler without clojures |
| 17:39 | Glenjamin | i'm assoc-ing them into the request map |
| 17:39 | Glenjamin | i expected #'handler to work, but for some reason it can be broken with tools.namespace/refresh |
| 17:39 | Glenjamin | so i do (find-var 'handler) instead |
| 17:40 | Glenjamin | where handler is in another namespace |
| 17:40 | Glenjamin | this is still fairly trial and error, i intend to poke into what clojure is actually doing under the hood and maybe write this up as a blog post |
| 17:41 | justin_smith | I wonder what the cases are for using find-var vs. resolve |
| 17:41 | Glenjamin | it seems like a var can end up pointing at the old value when tools.namespace destroys and rebuilds a namespace |
| 17:41 | amalloy | Glenjamin: i bet t.n/refresh doesn't just re-def the vars; it deletes the namespace wholesale and starts over |
| 17:41 | Glenjamin | it does, yes |
| 17:41 | Glenjamin | ,(doc resolve) |
| 17:41 | clojurebot | "([sym] [env sym]); same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)" |
| 17:42 | amalloy | right, so naturally the old var still exists, and a new one with the same name is created |
| 17:42 | amalloy | vars aren't interned by name like keywords are |
| 17:43 | amalloy | so ring still has a handle on the old var, which is pointing to the same function it always did |
| 17:43 | Glenjamin | hrm, seems like (ns-resolve) should do roughly the same thing as (find-var) |
| 17:43 | Glenjamin | sounds right amalloy |
| 17:43 | justin_smith | Glenjamin: yeah, they seem similar, which makes me wonder what would indicate one vs. the other is appropriate |
| 17:43 | amalloy | i don't understand your point re ns-resolve vs find-var |
| 17:44 | Glenjamin | from my limited understanding, they seem to do the same thing |
| 17:45 | justin_smith | Glenjamin: well, one difference is resolve does not require that its arg be fully qualified |
| 17:52 | justin_smith | ,(/ 2) TIL |
| 17:52 | clojurebot | 1/2 |
| 17:53 | justin_smith | handy |
| 18:00 | Raynes | mdeboard: We both use rdio <3 |
| 18:00 | Raynes | We're rdibros |
| 18:03 | mdeboard | Raynes: lol |
| 18:25 | danielcompton | Any spotifriends out there? |
| 18:54 | catern | What is the idiomatic way to iterate through a sequence with a function, passing a state variable along? |
| 18:55 | technomancy | catern: reduce? |
| 18:55 | catern | Ahhh right yes |
| 18:57 | justin_smith | pedantically it's not state and its not a variable - its an argument to a function that gets a new binding on each iteration |
| 18:57 | justin_smith | (unless you also make it be an atom or something) |
| 18:59 | technomancy | hm; I don't see how it's not state |
| 18:59 | justin_smith | it's a local, non-mutable, non-shared, per-execution state I guess |
| 19:00 | justin_smith | but one usually doesn't describe eg, the value of x inside (fn [x y] (+ x y)) as being a state or a variable |
| 19:00 | justin_smith | it's a binding |
| 19:00 | technomancy | it seems to match the mathematical definition of a variable |
| 19:01 | justin_smith | yeah, but that's kind of overloaded with some other implications in programming |
| 19:01 | technomancy | I just take it as a given that the other definitions don't apply because they can't apply. |
| 19:02 | amalloy | wait, when did (str (range)) change to be non-terminating? it used to just return "clojure.lang.LazySeq@1234567" or similar |
| 19:02 | turbofail | how could (str ...) return a lazy sequence? |
| 19:03 | turbofail | oh nm |
| 19:03 | justin_smith | turbofail: the string form of a lazy sequence was just an opaque object, and did not realize or reveal the contents |
| 19:03 | Bronsa | ,(str (range 10)) |
| 19:03 | clojurebot | "clojure.lang.LazySeq@9ebadac6" |
| 19:03 | amalloy | but now the way it tries to hash the collection apparently involves realizing all its elements |
| 19:04 | justin_smith | ,(str (range)) |
| 19:04 | clojurebot | #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space> |
| 19:04 | justin_smith | yeah, that seems like a regression |
| 19:04 | amalloy | i think this was actually in like 1.4 or 1.5. it's not super-recent |
| 19:05 | Bronsa | amalloy: just checked with 1.3.0, same behaviour |
| 19:05 | amalloy | 1.2? |
| 19:05 | Bronsa | ditto for 1.2 |
| 19:05 | amalloy | man, i don't wanna be crazy. i'm sure this wasn't always the case |
| 19:05 | amalloy | but 1.2 is when i started |
| 19:06 | Bronsa | amalloy: looks LazySeq's hashCode always depended on the realized seq |
| 19:09 | amalloy | would it be crazy to reimplement toString on LazySeq to be like: {return "clojure.lang.LazySeq@" + System.identityHashCode(this);} ? |
| 19:09 | amalloy | so that you can at least print the damn things |
| 19:10 | technomancy | amalloy: right, I always assumed the "clojure.lang.LazySeq@9ebadac6" representation was specifically there to allow them to be str'd without realizing them |
| 19:10 | Bronsa | same here |
| 19:11 | amalloy | stuart s noticed this three years ago, and nobody cared: https://groups.google.com/forum/#!topic/clojure-dev/F68GRPrbfWo |
| 19:18 | amalloy | anyway, i re-realized this because i ran into a scala collection that has a non-terminating toString, and i wanted to herald clojure's moral superiority, because i know (str (range)) doesn't suck. but it turns out i was wrong |
| 19:23 | {blake} | OK, I've forgotten how to do this: "(defn myproc [parm & more] ... (myproc (first more) (rest more))..." The "rest more" creates a list but so does the & in the parm list. How do I stuff the remaining params back into the proc without ending up with a nested list? |
| 19:24 | turbofail | apply |
| 19:25 | turbofail | (apply myproc (first more) (rest more)) |
| 19:25 | {blake} | turbofail, Yeah, I was trying to figure out how to fit apply in there. |
| 19:25 | amalloy | (apply myproc more) |
| 19:25 | {blake} | turbofail, OK, so I was thinking of trying to de-listify rather than ... lemme see if I got that... |
| 19:26 | turbofail | yeah actually amalloy's version is equivalent |
| 19:26 | amalloy | although, really, consider making myproc just take a list of params, instead of &args params |
| 19:27 | {blake} | amalloy, OK...but let's say--oh, that makes sense yeah. And if it's not "(first more)" but "(someothervaluederivedfromfirstmore)", I could put that into the list... |
| 19:27 | {blake} | For the purposes of this exercise, I have discrete items, not a list. |
| 19:28 | skinkitten | is there a shorter/simpler way of doing this? http://cryptb.in/zkEf#afb8d04ad2702274261bd938ca252d99 |
| 19:29 | justin_smith | for the impl? (repeat 1) |
| 19:29 | justin_smith | ,(repeat 1) |
| 19:29 | clojurebot | (1 1 1 1 1 ...) |
| 19:30 | {blake} | (because I remembered amalloy recommending using lists as parameters from last week.) |
| 19:32 | skinkitten | justin_smith, nice. thank you. |
| 19:42 | skinkitten | justin_smith, how about this? http://goo.gl/JS5Dxh |
| 19:42 | mdeboard | What is the proper syntax for `require` in the repl? |
| 19:43 | mdeboard | Is there any reason to not just use `use`? |
| 19:44 | AWizzArd | mdeboard: (require 'com.example.ns) |
| 19:44 | justin_smith | mdeboard: use leads to harder to refactor code, but in a repl there is often reason to just do use |
| 19:44 | AWizzArd | Or (require '[com.example.ns :as exns]) |
| 19:44 | Raynes | mdeboard: (require '[foo.bar :refer [things]]); (require 'foo.bar); (require '[foo.bar :as barness]) |
| 19:44 | justin_smith | or (require '[com.example.ns :as ex]) |
| 19:44 | Raynes | mdeboard: There is every reason to not use `use`. |
| 19:45 | mdeboard | what about :refer :all |
| 19:45 | Raynes | require is now a superset of `use`'s functionality. |
| 19:45 | technomancy | Raynes: eh; even in the repl? |
| 19:45 | mdeboard | When I try to use that I get an error, e.g. (require '(foo.bar :refer :all)) |
| 19:45 | AWizzArd | Innocent question, storm of answers (: |
| 19:45 | Raynes | You should almost never use that anyways. |
| 19:45 | Raynes | technomancy: Yes, even in the repl. |
| 19:45 | Raynes | :refer :all |
| 19:45 | technomancy | I still use `use` in the repl because it's short |
| 19:45 | Raynes | There is not one single good reason to use that god forsaken function. |
| 19:45 | mdeboard | it's shorter |
| 19:45 | Raynes | That's not a reason. |
| 19:45 | mdeboard | that's a good reason |
| 19:45 | technomancy | no one has to know |
| 19:46 | mdeboard | I put on my wizard robe and hat |
| 19:46 | Raynes | I pick up my rifle. |
| 19:46 | Raynes | I see where this is going. |
| 19:46 | amalloy | (use 'require) |
| 19:48 | AWizzArd | I think we now have a clear winner. |
| 19:48 | AWizzArd | amalloy: can you also require use? |
| 19:48 | amalloy | you can, but it's not required |
| 19:49 | technomancy | granted the only thing I use is clojure.pprint |
| 19:49 | technomancy | because I know exactly what's going to happen |
| 19:50 | justin_smith | what about clojure.repl? |
| 19:50 | technomancy | personally I would never do that |
| 19:52 | technomancy | but if you're not an emacs user it might make sense |
| 19:53 | amalloy | clojure.reflect is about as reasonable as clojure.pprint, probably |
| 19:54 | technomancy | basically any time I do a use, it's because nrepl-discover doesn't work yet. |
| 19:56 | Bronsa | I still (use 'clojure.repl) from slime because I never remember how to do apropos otherwise |
| 19:57 | AWizzArd | Best way to get (into (sorted-map-by-val) some-map)? |
| 19:58 | AWizzArd | {:b 2, :c 3, :a 1} ==> {:a 1, :b 2, :c 3} |
| 19:58 | AWizzArd | {:b 2, :a 3, :c 1} ==> {:c 1, :b 2, :a 3} |
| 19:59 | AWizzArd | Not really possible I guess. |
| 20:01 | amalloy | maps sorted by value are not really a thing. you don't address what to do in the case of value collisions, for exampl |
| 20:02 | amalloy | but for many cases where you think you want a map sorted by value, a priority queue can suffice |
| 20:02 | metellus | ,(= {:a 1 :b 2} {:b 2 :a 1}) ;; there's also the fact that this is true |
| 20:02 | clojurebot | true |
| 20:02 | metellus | you could go from a map to a seq sorted by keys within the map |
| 20:02 | Bronsa | isn't that like a priority map? |
| 20:03 | Bronsa | https://github.com/clojure/data.priority-map |
| 20:03 | AWizzArd | amalloy: I just wanted this for testing purposes. My classifier outputs a map with tons of classes and without sorting it’s not possible to visually match the winner. I’ll go with (sort-by val #(compare %2 %1) (classify …)) now. |
| 20:04 | AWizzArd | Bronsa: looks good. |
| 20:13 | Shayanjm | What do you guys think of the clojure for the brave and true book? |
| 20:17 | catern | i read it to learn clojure! very recently! it was pretty good I think |
| 20:17 | catern | but I already knew Lisp from SICP |
| 20:18 | catern | also, I thought it needed an appropriate soundtrack with that kind of title, so I listened to https://www.youtube.com/watch?v=atM3ZhF8MVs all throughout |
| 20:18 | Shayanjm | haha cool :) This is my first venture into any functional programming so I figured I'd litmus test some opinions. |
| 20:20 | AWizzArd | ,(key "foo") |
| 20:20 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map$Entry> |
| 20:22 | AWizzArd | catern: I will follow that youtube link now but surely hope it’s not the 10-hour version of the Nyan cat! |
| 20:33 | justin_smith | skinkitten: another thing I noticed as I was closing that tab just now: if you bind the lazy sequence in a def, that holds onto the head and it can't be collected unless you clear the var. If you instead call (repeatedly 1) at the place in code where you need the sequence, the values are not bound or held so they can be cleaned up immediately |
| 20:34 | justin_smith | skinkitten: IOW don't bind to the head of a lazy sequence if it is that cheap to generate |
| 20:38 | skinkitten | justin_smith, how about this (def ones (repeat 1)) |
| 20:39 | catern | AWizzArd: no, much more appropriate, don't you think? |
| 20:39 | catern | now I listen to it often when I clojore-code |
| 20:39 | catern | it puts me in the mindset of the parenkin - Lispborn! |
| 20:40 | skinkitten | justin_smith, what's "clear the var"? |
| 20:41 | AWizzArd | catern: yes is good. I typically listen to brown noise: http://simplynoise.com/ |
| 20:42 | justin_smith | skinkitten: the problem is that if someone uses 1000000 values from 1s, then that var now holds that long a sequence |
| 20:43 | justin_smith | skinkitten: if, instead, you just use (repeat 1) inside any call where you need (1 1 1 1 ...) then you never need more than chunksize to exist at any time, and they can be garbage collected |
| 20:43 | justin_smith | clearing the var would be reassigning it so the previous value can be reclaimed |
| 20:44 | turbofail | though for this particular example it doesn't really matter |
| 20:44 | skinkitten | justin_smith, wow yeah. totally makes sense. |
| 20:44 | skinkitten | thanks |
| 20:44 | turbofail | but if you were doing say (reduce + (take 10000000 ones)) then you'd probably want to do as he says |
| 20:45 | justin_smith | turbofail: yeah, it's the general principle of the thing |
| 20:46 | justin_smith | any unbounded lazy seq tied to a var should be treated as a potential memory leak (see also line-seq from some reader, etc.) |
| 20:46 | skinkitten | justin_smith, (take 10 (repeat 1)) returns '(1 1 1 1...) ? I might have read you incorrectly, I had imagined it would just return 1 |
| 20:47 | justin_smith | ,(take 10 (repeat 1)) |
| 20:47 | clojurebot | (1 1 1 1 1 ...) |
| 20:49 | skinkitten | ,(take 10 1) |
| 20:49 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 20:49 | nullptr` | ,(take 10 [1]) |
| 20:49 | clojurebot | (1) |
| 20:50 | amalloy | justin_smith: chunksize? i don't see how that's relevant to the discussion |
| 20:51 | amalloy | repeat isn't chunked, after all. but even if it were, introducing chunking is just a distraction to someone who's just learning how to deal with lazy sequences. (to be honest, it's a distraction to almost anyone, since chunking so rarely matters) |
| 20:51 | justin_smith | amalloy: with some other lazy sequences, I imagine that would be a lower bound on how much would be realized at a time, even if you did not hold onto the head |
| 20:52 | justin_smith | amalloy: fair point |
| 20:53 | amalloy | justin_smith: chunk size can vary across seqs, actually. for example, filter preserves chunkiness, but produces chunks of varying size according to your predicate |
| 20:53 | amalloy | if the incoming sequence has a chunk size of 32, and only 5 elements of that chunk pass your predicate, then the chunk that comes out will have a chunk size of 5 |
| 20:56 | skinkitten | in racket I made it this way (define ones (lambda () (cons 1 ones))). Whats the direct translation of that in clojure? |
| 20:57 | hiredman | skinkitten: well it looks like user error |
| 20:57 | gratimax | (repeat 1) |
| 20:57 | hiredman | skinkitten: what are you trying to create with that? |
| 20:58 | amalloy | hiredman: i mean, you can cons a number onto a lambda, and that's not a totally crazy way to represent lazy sequences in racket |
| 20:58 | hiredman | amalloy: right, but it doesn't seem likely to be what he meant to do |
| 20:58 | hiredman | which is why I asked |
| 20:59 | skinkitten | well before reading streams in clojure docs, I use to call that function a stream but I'm unsure of naming it that, here is the output from racket '(1 . #<procedure:ones>) |
| 20:59 | hiredman | seqs |
| 21:00 | hiredman | streams in clojure are a historical expirement that never made it in to the language |
| 21:00 | hiredman | skinkitten: right, so it creates a pair of a 1 and a function that returns a pair … |
| 21:01 | hiredman | skinkitten: is your intent to use that to represent what is logically an infinite list of 1? |
| 21:01 | skinkitten | hipsterslapfight, yes |
| 21:01 | gratimax | like I said, (repeat 1) |
| 21:01 | gratimax | ,(take 5 (repeat 1)) |
| 21:01 | clojurebot | (1 1 1 1 1) |
| 21:01 | amalloy | hahaha. a new nickname for hiredman |
| 21:01 | gratimax | ,(take 10 (repeat 1)) |
| 21:01 | clojurebot | (1 1 1 1 1 ...) |
| 21:02 | hiredman | :| |
| 21:02 | skinkitten | ,(take-nth 10 (repeat 1)) |
| 21:02 | clojurebot | (1 1 1 1 1 ...) |
| 21:02 | skinkitten | ,(last (take 10 (repeat 1))) |
| 21:02 | clojurebot | 1 |
| 21:03 | gratimax | (repeat 1) is just an infinite list, done with lazy-seq |
| 21:03 | gratimax | it behaves like a list |
| 21:04 | gratimax | a more transparent translation of your code would be something like (def ones (cons 1 (lazy-seq ones))) |
| 21:04 | justin_smith | skinkitten: so the point I was trying to make above, is if you had (def ones (repeat 1)) then somewhere else did (last ones), you would not only waste a bunch of CPU cycles, you would also run out of heap space. If instead of (last ones) they did (last (repeat 1)) you only waste CPU and don't fill up the heap because the elements can be reclaimed as they are used |
| 21:06 | allenj12 | anyone here familirar with hoplon? |
| 21:07 | amalloy | ~anyone |
| 21:07 | clojurebot | anyone is anybody |
| 21:07 | hiredman | ~laugh |
| 21:07 | clojurebot | ha ha |
| 21:07 | cbp | (inc clojurebot) |
| 21:07 | amalloy | hiredman: is it possible to nuke these definitions that get in the way of useful canned responses? |
| 21:08 | mynomoto | allenj12: people gather on #hoplon to talk about hoplon... |
| 21:08 | amalloy | iirc "forget anyone |is| anybody" doesn't help, because he's inferring it from some other stupid path |
| 21:08 | allenj12 | mynomoto: o kk thanks |
| 21:08 | dbasch | ~everybody |
| 21:08 | clojurebot | everybody looks good in a sheinhardt |
| 21:09 | hiredman | amalloy: I just have to remember to look in to next time I crack the database open |
| 21:10 | skinkitten | ,(last (repeat 10 1)) |
| 21:10 | clojurebot | 1 |
| 21:10 | skinkitten | justin_smith, is that space/cycle saving way to call it? |
| 21:11 | justin_smith | the trick is not binding the head of the sequence |
| 21:11 | skinkitten | so without (def ones (repeat 1)) ??? |
| 21:11 | justin_smith | right, just use (repeat 1) in place where you need the sequence |
| 21:12 | justin_smith | and as others have noted, this likely isn't a big deal here, but it is good to be in the habit of not binding the head of indeterminate lazy things |
| 21:13 | skinkitten | justin_smith, what about here? http://goo.gl/JS5Dxh |
| 21:13 | skinkitten | it isn't infinite. so thats ok? |
| 21:14 | mdeboard | If (use) is so freaking terrible then why is the syntax of require so inconsistent in the repl? |
| 21:14 | mdeboard | fook the king |
| 21:15 | amalloy | inconsistent in the repl? how is it any different from in ns, or from use? the only difference is that in ns it doesn't want a quote |
| 21:15 | mdeboard | If I want to refer all symbols from clojure.core.match namespace, how would I do that in the repl? |
| 21:16 | mdeboard | I've been trying variations on (require '[clojure.core.match :refer :all]) |
| 21:16 | justin_smith | skinkitten: that is hypothetically unbounded, but if you know you are only using only the first N you have the excuse that the elements have some computational cost you are minimizing |
| 21:16 | amalloy | what you just typed. right there. that's hwo you do it |
| 21:18 | mdeboard | Sure now it works. |
| 21:19 | skinkitten | justin_smith, thanks |
| 21:20 | skinkitten | I'm going to redact the factorial implementation |
| 21:22 | amalloy | i just noticed something interesting about treating Iterable objects as if they were seqs: one more element than necessary is requested from the iterator. https://www.refheap.com/86424 |
| 21:24 | justin_smith | skinkitten: one option for factorial would be to make a function using iterate, perhaps memoizing it |
| 21:25 | justin_smith | amalloy: will a memoized function have the same heap usage issues as a lazy seq with the head held onto, or is it able to drop memoizations after a certain memory pressure? |
| 21:25 | dbasch | amalloy: that’s probably because hasNext needs to know |
| 21:27 | amalloy | justin_smith: just read the source for memoize. i'm pretty sure you're experienced enough to answer that question with just a quick scan |
| 21:27 | amalloy | dbasch: i actually am not quite sure what's going on. it turns out that (.next (.iterator (tricky))) also throws |
| 21:28 | justin_smith | OK yeah, it will actually be more expensive memory wise than just binding the lazy seq would be (but faster for grabbing a specific result) |
| 21:29 | dbasch | amalloy: (.hasNext (.iterator (tricky))) returns true |
| 21:29 | amalloy | yeah |
| 21:30 | dbasch | so probably .next makes it so that (.hasNext (.next …)) needs to be evaluated |
| 21:32 | Bronsa | justin_smith: core.memoize offers some smarter implementations |
| 21:32 | amalloy | it shouldn't, in theory though, right? if you can call first, you ought to be able to call next |
| 21:32 | mdeboard | What is meant by a "transient set" as opposed to a "new set" in the docs for disj/disj! |
| 21:32 | amalloy | or rather, .next |
| 21:33 | justin_smith | Bronsa: yeah, that's probably what I was thinking of |
| 21:36 | amalloy | but that's more a question of how LazySeq/iterator is implemented, whereas i was hoping to find something out about how iterating over other iterable works |
| 21:40 | dbasch | amalloy: next “Returns the next element in the list and advances the cursor position.” |
| 21:41 | amalloy | dbasch: okay, but the cursor could be pointing at (lazy-seq (throw (Exception.))) without exploding until you actually call .next or .hasNext |
| 21:42 | dbasch | amalloy: yes, in theory it should |
| 21:42 | amalloy | but in reality, what happens is lazy-seq delegates to (.seq this) for most of its methods |
| 22:19 | DomKM | Does Leiningen try to compile my-project.main even if a :main key isn't specified in project.clj? |
| 22:21 | DomKM | I'm getting FileNotFoundExceptions when trying to compile cljx because it is trying to compile a main namespace first, which requires the generated clj namespace. |
| 22:45 | Shayanjm | weird |
| 22:45 | Shayanjm | I'm using Lighttable and working through the brave clojure book |
| 22:46 | Shayanjm | I'm at the part where it discusses multiple namespaces & refer |
| 22:46 | Shayanjm | I passed :only into my refer, but for some reason I'm able to access other vars from inside a different namespace in my repl |
| 22:46 | Shayanjm | any ideas why? |
| 22:49 | pcn | Shayanjm: http://clojuredocs.org/clojure_core/clojure.core/refer refer doesn't prevent you from explicitly naming variables in other namespaes. |
| 22:50 | pcn | It only prevents all of the names from an required namespace from being bound in the current ns. Does that answer your question? |
| 22:50 | Shayanjm | I'm not sure if I understand correctly - I'm a bit new to clojure sorry haha bare with me |
| 22:51 | Shayanjm | So if I have ns1 and ns2, ns1 has thing1 and thing2 defined |
| 22:51 | Shayanjm | i switch in to ns2, and do something like |
| 22:51 | Shayanjm | (clojure.core/refer 'ns1 :only ['thing1]) |
| 22:52 | Shayanjm | intuitively - I would think that clojure only referred thing1 out of the entire ns1, therefore thing2 should be inaccessible from ns2, right? |
| 22:52 | Shayanjm | this also seems to be the behavior that the book depicts, though doesn't seem to be the case when I run it in my own REPL |
| 23:00 | dbasch | Shayanjm: refer just created a mapping for thing1, which you can see in (ns-map ‘ns2) |
| 23:00 | dbasch | Shayanjm: but you can still use ns1/thing2 |
| 23:01 | Shayanjm | dbasch: my point is that it thing1 and thing2 are both usable from ns2 |
| 23:01 | Shayanjm | so it looks like both got a mapping |
| 23:01 | catern | Yes, they should be even if you didn't refer them |
| 23:02 | Shayanjm | Why's that? I thought thing1 and thing2 are stuck in their ns until I refer them? |
| 23:03 | Shayanjm | and if I explicitly only refer thing1, thing2 should still be stuck in its ns (still usable via ns1/thing2, but not as thing2 from ns2) |
| 23:03 | catern | Yes, but you're addressing them by a full namespace path thing |
| 23:03 | catern | Oh |
| 23:03 | Shayanjm | nope |
| 23:03 | catern | Misunderstood you then |
| 23:04 | Shayanjm | Sorry haha - let me try to be clearer |
| 23:04 | Shayanjm | ns1 contains: thing1, thing2. I switched in to ns2, refered -only- thing1 |
| 23:04 | Shayanjm | when i call thing1 from ns2, works as expected |
| 23:04 | Shayanjm | but then I realize I can also call thing2 from ns2 as is, without using the full namespace path |
| 23:04 | Shayanjm | even though I only referred thing1 |
| 23:04 | catern | Have you tried restarting your repl and getting the issue down to a few commands? |
| 23:05 | Shayanjm | yup. Granted, I've been working within the lighttable repl |
| 23:05 | Shayanjm | let me try with lein repl |
| 23:07 | Shayanjm | ah, works in lein repl |
| 23:07 | Shayanjm | weird |
| 23:07 | Shayanjm | so must be a lighttable bug |
| 23:08 | pcn | That makes sense. That would be a good bug to fil. |
| 23:09 | Shayanjm | http://puu.sh/9mOvq/4e0d594002.png |
| 23:11 | amalloy | Shayanjm: are you sure ns2 doesn't already have namespace mappings in it, eg from requiring a .clj file? if this works for two namespaces that didn't exist previously, that would indeed be a bug in light table |
| 23:11 | Shayanjm | amalloy: this is a clean instaREPL in light table & I created (and checked) both namespaces in the repl itself |
| 23:12 | Shayanjm | granted I'm also really really new to Clojure, so I'm not sure if I just did something stupid or if this is actually a bug |
| 23:12 | Shayanjm | either way I'll open up an issue w/ lighttable and see if it gets sorted, or if I get flamed for being a noob ;) |
| 23:14 | amalloy | Shayanjm: i'd recommend (a) using refheap.com instead of a screenshot, and (b) including some evidence that the namespaces are clean before you started doing stuff (eg, above all of this other stuff, going into ns2 and showing that evaluating thing2 leads to an exception) |
| 23:14 | Shayanjm | gotcha. |
| 23:25 | Shayanjm | amalloy: https://github.com/LightTable/LightTable/issues/1520 |
| 23:25 | Shayanjm | I started just copying the commands to refheap, but I realized that I could illustrate the inconsistencies easier (IMO) via screenshots |
| 23:25 | Shayanjm | but its only a grand total of maybe 4 commands, so easy to replicate even without copy-pastable code. |
| 23:27 | catern | Is light table not using JVM backed Clojure or something? |
| 23:28 | Shayanjm | not a clue tbh |
| 23:32 | locks | light table is clojurescript |
| 23:34 | locks | but it should be using regular clojure for the eval, i think |
| 23:38 | PigDude | what's the name of a binding like [arg] as opposed to a let-style binding [name val]? |
| 23:38 | PigDude | for documentation purpose? |
| 23:39 | PigDude | for creating a macro like (with-some-resource [some-name] BODY...) |
| 23:39 | andyf | In defn and defmacro, such things are sometimes called the argument vector or arg vector |
| 23:40 | PigDude | i don't see them used much elsewhere |
| 23:40 | andyf | Not sure if that applies as well to your example. |
| 23:40 | PigDude | yea, definitely |
| 23:40 | andyf | Where does the value for some-name come from in your example? |
| 23:41 | PigDude | not from the code user |
| 23:41 | PigDude | (value supplied by library) |
| 23:41 | andyf | Could there be more than one in the vector? |
| 23:41 | PigDude | no, never |
| 23:41 | andyf | Then why a vector? |
| 23:41 | PigDude | as the macro's semantics are for selecting one thing at a time (looping) |
| 23:42 | PigDude | i have a funky test suite right now and i wanted to run the same tests over different inputs |
| 23:43 | PigDude | so i was using a macro for a convenient way to define these tests, which are automatically tested against several implementations |
| 23:43 | andyf | and some-name will occur one or more times in BODY? |
| 23:44 | PigDude | come to think of it, it wouldn't, i just was hoping to come up with something cleaner than what i have now: a macro that creates a 'deftest' which runs the body over different implementations |
| 23:44 | PigDude | it does this using (binding), and an agreement that test utility functions use the bound name |
| 23:45 | PigDude | ugly. Ugly! |
| 23:45 | PigDude | at least they are effective tests |
| 23:48 | PigDude | if anyone has ideas for improving my tests, i greatly appreciate it, because this organization is not ideal |
| 23:49 | andyf | Just looking for anything similar in clojure.core -- haven't found anything quite like it, especially if the name is not used for anything. |
| 23:49 | PigDude | yea, it was a stupid idea, sorry :) |
| 23:49 | andyf | You can do loops inside of a deftest, if you think that would help. |
| 23:50 | justin_smith | PigDude: any function can call test/is, and if that function is called in a deftest during test time, the is call does the right thing |
| 23:50 | andyf | e.g. (doseq [f [fn1 fn2 fn3 ...] (test f here)) |
| 23:50 | justin_smith | PigDude: so you don't need macros for this, you can just define some functions and call them in your tests |
| 23:51 | PigDude | don' you lose locality on test failure then |
| 23:51 | PigDude | like you do in most languages when composing tests w/o macros |
| 23:51 | justin_smith | PigDude: nope, it tells you which test failed |
| 23:51 | justin_smith | and the line number points the the function, called in that test |
| 23:51 | PigDude | hm OK, will give that a try, thanks justin_smith ! |
| 23:53 | PigDude | wish i could find more on testing w/ clojure tools, some stuff i see jumps right into generative testing/property-based stuff |
| 23:54 | justin_smith | PigDude: for me, the big revelation was that if your code is functional, all you need to do is check inputs and outputs |
| 23:55 | justin_smith | no need for mocking, scaffolding, yadda yadda |
| 23:55 | justin_smith | because you know that stuff won't affect what the function actually does |
| 23:56 | PigDude | you know the only reason i do (binding) in these tests is because use-fixtures has no way to send parameters to the test? or am i missing something? |
| 23:56 | PigDude | i mean the nuts & bolts, having worked in erlang a lot i know how to write decent tests, but erlang has very good test tools and i miss them |
| 23:57 | PigDude | common test, stuff like that? |
| 23:57 | PigDude | i find in-depth material on property-based testing, and shallow material on ordinary unit testing :( no big deal, but i'm happy for suggestions |
| 23:59 | PigDude | not being able to access "fixture" data except via dynamic variables is by far my biggest pain point in clojure right now |