2013-07-01
| 02:36 | kyled | Hello all, quick question about design patter. I'm writing some clojurescript to draw some stuff on the canvas element. I find myself having to pass around the canvas ctx to a lot of functions. This seems a bit repetitive and unnecessary...would it better to use def-type, pass in the canvas element, and then add the functions to the new type? |
| 02:37 | kyled | seems more like OOP that way, but ..again state isn't being preserved since drawing to an element does produce side effects |
| 02:40 | noidi | maybe instead of directly manipulating the canvas you could collect all your operations into a data structure, and then perform them once on the canvas e.g. using doseq? |
| 02:41 | noidi | e.g. you'd have a seq of operations such as [:line :red [10 10] [100 100]] |
| 02:43 | noidi | then your drawing functions would not need to know about the canvas object |
| 02:43 | kyled | noidie: i started to go that route, and works fine in some places. but in others it breaks. To sum up the project I am working on it's a lisp-like syntax for creating flowcharts quickly |
| 02:44 | kyled | so i broke it up where i have "boxes" and w/e text is in them |
| 02:44 | kyled | at some point though, i need to draw connecting lines. To keep things simple I have a function that when given text to create a box, you supply it with a canvas element, and the text you want in the box, and the box type |
| 02:45 | kyled | in that function it calculates the required dimensions of thie box |
| 02:46 | noidi | to you read the canvas' dimensions from the canvas object to perform the calculation? |
| 02:46 | kyled | noidis: not quite, i interact with the canvas to get the text height for example at one part, then later on in the code i use the calls to the canvas to do the drawings..but mabey you are right there is abit of code smell going on |
| 02:47 | kyled | before drawing i really should just have a collection of hashmaps or what have you,without dimension information |
| 02:47 | kyled | since dimension information can only be determined by accessing the canvas element (ie, getting the font height0 then figuring out how much spacing the lines will take up) |
| 02:49 | kyled | but anyways im at the point of drawing, and i have functions that look like this |
| 02:49 | noidi | nowadays I try to push all interaction with the world (i.e. side-effects) near the entry point of the system and keep as much of the system pure as possible |
| 02:50 | kyled | (defn drawLine [ctx ...]) (defn drawRect [ctx ..]) (defn drawNode [ctx ...]) |
| 02:50 | kyled | so mainly , my question is for all my draw functions, since they operate on the same canvas context |
| 02:51 | kyled | does it make sense to remove the 1st parameter? |
| 02:52 | kyled | i think it will clean up my code a bit, since im not having to pass the same thing around to a whole bunch of functions |
| 02:55 | noidi | you could use a dynamically bound var *ctx* to eliminate the parameter, but I believe that style of API design is generally frowned upon in the Clojure world |
| 02:55 | kyled | noidi: exactly... |
| 02:55 | kyled | thats why i was thinking about using closure scope or something |
| 02:56 | kyled | again, all this canvas stuff isn't really functional..i think of the canvas as IO bound stuff with side effects |
| 02:57 | kyled | anyways i have to leave for the night, thanks for your input. i will leave the window open incase you would like to add something. |
| 02:58 | kyled | noidi: quick q though, do you think defprotocl would be fitting though? |
| 02:58 | kyled | i mean, deftype? im not sure if that is the right instruction, im still new to clsure |
| 02:59 | kyled | but i thought you can supply an argument, and w/e method is in the deftype arguments is accessible by all the functions defined in the type |
| 03:06 | noidi | kyled, you'll still have to pass in the "this" parameter manually with protocols |
| 03:09 | noidi | I have no idea about your problem domain, but I think you could separate the drawing to three phases: 1) form an abstract model of the graph (e.g. "a box with text 'foo'"), 2) build a sequence of drawing operations required to render the model (e.g. [:line [10 10] [5 100]]), 3) perform the operations on the canvas |
| 03:10 | noidi | (1) would not need the canvas at all, (2) would need only some data obtained from the canvas (e.g. the text height), (3) would need the canvas, but there would only be a small number of primitive drawing commands that would need the canvas as an argument |
| 03:11 | noidi | if you feel like half your functions need the canvas as an argument, I suspect you might be conflating calculations about the chart with rendering the chart |
| 03:18 | amalloy | i like noidi's approach. but instead of a sequence that has to be "interpreted" by your drawing code, i'd suggest instead building up a lambda that eventually wants to be called with the canvas |
| 03:19 | amalloy | you would probably also learn a lot from watching the SICP lecture (or reading the chapter) on the importance of abstraction barriers, since they use drawing as an example case study |
| 03:20 | amalloy | really it applies to any domain, but it will feel extra-topical at the moment, kyled |
| 03:43 | noidi | kyled, another presentation that you might find helpful is Stuart Sierra's Thinkin in Data http://www.infoq.com/presentations/Thinking-in-Data |
| 03:43 | noidi | it has a bit about separating side effects from the code that calculates which side effects should occur |
| 03:44 | turtil | [M ?M/quit |
| 03:46 | ddellacosta | hmm…is there a way to ensure that you use the same version of CLJS across everything (libs/plugins) you have loaded in your project.clj? |
| 07:37 | jtoy_ | is clostache or stencil the recommended choice for a mustache implementation? |
| 07:47 | dark_element | jtoy_ i use stencil. Works flawlessly and follows mustache spec pretty well |
| 07:54 | jtoy_ | dark_element: thanks |
| 09:12 | BeLucid_ | Hello all, I have a macro question. What's the right way to share something a macro "learns" at runtime with the body? As a simplified example: https://gist.github.com/belucid/5900560 |
| 09:13 | BeLucid_ | Obviously in the real world case, I have something more interesting to share with the body than [let foo "bar"], but this example is sufficient to capture my dilemma. |
| 09:13 | BeLucid_ | What's the right way to let the body code take advantage of something that's been calculated by the macro code. |
| 09:14 | ucb | BeLucid_: normally I'd use autogen'ed symbols like foo#, however your body doesn't know these names beforehand :/ |
| 09:14 | BeLucid_ | right... I tried that path |
| 09:14 | BeLucid_ | and the macro is then generating the right thing with a let |
| 09:15 | BeLucid_ | but the body has no way of knowing what the symbol is going to be |
| 09:15 | ucb | indeed |
| 09:16 | BeLucid_ | my real world use, in case it spurs any ideas, is a macro with-collection. It takes a collection name... does a bunch of DB look ups and checks and things, and if everything is all good, it needs to provide the collection id to the body. |
| 09:18 | BeLucid_ | need the macro so all the cruft about finding and validating a collection goes away and isn't duplicated, but everything that needs the macro only has the name but needs an id |
| 09:19 | BeLucid_ | here's a (non-working) start at the real thing: https://gist.github.com/belucid/5900620 |
| 09:20 | BeLucid_ | coll-id# is autogen'ed, so then body doesn't know what it is, or coll-id gets qualified by the macro and is then not a valid form for the let. |
| 09:21 | BeLucid_ | Either way, no love. Seems that this would be a not so incredibly uncommon case. But so far I haven't found anything that addresses how to do it. |
| 09:34 | BeLucid_ | ahh... it seems that def, thereby creating a var that's local to the macro (I presume) works: https://gist.github.com/belucid/5900746 |
| 09:35 | BeLucid_ | thanks for being a sounding board everyone, if anyone has any commentary on how idiomatic or not that is, I'm all ears |
| 09:36 | hyPiRion | BeLucid_: It's a silent time now, too early/late for Americans |
| 09:37 | hyPiRion | You may want to post it on the google group or come back in some hours |
| 09:37 | hyPiRion | (And I'm a bit busy, so I haven't time to look at it now, sorry) |
| 09:37 | BeLucid_ | I'm an (unconscionably early rising) East Coast American. I guess that makes me a singleton. |
| 09:38 | BeLucid_ | No worries, I'll post it to the group, thanks. |
| 09:39 | hyPiRion | oh, it's later than I thought it was |
| 09:41 | BeLucid_ | yeah... turns out the def doesn't work in the real world case, only worked in the REPL cause the macro and it's use were in the same ns. |
| 09:41 | BeLucid_ | In the real world case, I get: CompilerException java.lang.RuntimeException: Can't create defs outside of current ns |
| 10:46 | dnolen_ | timer coalescing in core.async is kinda genious |
| 10:51 | bbloom | github really needs to fix their shitty news feeds |
| 10:52 | bbloom | literally one solid page of "$user starred brandonbloom/asyncx" |
| 10:52 | bbloom | surely that should be like retweets or favorites on twitter |
| 10:52 | bbloom | compressed down to "22 people starred brandonbloom/asyncx" |
| 10:56 | drewolson | quick question about core.async. I'm using map with <! in go blocks and i'm seeing an error. am i doing something wrong? https://gist.github.com/drewolson/5212fcb3ae46f4c58bd6 |
| 10:57 | pjstadig | drewolson: map is lazy so you probably need to wrap your map call in (doall ...) |
| 10:57 | drewolson | pjstadig: ah :) that maps perfect sense, thanks |
| 10:58 | drewolson | it also explains why it works if the function passed to make makes its own go block |
| 10:58 | drewolson | s/make/map/g |
| 10:58 | hyPiRion | mapv perhaps |
| 10:59 | gfredericks | man I've been doing (.printStackTrace *e) in my repl for months thinking it was a bug that it wasn't working |
| 10:59 | gfredericks | time to start using pst |
| 10:59 | bbloom | you can't use <! in a higher order fasion anyway |
| 10:59 | drewolson | bbloom: interesting. seemed to work for me to use <!! in a map |
| 10:59 | bbloom | <!! works |
| 10:59 | bbloom | not <! |
| 10:59 | bbloom | https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L77-L81 |
| 11:00 | bbloom | go blocks have lexical, not dynamic extent |
| 11:00 | drewolson | ok, that's a big help, thanks |
| 11:01 | bbloom | i dunno what the main core.async people would say, but you should try to use the double bang operations only at the "edges" |
| 11:01 | bbloom | prefer go and single bang operations everywhere in the middle, since those will be portable to cljs (where there are no blocking threads) and will be multiplexed onto os threads |
| 11:01 | drewolson | bbloom: that was my intuition as well. basically only to block the "main" thread when waiting on work |
| 11:02 | bbloom | yup |
| 11:02 | bbloom | drewolson: here's what i came up with for a higher order, non-blocking map: https://github.com/brandonbloom/asyncx/blob/master/src/asyncx/core.clj#L291-L305 |
| 11:03 | drewolson | bbloom: here |
| 11:03 | drewolson | here's my pmap implementation from last week: https://gist.github.com/drewolson/5888365 |
| 11:04 | bbloom | cool |
| 11:05 | bbloom | heh, so many channels haha |
| 11:05 | bbloom | it feels kinda weird at first, being used to working w/ sockets and the like where you have like ONE or TWO of them |
| 11:06 | jtoy_ | i hate the name go blocks |
| 11:06 | jtoy_ | it sounds like it means its coming from go the language |
| 11:06 | bbloom | having cheap first class channels takes some getting used to |
| 11:06 | jtoy_ | bbloom: are you using them already for projects? |
| 11:06 | bbloom | not beyond my little learning experiments |
| 11:07 | bbloom | i don't have a strong need for them yet |
| 11:07 | drewolson | bbloom: yes. i've been experimenting with go for a while so i'm a bit more used to it. but i'm not a fan of go's type system at all, so this is a breath of fresh air |
| 11:08 | hyPiRion | drewolson: haha, the type system is funny |
| 11:08 | drewolson | bbloom: i think if you only implement it using a single channel, you'd at least need to make it buffered so that the computation was actually parallel. otherwise it would just be lazy, which it already is |
| 11:22 | bbloom | drewolson: my library isn't concerned with parallelism. only concurrency |
| 11:23 | drewolson | makes sense |
| 11:23 | supersym | using positions instead of .indexOf, positions is a lot faster. When I use it to lookup nth, its exactly the other way around |
| 11:23 | supersym | does that make any sense? |
| 11:26 | supersym | oh well..guess I care less about the 'how' now :) |
| 11:36 | timvisher | i'm trying to view a matrix in incanter and having trouble. i figured i'd simplify and go for getting something directly out of the docs to work and that also fails. i get an exception stating that there is no multimethod dispatch value for clatrix.core.Matrix. https://gist.github.com/timvisher/5901834 |
| 11:36 | timvisher | am i doing something wrong or are the docs out of date? |
| 11:50 | supersym | timvisher: I recall having that somewhere as well, don't think I found the solution tho...definitly clatrix as well |
| 11:57 | timvisher | supersym: good to know i'm not alone. :) |
| 12:01 | SegFaultAX | It's gonna be a good day: BART is went on strike + an excessive heat warning in the east bay (100+ everywhere). Yay Mondays! |
| 12:01 | SegFaultAX | BART went* |
| 12:01 | bbloom | SegFaultAX: meanwhile, here in NYC, there was a flash flood warning |
| 12:01 | bbloom | weeeee |
| 12:01 | SegFaultAX | bbloom: I'm sorry :( |
| 12:02 | bbloom | not nearly as bad as being unable to get to work |
| 12:02 | bbloom | WFH day! |
| 12:02 | bbloom | enjoy |
| 12:04 | SegFaultAX | Haha, yea. |
| 12:05 | gfredericks | does anybody know if org-babel and nrepl.el have any chance of working with each other? |
| 12:06 | gfredericks | the org-babel docs for clojure talk about version 1.1.0-alpha-SNAPSHOT and swank and similarly ancient concepts |
| 12:06 | kmicu | gfreII RC yes |
| 12:07 | kmicu | gfredericks: IIRC yes, it works |
| 12:08 | gfredericks | good to know |
| 12:11 | kmicu | You can find an example config in Stuart Sierra's dotfiles and in google ;] |
| 12:12 | hiredman | gfredericks: yes |
| 12:14 | hiredman | gfredericks: https://gist.github.com/5902187 is what I found somewhere on the internet that makes it use nrepl |
| 12:15 | gfredericks | hiredman: yeah, same thing stuartsierra has I think; thanks |
| 12:18 | gfredericks | holy crap it just worked |
| 12:19 | kmicu | gfredericks: https://www.refheap.com/16234 this is my last config, but I did not use it for a time |
| 12:25 | kovas | let the hacking commence |
| 12:29 | alandipert | kovas: rage |
| 12:29 | kovas | alandipert: f to the yea |
| 12:31 | manutter | mental block time: there's a technical term for things like "this" (in Java), where it's just defined for you. What's that term? |
| 12:33 | manutter | you can build them in Clojure using macros but that may or may not be a good idea |
| 12:33 | technomancy | manutter: anaphora, I think |
| 12:33 | manutter | that's it! |
| 12:33 | manutter | been on the tip of my tongue all day |
| 12:33 | manutter | thanks |
| 12:39 | dnolen_ | OK some subtle core.async bugs around alts! CLJS support fixed in master |
| 12:41 | bbloom | dnolen_: nice |
| 12:42 | dnolen_ | yeah, going to port the Go example to CLJS now :D |
| 12:43 | mrb_bk | baller |
| 12:46 | bbloom | kovas: (Math/pow f yea) |
| 12:47 | kovas | lol |
| 12:48 | kmicu | Why second example prints, but first not? https://www.refheap.com/16235 |
| 12:49 | devn | big ballin' |
| 12:50 | technomancy | AC/DC reference? |
| 12:50 | devn | sure, why not? |
| 12:53 | pbostrom | or Fat Pat |
| 13:17 | atyz | Aside from korma, are there any good ORM's worth looking at? |
| 13:18 | seancorfield | ORM sort of implies Objects... |
| 13:31 | enquora | just watched a video of dnolen talk on clojurescript with browser wired up to repl for live demonstration. what is the simplest way to configure something like that? |
| 13:32 | bbloom | it's not super simple at all… lein cljsbuild is your best bet, but the browser repl is a bit tricky to configure |
| 13:32 | enquora | am starting a project to create PDF generator that must run on server, in browser, an iOS, and am trying to find a starting point |
| 13:32 | nDuff | won't Light Table pretty much automate that (for its built-in browser)? |
| 13:32 | enquora | I'm not religious about the coding environment |
| 13:33 | enquora | perhaps I'm better serializing results to file and using Preview on OS X for testing then? |
| 13:34 | enquora | and worrying about the cljs part once the PDF generation code is working somewhat |
| 13:37 | pbostrom | enquora: piggieback is also an option to use with nREPL https://github.com/cemerick/piggieback |
| 13:37 | enquora | Is Light Table generally usable for real work in current state? |
| 13:39 | nDuff | enquora: My inclination is to say "no". Last time I did cljs, I did the work to set up a proper browser repl with emacs (which wasn't really very much work). |
| 13:39 | enquora | pbostrom: what does 'clojurescript repl' mean in this context? |
| 13:39 | nDuff | enquora: ...but it's been long enough that I'm not able to recount the steps. |
| 13:39 | enquora | sorry for being dense - have had *very* long last week and am having trouble grokking at the moment |
| 13:40 | enquora | need to interactively test results of PDFs I'm building as they will be viewed in web browser |
| 13:40 | pbostrom | enquora: it supports Rhino and browser REPL |
| 13:41 | enquora | pbostrom: so one might enter cljs in browser console and have it execute? |
| 13:42 | pbostrom | enquora: no, enter cljs in your normal REPL process, whether that's running in your terminal, or inside emacs |
| 13:42 | nDuff | enquora: ...so you want to enter cljs in _your browser_, rather than enter it in _your editor_ and have it executed in your browser? |
| 13:42 | enquora | no, want to code on desktop with keyboard, transparently generate PDF and send to browser |
| 13:43 | enquora | want to code in normal environment |
| 13:43 | devn | enquora want code in normal environment! |
| 13:43 | devn | :) |
| 13:43 | enquora | sorry |
| 13:43 | enquora | brain not working |
| 13:43 | devn | lol im just messing with you |
| 13:43 | pbostrom | enquora: what do you use for normal Clojure editing and REPL development |
| 13:43 | enquora | am in Calgary, have been working in flood zone for last week |
| 13:44 | Raynes | sorry cant brane today |
| 13:44 | Raynes | i got the dums |
| 13:44 | enquora | brain not working normally yet |
| 13:44 | enquora | pbostrom: having done anything serious in clojure yet |
| 13:44 | enquora | normally I'm a vim person |
| 13:45 | enquora | but am happy to use emacs, evil mode or not |
| 13:45 | enquora | have lisp experience from decades ago, but no real clojure experience |
| 13:46 | enquora | have need to create bit-identical PDFs in web browser, on server, and in native iOS app. Am now tackling library to do so |
| 13:46 | pbostrom | ok, well, lein has a nice REPL, nREPL, built in, you can run piggieback on top of that, another nice option is the lein cljsbuild plugin which also has a REPL |
| 13:48 | enquora | piggieback creates some sort of local http server then? |
| 13:50 | pbostrom | yes, on port 9000, although I think the actual work of creating the server is done by the core cljs libs, piggieback just sets up the plumbing between nREPL and the core cljs REPL |
| 13:59 | enquora | thks |
| 13:59 | dnolen_ | Rob Pike's Go multi search timeout example now works in core.async CLJS http://gist.github.com/swannodette/5903001 |
| 14:00 | kmicu | nice |
| 14:01 | edbond | dnolen_, can you add a link to original? |
| 14:03 | dnolen_ | edbond: to the Go code? |
| 14:03 | edbond | dnolen_, yes, where can I see "Rob Pike's Go multi search timeout example"? |
| 14:03 | bbloom | w00t. i'm glad i ported that little snippet. it's seeing a lot of milage :-) |
| 14:05 | edbond | dnolen_, ok, I found slides and presentation, anyway. |
| 14:05 | dnolen_ | edbond: updated |
| 14:05 | dnolen_ | with direct link to slide |
| 14:05 | edbond | dnolen_, yknow, for famous LOC comparision :) |
| 14:06 | edbond | dnolen_, great, thanks. |
| 14:08 | bbloom | i really want ><! :-) |
| 14:08 | bbloom | or <>! |
| 14:09 | bbloom | or something that somehow makes the order of arguments not ambiguous :-P |
| 14:09 | edbond | :-D put-or-take |
| 14:10 | bbloom | no, i want take-then-put |
| 14:14 | bbloom | go func() { … } () feels so heavy weight now :-) |
| 14:15 | bbloom | edbond: in go, what i want is basically "<- <-" |
| 14:16 | bbloom | http://play.golang.org/p/LKM85cobjd |
| 14:17 | kovas | i prefer words over symbols for everything but the very most common ops |
| 14:17 | kovas | so move! or route! or something |
| 14:17 | bbloom | sure, my biggest concern is the extra parens :-) |
| 14:17 | kovas | i agree |
| 14:17 | bbloom | i like move!, but i can never decide if i want (f src dest) or (f dest src) |
| 14:17 | technomancy | a little perl now and then is good for the constitution |
| 14:18 | technomancy | bbloom: whut |
| 14:18 | technomancy | who puts the destination first? |
| 14:18 | kovas | oh god, flashbacks of ln -s |
| 14:18 | bbloom | technomancy: assignment operators. |
| 14:18 | bbloom | (set! x 1) |
| 14:19 | bbloom | it also depends on whether you want variadic sources or variadic destinations |
| 14:19 | kovas | i think "from here to there" is the easiest to remember |
| 14:19 | kovas | a la mv |
| 14:19 | bbloom | mv some list of source files to here |
| 14:19 | bbloom | link this-file to each of these locations |
| 14:19 | technomancy | kovas: unless you're in an RTL language =) |
| 14:20 | bbloom | the real problem with ln is that the docs are ambiguous |
| 14:20 | bbloom | it says: ln [options] source_file … target_dir |
| 14:21 | enquora | pbostrom: I hope I'm not putting the cart before the horse worrying about setting up a repl to test PDF out in browser first. Final code will be packaged as javascript and jvm library - I'm naively assuming that there are no particular problems generating/packing the code once it is complete? The actual generation of the PDFs is dauntingly difficult and I'm anxious to get going on development of that, which will involve learning which p |
| 14:21 | enquora | of Clojure I need, too. |
| 14:21 | bbloom | but it's referring to the source and target OF THE LINK |
| 14:21 | bbloom | not the action of creating the link |
| 14:21 | bbloom | *d'oh* |
| 14:21 | kovas | technomancy: never seen that before, cool |
| 14:22 | TimMc | bbloom: Ugh, yeah. alias ln='ln -n' has saved my butt a few times. |
| 14:22 | kovas | the docs are terrible |
| 14:22 | kovas | i can never remember |
| 14:25 | MrGarlic | what are the advantages of clojure over lisp and/or scheme |
| 14:26 | bbloom | MrGarlic: http://clojure.org/rationale |
| 14:26 | awwaiid | MrGarlic: running on the jvm means accessing a bunch of libs, to start with. After that the first thing that comes to mind is having just a touch of extra syntax for hashes and vectors and sets and such |
| 14:26 | technomancy | MrGarlic: clojure is lisp |
| 14:27 | awwaiid | bbloom++ # thanks |
| 14:27 | bbloom | technomancy: presumably he means common lisp |
| 14:27 | MrGarlic | technomancy: a type of lisp? |
| 14:27 | nDuff | MrGarlic: A member of the LISP family of languages. |
| 14:27 | nDuff | MrGarlic: Common LISP is a specific language. LISP is not. |
| 14:27 | pbostrom | enquora: actually, I was going to mention that, it might be better to start with the lein cljsbuild plugin to first compile your cljs as a static js file. Once you get that loaded in your browser and get a feel for the development cycle, then you can add the browser repl, you can certainly be ver productive just autocompiling your cljs and reloading your browser window |
| 14:28 | MrGarlic | nDuff: It's not a dialect? |
| 14:29 | nDuff | *shrug*. |
| 14:29 | enquora | pbostrom: am going to sleep on this. it's a national holiday here and I need a break. I've been procrastinating on this for ages though, and wanted to force myself to get going |
| 14:29 | enquora | another part of the problem I didn't mention is that the PDFs contain many html-style tables, and will need constraint management |
| 14:30 | enquora | need to brush up on my prolog |
| 14:30 | enquora | err, core.logic |
| 14:31 | enquora | constraint satisfaction, I should say |
| 14:31 | gfredericks | so I have, a couple times, somehow or another by playing with core.async gotten my machine into a state where all cores are running at 100% doing nothing in particular |
| 14:32 | enquora | MrGarlic: clojure is *a* lisp |
| 14:32 | enquora | in my case, the advantage is that I need lisp-level chops to generate PDFs on server and in web browser without plugins |
| 14:33 | enquora | Clojure has a nice javascript target called Clojurescript |
| 14:33 | enquora | such things exist for Scheme too (Gambit, Chicken), but Clojure has the traction |
| 14:34 | technomancy | chicken targets JS? |
| 14:36 | enquora | I might be forgetting, but I think emscripten is your friend there |
| 14:37 | enquora | At one time I was planning to meet out need for native iOS execution by using the Scheme target for Clojure, then compiling to native, so I may be crossing wires |
| 14:38 | enquora | Not necessary now in any case, with iOS 7 and public API for JavascriptCore independent of browser context |
| 14:38 | enquora | makes me sad that I can't just use Quartz to generate the PDFs though :-( |
| 14:40 | technomancy | I've never heard of anyone generating PDFs in the browser |
| 14:40 | enquora | that's because it's never been done on this scale |
| 14:40 | technomancy | seems very unlikely you could get pixel-for-pixel fidelity across any two runtimes |
| 14:40 | enquora | technomancy: use data url to deliver the file |
| 14:41 | enquora | not with existing PDF libraries |
| 14:41 | enquora | but by writing at the core PDF primitive level it's easy |
| 14:41 | enquora | for some definition of 'easy' |
| 14:42 | enquora | the real problem is that these PDFs are mostly tabular, and need some serious attention to typesetting principles |
| 14:42 | enquora | so constraint satisfaction is a big issue too - column widths, font sizes and kerning for type placement |
| 14:42 | enquora | white-space management |
| 14:43 | enquora | Haven't begun to get my head around representing the Carousel Object System in clojure yet, either |
| 14:44 | enquora | which is the basis for the PDF format |
| 14:44 | enquora | all of which is to say, if anyone else has this problem, the line for volunteers forms here |
| 14:47 | enquora | technomancy: here's the one instance that's tried it: http://jspdf.com |
| 14:47 | enquora | It's only useful for trivial stuff though, and has no concept of real typesetting |
| 14:59 | gfredericks | seancorfield: ping |
| 15:07 | murphy607 | hi |
| 15:08 | murphy607 | i have a problem to get clojurescript running |
| 15:08 | jcromartie | murphy607: go ahead! |
| 15:08 | jcromartie | murphy607: I have just done this, myself, so I hope i can help |
| 15:08 | murphy607 | the repl-browser |
| 15:08 | murphy607 | creates problems |
| 15:08 | murphy607 | (require '[cljs.repl :as repl]) |
| 15:08 | murphy607 | (require '[cljs.repl.browser :as browser]) |
| 15:08 | murphy607 | (def env (browser/repl-env)) |
| 15:09 | murphy607 | if i do this i get the followig errtor: |
| 15:09 | murphy607 | java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.LazySeq |
| 15:09 | murphy607 | i use clojure in version 1.5.1 |
| 15:10 | jcromartie | running that exact code? |
| 15:10 | murphy607 | yes |
| 15:10 | murphy607 | this was cut and paste |
| 15:10 | jcromartie | have you tried them one at at ime? |
| 15:10 | jcromartie | one at a time |
| 15:11 | murphy607 | yes |
| 15:11 | Cho4 | hi |
| 15:11 | jcromartie | murphy607: and it's (def env (browser/repl-env)) that throws the error |
| 15:11 | murphy607 | yes |
| 15:11 | Bronsa | murphy607: which version of cljs are you using? |
| 15:12 | jcromartie | murphy607: using the repl script that comes with ClojureScript, (which uses Clojure 1.5.1), I have no problem evaluating your code |
| 15:12 | jcromartie | murphy607: are you in a REPL? |
| 15:12 | murphy607 | [org.clojars.bartonj/clojurescript "1.0.1-SNAPSHOT"] |
| 15:12 | Bronsa | that's not the official clojurescript |
| 15:12 | Bronsa | and it's probably an outdated one |
| 15:13 | murphy607 | ahhh ok... |
| 15:13 | Cho4 | https://www.refheap.com/16239 how can i make it work? |
| 15:13 | murphy607 | Bronsa: thats the one i found... but you are probably right |
| 15:13 | Cho4 | basicly i need to acess dynamic segment :id from context b-routes. |
| 15:14 | Bronsa | murphy607: [org.clojure/clojurescript "0.0-971"] |
| 15:14 | murphy607 | Bronsa: i guessed that it is a problem with tthe clojure versions... |
| 15:14 | Bronsa | err |
| 15:14 | murphy607 | Bronsa: thx |
| 15:14 | Bronsa | murphy607: [org.clojure/clojurescript "0.0-1835"] |
| 15:14 | murphy607 | k |
| 15:15 | Cho4 | weais it even possible? |
| 15:15 | murphy607 | Bronsa: it works! thanks |
| 15:16 | murphy607 | jcromartie: thanks too :) |
| 15:18 | Cho4 | https://github.com/weavejester/compojure/blob/1.1.3/src/compojure/core.clj#L180 not sure what happens with args |
| 15:26 | supersym | enquora: thats pretty sweet! ...didn't know it either |
| 15:26 | Cho4 | help |
| 15:42 | amalloy | Cho4: that looks to me vaguely like it ought to work. instead of periodically crying "help" with no clarification, why don't you tell someone what happened instead? |
| 15:47 | CapnKernul | Are (:use [foo :only [bar]]) and (:require [foo :refer [bar]]) the same? Is one more idiomatic than the other? |
| 15:49 | Cho4 | amalloy: it just doesn't sees id from b-routes. |
| 15:51 | supersym | CapnKernul: http://stackoverflow.com/a/872049/2508931 |
| 15:52 | pbostrom | supersym: CapnKernul: that SO answer is a bit dated, I think :use is considered deprecated in favor for :require :refer, although you will still see quite a bit of references to :use in new code/blog posts, so I doubt it will ever go away |
| 15:52 | Raynes | muhoo: ninjudd requests a sound sample of your fretless guitar. |
| 15:57 | CapnKernul | great, thanks. :) |
| 16:03 | dnolen_ | core.async + core.match is tasty http://gist.github.com/swannodette/5903968 |
| 16:03 | dnolen_ | core.match + core.async is tasty http://gist.github.com/swannodette/5903968 |
| 16:04 | ro_st | dnolen_: howdy |
| 16:04 | kmicu | double logic all the way |
| 16:04 | bbloom | dnolen_: YOU'VE GOT YOUR ERLANG IN MY CLJS |
| 16:04 | bbloom | awesome. |
| 16:05 | bbloom | can you match on multiple channels w/ alts? |
| 16:05 | ro_st | is there somewhere i can read up on this channel malarky? |
| 16:05 | bbloom | ro_st: 2 places, the clojure blog & the go community |
| 16:05 | ro_st | i've never encountered it before. and i want to understand it |
| 16:05 | bbloom | clojure.com/blog/2013/06/28/clojure-core-async-channels.html |
| 16:05 | bbloom | talks.golang.org/2012/concurrency.slide |
| 16:06 | ro_st | awesome, thanks Brandon |
| 16:06 | ro_st | enjoyed your talk in Oslo, dnolen_ |
| 16:07 | bbloom | dnolen_: presumably matching is a read-only operation. so could i match on a "channel group" or something & get multiplexing? |
| 16:07 | bbloom | (this is just a random though, no idea if it's a good idea) |
| 16:08 | ro_st | so in that latest gist from dnolen_, we have two independent channels that cause the handler to fire whenever they are written to with >! |
| 16:09 | ro_st | so the go macro is like callback retardant |
| 16:09 | dnolen_ | core.match and core.async together are tasty http://gist.github.com/swannodette/5903968 |
| 16:09 | bbloom | …. you said that already… twice… lol |
| 16:09 | bbloom | ro_st: "callback retardant", while entertaining, is putting it very simply :-) |
| 16:09 | kmicu | triple logic all the way |
| 16:09 | hyPiRion | dnolen_ is broken D= |
| 16:10 | ro_st | i smell an emacs lisp keybinding |
| 16:10 | hyPiRion | he just repeats himself! |
| 16:10 | bbloom | I KNEW IT! of course he had to be a robot! |
| 16:10 | bbloom | somebody reboot him |
| 16:10 | hyPiRion | $reload |
| 16:10 | lazybot | hyPiRion: It is not the case that you don't not unhave insufficient privileges to do this. |
| 16:10 | hyPiRion | whoops, wrong bot. |
| 16:11 | bbloom | heh |
| 16:11 | ro_st | bbloom: so i'm right about the other bits? |
| 16:12 | bbloom | ro_st: yeah, you pretty much got it |
| 16:12 | ro_st | wicked |
| 16:12 | bbloom | but there are some other interesting things going on worth noting |
| 16:12 | bbloom | for example, the sliding-buffer calls |
| 16:12 | dnolen | amalloy: seqable article is history is there something you want to know from it? |
| 16:12 | bbloom | if multiple mouse move messages come in while the handler is busy doing other stuff, only the last message will be delivered |
| 16:13 | amalloy | dnolen: someone had asked a question on SO about how to do something similar, and i was hoping to link them to your implementation |
| 16:13 | bbloom | much more sophisticated (and pleasant!) than callbacks |
| 16:13 | dnolen | sorry for the double post earlier, IRCCloud client was effed up |
| 16:14 | ro_st | bbloom: and that's controlled by the buffer size? |
| 16:14 | dnolen | bbloom: hmm maybe, re: multiplexing |
| 16:14 | bbloom | dnolen: good cover up…. BOT. |
| 16:14 | dnolen | hehe |
| 16:14 | dnolen | amalloy: yeah, it's a simple idea, I should probably repost that |
| 16:15 | bbloom | ro_st: you can have buffered or unbuffered channels. and if you have a buffer, then you can have one of 3 (currently) policies: drop newest, drop oldest, and block on full |
| 16:15 | dnolen | and you can of course provide your own buffer |
| 16:16 | ro_st | gotcha |
| 16:17 | dnolen | ro_st: thanks |
| 16:17 | ro_st | so in this case, on each pass in the while at the bottom, alts! is completing one of the two buffered channels and returning the map for the handler's match to destructure |
| 16:18 | dnolen | ro_st: yeah, one thing I realized - keep your go blocks small and call out as soon as possible |
| 16:18 | dnolen | putting a match expression in a go block is a recipe for disaster |
| 16:18 | ro_st | and if we made the buffer size bigger, alts! would consume the subsequent 'queued' ops on the channel on subsequent passes |
| 16:19 | ro_st | that makes sense. i should think you'd want to keep just your channel interactions inside go |
| 16:19 | dnolen | yeah |
| 16:20 | gfredericks | should creating 10000 go blocks be relatively cheap? |
| 16:20 | gfredericks | it maxes out all 4 of my cores for ~10 seconds |
| 16:21 | ro_st | would it make sense to wire network interactions up with channels? ie, (go (let [result (ajax action)] (do something with result))) |
| 16:21 | bbloom | gfredericks: can you share your benchmark? |
| 16:21 | gfredericks | bbloom: yeah one sec |
| 16:23 | gfredericks | bbloom: https://www.refheap.com/16243 |
| 16:23 | bbloom | heh… are you sure the printing isn't what's killing you? :-P |
| 16:23 | gfredericks | me? |
| 16:23 | bbloom | yeah |
| 16:23 | gfredericks | oh that |
| 16:23 | gfredericks | I forgot I printed; but no that should just be a few times |
| 16:24 | gfredericks | only once for each eval of line 10, no? |
| 16:24 | dnolen | gfredericks: I think you're going to create a lot of contention to read of that channel? |
| 16:24 | dnolen | channel ends points are locked |
| 16:24 | gfredericks | okay, if this is expected that's fine; just wanted to understand what I was doing that was unorthodox |
| 16:25 | gfredericks | so 30,000 go blocks listening on 1 channel is a bad idea? |
| 16:25 | atyz | Does anyone know if its possible to pass in a connection string like this: jdbc:mysql://localhost:3306/content_vu?user=root to korma? Or will I have to parse it for the different components? |
| 16:26 | bbloom | lol just discovered i had a zombie vim instance trying to eval some async code sucking up one of my cores |
| 16:26 | dnolen | gfredericks: it seems like a weird design to me, but I dunno |
| 16:26 | bbloom | my computer didn't feel any slower haha |
| 16:27 | gfredericks | dnolen: certainly weird; I'm just trying to understand the boundaries |
| 16:27 | ro_st | yay multi-core. shows you how much of your software isn't multi-core :-) |
| 16:28 | bbloom | dnolen: that region inference thing is sweeeet |
| 16:28 | bbloom | dammit too much cool stuff |
| 16:28 | bbloom | how will i ever get any actual work done? |
| 17:13 | kmicu | I C-g nrepl-toggle-trace and killed my emacs :( |
| 17:14 | clojurenewb | hi… I'm looking for the 'rest' equivalent of 'nnext'… but can't seem to find it… wondering if I am missing something ? |
| 17:15 | bbloom | clojurenewb: i don't think there is one. just define one (def rrest (comp rest rest)) |
| 17:17 | clojurenewb | bbloom: yeah thought that might be the case, just checking :-) |
| 17:19 | technomancy | huh, the guards must be off-duty today |
| 17:19 | technomancy | probably on strike to show solidarity with BART |
| 17:21 | amalloy | technomancy: https://groups.google.com/d/msg/clojure/CanBrJPJ4aI/S7wMNqmj_Q0J - who says only ruby can have confusing features like method-missing? |
| 17:21 | technomancy | ~guards |
| 17:21 | clojurebot | SEIZE HIM! |
| 17:23 | iwo | hey, does anyone know what the best/simplest way to get clj-http to send a map as json (in the body of a request) is? |
| 17:24 | iwo | is there no other option than to serialize the map into a string representation of json before sending to clj-http? |
| 17:24 | bbloom | amalloy: surely the problem with method-missing is the context sensitive nature of it |
| 17:24 | bbloom | amalloy: if vars were generated to created to back symbols resolved at module load time, that wouldn't be so bad |
| 17:25 | bbloom | and module load time ~= macro expansion time |
| 17:25 | bbloom | so what could go wrong? :-) |
| 17:26 | bbloom | also, this reminds me of swizzling in shader languages, which is a great feature |
| 17:27 | bbloom | ie you can have some vector and do things like v.xxyy |
| 17:27 | bbloom | or v.zyx |
| 17:27 | bbloom | or whatever you want |
| 17:28 | pbostrom | iwo: the cheshire lib by dakrone will serialize your map, it's probably outside the scope of what an http client should do |
| 17:33 | iwo | pbostrom: so, are you suggesting calling 'encode' from cheshire before adding the contents to under the :body key? |
| 17:34 | iwo | it's strange because clj-http will perform 'coercion' (parsing json data to a map) on a response body, but not a request body |
| 17:37 | brehaut | iwo: you may need to set the content type header on the request before clj-http will encode it |
| 17:38 | iwo | brehaut: this doesn't seem to make any difference :( |
| 17:38 | seangrove | Should we be able to map over a javascript array in clojurescript? |
| 17:38 | seangrove | I'm getting and error "Uncaught Error: is not ISeqable" |
| 17:39 | iwo | it looks like the only way to do this is: set all properties as form-params, set :content-type :json in the request map, use the wrap-form-params middleware |
| 17:39 | iwo | easier to call 'encode' i think |
| 17:40 | brehaut | iwo: and you have the appropriate middleware? |
| 17:40 | dakrone | iwo: you should be able to do (http/post "http://aoeu.com" {:body (encode {:my :thing})}) |
| 17:40 | SegFaultAX | callen: Ping. |
| 17:41 | iwo | darkrone: yes, i think i'll just call encode, it seems simpler than the middleware+form params route |
| 17:41 | dnolen | seangrove: it's working for me here |
| 17:41 | technomancy | seangrove: looks like clojure accidentally an error message |
| 17:42 | bbloom | blah. probably a (print nil) |
| 17:42 | bbloom | er str nil, i mean |
| 17:42 | iwo | darkrone: what do you think about the following change to clj-http: if json-enabled? and :content-type :json, and :body contains a collection, then use 'encode' on the body automatically (?) |
| 17:45 | dakrone | that would make the case when sending a string body kind of confusing, I'd personally rather have the encoding be explicit, especially because it's pretty easy to do right before sending |
| 17:48 | iwo | dakrone: i think it would be really nice to have something similar to :as :json, but for the request |
| 17:49 | seangrove | Ah, I think it may be mistaking null/strings for arrays... |
| 17:55 | gt`` | hi looking for some help on clojure and odbc |
| 18:49 | onceUponATime | I have $CLASSPATH set to ".:/usr/local/clojure-1.5.1/target:/usr/local/clojure-1.5.1" and "jline-0.9.94.jar" under "/usr/local/clojure-1.5.1/target" and when I run the command: "java -cp jline-0.9.94.jar:clojure-1.5.1.jar jline.ConsoleRunner clojure.main" I get the error message: "Error: Could not find or load main class jline.ConsoleRunner" |
| 18:49 | onceUponATime | Any idea?? |
| 18:49 | lazybot | onceUponATime: What are you, crazy? Of course not! |
| 18:50 | technomancy | onceUponATime: don't set $CLASSPATH, and try using absolute paths |
| 18:50 | technomancy | (assuming you have a good reason to be constructing `java` invocations by hand) |
| 18:50 | amalloy | also -cp overrides $CLASSPATH anyway |
| 18:50 | technomancy | oh, also jline 0.x is pretty terrible |
| 18:50 | onceUponATime_ | I tried that and got the same thing |
| 18:51 | onceUponATime_ | well do we have a choice? |
| 18:51 | amalloy | onceUponATime_: why is clojure in /usr/local anyway? a system-wide install of clojure is a pretty bad idea; use lein instead if you have any choice at all |
| 18:51 | onceUponATime_ | it runs only if I go to target directory and run from their |
| 18:52 | onceUponATime_ | why bad? |
| 18:53 | technomancy | onceUponATime_: it assumes you're only going to use one version of clojure at a time |
| 18:54 | onceUponATime_ | yes correct, am I missing something? do I need multiple clojures? |
| 18:54 | onceUponATime_ | yes correct, am I missing something? do I need multiple clojure versions that is? |
| 18:55 | technomancy | typically each codebase you work on will declare which version of clojure it's designed to work with |
| 18:56 | onceUponATime_ | Oh, I like that, didn't think of that. But then this assumes the language may change a lot down the road? |
| 18:56 | nDuff | onceUponATime_: It doesn't necessarily change _a lot_, but you'll still have libraries that require a given version. |
| 18:56 | onceUponATime_ | mm |
| 18:57 | technomancy | onceUponATime_: it assumes you can't depend on backwards-compatibility between various versions of a library, and it treats clojure as just another library. |
| 18:57 | nDuff | onceUponATime_: ...and letting leiningen take care of starting the version you need takes the effort out of your hair. |
| 18:57 | onceUponATime_ | mM |
| 18:57 | nDuff | onceUponATime_: ...you'll be using leiningen to manage your libraries' versions anyhow, so why not let in manage your language runtime too? |
| 18:57 | onceUponATime_ | yea |
| 18:57 | onceUponATime_ | i c |
| 18:58 | nDuff | s/let in/let it/ |
| 18:58 | onceUponATime_ | where does leiningen install clojure? |
| 18:58 | nDuff | onceUponATime_: Into your Maven cache (~/.m2), where all your other libraries live. |
| 18:58 | nDuff | ...or maybe it's your Ivy cache. Doesn't really matter. |
| 18:59 | onceUponATime_ | mm |
| 18:59 | onceUponATime_ | ye |
| 18:59 | onceUponATime_ | alright thanks for the advice |
| 19:00 | amalloy | nDuff: character rationing |
| 19:00 | amalloy | this way if the NSA has an equal likelihoof of looking at each character, they're less likely to notice him |
| 19:01 | seangrove | dnolen: seems to specifically happen with clojurescript 0.0-1835, not sure why. Something weird about map. |
| 19:02 | dnolen | seangrove: hrm, I just tried against master there's not much difference |
| 19:02 | seangrove | Ah, bummer, because piggieback depends on that version |
| 19:02 | dnolen | seangrove: are you sure you don't have an older version somehow? |
| 19:02 | dnolen | 1835 works as far as I know |
| 19:02 | dnolen | seangrove: did you try (seq (array 1 2 3)) ? |
| 19:02 | seangrove | Is there a runtime var available that I can check in the browser console? |
| 19:03 | dnolen | no there was a patch lying around for that, should probably get around to actually applying to make this easier |
| 19:03 | seangrove | I'll try it that line |
| 19:03 | dnolen | I think it doesn't apply any is why I haven't done it yet |
| 19:03 | onceUponATime_ | does clojurescript support concurrency? |
| 19:04 | dnolen | onceUponATime_: not really but there's some sweet process coordination now with core.async |
| 19:04 | onceUponATime_ | aha |
| 19:08 | technomancy | any heroku users around interested in testing out some clojure buildpack changes before I roll them out to everyone? |
| 19:13 | Raynes | technomancy: Do I have to sell my soul? |
| 19:13 | Raynes | technomancy: I can give it a shot for tryclojure if you'd like, since it is super simple. |
| 19:13 | Raynes | (and the only thing I still run on Heroku) |
| 19:13 | technomancy | cool, I'll msg you |
| 19:24 | seangrove | dnolen: I've tracked it down to arrays that come from a different context, map does something strange with them |
| 19:30 | seangrove | Yeah, looks like this is probably the problem: https://github.com/clojure/clojurescript/commit/46eb8627627a3b027cd0758ea73da50216a42fd2 |
| 19:34 | seangrove | Since cljs doesn't supprt objects coming from another context, I modified js->clj in my own utils that I use when I can guarantee that it's just basic types: https://www.refheap.com/6830dbd541df305be517d9eca |
| 19:34 | seangrove | Now even this is failing though from that commit |
| 19:35 | seangrove | How can I convert an array from another context to a clj object? I could do some janky thing where I eval javascript that reads through the keys and builds up a value-identical array in the local context, but that wouldn't be super fast |
| 19:36 | seangrove | Fast, super, or pleasant, really |
| 19:38 | seangrove | Definitely going to be happy when we can find a way to stop dealing with objects created in another context |