2012-01-25
| 00:00 | skelternet | Thank you, dnolen |
| 00:00 | dnolen | as you can see it can get complicated, easier to see if you use an editor that has pretty-printed macroexpansion |
| 00:00 | skelternet | lack of pretty-printing was what killed my interest in lisp in college |
| 00:01 | skelternet | they had us using some sort of environment that ate up white-space, too. was terrible. |
| 00:02 | clj_newb | println is kinda like cout; does clojure have osmething like cerr? (I hate it when my debugging print statements gets interleaved with the java stack trace exception) = hard to read |
| 00:02 | skelternet | ,(macroexpand '(doseq [i [1 2 3 4]] (print i))) |
| 00:02 | clojurebot | (loop* [seq_67 (clojure.core/seq [1 2 3 4]) chunk_68 nil count_69 ...] (if (clojure.core/< i_70 count_69) (clojure.core/let [i (.nth chunk_68 i_70)] (do (print i)) (recur seq_67 chunk_68 count_69 (clojure.core/unchecked-inc i_70))) (clojure.core/when-let [seq_67 (clojure.core/seq seq_67)] (if (clojure.core/chunked-seq? seq_67) (clojure.core/let [c__3921__auto__ (clojure.core/chunk-first seq_67)] (... |
| 00:03 | jayunit100 | dnolen i tried to make the clojure meetup in ny last wk but got busy ---- any chance of another one on the east coast soon where we do some intermediate lisp thinking / clojure programming . |
| 00:03 | adam_ | jayunit100, nice blog, i have read a couple of your entries! |
| 00:03 | jayunit100 | cool thanks adam :] |
| 00:03 | adam_ | no problem, I'm trying to use clojure for some bioinformatics stuff myself |
| 00:04 | dnolen | jayunit100: definitely! I try to go everytime but I had to miss the last one as well |
| 00:04 | jayunit100 | yeah. what are the odds that we schedule to do one in new haven. ... how many people you think would come ? |
| 00:04 | Raynes | clj_newb: (binding [*out* *err*] (println "some message")) |
| 00:05 | jayunit100 | adam_ you should contribute to RudolF with us. |
| 00:05 | jayunit100 | https://github.com/jayunit100/RudolF |
| 00:05 | clj_newb | Raynes: nice |
| 00:07 | adam_ | okay, that sounds good, I have been trying to get involved in a project |
| 00:07 | clj_newb | Raynes: nice; thanks |
| 00:07 | jayunit100 | u on github? |
| 00:07 | jayunit100 | @adam_ |
| 00:08 | adam_ | yeah, adamwespiser is my username |
| 00:08 | jayunit100 | @adam_ what type of bioinformatics do you do ? |
| 00:09 | adam_ | i am working in structural biology |
| 00:09 | adam_ | mostly on protein-protein interaction site prediction methods |
| 00:09 | jayunit100 | aweseome well you'll love the examples in RudolF. Integration with the PDB structural utilities. |
| 00:09 | skelternet | flashbacks to my summer at ciba-geigy |
| 00:09 | adam_ | yeah, check out the code base I am working on: |
| 00:10 | jayunit100 | check this out : http://writequit.org/papers/files/RudolF.pdf |
| 00:10 | dnolen | so is anyone offended by the inclusion of IFn to ClojureScript? It's now fully baked - https://github.com/clojure/clojurescript/compare/master...96-ifn |
| 00:10 | adam_ | http://pfaat.sourceforge.net/ is my boss's project that I contribute to |
| 00:12 | adam_ | jayunit100: has this paper been submitted anywhere? |
| 00:12 | amalloy | dnolen: what would be the reason for being offended? because js already has first-class functions and it's silly to invent our own, or what? |
| 00:13 | jayunit100 | yeah itng |
| 00:13 | adam_ | nice, good luck, i think its a great idea |
| 00:14 | dnolen | amalloy: heh, no reason really, IFn inclusion moves some ugliness into the compiler so people don't have to write yucky stuff by hand when adding fn capability to their custom types. |
| 00:15 | jayunit100 | adam_: BioClojure has been replaced by RudolF --- just saw you were following it . |
| 00:16 | adam_ | yeah, I am going to take a look at it, I'm sure there are features I can add |
| 00:17 | jayunit100 | in any case adam_ I have a publication idea i can write up if you want to help add some code. I'll ping you about it offline. |
| 00:18 | jayunit100 | oh nevermind you have no email : email me at jayunit100@gmail.com |
| 00:18 | jayunit100 | and ill add you to RudolF as a commiter also . |
| 00:20 | jayunit100 | looking at pfaat this would be great for venn. that would be awesome if you could add some lispy alignment examples |
| 00:21 | adam_ | okay |
| 00:24 | dnolen | bunch 'o goodies just landed in CLJS |
| 00:33 | adam_ | jay, can I download the venn source code and run it locally? |
| 00:47 | chouser | dnolen: are you still around? |
| 00:48 | chouser | trying to figure out native deps via lein, using your plugin. |
| 00:49 | dnolen | chouser: off I haven't messed w/ that in ages |
| 00:49 | dnolen | oof I mean |
| 00:49 | chouser | yeah, I guessed. |
| 00:49 | dnolen | chouser: it was a convention more than anything else really |
| 00:49 | chouser | your plugin looks helpful, and I've got to close. |
| 00:50 | dnolen | chouser: it never solved the packaging problem ever |
| 00:50 | chouser | I don't expect you to work through anything with me, but thought if you recognized my issue off the top of your head... |
| 00:50 | dnolen | it was just about making it easy to pull down native deps off clojars and expand them into the project folder |
| 00:50 | chouser | if I use -Djava.library.path on a manual java command line, I can load the native lib |
| 00:51 | dnolen | k |
| 00:51 | chouser | and I have :native set right in project.clj, I think, and can see a -Djava.l.p that looks right in a ps of the repl process |
| 00:52 | dnolen | and you ran- lein deps, lein native deps -in that order? |
| 00:52 | dnolen | lein native-deps rather |
| 00:52 | chouser | maybe not. let me try again. |
| 00:54 | chouser | UnsatisfiedLinkError |
| 00:54 | chouser | I don't get it. Using ps I definitely see -Djava-library-path=/home/chouser/shadowfax/native/linux/x86_64 |
| 00:54 | amalloy | chouser: i think the flatland projects tokyocabinet and jiraph show how to bundle and use a native dependency, if i understand what you mean by the term. they work in lein (used to be cake), but Raynes is probably the guy to ask about how to do the native-specific stuff |
| 00:55 | dnolen | hmm, sounds like the path isn't right |
| 00:55 | Raynes | For native deps to work properly, you need to be using leiningen off of the 1.x branch. |
| 00:55 | chouser | ls at that path shows my .so's |
| 00:55 | Raynes | Otherwise it wont set java.library.path |
| 00:55 | chouser | this is lein 1.6.2 |
| 00:56 | chouser | (System/getProperty "java.library.path") does *not* show my path |
| 00:57 | chouser | oh |
| 00:57 | Raynes | You don't need to run 'lein native-deps' at all. |
| 00:57 | Raynes | It just works. |
| 00:57 | Raynes | And you don't have to set :native either. |
| 00:57 | technomancy | jkkramer: did you evaluate neo4j for clojuresphere at all? |
| 00:57 | chouser | lein is using -Djava-library-path. Running java manually with -Djava.library.path works |
| 00:58 | Raynes | chouser: Yes, that's what I fixed in the 1.x branch of Leiningen. |
| 00:58 | Raynes | Which is what I just told you, BUT YOU DON'T LISTEN TO ME! |
| 00:58 | Raynes | Bah! |
| 00:58 | dnolen | chouser: perhaps native-deps is getting in the way :) |
| 00:58 | chouser | dashes simply don't work. dots do. |
| 00:59 | chouser | Raynes: I'm running 1.6.2. How is that not 1.x? |
| 00:59 | Raynes | It has to be specifically from the git repo 1.x branch. |
| 00:59 | Raynes | And a relatively recent commit on said branch. |
| 00:59 | chouser | oh |
| 01:00 | Raynes | It will be in the 1.7.0 release. |
| 01:00 | jkkramer | technomancy: i did not. does heroku support it? |
| 01:00 | Raynes | jkkramer: Yep. |
| 01:00 | technomancy | chouser: this is something I broke in 1.6.mumble |
| 01:01 | chouser | ok |
| 01:01 | technomancy | jkkramer: specifically asking because of http://neo4j-challenge.herokuapp.com/ |
| 01:02 | chouser | so my plan is to git clone lein and symlink ~/bin/lein to something in the git repo. Is that a sane plan? |
| 01:02 | chouser | I'm a lein newb and don't understand how it installs itself |
| 01:02 | technomancy | chouser: absolutely respectable |
| 01:03 | technomancy | chouser: also acceptable would be to fall back to 1.6.1 stable or 1.5.2, I can't remember which version introduced the bug |
| 01:03 | Raynes | technomancy: I don't support that. |
| 01:03 | jkkramer | technomancy: interesting. been meaning to play with neo4j |
| 01:03 | Raynes | technomancy: No version behind 1.6.2 works with lein-newnew for some reason. |
| 01:03 | technomancy | o_O |
| 01:03 | technomancy | odd |
| 01:03 | Raynes | Never did figure out why. |
| 01:03 | technomancy | maybe InsufficientUnicodeException? |
| 01:04 | Raynes | I don't think so. Look at the closed issues for lein-newnew. |
| 01:04 | technomancy | joke ruined! |
| 01:04 | Raynes | Oh. I didn't catch it. |
| 01:05 | technomancy | referring to the lack of © in newnew skeletons |
| 01:05 | Raynes | I assume that even the most ridiculous exceptions are plausible with any Clojure code using Java code. |
| 01:05 | technomancy | the readmes thereof |
| 01:05 | Raynes | Yeah, I'm going to get to work on all of those issues and such soon. Probably tomorrow. |
| 01:07 | technomancy | hah; no rush |
| 01:10 | chouser | heh. where'd rlwrap go? |
| 01:10 | brehaut | a circle of hell? |
| 01:10 | brehaut | or am i thinking of jline |
| 01:11 | hiredman | jline |
| 01:11 | hiredman | rlwrap is the one that works with unicode |
| 01:12 | brehaut | i'll rescind that joke then |
| 01:15 | chouser | so this snapshot lein seems to set the native lib path correctly, but doesn't use rlwrap |
| 01:18 | chouser | the jar I built has a 'native' dir that seems to be unpacked correctly, but it has a 'lib' dir with jars in it that are not on the classpath in lein repl |
| 01:19 | chouser | do my java .jars belong somewhere else besides in the 'lib' dir next to the 'native' dir? |
| 01:20 | hiredman | what does lein classpath say? |
| 01:23 | chouser | it includes my native-deps.jar but not the .jars inside it. |
| 01:23 | technomancy | http://p.hagelb.org/lein-os.png |
| 01:23 | hiredman | oh |
| 01:23 | hiredman | I see you have one of those weird things that is like an uberjar but not |
| 01:24 | chouser | I made my native-deps.jar according to the instructions for dnolan's native-deps plugin |
| 01:24 | technomancy | jars-inside-jars isn't supported; it's just the native .so-and-friends extraction that leiningen does |
| 01:25 | chouser | so I need separate deps for the .jars and the .so's they depend on? |
| 01:25 | hiredman | chouser: I think dnolen's plugin might have been from before lein got it's own native deps handling |
| 01:25 | chouser | hiredman: yes, I'm getting that impression. So I'm trying to learn how I ought to do it now. |
| 01:25 | technomancy | chouser: not necessarily; you could put the .so's in the same jars as the .class files |
| 01:26 | chouser | ah. hm. |
| 01:26 | technomancy | I didn't realize the old jars-in-jars was actually documented somewhere. |
| 01:26 | brehaut | technomancy: i was expecting a screenshot of a lein based distro |
| 01:26 | technomancy | chouser: where were you when I was trying to get testers when I was implementing this? =) |
| 01:29 | chouser | heh. The last time I touched any native deps was when writing clojure-jna. |
| 01:29 | technomancy | chouser: improved native-deps creation and documentation has been on the roadmap for a while; it's just a bit hard to find people interested in giving feedback. so expect a few pings down the line. |
| 01:30 | technomancy | native-deps consumption should make it into lein2-preview; creation might be a bit further off. |
| 01:30 | technomancy | anyway, off to bed |
| 01:30 | technomancy | feel free to ask on the mailing list if you get lost |
| 01:30 | chouser | that was about 6 months before your initial commit to lein. :-) |
| 01:30 | technomancy | hah |
| 01:31 | chouser | technomancy: if we end up using this for work, it's likely I'll be able to pitch in for docs, testing, etc. |
| 01:53 | unlink | Is there a function like this in the stdlib? (defn tails [xs] (when-let [s (seq xs)] (cons xs (lazy-seq (tails (next xs)))))) |
| 01:54 | hiredman | ,(doc iterate) |
| 01:54 | clojurebot | "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects" |
| 01:59 | unlink | True, it could have been written (defn tails [xs] (take-while identity (iterate next xs))). |
| 03:01 | clj_newb | Is there a way to have clojure compile errors (resulting rom load-file) to report the _full_ name, relative to `pwd`, rather than just the filename |
| 03:33 | Blkt | good morning everyone |
| 03:37 | casperc | good morning |
| 03:55 | kral | morning pals |
| 04:02 | muhoo | is there a way to tell the lein repl which port to listen on? |
| 04:03 | raek | muhoo: yes, check out sample.project.clj in the Leiningen docs |
| 04:04 | muhoo | ah, cool :repl-port, thanks |
| 04:17 | muhoo | using the jdbc stuff. it seems like everything is wrapped in with-connection. |
| 04:17 | muhoo | is there a way to store a connection somewhere globally, and then use it multiple times, instead of having to open and close connections with with-connection all the time? |
| 04:18 | muhoo | or, alternately, wrapping the whole program inside with-connection? |
| 04:27 | casperc | Is there a good way to set up a thread or daemon to perform a task at certain intervals? |
| 04:29 | casperc | in my specific case i want to check an event queue for new events to react to, but that's not important. Could be any task |
| 04:40 | llasram | muhoo: That's the sort of thing people tend to use ^:dynamic *vars* for |
| 04:42 | llasram | casperc: java.util.Timer? |
| 04:48 | casperc | llasram: hmm, might be a good option |
| 04:50 | Raynes | casperc: Would a thread that loops and sleeps for a certain amount of time be too simplistic? |
| 04:51 | llasram | casperc: If you need complicated stuff there's http://quartz-scheduler.org/ for which there's even https://github.com/pingles/clj-quartz, but I've never used either |
| 04:52 | casperc | Well, I would want a way to pause it and generally inspect its state (not quite sure yet what this would entail) |
| 04:54 | casperc | llasram: i hadn't thought of quartz actually. That might be a good option. |
| 04:55 | casperc | In essence we have a bunch of things which we will want to do a regular intervals. We want to be able to pause these tasks and inspect the state |
| 04:56 | casperc | I'll probably end up making a dashboard for it. |
| 04:58 | casperc | llasram & Raynes: thanks for the input. I'll have a look at quartz so see if it fits our needs :) |
| 04:59 | Raynes | 'our'. We are legion! |
| 05:00 | bluezenix2 | Are there methods to inspect a deftype? Say i have (deftype Dude [name, age]) ; is there a way to get a vector of [:name :age] or something simlar? |
| 05:01 | bluezenix2 | (props-or-whatever Dude) ; => ["name" "age"] |
| 05:03 | llasram | bluezenix2: defrecords will implement the map interface for you by default, but deftypes are barebones, so you'll need to implement anything like that yourself |
| 05:05 | bluezenix2 | right |
| 05:15 | morphling | bluezenix2: deftype (on the jvm at least) creates a class, so you should be able to get this information through reflection |
| 05:31 | student1 | test |
| 05:32 | student1 | you don't have to register nowadays, to be able to speak in #clojure? |
| 05:32 | raek | yeah |
| 05:32 | student1 | ok |
| 05:54 | bluezenix2 | when using (defrecord Dude [name age]) ; i can use (keys (Dude. "blue" 12)) |
| 05:55 | bluezenix2 | but what I want is to find the properties a Dude is allowed to have |
| 05:55 | bluezenix2 | like (keys Dude) |
| 05:55 | bluezenix2 | i can't construct a temporary Dude |
| 05:55 | bluezenix2 | so i guess i'll have to dig into java reflection? |
| 07:59 | samaaron | / |
| 08:03 | samaaron | Raynes: howdy |
| 08:15 | TimMc | bluezenix: You can create a map, and once it has all the attributes, convert it into the record. (I think...) |
| 09:07 | aidanf | Hi all, |
| 09:07 | aidanf | Can anyone tell me why this doesn't work as I was expecting? |
| 09:07 | aidanf | http://pastie.org/3249922 |
| 09:08 | aidanf | I was expecting the output from the two threads to be mixed up. |
| 09:08 | aidanf | But it seems to run all the way through f1 before starting f2 i.e. the threads are not running concurrently |
| 09:10 | TimMc | aidanf: That'll happen. Try a longer run e.g. 1e5, or just add some .sleeps in there. |
| 09:12 | aidanf | Thanks TimMc |
| 09:13 | clgv | aidanf: it works over here with my dualcore cpu |
| 09:13 | TimMc | To test concurrency stuff, you often have to simulate it with sleeps. :-/ |
| 09:14 | aidanf | cljv: Thanks, works for me now after adding Thread/sleep |
| 09:14 | TimMc | or long-running processes with lots of jittery computations. |
| 09:14 | clgv | TimMc: I never tested - does thread creation consume a decent amount of time? |
| 09:15 | clgv | looking at my run I'd say that shouldnt be the problem |
| 09:16 | TimMc | aidanf: Even running your original one several more times should get you some interleaving occasionally. |
| 09:21 | aidanf | TimMc: I tried it several times without sleep and got the same every time. Playing with it now - for small (range n) and no sleep I never see interleaving. If I add sleep or make n really big I see the results interleaving. |
| 09:23 | AWizzArd | clgv: Creating threads can be expensive. Typically I follow the rule of thumb that a calculation should take at least one msec for it to be outsourced into its own future or agent. |
| 09:25 | clgv | AWizzArd: yeah thats true. although 1ms isnt enough. in one of my experiment I parallel tasks with 20ms and the overhead ruined the performance |
| 09:31 | AWizzArd | clgv: I tried this: |
| 09:31 | AWizzArd | ,(time (count (map (fn [_] (Thread/sleep 1)) (range 1000)))) |
| 09:31 | clojurebot | "Elapsed time: 2206.241 msecs" |
| 09:31 | clojurebot | 1000 |
| 09:31 | AWizzArd | vs |
| 09:31 | AWizzArd | ,(time (count (pmap (fn [_] (Thread/sleep 1)) (range 1000)))) |
| 09:31 | clojurebot | "Elapsed time: 322.43 msecs" |
| 09:31 | clojurebot | 1000 |
| 09:31 | AWizzArd | The example with map took just a bit over one second on my machine, as expected. |
| 09:32 | AWizzArd | The second one runs here in 60 msecs. |
| 09:32 | clgv | ok. I had an algorithm with lots of double operations |
| 09:35 | clgv | AWizzard: btw. pmap has its "lazy problem" that it in fact does not do good cpu utilization since it tries to be lazy and the last task of a batch can prevent moving pmaps sliding window further. |
| 09:35 | clgv | thats almst only a problem when parallelizing tasks with different runtimes. |
| 09:40 | AWizzArd | clgv: but my example from above is flawed anyway, because when one Thread is sent to sleep then that thread becomes free for other jobs. This way I can have pmap running 25 threads that each sleep for one second within around one second, on 4 cores. |
| 09:41 | clgv | Awizzard: yes thats true. you need an active waiting loop ;) |
| 09:43 | jsabeaudry | dakrone, Is there any facility in clj-http to access the streams directly as available in the apache httpcomponents? (I'm working with responses too big to fit in memory) |
| 09:46 | AWizzArd | clgv: For example (time (count (map #(dotimes [i 10000] %) (range 1000000)))) runs in 2,8 seconds on my machine, and in 1,9 seconds with pmap. So on my system it seems that even for sub-msec tasks it is already worthwhile to run parallel. |
| 09:47 | AWizzArd | clgv: But for a dotimes 1000 finally map is much faster than pmap, because of the threading overhead. |
| 09:47 | clgv | AWizzard: you should calc the parallel efficiency value. its not even half the time with 4 cores - that does not seem good |
| 09:50 | jsabeaudry | dakrone, Found the answer right in the doc, "Note that where Ring uses InputStreams for the request and response bodies, the clj-http uses ByteArrays for the bodies." Too bad... |
| 09:51 | dakrone | jsabeaudry: I'd like to be able to provide a stream as a response, hopefully in the future |
| 09:54 | dakrone | *near future |
| 10:15 | jsabeaudry | Netty is so incredibly heavy I wonder how anyone can tolerate it |
| 10:16 | jsabeaudry | All that cpu spent in SelectorUtil.select... |
| 10:17 | lucian | jsabeaudry: are you joking? |
| 10:19 | jsabeaudry | lucian, Not at all, I'm cpu bound serving a file with netty. I do the same thing with Jetty and I get more than 10x the transfer rate |
| 10:19 | jsabeaudry | lucian, So I profiled Netty and more than 50% of the cpu time is spec in SelectorUtil.select |
| 10:19 | jsabeaudry | s/spec/spent |
| 10:20 | lucian | jsabeaudry: that sounds like a bug. select is the system call |
| 10:20 | lucian | although i'd expect netty to use epoll or something. what os? |
| 10:21 | jsabeaudry | linux, I tried both on Ubuntu and Angstrom with the same results |
| 10:21 | jsabeaudry | On the openjdk and on oracle's |
| 10:22 | lucian | it seems odd to me. i don't have experience with netty in particular, but it should behave like twisted |
| 10:22 | lucian | and use epoll when available, no cpu on I/O, etc |
| 10:23 | lucian | it sounds like a bug in netty, either in its select binding or in its sniffing of native async APIs |
| 10:30 | TimMc | jsabeaudry: Is this still on the little constrained platform? |
| 10:31 | jsabeaudry | TimMc, Yes and no, I tried on both, with the same results. The profiling was done on a regular ubuntu |
| 10:34 | gtrak`` | jsabeaudry: it's odd, but any particular reason to prefer netty? jetty uses NIO, too |
| 10:38 | jsabeaudry | gtrak``, Simply because aleph is built on netty |
| 10:39 | gtrak`` | I remember there being a perf issue with aleph and netty |
| 10:40 | romain_p | Hi everyone, could anyone help me understand functional programming with an example ? I am trying to represent NFAs in Clojure |
| 10:40 | gtrak`` | anyone recall what that was about? |
| 10:40 | romain_p | So my initial idea was: |
| 10:40 | romain_p | (defrecord NfaState [final char_transitions empty_transitions]) |
| 10:40 | romain_p | Using this or something else, how do I represent two nodes that point at each other? |
| 10:41 | romain_p | (for instance, two nodes transitioning to one another on the character 'a', char_transistion being a map<char, nfastate> in my mind) |
| 10:41 | gtrak`` | jsabeaudry: take a look at this hackernews: http://news.ycombinator.com/item?id=3135662 it might explain the discrepancy, specifically the post by prospero |
| 10:55 | jsabeaudry | Just tested it again, the only thing that changed in my code is switching from aleph/start-http-server vs noir.server/start, all the handlers are the same. Transfer rate with aleph/netty 330KB/s, transfer rate with noir/jetty 10.5 MB/s (maximum because 100Mbps ethernet) |
| 10:57 | gtrak`` | on the arm? |
| 10:57 | jsabeaudry | gtrak``, yes |
| 10:57 | gtrak`` | might be worth asking ##java if netty on arm sucks |
| 10:58 | jsabeaudry | gtrak``, good idea |
| 11:10 | clgv | romain_p: with immutable data you cant build direct referencing cycles. but you can build them by indirection like having edge ids and looking them up in a hash-map or such |
| 11:11 | romain_p | clgv: yup, so my graph would be a set of states, each one having a name (atom)... |
| 11:11 | gtrak`` | or atoms/refs? |
| 11:12 | clgv | gtrak: you often dont want to use them if you have no real concurrency scenario there. but they might be an option if suited |
| 11:12 | romain_p | clgv: well actually, not an atom |
| 11:13 | gtrak`` | clgv: if not concurrent, then they're quite fast |
| 11:13 | clgv | romain_p: you can have nodes and edges immutable if you do not insist to link them directly by reference |
| 11:14 | gtrak`` | an atom's just a java AtomicReference, a loop and a CAS, so mutating one is just a CAS in single-threaded code |
| 11:14 | clgv | gtrak``: but why should I make my data representation more complicate by using them? I think it really depends on what you are doing. |
| 11:15 | romain_p | Okay, bear with me (newbie and all): why does this throw an exception? |
| 11:15 | clgv | I think you'll have to discuss "indirection vs. atoms" for your concrete problem |
| 11:15 | romain_p | (defrecord NfaState [name final char_transitions empty_transitions]) |
| 11:15 | romain_p | (def my-graph {(NfaState. :a false {} {:b})}) |
| 11:15 | romain_p | user=> java.lang.ArrayIndexOutOfBoundsException: 1 |
| 11:16 | llasram | gtrak``: If you're going to use atoms that way, you might as well use `deftype' with mutable fields -- it'll be faster and the intent will be clearer |
| 11:16 | llasram | (IMHO) |
| 11:16 | Somelauw | Does clojure allow importing classes? This is probably a bad idea but sometimes convenient. For example when using Math. |
| 11:16 | clgv | romain_p: because of {:b} since you have a hash map with only the key and not the value |
| 11:16 | romain_p | clgv: OK so that's a map. How do I represent a set? |
| 11:16 | clgv | romain_p: #{:b |
| 11:17 | clgv | oops. #{:b} |
| 11:17 | romain_p | clgv: thanks! |
| 11:17 | seancorf` | anyone know if cascalog can be used with amazon's elastic map/reduce? or should i go ask on the cascalog ML? |
| 11:17 | Somelauw | So I can use sin, cos, tan directly? |
| 11:18 | llasram | Somelauw: Oh, you mean import static methods of a class? There isn't a builtin way to do that, but here |
| 11:18 | clgv | Somelauw: you can use whatever class you like by specifying it completely like java.util.Math/sin or importing it via (:import java.util.Math) within the ns statement and use it like Math/sin |
| 11:19 | llasram | s,here,there, used to be an 'import-static' in contrib, which you could rip off |
| 11:19 | romain_p | clgv: so given my previous definition, that would be a sensible method of representing graphs in clojure? : {(NfaState. :a false {} #{:b}) (NfaState. :b false {} #{:a})} |
| 11:20 | TimMc | llasram: It would also be lovely to be able to rename imports, like Math :as M |
| 11:20 | TimMc | M/sin would be acceptable. |
| 11:21 | TimMc | or Point2D$Double :as P2D ! |
| 11:22 | clgv | romain_p: "sensible" depends how you are using them. I went with nodes and edges as deftype but both referencing with IDs |
| 11:22 | dnolen | Somelauw: make a lib (defn sin ^double [^double n] (Math/sin n)) |
| 11:25 | llasram | TimMc: I've wanted that a few times, and it seems like it shouldn't be too hard, since normal importing works by interning the short name as a reference in the namespace to the class anyway |
| 11:25 | TimMc | clgv: I guess transients are no help here either, since they hide their mutability somewhat. |
| 11:25 | Somelauw | clgv: I tried (ns hello.hi (:import (java.util.Math))) on a repl and it didn't give an error, but I couldn't use sin directly. Maybe I did it wrong since I am still a bit new to clojure. |
| 11:26 | TimMc | llasram: Ooh, that would be a good group project at a meetup. |
| 11:26 | TimMc | Somelauw: You'll have to do Math/sin |
| 11:26 | dnolen | Somelauw: you can't use it "directly", it's not first class |
| 11:26 | dnolen | Somelauw: make a lib and then you're all set and you have something first class |
| 11:26 | dnolen | Somelauw: no overhead it will inline |
| 11:26 | clgv | Somelauw: like I wrote and the others told you, it's Math/sin you can use then |
| 11:27 | TimMc | dnolen: It doesn't even need an :inline clause? |
| 11:27 | dnolen | TimMc: nope |
| 11:27 | TimMc | Because of HotSpot, or the Clojure compiler? |
| 11:27 | dnolen | TimMc: HotSpot |
| 11:28 | TimMc | OK, cool. |
| 11:28 | TimMc | <3 HotSpot |
| 11:28 | Somelauw | okay, Math.sin works |
| 11:28 | TimMc | Somelauw: Math.sin or Math/sin? |
| 11:29 | Somelauw | Math/sin |
| 11:29 | dnolen | clgv: not true |
| 11:29 | dnolen | clgv: the expansion has to be something inlineable by HotSpot |
| 11:31 | Somelauw | Math/sin probably works anyway even if nothing is included |
| 11:32 | TimMc | Somelauw: Right, java.lang.* are automatically imported. |
| 11:33 | gtrak`` | Math's not a package, it's a class |
| 12:01 | chouser | dnolen: thanks for the help last night. Got some native deps working in the end. |
| 12:03 | dnolen | chouser: sorry I couldn't be of more help :) I've pretty much forgotten everything I learned as far as native-deps :) |
| 12:12 | phil_ | why is (for [x (range) :when (< x 100)]) not terminating? |
| 12:13 | phil_ | ah cause :when is a filter not a stop condition |
| 12:13 | phil_ | sry :D |
| 12:13 | TimMc | phil_: :while |
| 12:13 | phil_ | TimMc: thx |
| 12:14 | semperos | way to see docs for fn's at cljs repl? |
| 12:14 | TimMc | or [x (range 100)], but I assume that was a simplified example |
| 12:14 | dnolen | semperos: nope, I created a ticket for that in JIRA today. |
| 12:14 | semperos | dnolen: sweet |
| 12:15 | semperos | any metadata-querying abilities? |
| 12:15 | phil_ | TimMc: yeah i need to go through some seqs lazily while some condition holds |
| 12:15 | semperos | I saw meta in the source, but not sure on status of things |
| 12:15 | dnolen | semperos: metadata on the actually source is not available from the JS side, |
| 12:16 | dnolen | semperos: open question on how to best provide access to that stuff |
| 12:16 | semperos | dnolen: understood; happy to have it done right vs. fast |
| 12:16 | dnolen | it exists, it's just a matter of how to get to it |
| 12:16 | dnolen | currently hooking into the analyzer from CLJS REPL means a macro |
| 12:17 | dnolen | but it's a macro that can never work in your actual source |
| 12:17 | semperos | :) |
| 12:17 | dnolen | oh rather a macro is one way, not sure if it's the best |
| 12:18 | dnolen | another interesting way might be a reflection system, where the JS communicates back w/ the compiler/analyzer |
| 12:19 | dnolen | then we can avoid the macro goofiness. perhaps a special reflect namespace or something ... |
| 12:19 | semperos | right |
| 12:24 | llasram | How reasonable would it be to try to get '_' added as an "internal whitespace character" (for lack of a better term) in numeric literals, like in Ruby? Ex: (= 50_000 50000) |
| 12:25 | dnolen | llasram: low I imagine |
| 12:25 | llasram | Oh? |
| 12:25 | dnolen | i mean the likelihood is low |
| 12:25 | llasram | Why so? |
| 12:28 | dnolen | llasram: it's a cosmetic enhancement - those get pretty very low priority. |
| 12:28 | hiredman | and it seems of questionable utility |
| 12:28 | llasram | Even with a patch? (Not that I've submitted a CA yet, although it is on my todolist) |
| 12:29 | llasram | hiredman: I find it pretty useful myself |
| 12:29 | dnolen | llasram: even with a patch, just based on my experience with patches like this |
| 12:29 | llasram | Ok. Fair enough |
| 12:33 | TimMc | llasram: 5e4 in that particular example. :-) |
| 12:34 | llasram | TimMc: But then it's floating-point :-p |
| 12:34 | TimMc | Oh man, you're right. I learned that at some point and totally forgot it again. |
| 12:36 | samaaron | dnolen: is there any documentation describing how the cljs repl works? It's all voodoo to me - particularly given the absence of eval |
| 12:37 | TimMc | I tried to reverse-engineer the cljs repl for try-cljs and totally failed. |
| 12:37 | TimMc | If there's documentation, it's not in the source. |
| 12:38 | dnolen | samaaron: TimMc: I know of no docs beyond the source, but it's not that complicated from what I've seen. |
| 12:39 | samaaron | dnolen: ok cool - i'll tackle it when i get some spare cycles |
| 12:39 | samaaron | my main issue is that i know no js |
| 12:39 | dnolen | I have a half-baked Node.js CLJS REPL that shows the basics, though it has some real issues. |
| 12:39 | samaaron | and i know nothign about how browsers present a js execution env |
| 12:39 | TimMc | dnolen: I never did figure out how to get cljs.core referred. |
| 12:39 | dnolen | samaaron: so how long before we get to run Overtone in the browser, Chrome Audio API is pretty cool :D |
| 12:40 | dnolen | TimMc: there's no magic, you just need to push the whole thing to get eval'ed |
| 12:40 | samaaron | dnolen: well, you'd have to build your own 'mini-supercollider' implementation |
| 12:40 | samaaron | and then use the standard Overtone stuff on top of that |
| 12:41 | dnolen | samaaron: heh, yeah i know, just day dreaming :) |
| 12:41 | samaaron | :-) |
| 12:41 | dnolen | TimMc: samaaron: https://github.com/swannodette/clojurescript/tree/node-repl |
| 12:41 | dnolen | https://github.com/swannodette/clojurescript/blob/node-repl/bin/repl.js |
| 12:41 | samaaron | we've been talking about building protocols for defining and controlling synths |
| 12:41 | dnolen | https://github.com/swannodette/clojurescript/blob/node-repl/src/clj/cljs/repl/node.clj |
| 12:41 | dnolen | those are the relevant files for a minimal hacky REPL, at least for Node.js |
| 12:41 | samaaron | so then it would "simply" be a matter of implementing them on top of the Audio API ;) |
| 12:41 | dnolen | samaaron: neat :) |
| 12:42 | samaaron | yeah, Overtone seriously needs a good looking at from a protocol perspective |
| 12:42 | samaaron | we really need to make more stuff modular and pluggable |
| 12:42 | samaaron | and much less monolithic |
| 12:43 | TimMc | dnolen: THanks, I'll try to figure out why that works and mine doesn't. |
| 12:55 | jaley | hey guys. I'm using Clojure 1.3 for some java interop which used to work with 1.2. The problem is all numbers are now java.lang.Long and that won't cast to Integer. How do I force Clojure to use an Integer? I've tried (int x), (.intValue x), nothing seems to work... |
| 12:59 | TimMc | (Integer. ...) |
| 13:00 | TimMc | You need to produce an Integer object, since an int will get turned into a Long. :-/ |
| 13:00 | semperos | jaley: ^^^ what TimMc said |
| 13:00 | AimHere | jaley: ^^^ what semperos said |
| 13:01 | jaley | semperos: but Integer has no constructor that takes a Long? |
| 13:01 | jaley | & (class (Integer. 1)) ;; appears to work |
| 13:01 | lazybot | ⇒ java.lang.Integer |
| 13:01 | gtrak`` | Integer.valueOf? |
| 13:01 | gtrak`` | &(class (Integer.valueOf 1)) |
| 13:01 | lazybot | java.lang.ClassNotFoundException: Integer.valueOf |
| 13:02 | TimMc | THat's a static and it takes a string. |
| 13:02 | jaley | but once compiled, I get a runtime error that it can't find the constructor |
| 13:02 | muhoo | jsabeaudry: isn't there an async package in clojure? "aleph", IIRC? , instaead of natty/jboss? |
| 13:02 | TimMc | &(Integer. 50L) |
| 13:02 | lazybot | java.lang.NumberFormatException: Invalid number: 50L |
| 13:02 | TimMc | oops |
| 13:03 | gtrak`` | ah, so you can't use the integer cache without having to convert to string? lame |
| 13:03 | TimMc | &(let [l 50] [(class l) (Integer. l)]) |
| 13:03 | lazybot | ⇒ [java.lang.Long 50] |
| 13:03 | TimMc | gtrak``: No, it turns out it will take a long. |
| 13:03 | TimMc | Not sure why, looking at the docs. |
| 13:04 | gtrak`` | hmmmmmm |
| 13:04 | TimMc | &(let [l (Long. 50)] [(class l) (Integer. l)]) ; just to be sure |
| 13:04 | lazybot | ⇒ [java.lang.Long 50] |
| 13:04 | gtrak`` | TimMc: http://docs.oracle.com/javase/6/docs/api/java/lang/Long.html |
| 13:04 | gtrak`` | looks like it was added in 1.6 |
| 13:05 | gtrak`` | &(class (Integer/valueOf 1L)) |
| 13:05 | lazybot | java.lang.NumberFormatException: Invalid number: 1L |
| 13:05 | TimMc | gtrak``: Oh, good. But that doesn't resolve my confusion over Integer's constructor. |
| 13:05 | gtrak`` | &(class (Integer/valueOf 1)) |
| 13:05 | lazybot | ⇒ java.lang.Integer |
| 13:05 | gtrak`` | what's the confusion? |
| 13:06 | TimMc | gtrak``: Integer's constructors in Java v1.6 take String or int, not long |
| 13:07 | jaley | TimMc: yeah, that's exactly what's messing me up[ |
| 13:07 | gtrak`` | ah, you're right, I gave you the Long html page |
| 13:07 | jaley | TimMc: it works at my repl - i'm guessing clojure is detecting I need something other than a long and passing the right object appropriately? |
| 13:07 | gtrak`` | maybe it gets cast automatically |
| 13:08 | jaley | TimMc: but it won't work after compilation for some reason |
| 13:08 | gtrak`` | really? now that's odd |
| 13:08 | jaley | No matching ctor found for class java.lang.Integer |
| 13:08 | jaley | my mind is full of **** :p |
| 13:08 | TimMc | Well, I thought at first that (Integer. 50) was getting an int 50 because the compiler saw that it didn't need to promote it to long, but... nope, works with (Long. 50) input. |
| 13:09 | jaley | TimMc: yeah I just tried that too. it's bizarre |
| 13:10 | jaimef | anyone run clojure apps on embedded hardware? |
| 13:10 | TimMc | jaimef: jsabeaudry is doing some work on an arm7 device or whatever it is |
| 13:16 | jaimef | ok. just wondering if 256 megs of ram is sufficient for lein deps/jar on compojure |
| 13:18 | technomancy | best not to run lein itself on the device |
| 13:18 | technomancy | just prep an uberjar |
| 13:19 | jaimef | k |
| 13:20 | jaley | i think i'm going to have to revert to 1.2 :( |
| 13:20 | jaley | there's just no way i can find to prevent it from using Long |
| 13:21 | TimMc | jaley: Of course there is. |
| 13:22 | TimMc | ...and I'm not even getting the compilation error that you were. WTF? |
| 13:22 | jaley | TimMc: well... I think the problem is that I'm adding them to a collection, then the java app expects Integer to come up |
| 13:22 | TimMc | jaley: (Integer. (int ...)), does that work? |
| 13:23 | jaley | TimMc: nope. wait let me see if i can give an isolated example... |
| 13:25 | Somelauw | jaley: please describe the error you are getting |
| 13:26 | Somelauw | I mean the console output |
| 13:26 | jaley | Somelauw: for which method of creating an integer? the constructor call one? |
| 13:27 | dnolen | jaley: (Integer. (int n)) |
| 13:28 | Somelauw | Or I can just wait for the isolated example |
| 13:28 | pandeiro | are <_include>s in clojurescript one's templating lib supposed to show up in development mode? |
| 13:29 | jaley | dnolen: that works! |
| 13:29 | Somelauw | I was just wondering if it just said RuntimeError or if there was further info |
| 13:30 | jaley | Somelauw: so for some reason, if I do (Integer. 1), I get an integer in my repl, but then putting that in a java object collection, then passing that collection to a java library that casted it back to Integer was giving a cast error, claiming the object was a Long |
| 13:31 | dnolen | jaley: (Integer. 1) won't work, 1 is primitive long |
| 13:31 | dnolen | ,(Integer. 1) |
| 13:31 | clojurebot | 1 |
| 13:32 | Somelauw | And (Integer. (int 1)) does work instead? |
| 13:32 | dnolen | ,*clojure-version* |
| 13:32 | clojurebot | {:major 1, :minor 3, :incremental 0, :qualifier nil} |
| 13:32 | jaley | dnolen: should (int 1) without the Integer constructor call work? |
| 13:33 | dnolen | huh weird oh well |
| 13:35 | dnolen | oh ok, prim long can cast to prim int |
| 13:35 | dnolen | jaley: you were seeing something like this |
| 13:35 | dnolen | ,(Integer. (fn [] 1)) |
| 13:35 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Integer> |
| 13:35 | dnolen | ,(Integer. (int (fn [] 1))) |
| 13:35 | clojurebot | #<ClassCastException java.lang.ClassCastException: sandbox$eval105$fn__106 cannot be cast to java.lang.Character> |
| 13:35 | dnolen | ,(Integer. (int ((fn [] 1)))) |
| 13:35 | clojurebot | 1 |
| 13:35 | dnolen | ,(Integer. ((fn [] 1))) |
| 13:36 | clojurebot | 1 |
| 13:36 | hiredman | I was gonna say |
| 13:36 | jaley | dnolen: I was... when I was calling the constructor with a long, yes |
| 13:36 | dnolen | huh, I give up, don't know why that wasn't working |
| 13:36 | dnolen | jaley: I can't get it to break like you did |
| 13:37 | jaley | dnolen: well, (Integer. (int x)) seems to work |
| 13:37 | jaley | dnolen: so thanks for that guys - my head hurts now. i need beer. :-) |
| 13:37 | TimMc | dnolen: Any idea why (Integer. (Long. 50)) *does* work? |
| 13:38 | dnolen | TimMc: not really |
| 13:38 | TimMc | eep |
| 13:38 | dnolen | but the rule is simple, if Java interop wants prim int, prim to cast int |
| 13:39 | dnolen | cast to prim int |
| 13:39 | TimMc | I don't think that's true. |
| 13:39 | dnolen | TimMc: in what way? |
| 13:40 | TimMc | I've seen (Integer.) be required, (int) didn't work, |
| 13:40 | TimMc | although that may have been due to some overloading with Object or Long or something. |
| 13:41 | sr71-blackbird | what's a good way to do write a typed validation system/ err recommended in Clojure, defprotocol, defrecord? |
| 13:41 | dnolen | TimMc: that doesn't make any sense, if Integer is required, that pass Integer |
| 13:41 | dnolen | if prim int is required pass prim int |
| 13:42 | dnolen | sr71-blackbird: defprotocol deftype/record don't do validation |
| 13:42 | dnolen | sr71-blackbird: you could contribute to the analyzer |
| 13:42 | sr71-blackbird | analyzer? |
| 13:42 | dnolen | sr71-blackbird: https://github.com/frenchy64/analyze |
| 13:43 | sr71-blackbird | dnolen, I know, I was writing validate and convert methods to defprotocol and using that with records |
| 13:43 | sr71-blackbird | dnolen, analyzer actually looks sweet |
| 13:45 | dnolen | sr71-blackbird: it is, hopefully more people contribute |
| 13:46 | dakrone | sea |
| 13:46 | sr71-blackbird | dnolen, any quick easy issues to get my feet wet? or features needed? |
| 13:49 | dnolen | sr71-blackbird: you should message the maintainer, nice fellow |
| 13:50 | TimMc | dnolen: Checked the logs -- I misremembered re: Integer. |
| 13:50 | dnolen | sr71-blackbird: also https://github.com/frenchy64/typed-clojure |
| 13:51 | TimMc | Hmm, javac bails on new Integer(new Long(50)) |
| 13:58 | phil_ | why is this running out of memory? |
| 13:58 | phil_ | https://gist.github.com/1677918 |
| 13:58 | phil_ | it is an attempted solution to problem #108 on 4clojure: https://www.4clojure.com/problem/108 |
| 14:00 | gtrak`` | 4clojure looks to be hung |
| 14:00 | phil_ | desc: Given any number of sequences, each sorted from smallest to largest, find the smallest number which appears in each sequence. The sequences may be infinite, so be careful to search lazily. |
| 14:01 | llasram | phil_: I believe the problem is `:when' vs `:while' in `for' |
| 14:01 | llasram | (or if not versus, you do need some terminating condition) |
| 14:01 | gtrak`` | Raynes: I get a 504 gateway time-out on 4clojure |
| 14:02 | phil_ | llasram: doesnt for return a lazy seq? |
| 14:02 | Raynes | Damn. And Alan isn't here. Guess that means I have to *gasp* restart it myself. |
| 14:02 | llasram | phil_: Oh, it does. I missed that `first' should be being applied to it |
| 14:03 | apwalk | gtrak``: glad you see it too. i thought my solution was just *that* good. |
| 14:03 | Raynes | apwalk: It probably was. ;) |
| 14:03 | Raynes | Alex is bringing it back up. |
| 14:03 | phil_ | yea, for small ranges it terminates and if there are no matching numbers then its gonna hang but its not part of the requirements :) |
| 14:04 | phil_ | however it bombs out with an outofmemoryexception actually |
| 14:04 | llasram | Oh, wait |
| 14:04 | llasram | Actually, nm. :-) |
| 14:05 | phil_ | can it be because lazy seqs are cached? |
| 14:05 | phil_ | but shouldnt they be garbage collected whenever they go out of scope? |
| 14:05 | gtrak`` | they're not? |
| 14:06 | phil_ | gtrak``: theyre not? |
| 14:06 | Raynes | gtrak``, apwalk: It's back up. |
| 14:06 | gtrak`` | lazy seqs aren't cached, if you hold on to a reference as you iterate though, they'll never be freed |
| 14:06 | TimMc | Without looking at the code, I'm gonna say you're holding onto the head of some seq. |
| 14:06 | Raynes | Thanks for reporting it. |
| 14:06 | gtrak`` | Raynes: thankyousir |
| 14:08 | phil_ | ok im a little confused now... if they arent cached, holding on to the head shouldnt cause any additional memory consumtion? |
| 14:08 | TimMc | phil_: THey aren't so much *cached* as nonexistent before they are realized and... existent... after they are realized. |
| 14:08 | gtrak`` | if you have an infinite seq, you can realize it, you'll get an oom if you hold on to the head and an infinite loop otherwise |
| 14:10 | gtrak`` | &(range) |
| 14:10 | lazybot | java.lang.OutOfMemoryError: Java heap space |
| 14:10 | phil_ | ok, just to have a clear concept, what is cached then? i read somewhere that some type of seq was cached, i.e. elements arent recomputed on subsequent queries |
| 14:10 | gtrak`` | it's not cached, you've realized it |
| 14:10 | TimMc | phil_: Would you say that the elements of [1 2 3 4 5] are cached? |
| 14:11 | gtrak`` | if you can access a prior value, that means you've held on to the head of a seq |
| 14:11 | gtrak`` | if you discard it, then the GC can collect it |
| 14:12 | llasram | phil_: I for some reason can't see why, but if add a :while condition to terminate the `for' when y exceeds x, the function generates no results. So some logic error is causing you to walk all of (range) |
| 14:12 | gtrak`` | if you can only care about 'first' and 'rest' in your iteration then you're fine |
| 14:12 | phil_ | from clojure.org/lazy: (talking about lazy-seq): returns a logical collection that implements seq by calling the body |
| 14:12 | phil_ | invokes the body only the first time seq is called on it, caches result |
| 14:12 | phil_ | will call seq on the body's return value if not already a seq or nil |
| 14:13 | gtrak`` | and? |
| 14:13 | phil_ | well here they talk about caching |
| 14:13 | tavis | dnolen: jumping back to what you were talking about earlier, re the cljs metadata open question: is metadata something that is definitely on the roadmap? |
| 14:14 | phil_ | or is "realizing" a seq and "caching" a seq the same thing? |
| 14:14 | TimMc | phil_: And I'm encouraging you to think about it differently. |
| 14:14 | gtrak`` | the function caches its value so it doesn't have to compute it again, it's up to you to hold on to that cache by holding on to a reference and preventing the GC from doing its job, there's no global seq cache |
| 14:15 | phil_ | TimMc: yes, i just wanted to understand if those two things are different concepts or not |
| 14:15 | TimMc | They are confusingly similar in this instance. |
| 14:15 | phil_ | gtrak``: yes, i wasnt implying that there was a global cache |
| 14:16 | phil_ | TimMc: but still different? then, when is a seq cached and when realized? |
| 14:16 | gtrak`` | well, so if there was a cache, you'd have to be holding a reference to it for it to matter |
| 14:17 | TimMc | phil_: "cache" implies an eviction algorithm or timeouts |
| 14:17 | TimMc | at least to me |
| 14:17 | gtrak`` | phil_: it's really an implementation detail that shouldn't affect how you use seqs |
| 14:17 | cemerick | "never" isn't an eviction strategy? :-P |
| 14:17 | TimMc | heh |
| 14:18 | TimMc | phil_: I'll say this, then get back to work: An infinite lazy seq is always only partially constructed, there's always a dangly bit at the end that's just an IOU promising to construct some more as needed, a.k.a. lazily. The more you ask for, the more gets constructed (realized), and the bigger it gets. |
| 14:19 | phil_ | when i say cache i mean that the body isnt recomputed again on subsequent calls, whenever the ref to the seq goes out of scope then the "cache" is garbage collected |
| 14:19 | TimMc | phil_: Since it is a linked list, you can drop stuff off the beginning by dropping your references to it. |
| 14:19 | TimMc | phil_: There is *no cache*. |
| 14:19 | gtrak`` | phil_: there are other details like chunking that are also irrelevant |
| 14:19 | TimMc | The seq *is the cache*. |
| 14:20 | phil_ | TimMc: "cache" in this context meaning the head |
| 14:20 | llasram | phil_: AH! It's the order of iteration in the for. The recursive call is lazy, but generates over a potentially lazy list. Since there's no terminating condition in the `for', the penultimate recursive call waits forever for the ultimate recursive call to generate more values |
| 14:20 | llasram | phil_: If you swap to [y (apply ! more), x a], then it works |
| 14:20 | TimMc | phil_: "cache" in this context meaning you're going about this all wrong. |
| 14:20 | phil_ | llasram: but if you swap the arguments? is it gonna work as well? :/ |
| 14:21 | llasram | phil_: Er, why wouldn't it? |
| 14:21 | phil_ | TimMc: i think i understand the whole concept, it just seems the word "cache" is the wrong one |
| 14:22 | phil_ | TimMc: sry if i made you rage :) |
| 14:23 | phil_ | llasram: well try it, [1 2 100] (range) [3 5 100] |
| 14:24 | llasram | Oh. If you need it to work in that case, you need a :while condition in your `for'. Otherwise you'll always be iterating over a potentially infinite list (which never actually generates more than one result) |
| 14:24 | gtrak`` | &(println (range)) |
| 14:24 | lazybot | java.lang.OutOfMemoryError: Java heap space |
| 14:25 | gtrak`` | it's odd that it actually tries to print in my cmd repl, I wonder how that works |
| 14:26 | phil_ | gtrak``: maybe print just iterates over the seq if the argument is a seq |
| 14:26 | phil_ | lazily |
| 14:27 | TimMc | phil_: Reading the source of LazySeq.java is quite illuminating, actually. (Even though there are no docs...) |
| 14:28 | gtrak`` | phil_: hmm, I don't see it yet |
| 14:29 | phil_ | llasram: well for returns a lazy seq and i access the first element, so it shouldnt iterate over the whole infinite seq, i.e. [100 101] (range) and (range) [100 101] both wok |
| 14:30 | phil_ | work* |
| 14:32 | phil_ | TimMc: yes, and what else is sval() if not a one-value cache? |
| 14:32 | phil_ | i.e. if you already know the value of fn.invoke() dont recompute it again |
| 14:33 | amalloy | are we asking why lazybot doesn't "try" to print (range)? |
| 14:33 | llasram | phil_: Without a termination condition, the ultimate (deepest) call to `for' returns a lazy infinite sequence. Then the penultimate `for' (the one containing the recursive function call which makes the depeest `for') iterates over that sequence. If it can't generate any results from the values the deepest `for' generates, then it iterates over the deepest lazy sequence forever |
| 14:33 | llasram | phil_: The solution is to add a :while to your `for' so that it terminates |
| 14:34 | gtrak`` | amalloy: well I think I get why lazybot doesn't try, I'm just not sure why the real repl does try |
| 14:34 | amalloy | gtrak``: print just walks the sequence streaming to *out* |
| 14:35 | amalloy | lazybot has *out* bound to a StringWriter, so it just chews up memory until it runs out; it doesn't stream like the built-in output stream |
| 14:35 | Raynes | It'd get a little hairy streaming to IRC. ;) |
| 14:35 | phil_ | llasram: but why shouldnt it be able to generate values from the values of the deepest for? this is what i dont understand |
| 14:36 | TimMc | Raynes: I do it all the time! |
| 14:36 | TimMc | A user, after all, is just a slow, buggy I/O device. |
| 14:36 | amalloy | Raynes: clojurebot actually does something fairly close to that, i think |
| 14:36 | Raynes | amalloy: I'm pretty sure it sets *print-length*. |
| 14:36 | amalloy | for sure |
| 14:36 | Raynes | And it prints a new message per newline. |
| 14:36 | Raynes | But I don't think streaming is the right word for either of those things. |
| 14:37 | Raynes | We should probably set *print-length* too, just for fun. |
| 14:37 | phil_ | llasram: the probelm is that i dont see a valid :while condition in this case, but it should terminate in any case :/ |
| 14:37 | amalloy | ,(dotimes [x 3] (Thread/sleep 1000) (println x)) |
| 14:37 | clojurebot | 0 |
| 14:37 | clojurebot | 1 |
| 14:37 | clojurebot | 2 |
| 14:38 | amalloy | Raynes: he prints those as they arrive, rather than bundling them up: streaming |
| 14:38 | amalloy | he flushes the stream at each newline |
| 14:38 | TimMc | amalloy: Hard to tell with that slowpoke. |
| 14:39 | Raynes | amalloy: Okay, sure, but he isn't streaming character by character to IRC. It has to be a single message per. |
| 14:39 | llasram | phil_: why not?: :while (>= x y) |
| 14:39 | TimMc | I get the same timing with sleep 1. |
| 14:39 | amalloy | Raynes: no argument there |
| 14:39 | amalloy | ,(dotimes [x 3] (Thread/sleep 4000) (println x)) |
| 14:39 | clojurebot | Execution Timed Out |
| 14:39 | amalloy | okay, maybe you win this time, TimMc |
| 14:40 | TimMc | I think it's a rate limiter between messages. |
| 14:40 | TimMc | ,(dotimes [x 3] (println x)) ; no sleep, ma! |
| 14:40 | clojurebot | 0 |
| 14:40 | clojurebot | 1 |
| 14:40 | clojurebot | 2 |
| 14:40 | amalloy | yeah. i seem to have misinterpreted it as a streaming thing |
| 14:41 | Raynes | Even Einstein was wrong a couple of times. |
| 14:41 | phil_ | llasram: still bad, try it on (map #(* % % %) (range)) (filter #(zero? (bit-and % (dec %))) (range)) (iterate inc 20) |
| 14:43 | llasram | phil_: wfm |
| 14:43 | phil_ | llasram: and while (>= x y) is still gonna produce an infinite seq if both are infinite |
| 14:44 | phil_ | llasram: really? what is the result? |
| 14:44 | llasram | 64 |
| 14:44 | phil_ | can you paste the soure somewhere? |
| 14:46 | llasram | Hmm. |
| 14:46 | phil_ | llasram: nvm |
| 14:46 | phil_ | i got it |
| 14:46 | phil_ | now i must understand it :) |
| 14:47 | phil_ | llasram: thanks a lot for the help! |
| 14:48 | llasram | phil_: np! It was a fun puzzle. It can be hard debugging these sorts of problems |
| 14:48 | phil_ | llasram: yea, it definately can :) did you some tracing macro or just the old good brain? :D |
| 14:49 | geef | what do clojurers use instead of cadr,cdadr and caaar? |
| 14:50 | TimMc | geef: get-in |
| 14:50 | TimMc | and less reliance on lists of lists of lists of lists... |
| 14:50 | Raynes | Logical sentences. |
| 14:50 | llasram | phil_: Tracing is hard when the problem is getting infinite list somewhere :-) I do wish there were better tooling for such issues, but I'm not sure what it would look like |
| 14:50 | Raynes | Words with definitions. Etc. |
| 14:52 | phil_ | llasram: yea, functional debugging is a lot harder it seems... unfortunately :while doesnt work either: [1 2 3 4 5 6 7] [0.5 3/2 4 19] |
| 14:52 | phil_ | it returns 1 instead of 4 |
| 14:52 | cemerick | FYI: use couchdb like it was a clojure collection: http://groups.google.com/group/clojure-clutch/browse_frm/thread/4520716eb37a90cc |
| 14:52 | cemerick | feedback on the API, etc. most welcome |
| 14:54 | brehaut | cemerick: thers no magic for views yet with that new api right? |
| 14:54 | Raynes | cemerick: I want to use couchdb like a couch. And sit on it. |
| 14:54 | llasram | phil_: Like this? https://gist.github.com/1678269 |
| 14:55 | cemerick | brehaut: aside from _all_docs via seq, no |
| 14:55 | cemerick | coming, coming :-) |
| 14:55 | cemerick | views are tricky bastards |
| 14:55 | amalloy | geef: fewer cons cells |
| 14:55 | brehaut | cemerick: dont mean to sound pushy. i've not updated all my code to the 0.3.0 stuff yet :P |
| 14:56 | Raynes | cemerick: Wow, that's pretty awesome. |
| 14:56 | Raynes | amalloy: I bet he is writing down all of our clever responses so that he can worship them later. |
| 14:57 | amalloy | heh |
| 14:57 | llasram | cemerick: OOC, does clutch support lazily generating results from couch's 'Transfer-encoding: chunked'? |
| 14:58 | phil_ | llasram: perfect, thanks a lot again :) |
| 14:59 | Raynes | cemerick: We plan to add proper Github-like rendering of markdown to refheap. You should add asciidoc support. |
| 15:01 | Raynes | cemerick: I'm basically throwing that off to you in order to avoid grumbling about not supporting it in the future. I can just say "well, I told you to do it ages ago". |
| 15:01 | TimMc | I'm not actually a fan of GitHub-flavored Markdown. Specifically, I wish single line breaks were ignored so I could write super-ragged (SCM-friendly) docs. |
| 15:11 | cemerick | f'n macbook BSOD'd on me. :-X |
| 15:11 | cemerick | llasram: you asked something? |
| 15:11 | gtrak`` | is it blue on a macbook? |
| 15:12 | cemerick | gtrak``: it actually a very well-styled gray, logoed screen with antialiased text indicating that you're SOL. |
| 15:12 | llasram | Oh, sorry. I was just wondering if clutch can allow lazy processing of results as couch streams them via chunked-encoding |
| 15:12 | gtrak`` | ha, it's good to bomb out in the most aesthetically pleasing way |
| 15:13 | cemerick | My problem is actually not that — every now and then, the whole business freezes, with the screen frozen with odd animated artifacts. I think it's either an overheating video card, or bad memory. |
| 15:13 | llasram | I don't know my underlying Java well enough to tell if the HTTP facilities support that... |
| 15:13 | cemerick | llasram: Yes, absolutley |
| 15:13 | llasram | Awesome! |
| 15:13 | brehaut | cemerick: is that the multiligual F U bezel ? |
| 15:13 | cemerick | brehaut: yeah, something like that! |
| 15:14 | brehaut | mac os x has a more dire error mode; kernel panic text just slowly rights down the screen over everything |
| 15:14 | cemerick | I'm lucky enough to have never seen that. |
| 15:14 | brehaut | you need to seriously damage the mobo i think |
| 15:14 | cemerick | I'm salivating at the next upgrade. |
| 15:14 | brehaut | (or have it ship with a dodgy nvidia card) |
| 15:15 | brehaut | oh yeah? |
| 15:15 | sritchie | do you guys know how to use the multi-arity version of aset? |
| 15:15 | sritchie | ,(doto (int-array 10) (aset 1 10)) |
| 15:15 | clojurebot | #<int[] [I@1449b2b> |
| 15:15 | sritchie | ,(seq (doto (int-array 10) (aset 1 10))) |
| 15:15 | clojurebot | (0 10 0 0 0 ...) |
| 15:15 | cemerick | mmm, maybe I should switch to use the on-chip video… |
| 15:16 | sritchie | not sure how to use this version: [array idx idx2 & idxv] |
| 15:16 | cemerick | sritchie: that's for N-dimensional arrays |
| 15:16 | brehaut | cemerick: i get the occasional f u bezel from sshing into VBox bridged vms |
| 15:16 | sritchie | cemerick: I see, so setting a corner of 2d array would be (aset arr 0 0 10) |
| 15:18 | cemerick | sritchie: yeah, although, you should never really use it: it uses apply, so boxes like mad. You want to use deep-aset from http://clj-me.cgrand.net/2009/10/15/multidim-arrays or the much-enhanced version that's in the book. |
| 15:18 | cemerick | (we should put that out in a separate project…) |
| 15:18 | sritchie | I'm going through clojure.core w/ Anki |
| 15:18 | sritchie | cemerick: awesome, thanks for the reference |
| 15:18 | brehaut | cemerick: have they told you when to expect the next revision of the pdf to occur? |
| 15:19 | cemerick | brehaut: Any minute now? |
| 15:19 | sritchie | Love cgrand's blog heading: »When the pupil is ready to learn, a teacher will appear |
| 15:19 | brehaut | cemerick: awesome :) |
| 15:19 | cemerick | It's like trying to choose the right pipe out of 100 into which one can drop a message, and hope it hits the right person in the head. |
| 15:28 | chouser | cemerick: congrats, btw. feeling the relief yet? |
| 15:29 | cemerick | chouser: Thanks :-) |
| 15:29 | cemerick | To some degree. It's a bit odd — the days are so much longer all of a sudden! |
| 15:31 | chouser | :-) |
| 15:32 | chouser | does anyone know how to declare a dep on a particular version of a snapshot dep? |
| 15:32 | chouser | the jar I want is in me ~/.m2, but I can't figure out how to tell lein that's the one I want (vs. the newer broken version it's trying to use) |
| 15:33 | cemerick | chouser: that's called "locking snapshots" in maven-land |
| 15:33 | cemerick | replace SNAPSHOT with the timestamp from the particular rev you want |
| 15:37 | sritchie | technomancy: quick question on dependency resolution |
| 15:37 | chouser | I tried that, but I screwed it up. Trying again... |
| 15:37 | jsabeaudry | what exactly is reported when clojurebot says "recently on clojars.org..." Is is that a new version was uploaded? |
| 15:38 | sritchie | I'm pulling from an artifactory repo where some dependencies are <packaging>jar</packaging> and some are <packaging>pom</packaging> |
| 15:38 | TimMc | yeah |
| 15:38 | sritchie | technomancy: the pom packages are just bundles of jar dependencies |
| 15:38 | TimMc | jsabeaudry: I think it's a different message when something new is added. |
| 15:38 | sritchie | leiningen doesn't seem to be able to handle these properly, though everything works fine if I manually include everything |
| 15:38 | chouser | cemerick: thanks, that did it. I was repeating the package name in the version string. for some reason *that* didn't work. :-P |
| 15:39 | jsabeaudry | TimMc, So what does this one mean exactly? Someone downloaded a library? |
| 15:39 | TimMc | jsabeaudry: Nah, someone uploaded a new version of something. |
| 15:40 | jsabeaudry | TimMc, Ah ok! Thanks! |
| 15:40 | cemerick | sritchie: what if you specify packaging of "pom" in your relevant :dependencies? |
| 15:40 | cemerick | chouser: Good; something to automate that really should be in lein. |
| 15:40 | sritchie | cemerick: interesting, like :packaging "pom" ? |
| 15:41 | sritchie | I know the exclusions key |
| 15:41 | sritchie | cemerick: the problem is when some jar pulls in a dependency that's packaged like this |
| 15:41 | sritchie | I can explicitly include it in project.clj, but that doesn't feel right, really |
| 15:42 | cemerick | sritchie: looks like it's :type "pom" |
| 15:42 | cemerick | sritchie: do you have an example (publicly-accessible) dep that has this issue? |
| 15:43 | cemerick | It's been a while since I messed with pom deps. |
| 15:43 | sritchie | me too, I don't know where I can find one of these guys |
| 15:43 | sritchie | or how to deploy one to clojars, for that matter |
| 15:44 | cemerick | Why would you want to deploy one to clojars? |
| 15:44 | sritchie | that's the only public maven repo I know of that I can push an example to |
| 15:44 | cemerick | oh, I see :-) |
| 15:44 | cemerick | There's plenty of pom deps in central, I just don't know of one off the top of my head |
| 15:45 | cemerick | Probably gobs of 'em in spring, etc. |
| 15:45 | brehaut | they are seasonal? |
| 15:46 | sritchie | :type "pom" works |
| 15:46 | sritchie | cemerick: but not if some other dependency pulls in a pom packaged dep |
| 15:46 | sritchie | even if I override it, it'll still fail |
| 15:46 | sritchie | let me check central |
| 15:47 | sritchie | [org.kohsuke/pom "2" :type "pom"] works, [org.kohsuke/pom "2"] fails |
| 15:53 | sritchie | cemerick: https://github.com/sritchie/Example-Deps-Issue |
| 16:05 | jodaro | huh |
| 16:05 | sritchie | technomancy: issue here: https://github.com/technomancy/leiningen/issues/380 |
| 16:05 | jodaro | i don't seem to be getting any google group digests |
| 16:06 | Raynes | jodaro: You're a blessed man. |
| 16:06 | jodaro | i know |
| 16:07 | jodaro | except there are a couple i kinda like |
| 16:07 | jodaro | for example |
| 16:07 | jodaro | clojure |
| 16:07 | cemerick | sritchie: that's expected behaviour AFAIK |
| 16:07 | sritchie | cemerick: the question is how I can deal with dependencies that haven't formatted their poms in the way that lein expects |
| 16:09 | cemerick | sritchie: a pom dependency that doesn't declare a <type> is broken |
| 16:09 | jsabeaudry | Anyone has some experience with clj-time? (No matter if I use (from-time-zone or not the time is always printed in UTC) |
| 16:09 | cemerick | <type> defaults to "jar", and shouldn't ever resolve to a .pom AFAIK |
| 16:10 | cemerick | although, presumably, they *are* working, so… |
| 16:12 | cemerick | sritchie: adding the <type>-less dep on org.kohsuke/pom to a maven project yield a dependency resolution error (Could not find artifact org.kohsuke:pom:jar:2 in central) |
| 16:13 | sritchie | I'll see if I can track down this issue on the twitter side and make them fix it |
| 16:13 | jsabeaudry | Ah all is well, from-time-zone was erroneous I was supposed to use .withZone on the formatter |
| 16:23 | cemerick | sritchie: It'd be interesting to hear what would make that succeed, if you ever find out. :-) |
| 16:27 | technomancy | so it sounds like the problem is with the dependency? |
| 16:28 | sritchie | technomancy: yeah, and with my maven understanding, I guess |
| 16:28 | sritchie | I had thought there was some way to look at the deps in the pom to figure out the type |
| 16:28 | technomancy | ok. |
| 16:28 | sritchie | if that's missing from the pom (the type), then there's nothing we can do |
| 16:29 | sritchie | except fix it up inside twitter, which I'll do |
| 16:29 | technomancy | sritchie: btw, I think the user-level repos thing you mentioned earlier is something you get for free with profiles in lein 2 |
| 16:29 | sritchie | technomancy: nice |
| 16:29 | sritchie | the profile isn't project-based? |
| 16:29 | technomancy | except it's basically repeatability-poison, so it will probably emit a big ol' warning |
| 16:30 | technomancy | profiles are read from the project and the user config |
| 16:30 | sritchie | I think it'd be nice to be able to have an internal config for leiningen |
| 16:30 | sritchie | so you could use lein in a closed environment |
| 16:30 | technomancy | yeah, cemerick has sketched some of that out; shared project middleware |
| 16:31 | technomancy | sritchie: https://github.com/technomancy/leiningen/wiki/Project-Middleware |
| 16:31 | technomancy | feedback welcome |
| 16:31 | cemerick | that was actually ninjudd |
| 16:31 | technomancy | oh? |
| 16:31 | cemerick | well, I was instigating something, I'm sure :-P |
| 16:31 | technomancy | oh right; he wrote it up, but I thought that it addressed a number of use cases you were pining for |
| 16:32 | cemerick | yeah |
| 16:32 | cemerick | I think my initial email to the lein ML described a couple of scenarios that profiles and middleware will address |
| 16:32 | cemerick | technomancy: readability is only going to get more important; viz. chouser wanting to lock snapshots earlier |
| 16:32 | cemerick | stuff like that can and should be automated. |
| 16:34 | technomancy | I agree, but giving up the ability to comment your project is a ridiculously high cost. |
| 16:35 | cemerick | I think a formatting- and comment-preserving alternative reader impl would be a perfectly fine idea. |
| 16:35 | technomancy | absolutely |
| 16:35 | technomancy | just don't want to be the one to write it |
| 16:35 | cemerick | it's not like requirements like this are going to get less common |
| 16:35 | cemerick | :-D |
| 16:35 | technomancy | heh |
| 16:35 | technomancy | I'd consider it a prerequisite to automated project.clj modification |
| 16:35 | brehaut | i could throw out so much code if there was a preserving reader that i could use in clojurescript |
| 16:35 | cemerick | technomancy: don't talk the task down! |
| 16:36 | chouser | a preserving reader would be great in so many contexts |
| 16:36 | chouser | cemerick: gah! crossed posts! I wasn't volunteering! |
| 16:36 | cemerick | LOL |
| 16:36 | cemerick | chouser: it's so great that it worked out that way, though! |
| 16:36 | technomancy | hiredman: you spiked out a lossless reader, right? |
| 16:37 | technomancy | that'd make a great demo at the next seajure |
| 16:39 | chouser | if everything that could be read could hold metadata, that'd be an intruiging option. But without that, I'm not even sure what such a reader should return. |
| 16:42 | TimMc | How does Eclipse handle refactoring Java code? |
| 16:42 | gtrak`` | TimMc: it has its own compiler |
| 16:42 | TimMc | That sort of thing might be a good research starting point. |
| 16:43 | gtrak`` | in other words, they have control of the AST |
| 16:43 | technomancy | this is actually the one interesting thing about Go IMO; the AST is actually an explicit part of the language spec |
| 16:44 | cemerick | it seems like comments and contiguous whitespace just turn into instances of some other type; no reason why a lossless reader wouldn't return (mostly) the same as what the current reader does |
| 16:44 | cemerick | And then 1:1 correspondence is a postwalk away |
| 16:45 | TimMc | There are some tough questions about insertion of forms and preserving indentation, etc. Eclipse has a configurable formatter built in, which is probably what they fall back to. |
| 16:46 | gtrak`` | the formatter's not terribly smart |
| 16:53 | arohner | cemerick: I just started using bandalore. it looks good. Great docs too |
| 16:54 | cemerick | arohner: oh, cool. :-) I haven't touched it in a while, glad it's still up to snuff. |
| 16:54 | cemerick | well, great docs if github wasn't so bloody broken these days :-X |
| 16:55 | arohner | cemerick: so far, I've only done the 'send' side of hello world. I'll you know about the rest soon :-) |
| 16:55 | arohner | yeah, but the docstrings are good too |
| 16:55 | cemerick | glad it's clear for you |
| 16:56 | cemerick | I really have no idea why markdown holds such sway with programmers. |
| 16:56 | brehaut | historical accident i think |
| 16:56 | technomancy | least-common denominator |
| 16:57 | technomancy | just be glad textile seems to have withered; it was king of '06-era rubyland |
| 16:57 | brehaut | gruber wrote good docs and a solid implementation for it back when tools of its ilk were rare. the php port that everyone used with wordpress was also pretty good |
| 16:58 | Raynes | cemerick: I know markdown. I do not know asciidoc. |
| 16:58 | Raynes | Is that not good enough? |
| 16:58 | technomancy | he forgot to write a spec, unfortunately |
| 16:58 | brehaut | indeed |
| 16:58 | brehaut | and its a big bag of regexps to bash against the input, so good luck reverse engineering that |
| 16:58 | cemerick | Raynes: insofar as markdown is an impoverished format, no. |
| 16:59 | Raynes | $dict impoverished |
| 16:59 | lazybot | Raynes: adjective: Reduced to poverty; poverty-stricken. See Synonyms at poor. |
| 16:59 | Raynes | cemerick: Everything you say to me makes me feel like an illiterate hick. Just FYI. |
| 16:59 | jsabeaudry | Typically does version "0.0.1-SNAPSHOT" come before or after version "0.0.1" ? |
| 16:59 | Raynes | Way, way before. |
| 17:00 | technomancy | (as well as immediately before) |
| 17:00 | brehaut | jsabeaudry: -SNAPSHOT is the untrustworthy imposter release of the version. |
| 17:00 | Raynes | I never use snapshots. |
| 17:01 | jsabeaudry | Alrighty, thanks, I guess I can see snapshot as some kind of RC0 |
| 17:01 | cemerick | Raynes: You're plenty erudite, don't worry. :-P |
| 17:01 | Raynes | If I need to release something before a stable release, I release alphas and betas. |
| 17:01 | Raynes | 0.1.0-alpha1. |
| 17:01 | Raynes | $dict erudite |
| 17:01 | lazybot | Raynes: adjective: Characterized by erudition; learned. See Synonyms at learned. |
| 17:01 | Raynes | cemerick: I'm learned! |
| 17:01 | gtrak`` | maven tends to always check for new snapshot releases upstream, is this true for lein as well? |
| 17:01 | jodaro | nice |
| 17:02 | technomancy | gtrak``: once a day |
| 17:02 | technomancy | gtrak``: actually, no with the latest lein it's only whenever your :dependencies list changes |
| 17:02 | technomancy | or when you explicitly run "lein deps" |
| 17:02 | gtrak`` | ah |
| 17:02 | TimMc | so if deps doesn't run, the daily SNAPSHOT check doesn't run |
| 17:03 | gtrak`` | that makes sense |
| 17:03 | TimMc | Raynes: Wait, I thought 1.0.0-SNAPSHOT came after 1.0.0 because it's not known what the next version will be. |
| 17:04 | gtrak`` | WRONG |
| 17:04 | gtrak`` | :-D |
| 17:04 | Raynes | TimMc: I thought that the chicken came before the egg, but even that is cloudy these days. |
| 17:04 | brehaut | actually the chicken came from asia and is a domesticated red jungle fowl |
| 17:05 | hiredman | sounds correct to me |
| 17:05 | hiredman | just don't check wikipedia |
| 17:06 | TimMc | gtrak``: This is terrible. I thought it was such a cool thing! |
| 17:06 | jodaro | $know chicken |
| 17:06 | lazybot | jodaro: chicken (the domesticated bird) |
| 17:06 | jodaro | vague but not incorrect |
| 17:07 | Raynes | $know leiningen |
| 17:07 | lazybot | Raynes: "Leiningen Versus the Ants" by Carl Stephenson, the classic short story published in the December 1938 edition of Esquire Magazine |
| 17:07 | TimMc | Raynes: The egg came first, because the genetics are what matters, and the egg has the same genetics as the chicken it turns into, not its parents. Whereever you draw the line across the lineage, it will be between an egg and its parents. |
| 17:07 | Raynes | technomancy: ^ lazybot knows. It *knows*. |
| 17:08 | Raynes | TimMc: You and aren't friends anymore. |
| 17:08 | TimMc | me and some invisible username? |
| 17:08 | Raynes | Yes. |
| 17:08 | TimMc | I'm pedantic for your benefit, Raynes. |
| 17:09 | jodaro | i think we all benefit from said pedantry |
| 17:10 | TimMc | I know *I* do. |
| 17:19 | TimMc | So, is there any way to version something as v.Next? |
| 17:21 | TimMc | LATEST, is that it? |
| 17:22 | TimMc | Never mind, that's instead of a version range. |
| 17:24 | technomancy | holy smokes, do you really need to set the JAVA_HOME environment variable to use Oracle's JDK on windows? |
| 17:25 | Raynes | technomancy: I've just given up on supporting Windows in anything I do ever. |
| 17:25 | Raynes | I'm mostly a "patches welcome if you need windows support" kind of guy, though the Windows patches I get tend to be completely insane and unformatted by people who don't really know Clojure. |
| 17:26 | technomancy | oh man, this guy is telling people to manually download libssl in order to do curl in order to do lein self-install. |
| 17:26 | Raynes | Haha |
| 17:27 | technomancy | I don't even know; that could be a reasonable thing to tell people to do on Windows? |
| 17:29 | TimMc | technomancy: Is that with Cygwin? |
| 17:30 | technomancy | TimMc: nah |
| 17:30 | TimMc | I mean, if you're doing anything outside of Cygwin, it's going to be that nmuch worse. |
| 17:31 | technomancy | "disable your antivirus to allow lein plugin install to work" =( |
| 17:31 | technomancy | is this the price of enterprise domination? |
| 17:31 | the-kenny | Also, try to reboot if M-x clojure-jack-in doesn't work. |
| 17:31 | brehaut | lets just let the enterprise use F# |
| 17:32 | technomancy | brehaut: tempting! |
| 17:32 | technomancy | I wonder if relevance's sponsorship of CCW was a strategic move in that direction |
| 17:33 | brehaut | a reasonably hypothesis |
| 17:33 | brehaut | and a more approachable enviroment than emacs |
| 17:34 | the-kenny | Well, if I had to use windows, I'd use emacs. |
| 17:34 | the-kenny | So I have at least some kind of abstraction between me and Windows :) |
| 17:34 | technomancy | brehaut: what; that's a reasonable thing to say. |
| 17:34 | TimMc | brehaut: Emacs is in no way approachable... and you'll have to pry it from my cold, dead RSI-riddled hands. |
| 17:34 | brehaut | technomancy: yes, but i fear jihad nontheless |
| 17:34 | gtrak`` | the-kenny: then all you'd need is a decent text editor |
| 17:35 | TimMc | I'm sure you canload vim in a buffer. |
| 17:35 | the-kenny | gtrak``: I can use vim inside emacs for that. |
| 17:35 | technomancy | brehaut: the objections come when people value approachability over other good things |
| 17:35 | brehaut | the-kenny: visual studio + F# is actually a pretty good buffer too |
| 17:35 | technomancy | fortunately you have to already understand that familiarity is orthogonal to elegance and power to even want to use Clojure in the first place |
| 17:36 | Scriptor | + |
| 17:36 | technomancy | so we don't get too many of those types |
| 17:36 | technomancy | (the mailing list being the exception that proves the rule I guess?) |
| 17:36 | brehaut | totally |
| 17:36 | AimHere | I always thought of emacs as RMS's method of having some kind of usable abstraction between him and Unix ;) |
| 17:37 | technomancy | AimHere: for a long time it was the only thing keeping the dream of the Lisp Machine alive |
| 17:37 | AimHere | Yup |
| 17:38 | brehaut | actually, i think i avoid the ML because of google groups more than any personalities |
| 17:39 | technomancy | ugh; the stupid new hashbang UI |
| 17:39 | technomancy | brehaut: it has a nice email interface too, you know =) |
| 17:39 | brehaut | brehaut: haha nah they broke that for me with my apps for domains accoutn |
| 17:40 | brehaut | i gave up trying to fix it |
| 17:40 | TimMc | I used to have my domain email hosted with Google but now I use Cotse -- much less sketchy. |
| 17:40 | TimMc | although I do miss the UI |
| 17:40 | brehaut | TimMc: yeah thats why ive stayed with gmail; my family also have email addresses at my domain |
| 17:41 | TimMc | aha |
| 17:41 | brehaut | gmail and reader are the only things i use google for these days |
| 17:41 | technomancy | not jabber? |
| 17:41 | brehaut | oh |
| 17:41 | brehaut | maybe i do actually |
| 17:41 | brehaut | that'd be trivialy to switch out though |
| 17:41 | llasram | technomancy, brehaut: And a usenet interface via gmane! |
| 17:42 | technomancy | llasram: hm; I should check that out |
| 17:42 | technomancy | probably not as sluggish as gnus+imap |
| 17:44 | brehaut | TimMc: you havent lived till you've tried to read comp.lang.lisp |
| 17:45 | TimMc | heh, I bet |
| 17:45 | fhd_ | Can't seem to find something equivalent to seq-utils/find-first (from contrib) in 1.3, any leads? |
| 17:45 | jodaro | wouldn't that make it unusednet? |
| 17:45 | AimHere | If you ever go on Usenet, TimMc, just type the word 'Kibo' in there somewhere, as a test |
| 17:45 | TimMc | AimHere: Oh, I've browsed around his site. |
| 17:46 | AimHere | I'm just curious as to if he still greps all of Usenet |
| 17:46 | AimHere | Kibo was the Candyman of the internet back in the day |
| 17:46 | TimMc | fhd_: You mean (first (filter ...)) ? |
| 17:46 | fhd_ | TimMc: No, I don't want to filter the whole seq, only up to the first match |
| 17:46 | fhd_ | TimMc: But filter is lazy, eh? |
| 17:47 | fhd_ | TimMc: OK, thanks :) |
| 17:47 | brehaut | fhd_: thanks to the magic of lazy seqs, thats mostly true (except for chunked seqs) |
| 17:56 | TimMc | &(first (filter #(do (println %) true) (range))) |
| 17:56 | lazybot | ⇒ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0 |
| 17:56 | TimMc | I guess filter is chunked! |
| 17:57 | brehaut | range and vector produce chunked seqs, rather than filter being chunked isnt it? |
| 17:57 | TimMc | Hmm... |
| 17:57 | technomancy | brehaut: yes |
| 17:57 | brehaut | TimMc: have a look at (source filter); its got a bunch of extra code to handle chunked seqs though |
| 17:57 | TimMc | filter isn't in control of what its predicate gets applied to? |
| 17:58 | TimMc | &(first (filter #(do (println %) true) (iterate inc 0))) |
| 17:58 | lazybot | ⇒ 0 0 |
| 17:58 | franks | technomancy: the 1.7.0-SNAPSHOT code for lein still doesn't seem to use rlwrap - you mentioned before that you may have accidently deleted it... should I submit an open issue for that? |
| 17:58 | brehaut | TimMc: it does maintain a chunked-seq if it gets one, buti it doesnt generate one otherwise |
| 17:58 | TimMc | ANd now I see the purpose of unchunk. |
| 17:58 | brehaut | ,(apropos 'chunk) |
| 17:59 | clojurebot | (chunked-seq? chunk-buffer chunk-cons chunk-append chunk-rest ...) |
| 17:59 | TimMc | brehaut: It's not a standard fn. |
| 17:59 | amalloy | brehaut: i believe that describes all chunked-seq functions (those that take a seq as input, anyway; i'm not including range here) |
| 17:59 | brehaut | amalloy: yes i think you are right; i was just using it as an example |
| 17:59 | technomancy | franks: hmm; I thought I had fixed that |
| 18:00 | technomancy | apparently not! feel free to open an issue and/or pull request |
| 18:00 | franks | technomancy: maybe i'm looking in the wrong branch... |
| 18:00 | technomancy | nope; it's gone |
| 18:00 | franks | ok |
| 19:13 | franks | technomancy: is the "-XX:+TieredCompilation" option for the jvm valid in general or only for the trampoline case? |
| 19:26 | technomancy | franks: no, it should always be active |
| 19:54 | pickles | anyone have any tips on general optimization? |
| 19:54 | pickles | any functions to avoid? |
| 19:54 | pickles | I rewrote part of a program, and what would take a few seconds before in the old, ugly code on my netbook's Atom now takes over 15 on my dual-core athlon |
| 19:55 | pickles | (granted I'll have to review the algorithms I'm using now, but any tips would be appreciated) |
| 19:55 | dnolen | pickles: look at test.benchmark for ideas when perforamnce is actually critical |
| 19:56 | pickles | mmk, I'll take a look |
| 19:56 | pickles | (I'm still new to clojure so I'm not that familiar with things yet) |
| 19:56 | dnolen | pickles: common pitfalls including trying to do operations like nth and count on seqs |
| 19:56 | pickles | mm... I am doing a couple of count calls |
| 19:56 | dnolen | including -> include |
| 19:56 | pickles | []s are seqs, right? |
| 19:57 | dnolen | pickles: vectors are random access, but not if you put them through seq operations like map/filter/etc |
| 19:57 | pickles | yup, using map and mapcat alot |
| 19:58 | pickles | on vectors |
| 19:58 | dnolen | pickles: there's nothing wrong with those use well, but expect operations like nth and count to be linear after those have been applied, you longer have a vector but a seq |
| 19:58 | dnolen | used well |
| 19:58 | pickles | hm |
| 19:58 | pickles | so if i wrap it in a vect cal will it ease that a bit? |
| 19:59 | pickles | i was using that alot more in my earlier code |
| 19:59 | dnolen | pickles: 1.4.0 alphas have mapv / filterv as well |
| 19:59 | pickles | i'm still on 1.2 atm |
| 19:59 | dnolen | pickles: but yes you could put them back into vectors (into [] ...) |
| 20:00 | pickles | ok, would you recommend that before counts, or just generally after maps? |
| 20:00 | dnolen | anything that would be linear otherwise |
| 20:00 | pickles | mm |
| 20:01 | technomancy | pickles: my advice would be don't optimize before you profile |
| 20:01 | dnolen | pickles: and I'm not recommending that in general, just depends on what you're doing |
| 20:01 | pickles | right (to both) |
| 20:01 | technomancy | a common cause of slowdown is reflection, but until you've confirmed that's a problem you don't want to waste your time with type hints |
| 20:01 | pickles | right |
| 20:01 | technomancy | especially considering it's likely you only need a handful of them in a few strategic locations |
| 20:02 | pickles | was just reading something to that effect |
| 20:02 | dnolen | pickles: best to assess your changes since an order of magnitude slowdown sounds weird |
| 20:02 | pickles | yeah |
| 20:03 | pickles | sadly that'll have to wait till another nite, when my brain isn't so fried |
| 20:03 | brehaut | re:type hinting and global *warn-on-reflection*, if you set w-o-r to true in lein, do all the dependancies also warn? |
| 20:03 | pickles | thx for the help guys |
| 20:04 | pickles | time for some profiling |
| 20:04 | technomancy | brehaut: they should, possibly except for the ones that have been AOTd? |
| 20:04 | technomancy | I actually have no idea; I never profile or AOT personally. |
| 20:04 | brehaut | technomancy: right. so if you were to release a library, would you type hint it so that it had no reflection warnings ? |
| 20:04 | brehaut | (ie, to prevent it being noise in someone elses codebase) |
| 20:05 | technomancy | I would release it with reflection and wait till someone yelled at me, then I would accept a pull request from them. =) |
| 20:05 | brehaut | lol :) |
| 20:05 | brehaut | fair enough :) |
| 20:05 | technomancy | it depends on the lib and its likelihood to be used in a tight loop I guess |
| 20:05 | brehaut | ie, its a complete waste of time in an xml-rpc lib ;) |
| 20:06 | brehaut | and i shouldnt have bothered |
| 20:06 | technomancy | the problem tooling-wise is that there's no way to say "I don't care about reflection warnings from these namespaces; they are all I/O bound anyway" |
| 20:06 | technomancy | I don't think you can fix that outside the compiler |
| 20:06 | brehaut | right |
| 20:06 | franks | technomancy: just checked-in a pull-request for that rlwrap fix for the 1.7.0-SNAPSHOT branch... |
| 20:07 | technomancy | brehaut: so someone could have a legitimate need for warn-on-reflection but have the useful info they need buried by my crap, and that would make me feel at least marginally bad even if it's not necessary for my code |
| 20:07 | technomancy | but really I would shift most of the blame to clojure itself =) |
| 20:07 | technomancy | franks: great; thanks! |
| 20:10 | amalloy | mapv, interesting. i guess that avoids creating as many temporary seqs? |
| 20:10 | brehaut | and can use a transient ? |
| 20:10 | technomancy | hmm; I smell a doall/map replacement =) |
| 20:11 | franks | technomancy: ...just one other issue that I noticed - you only enable rlwrap for options of repl/interactive, which doesn't allow a plugin to enable rlwrap... I kind of hardcoded my plugin in there for now - you should be able to enable rlwrap always and still pipe input in thru stdin without rlwrap getting in the way - otherwise maybe enable for any plugin starting with "repl*" ;-) |
| 20:11 | technomancy | franks: yeah, I do feel a bit bad about special-casing the built-in tasks. it's probably fine to enable in unconditionally. |
| 20:12 | brehaut | answering my own question: yes |
| 20:13 | franks | technomancy: you could still test whether there is a terminal connected to enable rlwrap... |
| 20:13 | brehaut | whoa. the definition for *clojure-version* is way more complicated than i expected |
| 20:13 | technomancy | franks: should already be doing that actually |
| 20:17 | franks | technomancy: correct - and that test alone should suffice |
| 20:26 | franks | technomancy: modified the pull-request to include a change that would remove the tests for internal tasks. |
| 20:44 | jedahu | trying to get lein to start a rhino repl |
| 20:44 | jedahu | no joy: http://paste.lisp.org/display/127304 |
| 20:45 | dgrnbrg | Is there a good way to report an error from inside a macro and get a stacktrace? |
| 20:45 | dgrnbrg | Can I just (throw (RuntimeException. msg))? |
| 20:45 | dgrnbrg | Can I integrate with clojure's compiler errors? |
| 20:46 | jedahu | you know macros don't create stack frames right? |
| 20:46 | technomancy | franks: sorry if I was unclear; the removal of the check for the trampoline task was intentional |
| 20:46 | amalloy | jedahu: that's an overstatement that assumes something about what he means |
| 20:46 | technomancy | since with the addition of :plugins we need to be able to trampoline from arbitrary tasks |
| 20:47 | jedahu | amalloy: just trying to clarify exactly that :-) |
| 20:47 | dgrnbrg | I am writing some code that does very complex tasks within macros |
| 20:47 | dgrnbrg | and they can fail |
| 20:47 | amalloy | an error occuring during macroexpansion will certainly result in a stacktrace in the compile phase |
| 20:47 | dgrnbrg | I want the line number where they fail |
| 20:47 | dgrnbrg | amalloy, that's what I'm wondering |
| 20:47 | dgrnbrg | I feel like i've seen my environment not give me stacktraces |
| 20:47 | dgrnbrg | sometimes, but other times I see them |
| 20:49 | dgrnbrg | Is there a shortcut to throw a runtime exception? Like, a utility function or the like? |
| 20:49 | brehaut | throw ? |
| 20:49 | dgrnbrg | But I want to write (throw "problem is this var" the-var) |
| 20:50 | dgrnbrg | Write my own? |
| 20:50 | amalloy | dgrnbrg: so write a function for that, problem solved |
| 20:50 | technomancy | slingshot sorta does that |
| 20:50 | dgrnbrg | I like to not maintain my system |
| 20:50 | dgrnbrg | and to integrate with the best solutions |
| 20:51 | dgrnbrg | so that I can just focus on my actual problem, instead of the solved problem |
| 20:51 | dgrnbrg | is slingshot the conditions lib? |
| 20:51 | technomancy | yeah, its successor |
| 20:51 | brehaut | a one line function isnt really that onerous is it? |
| 20:51 | dgrnbrg | right, i've read about that |
| 20:52 | dgrnbrg | brehaut, ;) |
| 20:52 | jedahu | technomancy: any ideas? |
| 20:52 | clojurebot | Gabh mo leithscéal? |
| 20:54 | technomancy | jedahu: weird... I haven't done any clojurescript beyond hello world, so it's hard to say |
| 20:55 | technomancy | the task function looks legit though |
| 20:56 | technomancy | I tend to use fully-qualified references + require instead of require :as in eval-in-project, but that's just a style thing |
| 20:57 | jedahu | technomancy: thanks for looking |
| 20:57 | dgrnbrg | what is a better way of doing (flatten (partition 1 2 [1 2 3 4]))? |
| 20:58 | dgrnbrg | ,(flatten (partition 1 2 [1 2 3 4])) |
| 20:58 | clojurebot | (1 3) |
| 20:58 | jedahu | there isn't a channel where clojurescript gurus hang out is there? |
| 20:58 | dgrnbrg | rather, is that idiomatic? |
| 20:59 | technomancy | clojurebot: flatten? |
| 20:59 | clojurebot | flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with. |
| 20:59 | amalloy | &(take-nth 2 [1 2 3 4]) |
| 20:59 | lazybot | ⇒ (1 3) |
| 20:59 | amalloy | jedahu: #clojure |
| 21:00 | dgrnbrg | amalloy, take-nth is exactly the function. And thanks for telling me about concat--I forgot about it |
| 21:03 | phil | is it considered cleaner style to work with defprocols/records or with just maps of functions when polymorphism isnt needed? |
| 21:33 | jeremyheiler | Is it conventional to have an ! at the end of a function name that does IO? |
| 21:35 | apwalk | "Use the bang! only for things not safe in an STM transaction." |
| 21:35 | apwalk | http://dev.clojure.org/display/design/Library+Coding+Standards |
| 21:40 | dgrnbrg | How do I diff data structures? |
| 21:40 | dgrnbrg | ahh, clojure.daat |
| 21:41 | jeremyheiler | apwalk: What is considered not safe? I suppose if I'm not touching the transaction, then it's safe. |
| 21:42 | jeremyheiler | Well, by "touching" I mean not changing a var/ref/agent/atom etc. |
| 21:45 | apwalk | I'm new, but I'd say yes, that and using transients. |
| 21:46 | apwalk | I'm looking through the source of *! functions on clojuredocs and looking for patterns. |
| 21:48 | apwalk | Pretty looks like anything that's expected to have side-effects, unless protected by STM. |
| 21:48 | jeremyheiler | Nice, yeah, I would agree. |
| 21:48 | jeremyheiler | Thanks |
| 21:49 | brehaut | functions whose name end in a ! are not safe for use within an STM transaction |
| 21:49 | brehaut | (rather than side effects in general like in other lisps) |
| 21:50 | apwalk | Ah, so replace my "unless" with "and can't be" ... |
| 21:51 | jeremyheiler | brehaut: Yeah, I was thinking the definition could also include other side-effecty things, but now that we've talked about it, it makes sense to keep it STM related stuff. |
| 21:52 | jeremyheiler | Given that STM is essential here |
| 21:52 | brehaut | send is a good example: its side effecting, but the STM holds all agent sends till after the transaction succeeds |
| 21:52 | brehaut | contrast with atoms that have swap! |
| 21:53 | brehaut | im pretty sure this is _somewhere_ on the dev.clojure.org site, but i can never find it |
| 21:53 | jeremyheiler | apwalk provided the link to the one-liner, but that doesn't explain much. unless you're thinking of something else? |
| 21:54 | brehaut | maybe ive confused two articles then |
| 21:54 | brehaut | because thats the article i was thinking of, but not not the right exposition |
| 21:56 | brehaut | im curious how dosync and send actually coordinate the holding back of the agent message |
| 21:57 | brehaut | send itself is rather brief |
| 21:57 | jeremyheiler | http://clojure.org/refs explains it very well, but doesn't mention the formality of the bang |
| 21:57 | brehaut | sorry, i mean the implementation details |
| 21:58 | dgrnbrg | I'm trying to test out a macro, and I'm noticing that if I use macroexpand-1 in a deftest, it doesn't seem to expand the macro |
| 21:58 | jeremyheiler | brehaut: no, my bad, I was replying to your message about the article |
| 21:59 | brehaut | ah i see. clojure.lang.Agent dispatchAction explicitly looks for the running transaction https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L248-258 |
| 21:59 | jeremyheiler | was just loading that file on github myself haha |
| 22:01 | jeremyheiler | so basically then it just queues it up into the transaction. but that doesn't mean it waits until the end, or does it? |
| 22:01 | dgrnbrg | Hmm, the tests work if I namespace-qualify the quoted macro form I want to expand |
| 22:01 | dgrnbrg | but I don't need to on the repl |
| 22:01 | brehaut | jeremyheiler: looking at LockingTransaction it does |
| 22:01 | jeremyheiler | oh nevermind, i see iterate over the actions in the finall block |
| 22:02 | jeremyheiler | i see it* |
| 22:02 | jeremyheiler | finally* |
| 22:02 | brehaut | i wonder why its specific to agents |
| 22:02 | brehaut | and not just arbitrary ifns |
| 22:03 | brehaut | it seems like it would useful to package up all sideeffecting, non transactional stuff like that |
| 22:05 | jeremyheiler | it seems like you could by referencing all your side effecty objects with an agent? |
| 22:05 | brehaut | i guess so |
| 22:06 | brehaut | that does make them asyncronous, i wonder if thats a problem |
| 22:06 | brehaut | this is all well above my pay grade |
| 22:06 | jeremyheiler | im not sure what the bounds of a transaction are yet, though. but i can imagine you may not want... yeah, asynchronous. |
| 22:06 | jeremyheiler | lol |
| 22:08 | jeremyheiler | it' |
| 22:08 | jeremyheiler | it's cool to think about, though. |
| 22:08 | amalloy | dgrnbrg: deftest has all kinds of weird and crazy behaviors, especially related to macros |
| 22:10 | brehaut | jeremyheiler: definately is. ive learnt a lot by spelunking like that |
| 22:11 | amalloy | i believe this is because (deftest foo (blah)) expands to something like (defn ^{:test (fn [] (blah))} foo []), and there's something weird about metadata that i don't entirely understand |
| 22:13 | jeremyheiler | brehaut: do you know what the bounds of a transaction are? |
| 22:14 | brehaut | jeremyheiler: well, the body of a transaction is wrapped in a thunk fn and passed to LockingTransaction.runInTransaction |
| 22:14 | brehaut | so i presume that the thunk defines the bounds |
| 22:14 | brehaut | (unless it happens to be within an existing transaction) |
| 22:15 | jeremyheiler | thunk? |
| 22:15 | brehaut | function of zero arguments |
| 22:15 | brehaut | (fn [] :foo) |
| 22:15 | jeremyheiler | ah ok |
| 22:16 | brehaut | clojure's transactions have a very simple nesting model: if you are in a transaction already, just run the thunk with that, otherwise, create a new transaction. If any of the transactions fail for some reason, then it rolls back the entire thing |
| 22:17 | brehaut | the details however, are a little more involved ;) |
| 22:19 | jeremyheiler | Yeah, i'm fully aware of the complexity of concurrency :-P but that sounds like the transactions work like java reentranlocks |
| 22:19 | brehaut | last time i really looked at java's concurrency primatives was 2003 ;) |
| 22:20 | jeremyheiler | nice, i did some stuff a couple years ago with jsr166 before it was released into java 7, but i haven't done much since :-P |
| 22:20 | brehaut | jeremyheiler: a lot of the magic is actually in tracking what refs have been touched |
| 22:21 | brehaut | part of what appealed to me about clojure was that id done threaded stuff in python and it hurt a lot |
| 22:21 | brehaut | even with blocking queues |
| 22:24 | jeremyheiler | yeah, i know what you mean. there are some interesting and cool agorithms, like non-blocking queues that leave messes, but the next guy to come through knows how to clean it up. i got a chance to learn form doug lea himself, and it's crazy all the little tiny details that need to be taken care of in order to implement something seemingly simple. |
| 22:25 | jeremyheiler | because of that, is why I started to learn clojure |
| 22:26 | jeremyheiler | with clojure, you can still learn the nitty gritty details, but not have to worry about it if you don't want :-P |
| 22:26 | adam_ | i concur, the transaction system is why i'm learning clojure now |
| 22:26 | brehaut | ironically, most of the code ive written with clojure hasnt used the concurrency features :P |
| 22:26 | brehaut | (at least, not explicitly) |
| 22:26 | adam_ | yeah, Purely Functional Data Structures by Okasaki has a lot to teach you about data struts |
| 22:27 | jeremyheiler | brehaut: i know what you mean, it's been the same here, but it's ok because I plan on getting into it more as clojure takes over my projects. |
| 22:28 | jeremyheiler | adadm_: I read his "follow" up article to that book a few weeks ago. good stuff. |
| 22:28 | jeremyheiler | adam_: ** |
| 22:29 | jeremyheiler | but, i'll have to put the actual book at the end of my very long book queue |
| 22:29 | adam_ | it does a pretty good job explaining how lazy evaulation |
| 22:29 | adam_ | yeah, i got it with some christmas money, i've only read the first couple chapter, its been time well spent |
| 22:29 | adam_ | the only downside is that it's written in ML and Haskell, so understanding those languages is a must |
| 22:30 | brehaut | thats not a downside :P |
| 22:30 | jeremyheiler | adam_: nice that's good to hear. |
| 22:30 | brehaut | its an opportunity |
| 22:30 | jeremyheiler | adam_: any excuse to learn haskell is probably a good one :-P |
| 22:30 | jeremyheiler | adam_: because we all know nothing useful can be done with it (jk jk) |
| 22:30 | phil | is it considered cleaner style to work with defprocols/records or with just maps of functions when polymorphism isnt needed? |
| 22:30 | adam_ | yeah, i went thought Learn You a Haskell for Great Good |
| 22:30 | adam_ | its free online |
| 22:31 | adam_ | the problem with Haskell is everything is so damn hard to do |
| 22:31 | Raynes | Meh. |
| 22:31 | Raynes | Not really. |
| 22:31 | Raynes | Everything is hard to do until you know the language |
| 22:31 | adiabatic | For someone who's already fluent in functional style, how different are, say, Clojure, ML, and Haskell? I know the latter two are statically, strongly typed, but how big of a deal is that? |
| 22:31 | Raynes | You have to understand that everything is input to something. |
| 22:31 | adam_ | yeah, and get your phD in functional languages |
| 22:32 | jeremyheiler | meh, it's good to learn to think abstractly anyway. syntax should be moot |
| 22:32 | jeremyheiler | (well, for any reasonable language) |
| 22:32 | brehaut | adiabatic: it depends what you are building. if you are just building websites, haskell is going to hurt a lot more than clojure |
| 22:32 | TimMc | phil: Work with maps. You can still get polymorphism with multimethods dispatching on some key in the map. |
| 22:32 | Raynes | adam_: Those are mostly tired jokes. |
| 22:32 | adiabatic | brehaut: Why? |
| 22:32 | Raynes | adam_: I started learning Haskell at 13-14. I managed better in it than any other language I used at the time. |
| 22:33 | Raynes | I don't buy into the "it's so hard mathy and academic" stuff. |
| 22:33 | brehaut | adiabatic: because websites are programs that take some semi-structured goop from DBs, Forms, Ajax briefly mashing them around and push them out as differently semi-structured goop |
| 22:33 | Raynes | No, it isn't what you're used to. But neither was programming in the first place when you started. |
| 22:33 | adiabatic | Raynes: You're probably very good at hard, mathy things :) |
| 22:33 | phil | TimMc: thx |
| 22:33 | brehaut | if you have to satisfy a typechecker you have a bunch more work that has very little reward |
| 22:33 | Raynes | You get more done by doing and much less done by worrying about how hard something might be. |
| 22:34 | phil | bradwright: why? you still have to get the "types" right in a dynamic langugage and haskells type checker doesnt get in your way |
| 22:34 | Raynes | adiabatic: Absolutely. I'm a child genius. Chip off of the ol' block. I've had papers written about me, I have. |
| 22:35 | brehaut | phil: i presume you misaddressed that? |
| 22:35 | phil | brehaut: yes, sorry |
| 22:36 | brehaut | phil: im entirely aware how nice haskells type checker is |
| 22:37 | phil | brehaut: what i mean is that when the type checker complains about something thant its likely a bug (more often than not) |
| 22:37 | brehaut | phil: on the other hand, the points where data comes into a web app typically already do the transformations to correct types for you |
| 22:38 | adam_ | Raynes, haskell is a really beautiful langauage, but for what I'm trying to accomplish clojure is much better |
| 22:39 | phil | Raynes: i think the language itself is not that hard, but one has to rather adjust to the constructs around it, like if you want state you need the state monad and you need to know what monads, applicative functors etc etc are in the first place |
| 22:39 | Raynes | adam_: I'm not trying to argue Haskell vs Clojure. |
| 22:39 | brehaut | phil: thats incorrect |
| 22:39 | phil | Raynes: in a tradition language you just say a = 4, done |
| 22:39 | brehaut | the state monad is just one approach |
| 22:39 | Raynes | I'm trying to make you look stupid for saying things like "[21:34:31] <adam_> yeah, and get your phD in functional languages" |
| 22:39 | phil | brehaut: i was oversymplyfing |
| 22:39 | brehaut | io, ST, STM monads all provide very simple approaches to state |
| 22:39 | phil | brehaut: but you need *some* monad in any case |
| 22:40 | brehaut | phil: so? |
| 22:40 | brehaut | its only hard if you want it to be |
| 22:40 | Raynes | phil: You just described functional programming. |
| 22:40 | brehaut | if you just use IO |
| 22:40 | adam_ | yeah, Rich's article on state in clojure is what really got me into it |
| 22:40 | brehaut | then you are writing slightly quirky C code |
| 22:40 | Raynes | $he let x = 1 in x + 1 |
| 22:40 | lazybot | ⇒ 2 |
| 22:40 | Raynes | Done. |
| 22:40 | brehaut | Raynes: OMG head asplode. warn me next time and i'll get my PhD ready! |
| 22:41 | Raynes | :) |
| 22:41 | jeremyheiler | i always thought haskell's syntax was driven by being somewhat notational. |
| 22:41 | jeremyheiler | and not something so terse it's hard to understand ( although it could get crazy) |
| 22:42 | Raynes | They have a Perlish fetish of symbols. |
| 22:42 | brehaut | jeremyheiler: i think the trickiest thing is grasping how pervasive partial application is |
| 22:42 | brehaut | and how operator binding interacts with parenless application |
| 22:42 | jeremyheiler | brehaut: yeah, i think i'll agree with you on that point |
| 22:42 | phil | Raynes: come on... but what happens if you want to manage a widget hiearchy for example? to add a subwidget to a widget you have to first know the path to that widget or use some other construct like a zipper, than replace it, then update some state monad holding the widget hierarchy you have to pass in to the add-subwidget function etc etc etc |
| 22:42 | phil | as opposed to just addWidget(widget); |
| 22:43 | brehaut | jeremyheiler: i think the hardest thing about typical stateM tutorials is that they brush over that they are using a partially applied type constructor ;) |
| 22:43 | Raynes | phil: Learning to program. |
| 22:44 | phil | Raynes: so if you dont use a state monad + tree zipper for managing a widget hierarchy you cant program? |
| 22:44 | brehaut | wait. not type constructor, field accessor |
| 22:44 | Raynes | No, not what I'm saying. |
| 22:44 | TimMc | brehaut: I got a taste of the partials stuff when I dabbled in OCaml. |
| 22:44 | brehaut | TimMc: its pretty addictive eh |
| 22:44 | TimMc | Hard to read when you're just coming from a sexp language. |
| 22:45 | TimMc | I had trouble with it, but mostly for visual/syntactic reasons. |
| 22:45 | Raynes | When you learn to program, both of those sets of concepts are equally unapproachable. Once you've learned to program in x way, y starts to look insane because you know how to do the same thing in the x way. |
| 22:45 | brehaut | phil: why do you keep insisting that state monad is hard to use? |
| 22:46 | phil | Raynes: but would you say that approach A may be better suited to some problems while approach B to others, or is one approach always better? |
| 22:46 | brehaut | phil: learning how the machinary works can be difficult, but then, its no different than learning how the interpreter for an imperative language works |
| 22:46 | Raynes | My approach in life has been to learn things as I go. When I need something that I don't understand, I just learn it. I don't waste time comparing it to other things. |
| 22:46 | Raynes | Sure. |
| 22:46 | phil | brehaut: im not saying it is "hard" to use, its just a lot of extra work for something very simple in an imperative mutable langugae |
| 22:46 | Raynes | I'll reiterate that I am not arguing Clojure vs Haskell. |
| 22:47 | Raynes | I'm arguing that it is only hard if you compare it to what you already know. |
| 22:47 | Raynes | When I first drove a stick, I was terrified and frustrated because it was so easy to drive an automatic. |
| 22:48 | Raynes | Are manual transmissions worse than automatic transmissions because I learned on an automatic? |
| 22:48 | phil | Raynes: im not arguing a > b either, im also constantly questioning things... just at the moment i cant say im convinced pure fn programming is the answer to everything |
| 22:48 | Raynes | I can't say I am either. |
| 22:48 | Raynes | On that we agree. |
| 22:49 | adam_ | Raynes, we're just trying to compare languages, and you're making arguments for argument sake |
| 22:50 | Raynes | Actually, I've pointed out at least twice that I am not comparing languages and phil still responded to me, indicating to me that he wasn't just comparing languages. *shrug* |
| 22:50 | Raynes | I thought it was a worthwhile discussion. But you're the one who brought it up. :) |
| 22:51 | Raynes | I'd use that monad. |
| 22:51 | TimMc | You just did, without knowing it! |
| 22:51 | Raynes | Bang! |
| 22:51 | adam_ | that should be the first monad you learn |
| 22:51 | phil | i just wanna hear other points of view, doesnt matter if they are "a > b" or "a != b", they open up new perspectives to think about things |
| 22:52 | phil | :D |
| 22:52 | phil | how would one define >>= on that monad :/ |
| 22:55 | brehaut | TimMc: jsut as long as you implement an instance of MonadPlus so we can fail in style |
| 22:56 | adam_ | is anyone here using monads in their clojure program? and if so, what for? |
| 22:56 | brehaut | adam_: i use them for error handling, nondeterminism, and parsing |
| 22:56 | TimMc | adam_: They're just not called monads. |
| 22:57 | adam_ | what would you call them then? |
| 22:57 | Raynes | I call them code. |
| 22:57 | TimMc | s I understand it, there are a bunch of common functional programming design patterns that Haskellers instantly recognize as monads. :-) |
| 22:58 | brehaut | (variations of maybe-m, seq-m, seq-m and for, parser-m (aka state-t seq-m)) |
| 22:58 | TimMc | I assume brehaut uses formalized versions of them. |
| 22:58 | adam_ | yeah, i mean the clojure.contrib.monads library |
| 22:58 | brehaut | clojure.algo.monads |
| 22:58 | TimMc | Ah, well that's the extent of my knowledge on monads, |
| 22:58 | brehaut | TimMc: yes |
| 22:59 | scottj | adam_: the monads library is not used very much in open source clojure code. |
| 22:59 | brehaut | TimMc: (i use the formal ones as well as the informal ideas) |
| 22:59 | TimMc | and goddamnit why does the comma have to be next to the period. |
| 22:59 | brehaut | TimMc: to increase mistakes |
| 23:00 | seancorf` | i'm looking forward to the next "Monads Made Easy" talk at a Clojure conference ;) |
| 23:00 | jeremyheiler | brehaut: maybe to minimize more serious errors. |
| 23:00 | adam_ | i'll have to go then! |
| 23:00 | adam_ | i just started a monad tutorial in clojure |
| 23:00 | brehaut | seancorf`: lol |
| 23:01 | brehaut | adam_: following or writing? |
| 23:01 | adam_ | note taking |
| 23:01 | phil | brehaut: i read about cdelim this morgning |
| 23:01 | adam_ | i learn best by taking copious amounts of notes |
| 23:01 | phil | dunno what id use it for but ill think of something for sure :D |
| 23:01 | adam_ | so i guess following would be the category |
| 23:03 | brehaut | adam_: i found doing the reductions by hand made each individual monad make more sense |
| 23:04 | brehaut | (especially complicated ones like state-m) |
| 23:05 | adam_ | nice, i'm actually working through state-m right now |
| 23:51 | clj_newb | is the following correct? clojure is so amazingly smart, it forces me to use agents ... then automatically, behind my back, executeds functions went to agents, and watchers sent on agents, in separate threads -- and it can do so safely due to clojure's concurrency constructs? |