2010-12-14
| 01:10 | amalloy | is there a convenient way to tell whether (:foo some-map) returned nil because :foo is present with a value of nil or not present? |
| 01:11 | cky | amalloy: Of course there is! Just don't allow the map to contain nil, and you're all set. :-P |
| 01:11 | cky | amalloy: (Cue strategy used by Java's concurrent collections.) |
| 01:12 | amalloy | cky: psh. so you'd think, but then it turns out you have to cater to users who will have your code to sneak a nil in :) |
| 01:12 | amalloy | *hack |
| 01:13 | cky | Yipes! |
| 01:16 | technomancy | amalloy: (:foo some-map ::not-found) |
| 01:16 | amalloy | technomancy: yeah, i guess |
| 01:16 | amalloy | i was hoping for a choir of angels, i guess, or something equally magic |
| 01:17 | technomancy | CL does it with multiple return values, but that seems like an annoying special-case to have to support |
| 01:20 | amalloy | technomancy: yeah. multiple return values seem useful on the surface, but i'm pretty happy with having simple&powerful destructuring-bind instead |
| 01:21 | cky | Both have uses. |
| 01:21 | cky | Sometimes, you do need to distinguish between a list return and an MV return. :-) |
| 01:24 | amalloy | cky: you never have to distinguish. in the cases where you might want either one, just always return a list; [[1 2]] vs [1 2] is a fine distinguisher |
| 01:25 | cky | But that requires a special protocol: "always return a list/vector". |
| 01:25 | joshua__ | amalloy: you could create a choir-of-angels predicate function and have that predicate return true if it turns out the item [:symbol nil]. |
| 01:25 | joshua__ | Than do something like (some choir-of-angels your-map) ;p? |
| 01:26 | cky | I'm thinking of a generalised comp(ose) function. If you have a binary function somewhere in the chain, some way for the previous function to return two values would be nice. |
| 01:26 | cky | Without requiring all the functions in the chain to return a list, that is. |
| 01:26 | amalloy | cky: that's true, i guess |
| 01:27 | amalloy | i haven't lived in that environment long enough to see how often it's useful, but i can imagine it would be |
| 01:27 | cky | *nods* I've certainly come to discover that CL, Scheme, and Clojure programmers all think in very, very different ways, according to what their respective language affords. |
| 01:28 | amalloy | cky: i've tasted all three, but only stuck around for the second sip of clojure |
| 01:28 | cky | I certainly cannot claim to know how CL or Clojure programmers think. :-) |
| 01:28 | amalloy | it's more of a judgment on me than the languages, i think |
| 01:28 | cky | *nods* |
| 01:28 | cky | And I'm sure there are many Clojure idioms that I have yet to appreciate, for sure. |
| 01:29 | amalloy | since i tried scheme...eight years ago, and CL during a depressive phase |
| 01:29 | cky | Hahahahaha. |
| 01:30 | amalloy | cky: the elegant clojure trick that still blows my mind is http://rosettacode.org/wiki/Fibonacci_sequence#Clojure |
| 01:30 | joshua__ | cyk: Watching the videos of the things clojure has to offer is sort of odd for me. I'm like, "wow this stuff is all so neat I wonder when I'll use some of it." |
| 01:32 | cky | $source iterate |
| 01:32 | sexpbot | iterate is http://is.gd/iImcN |
| 01:33 | cky | amalloy: That's pretty neat. I'm going to see what iterate is all about. :-P |
| 01:33 | amalloy | joshua__: most IRC clients have a tab-completion feature for nicks, so that you don't have to spell out the name (i mention this because you got cky wrong, no offense intended) |
| 01:33 | cky | Hahaha, Clojure implements what's known as "odd streams". |
| 01:34 | cky | I hear (but am not knowledgeable enough about streams to say anything authoritative) that odd streams are problematic, and that even streams don't have those problems. |
| 01:35 | cky | The automatic use of lazy-seq for things like map, etc. is pretty neat, though. |
| 01:36 | joshua__ | amalloy: Thank you so much, that is such a nice feature. |
| 01:36 | amalloy | cky: i don't know anything about stream modulo, i'm afraid |
| 01:38 | cky | The Rationale section of http://srfi.schemers.org/srfi-41/srfi-41.html describes the two concepts, but their ramifications go way over my head. |
| 01:38 | amalloy | joshua__: use enough unix tools regularly, and you find yourself hitting tab whenever you don't feel like typing, just in case it works |
| 01:38 | amalloy | cky: yeah, the lazy-seqs everywhere make TCO a much less pressing feature |
| 01:38 | mabes_ | Rich's thoughts on it from 2008: http://groups.google.com/group/clojure/browse_thread/thread/d94f9434155703fd?pli=1 |
| 01:39 | cky | mabes_: Thanks for the link. |
| 01:39 | hiredman | thats outdated |
| 01:40 | mabes_ | figured |
| 01:40 | hiredman | clojure seqs are full lazy, baring chunking |
| 01:40 | amalloy | cky: it looks like you can make clojure seqs even or odd, and odd is the default in things like map |
| 01:40 | technomancy | interesting that the laziness semantics changed twice about a year apart |
| 01:42 | cky | *nods* |
| 01:42 | amalloy | er, even is the default, rather. because they look like (delay (cons 1 (delay (cons 2 (delay ()))))) |
| 01:43 | amalloy | you happened to look at iterate, which puts x first in a non-lazy way, because x is already known |
| 01:45 | cky | Ah, okay. |
| 01:54 | notsonerdysunny | Can I have protocols dispatch on the types of the arguments ..? |
| 01:54 | notsonerdysunny | or does it necessarily have to be only the arity? |
| 01:56 | raek | only dispatch on the first type (one per arity) |
| 01:57 | raek | i.e. the way java methods work |
| 01:59 | notsonerdysunny | raek .. I am not familiar with java .. but what exactly I want is .. let us say I have complex data type which defines the function * .. I would like * to work different depending on whether both arguments are complex or if one of them is a real number .. how can I achieve this? |
| 01:59 | raek | sounds like a use case for multimethods |
| 01:59 | notsonerdysunny | I come from C++ is it similar to c++ |
| 02:00 | raek | yes |
| 02:00 | raek | the restrictions of what protocols dispatch on, that is |
| 02:01 | notsonerdysunny | in c++ I can do this using method overloading .. I can have (* complex complex) (* complex int) can this be done with protocols? |
| 02:03 | raek | hrm, I don't think so (someone, please correct me if I'm wrong) |
| 02:03 | raek | if my assumption is correct, protocol methods are only Objects to Object |
| 02:05 | raek | notsonerdysunny: you might be interrested in this: http://clojuredocs.org/clojure_contrib/clojure.contrib.generic.arithmetic |
| 02:06 | raek | there you could define a method for [::complex ::complex] |
| 02:08 | dnolen | raek: notsonerdysunny: something like can be done with definterface and type hints. |
| 02:08 | dnolen | https://gist.github.com/740099 |
| 02:09 | notsonerdysunny | what do I gain from using protocols over definterface? |
| 02:09 | notsonerdysunny | to me they almost seem interchangable |
| 02:09 | dnolen | notsonerdysunny: definterface is low level, not fns. |
| 02:10 | dnolen | note that I call mehthods not fns. |
| 02:10 | zmyrgel | If I have (:use (foo bar)) in my baz file's ns macro, shouldn't the baz be able to resolve class name of record defined in foo/bar.clj? |
| 02:11 | opqdonut | no, you need to import that class separately |
| 02:11 | opqdonut | and, get this, import it after the use |
| 02:11 | raek | the definterface way has one restriction that the multimethod way has not: you have to enumerate all type combinations. it is not possible to add one case later. |
| 02:11 | opqdonut | or just use the fully qualified name foo.bar.Record |
| 02:15 | zmyrgel | hopefully clojure namespace handling gets simpler in the future... |
| 02:17 | raek | another common solution (which has other benefits as well) is to expose a constructor function to the lib users, rather than making them calling the record constructor themselves |
| 02:18 | replaca | anyone hanging out here you uses both paredit and tmux? |
| 02:18 | zmyrgel | I use constructor function with my other class |
| 02:26 | notsonerdysunny | thanks dnolen .. I think your gist helps .. |
| 02:26 | notsonerdysunny | Thanks raek .. |
| 02:27 | notsonerdysunny | would you expect interfaces to be more efficient when compared to protocols.. |
| 02:28 | dnolen | notsonerdysunny: I would still do it with protocols and use instance? |
| 02:29 | dnolen | notsonerdysunny: https://gist.github.com/740099 |
| 02:29 | dnolen | definterface 1 second vs. protocols 13ms for 1e6 iterations |
| 02:29 | dnolen | because of reflection |
| 02:30 | dnolen | sleep time for me, hope that helps. |
| 02:31 | notsonerdysunny | thanks dnole |
| 02:31 | notsonerdysunny | good night |
| 02:31 | notsonerdysunny | thanks dnolen |
| 02:36 | amalloy_afk | notsonerdysunny: i wouldn't put a lot of weight behind dnolen's benchmark - it looks like he threw it together in a hurry, and it's not comparing anything meaningful |
| 02:37 | amalloy_afk | or maybe i'm just having trouble reading it |
| 02:40 | amalloy | eg the JIT won't be warmed up while definterface is running, but i think most of my other objections were misunderstandings. sorry dnolen! |
| 02:41 | LauJensen | amalloy: There a blogpost on benchmarking on Best In Class :) |
| 02:41 | amalloy | LauJensen: augh, will i never escape from my one careless remark!? :) |
| 02:42 | LauJensen | No! But, I have noticed that you're giving superior advice these past days :) |
| 02:42 | amalloy | LauJensen: i haven't read BIC for a couple weeks...maybe that's it |
| 02:43 | LauJensen | Aah. I see you make me regret paying a compliment. I wont repeat the mistake |
| 02:44 | LauJensen | (read that in a repressed angry japanese accent) |
| 02:44 | amalloy | *chuckle* |
| 02:50 | notsonerdysunny | https://gist.github.com/740122 |
| 02:50 | notsonerdysunny | It is unable to resolve the record name complex when I compile the tt1.clj file .. can anybody tell me as to where I am making a mistake? |
| 02:52 | tomoj | "foo." is a mark of java |
| 02:52 | tomoj | you need to import the class, not require |
| 02:53 | notsonerdysunny | ah thanks ..! |
| 02:53 | tomoj | in the case where you want both the constructor and the methods you have to both import and require |
| 02:53 | notsonerdysunny | oh ic |
| 02:54 | tomoj | better to just define a factory fn and require it all? |
| 02:54 | notsonerdysunny | I don't quiet get what you said last.. |
| 02:58 | tomoj | I mean, often you end up needing a factory fn anyway, some fn in the namespace that calls the constructor but is more convenient |
| 02:58 | tomoj | if so, you don't need to import the constructor because you can require the factory fn along with the methods |
| 02:59 | notsonerdysunny | ah ic .. thanks tomoj |
| 03:06 | notsonerdysunny | tomoj .. can you tell me as to how interface differs from protocols .. Is there a difference btw methods and functions? |
| 03:07 | tomoj | difference between interface methods and protocol functions? |
| 03:07 | raek | methods are not function objects, so you cannot pass them around as arguments to function, store them in variables, etc |
| 03:07 | raek | protocol methods are clojure functions too |
| 03:08 | raek | so defprotocol will def a number of functions on the current namespace |
| 03:09 | notsonerdysunny | yes tomoj .. that is what I meant to ask .. but I think raek's responses clear things up... |
| 03:10 | raek | also, when you call a java method without knowing which one of the overloaded variants that applies, clojure will generate code for looking up that at runtime |
| 03:12 | raek | when a call is made, it needs to iterate over the possible variants of the method in the interface and select the one that matches the types of the objects that you passed in that case |
| 03:12 | notsonerdysunny | so bottom line is if one does not care about storing the functions and passing them around as arguments to other higher-order-fns then definterface gives a better flexibility in terms of dispatch |
| 03:13 | raek | well, multimethods are always more flexible |
| 03:14 | raek | also, you need to create some "dummy object" that the method is invoked on, if you use the definterface aproach to your problem |
| 03:14 | raek | (.plus dumme-object float-argument complex-argument) |
| 03:15 | raek | and because of the reflection invloved, you won't get the performance that you usually expect with non-reflective method calls and protocol calls |
| 03:16 | raek | but, yes. definterface allows you to overload on type. |
| 03:16 | notsonerdysunny | so would definterface give me better performance than multimethods in this kind of dispatch? |
| 03:17 | raek | that's a good question... :) |
| 03:17 | raek | *measured |
| 03:19 | notsonerdysunny | Thanks raek .. |
| 03:20 | notsonerdysunny | It looks like finally things are falling in place |
| 03:21 | tomoj | if your choice between definterface and multimethods is about performance, mustn't you be pretty far along? |
| 03:24 | notsonerdysunny | It looks like I have to just use multimethods and stop worrying about performance .. until I am done ..:) |
| 03:24 | raek | (my feeling is that multimethods should have similar or better performance compared to reflective method calls. however, it would be nice if I could justify that feeling experimentally... :-) ) |
| 03:27 | amalloy | notsonerdysunny: i have the same feeling raek does. multimethods must be faster than plain reflection |
| 03:36 | raek | ...and the results! https://gist.github.com/740151 |
| 03:37 | raek | (criticism of the test is welcomed) |
| 03:38 | raek | notsonerdysunny: no matter whether flexibility, elegance or performance is concerned, it seems that multimethods is the winner for this problem |
| 03:56 | amalloy | raek: can't you avoid the reflection warnings in the interface version by type-hinting dummy? |
| 03:57 | amalloy | (add a comma before dummy if you prefer disrespectful suggestions( |
| 03:58 | raek | :) |
| 03:59 | raek | in the general case, the compiler would still not know the types of the two arguments at compile time (which was the point in this case) |
| 03:59 | raek | hinting with ^MixedAdditionImpl didn't change anything in my benchmark |
| 04:00 | amalloy | fair enough |
| 04:01 | raek | of course, hinting all the args gets the reflection away, ("Elapsed time: 57.745888 msecs"), but then one could as well have written two separate functions (since one knows the type in advance) |
| 04:01 | amalloy | raek: sure |
| 04:02 | amalloy | i just wanted to make sure there was no incidental complexity |
| 04:03 | raek | I appreciate the skepticism. :) |
| 04:03 | raek | or criticism... |
| 04:15 | amalloy | raek: speaking of criticism, http://is.gd/iIGFt seems to think i was unkind in http://is.gd/iIGOg - is he overreacting, or was i undiplomatic? |
| 04:18 | ejackson | Good Morning |
| 04:59 | kotarak | amalloy: He's certainly speaking about the second message. Which could be considered "undiplomatic" by a very small degree. All-in-all I think he's overreacting. |
| 06:52 | nunb | anyone using moustache for writing webapp routes? |
| 06:52 | nunb | experiences/kudos/gripes? |
| 06:54 | bsteuber | nunb: didn't use it a lot yet, but it works out nicely so far |
| 06:56 | kotarak | nunb: use it several times in smaaaall projects. Worked quite well so far. |
| 07:21 | raek | nunb: complete documentation. *everything* can be read from the grammer. I like it very much. |
| 07:22 | raek | my personal experience is that I tend to write complete handlers (modulo the stuff that I factor out into middleware) outside the routes, and only use moustache to select the right handler |
| 07:46 | GOSUB | nunb |
| 07:51 | fogus` | GOSUB: Good luck. That is a tough talk to give. :-) |
| 07:51 | GOSUB | fogus`: hehe, thanks. but I stand on the shoulders of giants :) |
| 07:52 | fogus` | GOSUB: Well, I'm sure you will be fine. It's the audience that is the tough part. |
| 07:56 | GOSUB | fogus`: I agree. This is going to be mostly Java people. |
| 07:56 | GOSUB | fogus`: I thought instead of doing a intro talk, it's better to talk about a problem they might understand. |
| 07:57 | GOSUB | fogus`: btw, is there a problem with the video of your talk on blip.tv? seems to be just about 18 mins in duration. |
| 07:57 | fogus` | No idea. I haven't watched it. |
| 07:57 | GOSUB | ok |
| 07:57 | cemerick | GOSUB: knock 'em dead :-) |
| 07:58 | GOSUB | cemerick: haha, don't want to kill those poor masochists :) |
| 07:59 | GOSUB | Java programmers remind me of Silas. |
| 07:59 | cemerick | GOSUB: hrm; ok, knock 'em into a delirious wonder, from which they'll emerge transformed. |
| 07:59 | GOSUB | cemerick: that, indeed, is the intention :) |
| 08:00 | GOSUB | will Clojure 1.3.0 be released within the next couple of weeks? |
| 08:00 | cemerick | almost assuredly not |
| 08:01 | GOSUB | cemerick: ah, these are just the alphas. the betas and RCs are yet to come. |
| 08:01 | cemerick | yeah, we've a ways to go. I'm hoping it gets tied up before, say, May |
| 08:02 | GOSUB | cemerick: hmm. are we expecting a lot of breaking changes from now? what features are in the pipeline? |
| 08:02 | GOSUB | basically I was wondering if we could start using 1.3.0-alpha-x for a new project. |
| 08:03 | cemerick | As far as features, anything @ http://dev.clojure.org/display/design/Home is presumably on the table, at the very least. |
| 08:03 | GOSUB | ok |
| 08:03 | cemerick | I was in production with 1.2.0 SNAPSHOTS before 1.1.0 was released, so… ;-) |
| 08:04 | GOSUB | wooh, async IO! |
| 08:05 | GOSUB | cemerick: you have titanium balls! |
| 08:06 | cemerick | lol |
| 08:06 | cemerick | GOSUB: you, sir, have a way with compliments! |
| 08:06 | GOSUB | cemerick: please don't mention it :) |
| 08:28 | fogus` | Sigh. The "Implementing multimethods in pure Clojure" thread had great potential. |
| 08:30 | GOSUB | cemerick: is there any way to tell jetty to reload a war once it has been modified (replaced by a new one) |
| 08:33 | cemerick | GOSUB: I believe there's a autodeploy option that will watch for new/updated war files in the designated directory. |
| 08:34 | GOSUB | cemerick: ok. checking. |
| 08:35 | GOSUB | cemerick: there seems to be some Maven plugin to do this. |
| 08:36 | GOSUB | cemerick: how would you recommend doing deployments without restarting the app? |
| 08:36 | cemerick | jetty-maven-plugin, sure, but that's at dev time -- I thought you were talking about in production |
| 08:36 | GOSUB | cemerick: yes, we need this feature for production. |
| 08:36 | cemerick | GOSUB: reloading a war implies restarting the app, though not necessarily restarting the container |
| 08:37 | GOSUB | cemerick: yes, we would want to restart the app, without restarting the container. |
| 08:38 | karmazilla | the way one usually does it involves having more than one server |
| 08:38 | GOSUB | karmazilla: fiddling with the load balancer config? |
| 08:38 | karmazilla | yes |
| 08:39 | GOSUB | karmazilla: that's one way for sure. but I am looking at some other ways. |
| 08:40 | cemerick | GOSUB: I agree with karmazilla. There are ways to do hot-deploy, but they vary from container to container. Check out the maven cargo plugin, which attempts to provide a common API and goals for such things. |
| 08:40 | GOSUB | cemerick: OK. is that plugin fine for production? |
| 08:41 | cemerick | GOSUB: I've only fiddled with it before. Restarting the container has always suited my needs. |
| 08:41 | GOSUB | cemerick: OK. |
| 09:15 | bobo_ | anyone got a tip for a small example task to show protocols or OO in general in clojure? something that you can write in 20mins or so |
| 09:19 | dnolen | bobo_: http://clojure.org/runtime_polymorphism, http://clojure.org/multimethods are good places to start first. |
| 09:19 | bobo_ | im trying to come up with some small tasks for the user group meeting tonight |
| 09:20 | chouser | bobo_: Implementing a Clojure print fn can be instructive, if a bit navel-gazing |
| 09:21 | dnolen | bobo_: personally I don't reach for protocols unless I'm pretty certain about the domain or performance is really a concern up front (I'll be generating millions instances even in small programs). |
| 09:21 | bobo_ | print sounds like a good idea, printing time maybe. to be able to take long and date or whatever |
| 09:21 | dnolen | bobo_: also I think multimethods are considerable easier to explain than protocols and defrecord/type anyhoo. |
| 09:22 | bobo_ | yes i agree, i like multimethods |
| 09:22 | chouser | oh, but that's polymorphism in particular. Just printing won't touch other OO concepts much. |
| 09:22 | gtrak | encapsulation? |
| 09:22 | gtrak | what else is there? |
| 09:23 | gtrak | encapsulation is just a function calling other functions :-) |
| 09:23 | bobo_ | i liked the talk about the expresion problem, cant remember who gave it but anyway, should say something about that |
| 09:24 | chouser | bobo_: you might choose to not call it the expression problem. LtU picked apart that particular term more than the talk itself. |
| 09:24 | bobo_ | realy? |
| 09:24 | bobo_ | and i see now you gave the talk ofc :-) |
| 09:24 | GOSUB | bobo_: http://freegeek.in/blog/2010/05/clojure-protocols-datatypes-a-sneak-peek/ |
| 09:25 | chouser | http://lambda-the-ultimate.org/node/4136 |
| 09:25 | clojurebot | #<RuntimeException java.lang.RuntimeException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated> |
| 09:25 | GOSUB | chouser: what do you think about Odersky's comment? |
| 09:25 | dnolen | chouser: ha, you mean Odersky mostly. I didn't that argument at all. "If it's harder to implement because of my static type system. It's not the same problem" |
| 09:26 | GOSUB | dnolen: I think he was trolling. |
| 09:26 | dnolen | GOSUB: totally. |
| 09:26 | GOSUB | dnolen: especially since he never defended his statement again. |
| 09:27 | dnolen | GOSUB: well, I'm sure he's a busy guy with better things to do than read LtU all the time. |
| 09:27 | chouser | Mostly it doesn't matter to me. I called it the expression problem because I thought that was what people called it. But regardless of its name, it *is* a problem that many languages have only poor solutions to. |
| 09:27 | GOSUB | chouser: let's call it "Strawman Problem" for our purposes. |
| 09:27 | GOSUB | or may be "Problem #X" |
| 09:27 | cemerick | We could just call our version of the expression problem the Odersky Problem. |
| 09:27 | chouser | right |
| 09:27 | chouser | heh |
| 09:28 | GOSUB | cemerick: haha |
| 09:28 | clojurebot | #<RuntimeException java.lang.RuntimeException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated> |
| 09:28 | GOSUB | someone please fix clojurebot |
| 09:28 | cemerick | I wonder if hiredman is up yet to fix clojurebot |
| 09:30 | GOSUB | chouser: are your slides from the strangeloop talk up somewhere? I am talking about the expresion problem on Saturday, may be I could draw some inspiration. |
| 09:31 | chouser | GOSUB: http://talk-expression-problem.heroku.com/#1 |
| 09:31 | dnolen | chouser: btw, any plans for implementing Finger trees with primitive arrays at some point? |
| 09:31 | clojurebot | #<RuntimeException java.lang.RuntimeException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated> |
| 09:31 | GOSUB | chouser: great. thanks. |
| 09:32 | chouser | dnolen: hm, nope. I'm not sure where I'd use them. |
| 09:32 | chouser | dnolen: you have an idea? |
| 09:34 | bobo_ | chouser: i like how thoose slides look, what did you write it in? |
| 09:35 | GOSUB | bobo_: showoff. |
| 09:36 | GOSUB | bobo_: https://github.com/schacon/showoff |
| 09:36 | bobo_ | yes found it. thanks |
| 09:37 | bobo_ | promising tagline on it |
| 09:37 | dnolen | chouser: well I'm curious how well they'd perform for a miniKaren impl. PersitentHashmaps are good, but I really shouldn't need to pay the cost of hashing for what I'm doing. |
| 09:38 | dnolen | chouser: you're using vectors underneath right? Why couldn't you use arrays? (I haven't look at the theory behind FTs. So I could be way off base here) |
| 09:40 | chouser | dnolen: no, there are no vectors in the finger tree impl anymore |
| 09:41 | chouser | dnolen: there were in earlier versions, but it now uses deftypes everywhere |
| 09:43 | dnolen | chouser: oh! nice. |
| 09:45 | chouser | there's never more than 4 child nodes for any kind of node, so it was reasonable to make 4 different datatypes, each exactly the right size |
| 09:45 | chouser | (via a macro of course) |
| 09:46 | cemerick | ;-) |
| 09:47 | chouser | Mine's called Digit4 |
| 09:47 | cemerick | Generation of it via a macro puts you on the side of the light, though. |
| 09:48 | chouser | whew |
| 09:49 | cemerick | The world waits with bated breath for my approval, I know. |
| 09:54 | dnolen | translating TCO heavy code to lazy sequences is kinda ... tricky. |
| 11:22 | jcromartie | would it be good to have a background namespace loader utility? |
| 11:22 | jcromartie | like... to be reloading certain namespaces at regular intervals |
| 11:22 | jcromartie | or when changed |
| 11:23 | ohpauleez | jcromartie: How are you going to identify the namespace has changed? |
| 11:23 | chouser | lazytest:watch does that |
| 11:24 | ohpauleez | oh yes, yes it does |
| 11:24 | jcromartie | interesting |
| 11:24 | jcromartie | I guess what I'm *really* asking is: how do I get more interactivity out of my interactive development? |
| 11:25 | jcromartie | Without doing (require 'some.stuff :reload) every 5 seconds |
| 11:25 | ohpauleez | ahh |
| 11:25 | ohpauleez | good point |
| 11:25 | jcromartie | because I'm running a repl and always having to reload my code and jump into namespaces |
| 11:25 | jcromartie | I have an init.clj but (in-ns myproject.core) doesn't seem to work, so I still have to type (in-ns 'myproject.core) every time I start |
| 11:26 | jcromartie | if that's what I want to do (and it usually is) |
| 11:26 | KirinDave | Man, some truly interesting papers (and programmer-cultural observations) hanging off this article: http://gnuu.org/2010/12/13/too-lazy-to-type/ |
| 11:26 | jcromartie | I mean, (in-ns 'foo) works fine from init.clj, but it only works in that context... not the repl |
| 11:26 | jcromartie | lein loads init.clj and then runs the repl, starting in 'user |
| 11:29 | jcromartie | maybe Squeak has me spoiled :) |
| 11:29 | jcromartie | I don't know of any REPL language that has that kind of instant reloading though |
| 11:29 | KirinDave | jcromartie: Erlang? |
| 11:30 | KirinDave | jcromartie: it's not "instant" in that it's two-phase, but I think that's what most people would prefer. Instant reloading could be somewhat surprising as your execution pointers fall into garbage. |
| 11:31 | jcromartie | execution what now? |
| 11:33 | KirinDave | jcromartie: Well, if you really hot-reloaded everything, your current instruction pointer (or EP, i think it's called in the erlang vm) could point to nonsense. :) |
| 11:33 | jcromartie | oh |
| 11:33 | jcromartie | I thought you were talking about Clojure |
| 11:34 | jcromartie | :) |
| 11:34 | jcromartie | that's where I lost you |
| 11:34 | KirinDave | No no. I said erlang. :) |
| 11:34 | jcromartie | right |
| 11:35 | KirinDave | Man, every rubyist I know is mad about that article. |
| 11:35 | Adamant | what article? |
| 11:35 | KirinDave | the one I posted |
| 11:35 | Adamant | the gnuu one, ok |
| 11:35 | KirinDave | http://gnuu.org/2010/12/13/too-lazy-to-type/ |
| 11:35 | KirinDave | Yeah |
| 11:35 | KirinDave | I should say "almost every" |
| 11:36 | ohpauleez | KirinDave: Thanks for the link, awesome read |
| 11:37 | KirinDave | It's funny too, because a lot of ruby metaprogramming is just pining for syntax hacking, which is just pining for lisp macros |
| 11:37 | KirinDave | It's sort of a sad day when they're convinced that programming is "dynamic" |
| 11:39 | Chousuke | I suspect the dynamic/static split occurs only because we don't yet have a good enough type system :P |
| 11:40 | cky | "We" meaning everyone other than Haskell and ML programmers, amirite? :-P |
| 11:41 | ohpauleez | haha |
| 11:41 | KirinDave | cky: No, even they have problems. |
| 11:41 | Chousuke | nah, Haskell has problems too |
| 11:41 | cky | :-P |
| 11:42 | Chousuke | I suppose ideal would be something that allows you to use arbitrary predicates |
| 11:42 | KirinDave | Chousuke: Probably. We've got to get to a point where the type system is an assist. I pine for a better evolution of what CL started |
| 11:42 | Chousuke | but I honestly have no idea how that would work in practice. :) |
| 11:43 | chouser | yes, arbitrary compile-time assertions |
| 11:43 | KirinDave | Chousuke: I mean, we have SOME ideas. :) |
| 11:44 | cemerick | Chousuke: Sounds like multimethods. In which case, the application running in production is really just a really long compile cycle. :-P |
| 11:45 | KirinDave | cemerick: If type inference is just multi-methods, a lot of people have been wasting their lives. |
| 11:45 | Chousuke | but if you could make declarations like "data structures of type Foo have the following properties: ..." and "this function takes a Foo and returns a Foo, that in addition has property X" |
| 11:45 | Chousuke | that might be interesting |
| 11:46 | cemerick | KirinDave: Insofar as desired behaviour exists that can't really be expressed statically…… |
| 11:46 | chouser | I'm more interested in "is a pain to express" than "can't be expressed" |
| 11:47 | KirinDave | cemerick: Well the whole point of the prior article is that it's actually fairly difficult to find a program that actually uses things which are unexpressable statically |
| 11:47 | cemerick | chouser: either/or :-) |
| 11:47 | KirinDave | cemerick: Most of what rubyists call dynamic are just macros that the runtime execution pays the price for. |
| 11:48 | cemerick | If that's true, then that's a problem for rubyists and their current practice. |
| 11:48 | dnolen | KirinDave: what are the rubyists mad about? most the article reiterated the kinds of analysis v8 does to get such good performance out of loosey goosey JS. types don't change much in real programs. |
| 11:48 | KirinDave | cemerick: What is difficult to express statically that is dynamic? |
| 11:48 | KirinDave | dnolen: They're mad that their assertions are being refuted. That is how the ruby community is, man. |
| 11:49 | bsteuber | does anyone know a good hadoop hosting prodiver? |
| 11:49 | chouser | the only thing about that article that bothers me is the suggestion that "dynamic" ever meant that all our arguments or containers will regularly have objects of widely varying types. |
| 11:49 | KirinDave | cemerick: Sufficient syntax hacking seems to be the solution to many of those woes. |
| 11:49 | KirinDave | chouser: Yes. |
| 11:49 | KirinDave | chouser: That bothered me as well. |
| 11:50 | fogus` | Oh no!!! I ran from Twitter to avoid this conversation... :-( |
| 11:50 | KirinDave | fogus`: Trololo. |
| 11:50 | KirinDave | fogus`: But it's interesting, man. And it lets us make fun of rabid rubyists (as if excuses or permission were needed). |
| 11:51 | fogus` | KirinDave: Oh... well then proceed |
| 11:53 | fogus` | The static guys are in a tizzy about that post too. Sigh. |
| 11:53 | technomancy | jcromartie: the repl will start in the :main ns if you provide one |
| 11:53 | technomancy | you can add :skip-aot metadata to the :main symbol in project.clj in the latest from git |
| 11:54 | jcromartie | hm |
| 11:56 | fogus` | Related: OOP --> POO http://github.com/raganwald/homoiconic/blob/master/2010/12/oop.md |
| 11:58 | tgk | Does anybody know if there is an idiomatic way of constraining arguments to functions or the return type of a function? I've tried #^, bit that doesn't seem to have an effect. |
| 11:59 | amalloy | tgk: see pre/post conditions |
| 11:59 | amalloy | fogus has an article on those somewhere |
| 11:59 | amalloy | $google clojure post conditions meta map |
| 11:59 | sexpbot | First out of 376 results is: Clojure - special_forms |
| 11:59 | sexpbot | http://clojure.org/special_forms |
| 11:59 | clojurebot | #<RuntimeException java.lang.RuntimeException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated> |
| 12:00 | cemerick | KirinDave: Off the top of my head, Scala's structural typing is an example of an absolutely painful corollary to what is trivial in a dynamic language. |
| 12:01 | KirinDave | cemerick: That's not really an answer to the question though. |
| 12:01 | KirinDave | cemerick: What scala is trying to do is satisfy its type system. It's not expressing anything different from what a piece of clojure code is expressing. |
| 12:01 | tgk | amalloy: writing pre and post conditions for the types don't really seem idiomatic... |
| 12:01 | dnolen | speaking of JS, with ArrayBuffers and Object.freeze, JS is looking like a damn fine Clojure target. |
| 12:03 | cemerick | KirinDave: For that example, I defer to chouser's difficulty threshold. |
| 12:03 | KirinDave | cemerick: But that's not inherent to static typing. :) |
| 12:04 | KirinDave | cemerick: That's inherent to scala's specific implementation. |
| 12:04 | KirinDave | cemerick: That said, I bet the numbers for structural typing are smaller than they are for multiple dispatch patterns, for example. |
| 12:04 | dnolen | tgk: what's not idiomatic about them? |
| 12:05 | tgk | dnolen: I guess idiomatic isn't the right word. I would just think (and I seem to remember) that there is some shorthand for restraining types. |
| 12:06 | dnolen | tgk: defrecord/type + protocols is another way. |
| 12:07 | dnolen | constrain on the first argument. |
| 12:07 | dnolen | tgk: multimethods yet another way, constrain on all arguments. |
| 12:07 | tgk | dnolen: Okay, but multimethods seems like overkill if there is only one implementation |
| 12:08 | dnolen | tgk: then use defrecord + protocol. call a protcol fn w/ the wrong type will always throw an error. |
| 12:09 | tgk | dnolen: Okay, I guess that's going to be my solution. I'll try it out, thanks. |
| 12:09 | jcromartie | so are there any tips or tricks on clojure + slime to make me more productive? |
| 12:09 | amalloy | jcromartie: use clojure and slime. each should make you a lot more productive |
| 12:09 | jcromartie | yeah :) |
| 12:09 | jcromartie | I've been using lein repl |
| 12:10 | jcromartie | but now I'm using slime |
| 12:10 | amalloy | are you familiar with emacs already, or starting anew there too? |
| 12:10 | jcromartie | at first I was like: lein repl |
| 12:10 | jcromartie | but now I'm all like: lein swank; M-x slime-connect |
| 12:10 | fogus` | tgk: http://blog.fogus.me/2009/12/21/clojures-pre-and-post/ but I suspect you mean something else |
| 12:10 | jcromartie | I am familiar with Emacs, but not Slime. |
| 12:11 | amalloy | C-c C-k compiles the current input file; C-c M-p sets the repl's ns to the ns of the current file; C-c C-m macroexpands the form at point |
| 12:11 | tgk | fogus: yeah, I was hoping for some shorter way of doing it, but thanks :) |
| 12:11 | jcromartie | amalloy: wow, those are great |
| 12:12 | amalloy | in the repl, M-p and M-n for command history; i'm not sure if that's a "given" in any emacs context |
| 12:12 | cemerick | tgk: type hints will constrain the types allowed within an *interop* form, and you can use cast to ensure return types |
| 12:12 | cemerick | The latter is very rarely used. |
| 12:12 | amalloy | in source files, M-p and M-n jump to compile errors |
| 12:13 | jcromartie | and now I'm all like: C-h m |
| 12:13 | jcromartie | :) |
| 12:13 | jcromartie | hm |
| 12:14 | jcromartie | seems C-c C-k is broken: Wrong number of args (4) passed to: basic$eval635$compile-file-for-emacs |
| 12:14 | amalloy | whoa what |
| 12:14 | amalloy | i know nothing about this (technomancy?), but it sounds like a slime/swank/emacs version mismatch somewhere |
| 12:14 | jcromartie | maybe something is out of date |
| 12:14 | jcromartie | yah |
| 12:15 | amalloy | jcromartie: oh, C-c C-e to eval an arbitrary clojure form in the minibuffer if you don't want to go all the way to the repl |
| 12:15 | jcromartie | "Versions differ: 20091016 (slime) vs. nil (swank). Continue? (y or n)" |
| 12:16 | jcromartie | In my project.clj :dev-dependencies [[leiningen/lein-swank "1.1.0"]] |
| 12:16 | amalloy | no swank at all, huh? maybe get a fresh copy of swank-clojure package from elpa? |
| 12:16 | jcromartie | I guess that's really out of date |
| 12:17 | amalloy | (and of course C-x C-e to eval the clojure form before point, just like regular lisp or .emacs editing) |
| 12:22 | jcromartie | what do you all have in project.clj for lein-swank? |
| 12:23 | amalloy | jcromartie: i think you want swank-clojure? |
| 12:23 | amalloy | :dev-dependencies [[swank-clojure "1.2.0"] ...] |
| 12:23 | jcromartie | buh |
| 12:23 | jcromartie | yeah I do |
| 12:23 | dnolen | Emacs is also a pretty killer way to work through rhickey's bookshelf. I got SWI-Prolog, Racket, Haskell, SML/NJ REPL all running together. |
| 12:23 | jcromartie | I've slapped my project.clj together from various Github REAME files |
| 12:23 | ejackson | dnolen: lol |
| 12:23 | ejackson | your brain must be muuuuuush |
| 12:24 | dnolen | :D |
| 12:25 | jcromartie | wow this is such an improvement |
| 12:25 | jcromartie | especially for debugging compilation |
| 12:25 | fogus` | dnolen: Been there, done that... still have the scars. :p |
| 12:25 | amalloy | jcromartie: i don't know if lein has a "global project", but with cake i can put that dev-dependency in ~/.cake/project.clj and forget about it; it gets magically loaded as a dep in every project |
| 12:25 | dnolen | fogus`: really? |
| 12:26 | jcromartie | amalloy: is cake a competitor to lein or what |
| 12:26 | technomancy | jcromartie: "lein install swank-clojure 1.2.0" will install it across the board |
| 12:27 | amalloy | jcromartie: more or less. they're cooperative competitors, in that they're largely drop-in compatible with each other |
| 12:28 | jcromartie | ah |
| 12:28 | fogus` | dnolen: I once had all manner of things working through Emacs... but I've cleaned up since then |
| 12:29 | amalloy | so it's not hard to try out the other one: if you're used to lein and want to try cake, you can more or less just install cake, then replace "lein" in all commands with "cake", or vice versa if you're used to cake |
| 12:30 | dnolen | fogus`: what was the problem? Not sure how to work with the the different langs with a reasonable REPL experience otherwise. |
| 12:31 | jweiss | anyone had a problem with emacs-starter-kit where if you do slime-connect, it says it connects, but there's no *slime-repl clojure* buffer? |
| 12:31 | fogus` | dnolen: No problem. Just rearranged my emacs cfg around and left a lot of stuff out. I add it back in as a find the need for it. |
| 12:32 | technomancy | jweiss: it's possible to install slime without slime-repl |
| 12:33 | jweiss | technomancy: hm that might have been it |
| 12:33 | dnolen | fogus`: yeah I don't do that stuff by hand anymore. I lean on customize-mode. |
| 12:34 | jcromartie | does this apply to swank-clojure? http://common-lisp.net/project/slime/doc/html/Examining-frames.html#Examining-frames |
| 12:36 | amalloy | jcromartie: not yet, i think |
| 12:37 | jweiss | technomancy: what is the autocomplete feature that i'm seeing in C-x C-w? i'm trying to write a new file but it insists on completing the name of an existing file when i hit enter. |
| 12:38 | scottj | jcromartie: v works and there there was a way to eval stuff in the top frame I think |
| 12:38 | amalloy | jcromartie: http://georgejahad.com/clojure/emacs-cdt.html is crazy awesome for a bit more time investment |
| 12:39 | amalloy | personally i've found the learning curve steep enough to discourage me, since my projects aren't complicated enough to need it |
| 12:42 | scottj | jcromartie: re clojure + slime tips/tricks, I made some screencasts at http://youtube.com/emailataskcom |
| 12:43 | technomancy | jweiss: that's ido, hit C-f to temporarily disable it |
| 12:48 | hugod | jweiss: or C-j to use exactly what you have typed |
| 12:49 | jweiss | i see thanks. and how do i customize the starter kit? i tried adding my color settings to .emacs but that results in the starter kit not loading at all |
| 12:50 | jweiss | should i just edit init.el? |
| 12:51 | jweiss | oh i see there's a hint in the readme |
| 13:07 | jcromartie | C-c C-c is the BEST THING EVER |
| 13:07 | amalloy | jcromartie: oh, i forgot to mention that one :) |
| 13:07 | amalloy | slime is a heady experience, isn't it |
| 13:08 | jcromartie | oh, the hyperbolization of our culture... :( why do I give in |
| 13:13 | ohpauleez | jcromartie: the power of g :) http://vim.wikia.com/wiki/Power_of_g |
| 13:35 | amalloy | jcromartie: the hyperbolization of culture will lead to the death of communication! you are contributing to a world-threatening problem! |
| 13:37 | jcromartie | amalloy: it is the BIGGEST PROBLEM EVER |
| 14:17 | jcromartie | paredit in the REPL? yes |
| 14:17 | jcromartie | thank you Emacs |
| 14:21 | jcromartie | the fact that I could type this correctly, the first time, in the REPL, is thanks entirely the paredit: (db/with-conn (def data-cols (into {} (map #(vector % (map first (comp db/text-type? second) (db/columns %))) data-tables)))) |
| 14:22 | amalloy | jcromartie: plz give teh c0dez. i had trouble setting up paredit in the repl and eventually gave up |
| 14:22 | jcromartie | M-x paredit-mode |
| 14:22 | jcromartie | that's all I ddi |
| 14:22 | jcromartie | did |
| 14:23 | amalloy | iirc that caused some problems for me |
| 14:24 | scottj | I use (dolist (i '(emacs-lisp-mode-hook lisp-mode-hook lisp-interaction-mode-hook clojure-mode-hook slime-repl-mode-hook)) (add-hook i '(lambda () (paredit-mode +1)))) |
| 14:25 | amalloy | jcromartie: oh right. multi-line input becomes hard - you have to use C-o or C-j |
| 14:26 | amalloy | since the input is always well-formed, RET always sends input instead of inserting a newline so you can edit |
| 14:26 | jcromartie | hm |
| 14:27 | joshua____ | amalloy, your here often ;) |
| 14:28 | amalloy | joshua____: 100% uptime for at least two weeks :P. my bouncer never logs off |
| 14:28 | amalloy | that doesn't mean i'm actually always here, although i *think* it renames me to amalloy_ when i'm not |
| 14:28 | joshua____ | I have a question about enlive. If you have lets say one link and you want to transform that into two different links that are seperated by a small bit of text how would you do it? Would you use clone-for? |
| 14:29 | joshua____ | amalloy, I saw you become amalloy_afk once. |
| 14:29 | amalloy | yeah, that was manual |
| 14:40 | amalloy | joshua____: i have to ask: what's with the orgy of underscores? |
| 14:43 | joshua____ | amalloy, when I logged on my name was changed to guest because I didn't register it with nickserv or something. So I tried to find a nick that didn't need to be registered. I failed. |
| 14:46 | edw | Is there a way to get locals to show up in SLIME? |
| 14:46 | edw | In it's debugger, that is. |
| 14:46 | edw | s/it's/its/ |
| 14:46 | sexpbot | <edw> In its debugger, that is. |
| 14:47 | amalloy | edw: i think you have to install/use either cdt or debug-repl |
| 14:47 | edw | Thanks! So spawn swank from debug-repl? |
| 14:48 | amalloy | heh, tbh i have no idea |
| 14:48 | amalloy | that sounds like a good plan though :P |
| 14:48 | edw | LOL. Sounds good. |
| 14:51 | hiredman | the multimethod's in clojure thread certianly shows how little people understand multimethods |
| 14:51 | hiredman | multimethods |
| 14:52 | hiredman | ~multimethods |
| 14:52 | clojurebot | multimethods is what separates the boy from the man. |
| 14:52 | amalloy | ~grammar |
| 14:52 | clojurebot | Titim gan éirí ort. |
| 14:52 | hiredman | it's chouser's or Chousuke's fault |
| 14:53 | amalloy | i shouldn't poke fun, since i like the "foo is bar" notation, and i know you have a way to avoid is, but he's so human sometimes that his mishaps look funny |
| 14:53 | hiredman | ~clojurebot |
| 14:53 | clojurebot | clojurebot has a lot of features |
| 14:54 | hiredman | clojurebot: clojurebot | has | a lot of features, most of which are broken |
| 14:54 | clojurebot | You don't have to tell me twice. |
| 14:55 | amalloy | hiredman: hey, even better than i thought it was. is the second pipe needed for some reason, or just to avoid false positives? |
| 14:59 | hiredman | amalloy: just the way I wrote the parser |
| 15:08 | tonyl | $mymail |
| 15:08 | sexpbot | From: amalloy, Time: 2010-12-14T01:16:17Z, Text: http://is.gd/iHEBY is very unsafe. this is functionally equivalent to your github password; there's a reason github asks you to keep it safe when you create it! |
| 15:08 | sexpbot | From: amalloy, Time: 2010-12-14T01:16:48Z, Text: remind me in a couple days to try defacing your account if you haven't fixed it :) |
| 15:10 | tonyl | ping amalloy |
| 15:10 | tonyl | thanks for the messages I am going to deal with it |
| 15:29 | Nikelandjelo | Swank 1.3 doesn't show stack trace on some exceptions. Is there a way to fix it? |
| 15:32 | hiredman | Nikelandjelo: swank is broken on clojure 1.3 |
| 15:34 | fliebel | Off-topic question that has been bothering me: Does anyone know if the free Amazon ec2 gives you "a free year" or "this year is free"? |
| 15:50 | jmatt | fliebel: I think it's a whole year but there are two killer conditions 1) all the good freebies require a new account 2) you have to setup a credit card in case you go over. |
| 16:26 | aria42 | r2 |
| 16:27 | tonyl | d2 |
| 16:43 | ordnungswidrig | hi all |
| 16:43 | ohpauleez | hi ordnungswidrig |
| 16:50 | alexyk | a barren Fortran-like desert, or just pre-holiday time? |
| 16:50 | tonyl | I would say pre-holiday time plus work |
| 16:52 | ohpauleez | yeah, pre-holiday |
| 16:52 | ohpauleez | for me, I'm trying to wrap up changes at work before I go on vacation/staycation |
| 16:52 | alexyk | or Tuesday just before 5pm EST |
| 16:53 | ohpauleez | ah, yes... it's nearly time for Bad Judgement Tuesday for the east coast |
| 16:53 | alexyk | ohpauleez: why is it Bad Judgement? |
| 16:53 | ordnungswidrig | can anybody help me with generation permutations by recursion in a special case? |
| 16:53 | ohpauleez | it's when you get drunk on Tuesday night |
| 16:54 | ohpauleez | because it destroys your productivity for the entire week |
| 16:54 | amalloy | ~anyone |
| 16:54 | clojurebot | Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 16:54 | KirinDave | Man, I keep kicking myself for not making my underlying implementation of clothesline monadic |
| 16:55 | ohpauleez | ordnungswidrig: What are you are trying to do and what problem do you see? |
| 16:55 | KirinDave | I will have to totally redo my state tests. :\ |
| 16:55 | KirinDave | Oh well, live and learn. |
| 16:55 | ohpauleez | KirinDave: for sure |
| 16:55 | amalloy | KirinDave: i feel like i told you to use monads, on account of monads solve everything |
| 16:55 | KirinDave | amalloy: I think the prevailing kirindavehate of the day was "why are you using macros and not arrows you fucking tard?" |
| 16:55 | KirinDave | The syntax part has worked out beautifully for the most part. |
| 16:56 | ordnungswidrig | ohpauleez: I want to create all those permutations for a collection where the first n elements of the permutation satisfy a predicate |
| 16:56 | KirinDave | I just did what was easiest at the time, but now I have all these elaborate warts in the test functions to preserve annotation results. |
| 16:56 | KirinDave | amalloy: That said, I have learned _so much_ about clojure=scala integration. What works, what does not, etc. |
| 16:56 | KirinDave | I find myself yearning desperately for a universal monadic interface and a universal function interface, even if type erasure significantly neuters them. |
| 16:56 | ordnungswidrig | ohpauleez: e.g. generate all permutations of (range 10) where the sum of the first n odd numbers is less than the sum of the first n even numbers |
| 16:57 | ordnungswidrig | ohpauleez: filtering the set of all permutation will not work because the total number of permutations is to big |
| 16:57 | alexyk | KirinDave: didn't I just see you in Scala peddling Sony migrations? Or was it a mirage? |
| 16:57 | ordnungswidrig | ohpauleez: thus i want to filter before doing the recursive call |
| 16:58 | KirinDave | alexyk: I was not peddling it. |
| 16:58 | KirinDave | alexyk: I was asking about it. |
| 16:58 | alexyk | KirinDave: yeah, tell it to the G-d of One and Only True JVM FP Language |
| 16:58 | KirinDave | alexyk: Callable is so close. :\ |
| 16:59 | alexyk | Clojure did something wrong to the brain area parsing Scala types and syntax -- it all looks gibberish now :( |
| 16:59 | alexyk | and, OO/FP type system invokes sighs and moaning :( |
| 17:00 | ohpauleez | ordnungswidrig: it sounds to me like you need to make something lazy, pass in higher order filtering functions, and then use take/repeat |
| 17:00 | alexyk | and endless seq of "why?" |
| 17:02 | ordnungswidrig | ohpauleez: a lazy sequence of all permutation will not work fine. Say, in the example above, you can dismiss all permutations starting with (9 7 0 2). Lazy is good if you need only the first n elements. I have to skip the first n elements :-) |
| 17:03 | amalloy | ordnungswidrig: he didn't say all permutations, he said "something lazy". your special lazy-recursive permutation impl can have some way to know when to not generate any more elements, |
| 17:04 | ohpauleez | right |
| 17:04 | ordnungswidrig | ok, that was wat I thought of |
| 17:05 | ohpauleez | yeah, that's the best approach I can come up with |
| 17:05 | amalloy | eg, (defn lazy-perms [pred coll] (lazy-seq (when-not (pred <previous elts>) <some recursive stuff>))) |
| 17:05 | ordnungswidrig | richt |
| 17:05 | ordnungswidrig | right |
| 17:05 | ohpauleez | right, and in another impl in my brain, you could trampoline (which you don't have to do if it's lazy) |
| 17:05 | ordnungswidrig | I'm fighting with <some recursive stuff>. |
| 17:06 | amalloy | ordnungswidrig: so pastie it up. it's tough to debug invisible code |
| 17:06 | ordnungswidrig | because i want lexical order of the permutations. In my case the evaluation of the predicate is costly |
| 17:06 | ordnungswidrig | ok, I'll paste sth. as soon as it does not work |
| 17:07 | Nikelandjelo | '(/ 1 3.75M) |
| 17:07 | Nikelandjelo | `(/ 1 3.75M) |
| 17:07 | amalloy | Nikelandjelo: & or , |
| 17:08 | Nikelandjelo | &(/ 1 3.75M) |
| 17:08 | sexpbot | java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. |
| 17:08 | Nikelandjelo | amalloy: Thanks |
| 17:13 | ordnungswidrig | here we go: https://gist.github.com/741207 |
| 17:14 | ordnungswidrig | the problem is that the result is nested sequences instead of a seq of permutations |
| 17:16 | amalloy | ordnungswidrig: ##(doc mapcat) |
| 17:16 | sexpbot | ⟹ "([f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection." |
| 17:16 | amalloy | so at the top level you want plain map, so that you get a seq of seqs; at all levels below that, mapcat to keep things from getting deeper |
| 17:17 | raek | "CoffeeScript includes a simple build system similar to Make and Rake. Naturally, it's called Cake" :/ |
| 17:18 | ohpauleez | We will wage a war |
| 17:18 | ordnungswidrig | amalloy: so i have another branch for the recursion? |
| 17:18 | ohpauleez | I don't even use Cake |
| 17:18 | ordnungswidrig | amalloy: I got it: always use mapcat but on the lowest level return [previous] |
| 17:18 | technomancy | raek: don't forget Cake the PHP framework |
| 17:19 | amalloy | ordnungswidrig: that won't work at the outermost level |
| 17:19 | amalloy | because you'll get [1 2 3 1 3 2] instead of [[1 2 3] [1 3 2]] |
| 17:19 | amalloy | so you need to do that, *and* at the outer level just use map |
| 17:19 | lancepantz | we figured they can't have both coffee and cake |
| 17:19 | ordnungswidrig | amalloy: therfor I return [previous] if rest is empty |
| 17:19 | clojurebot | Alles klar |
| 17:19 | lancepantz | i mean come on, pick one |
| 17:19 | ordnungswidrig | amalloy: I updated the gist |
| 17:20 | dnolen | I actually work at the Times with the developer of CoffeScript. Nice guy. I don't see much overlap between CoffeeScript users and Clojure users. |
| 17:21 | amalloy | ordnungswidrig: and have you tried it out? i think your change is necessary but not sufficient, so to speak |
| 17:21 | ordnungswidrig | amalloy: I tried it and it works |
| 17:21 | amalloy | well then |
| 17:21 | amalloy | mapcat to the rescue |
| 17:21 | ordnungswidrig | amalloy: I always forget about this beast |
| 17:22 | amalloy | ordnungswidrig: i often do too. you caught me at the right time, it seems |
| 17:22 | technomancy | dnolen: why's that? seems like a natural match. |
| 17:22 | ordnungswidrig | I need an emacs function that reminds me of mapcat if I work too long on a function using map |
| 17:22 | technomancy | nicer language on a widely-deployed runtime |
| 17:23 | amalloy | ordnungswidrig: once you've written it, send it to me so i can use it for (for) |
| 17:23 | ordnungswidrig | amalloy: the emacs function= |
| 17:23 | ordnungswidrig | ? |
| 17:23 | amalloy | yeah |
| 17:24 | dnolen | technomancy: it's pretty traditionally OO in design. I dunno, it's not coming from an FP point view at all. |
| 17:24 | raek | at least anonymous functions has a short syntax... |
| 17:24 | dnolen | I like it, but I also have no problems just writing plain old JS in FP style either. |
| 17:25 | ordnungswidrig | is there any work ongoing on compiling something like clojure to js? beside cic? |
| 17:25 | amalloy | $google clojurescript |
| 17:25 | sexpbot | First out of 52 results is: clojurescript at master from richhickey/clojure-contrib - GitHub |
| 17:25 | sexpbot | https://github.com/richhickey/clojure-contrib/tree/master/clojurescript/ |
| 17:26 | amalloy | i'm not sure how sophisticated it is, but... |
| 17:28 | ordnungswidrig | oh nice |
| 17:28 | amalloy | oh, and you should look at the one under clojure, not richhickey. google just wno't let go of that old, dead repo |
| 17:35 | will_l | I was trying to use memoize on a recursive method, and I'm curious about this behavior: https://gist.github.com/741240 |
| 17:38 | dnolen | now if CoffeeScript supported Dylan style macros, http://www.opendylan.org/books/drm/Rewrite_Rule_Examples |
| 17:38 | dnolen | maybe I'd get excited |
| 17:40 | ordnungswidrig | is there a function to check if a seq is sorted? |
| 17:40 | amalloy | &(doc sorted?) |
| 17:40 | sexpbot | ⟹ "([coll]); Returns true if coll implements Sorted" |
| 17:40 | amalloy | will_l: memoize creates a new copy of the function that is memoized. it can't know that foo is calling (foo) and somehow redirect that to (memoized-foo) instead |
| 17:40 | ordnungswidrig | (= coll (sort coll)) will have O(n*log(n)) but I think O(n) will do? |
| 17:42 | will_l | amalloy: so when a function is defined, it grabs hold of what it sees? Clojure doesn't do method lookup every time? |
| 17:42 | amalloy | ordnungswidrig: (every? #(apply > %) (partition 2 1 coll)) looks like a good start |
| 17:42 | amalloy | will_l: the function gets compiled, yes |
| 17:42 | will_l | amalloy: thanks |
| 17:43 | amalloy | ordnungswidrig: (modulo implementation details like using the right comparator) |
| 17:44 | amalloy | will_l: but i'm not sure you got what i meant. the point is not that foo calls (foo) and doesn't look up any new definitions of foo; it's that the definition of foo remains unchanged, and you create a new function called mem-foo |
| 17:45 | will_l | amalloy: oh. My confusion was that I was redefining foo as mem-foo, so I thought all references to the old foo were gone |
| 17:46 | amalloy | will_l: ah. then you did indeed get my point; the other thing you said was true, and is the relevant thing here |
| 17:46 | amalloy | you can force a lookup every time by calling the var instead of the function directly: (#'foo bar) |
| 17:46 | will_l | amalloy: is there a more idiomatic clojure way to do what I was trying to do? |
| 17:47 | ordnungswidrig | nice |
| 17:48 | dnolen | huh, Sealing in Dylan is pretty interesting, http://www.opendylan.org/books/drm/Sealing |
| 17:49 | amalloy | will_l: i try to avoid global memoization, since it means nobody can use your function lazily on some large number |
| 17:50 | will_l | amalloy: thanks! |
| 17:50 | amalloy | i'm not sure what you're trying to compute; you can often do stuff like this using ##(doc iterate) in some sneaky ways, but if you're just learning, you're probably better off avoiding sneakiness |
| 17:50 | sexpbot | ⟹ "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects" |
| 17:52 | will_l | amalloy: it was for http://projecteuler.net/index.php?section=problems&id=92 |
| 17:54 | amalloy | will_l: in that case, i'd forget about memoization; i doubt you're gaining that much time, and it's costing nontrivial memory |
| 17:55 | will_l | It took it from >2 min and running out of heap space to 20 seconds |
| 17:56 | ninjudd | does anyone know if server mode GC's PermGen (or more specifically classes)? |
| 17:57 | amalloy | will_l: no way it should run out of heap space; i'll throw something together and see what happens |
| 18:00 | will_l | amalloy: here's the full thing I did: https://gist.github.com/741240#file_my_full_solution.clj |
| 18:06 | amalloy | will: try (->> (range 1 1e4) (map #(iterate next-chain %)) (map #(take-while (complement #{1 89}) %)) (map (juxt identity count))) |
| 18:07 | amalloy | should tell you the length of every chain from 1 to 1000; you can easily modify it to tell you instead whether they end with 1 or 89 |
| 18:08 | amalloy | er, will_l: ^^ (i guess my version doesn't include the last number; i leave that as an exercise for the reader) |
| 18:11 | will_l | amalloy: i'm looking at it now, thanks |
| 18:17 | will_l | amalloy: thanks for your help |
| 18:38 | duncanm | in lein 1.4, how do i set compiler flags for javac? |
| 18:40 | amalloy | duncanm: it's java-opts to set java options, right? javac-opts might well work |
| 18:42 | duncanm | amalloy: doesn't look like it |
| 18:42 | amalloy | technomancy: okay, i checked that the computer was plugged in. now you debug the real problem for duncanm |
| 18:43 | duncanm | amalloy: i checked the src, it should be javac-options, lemme see if it works |
| 18:43 | duncanm | oh, so javac-options is not in [...] form |
| 18:44 | duncanm | eek, i need to know what a lancet task spec looks like? |
| 18:44 | duncanm | i just want -Xlint:deprecation |
| 18:45 | amalloy | duncanm: i also know lein respects the JAVA_OPTS environment variable; try setting JAVAC_OPTS? |
| 18:46 | duncanm | doesn't look to me it's working |
| 18:46 | duncanm | i'd be happy if there's a verbose mode and i can just try the javac command line myself |
| 18:46 | amalloy | a verbose mode? |
| 18:47 | lancepantz | duncanm: i think you can use hooks to redefine the compile task |
| 18:48 | duncanm | oh well |
| 18:48 | duncanm | i typed out the -cp part, i can see what's deprecated now |
| 18:48 | technomancy | duncanm: :javac-opts is supposed to be a map it looks like |
| 18:49 | technomancy | but I don't really know; I didn't write the javac task (since I don't know java) |
| 18:52 | cky | duncanm is alive?! |
| 18:52 | lancepantz | duncanm: wanna try with cake? |
| 18:52 | cky | duncanm: People in #scheme have been speculating on your fate. :-P |
| 18:53 | duncanm | cky: heh |
| 18:53 | duncanm | cky: been busy with work |
| 18:53 | cky | Awwww.... |
| 18:53 | duncanm | cky: is Taylor still active in the channel? |
| 18:53 | cky | Ye-. |
| 18:53 | cky | Yes. |
| 18:53 | duncanm | ah, i haven't heard from him in a while |
| 18:53 | duncanm | lemme go to #scheme ;-P |
| 18:54 | cky | :-P |
| 18:54 | technomancy | Riastradh? |
| 18:54 | technomancy | if so give him a high-five for me for paredit 22. |
| 18:54 | duncanm | technomancy: yeah |
| 18:55 | lancepantz | duncanm: in cake, you can set the :java-compile key in project.clj to a map of the options specified at http://ant.apache.org/manual/Tasks/javac.html |
| 18:55 | duncanm | lancepantz: what's cake? |
| 18:55 | duncanm | other than a tasty treat?/ |
| 18:56 | lancepantz | a lein alternative, it should be compatible with the same project.clj |
| 18:56 | lancepantz | https://github.com/ninjudd/cake |
| 18:56 | duncanm | hmm, competition! |
| 18:57 | lancepantz | competition is bad! |
| 18:57 | cky | lancepantz: That's what Oracle wants you to believe. :-P |
| 18:58 | lancepantz | hahah |
| 19:24 | duncanm | how should i test that a list consists of the same pair repeating over and over again? |
| 19:24 | duncanm | i tried (assert (= l (cycle (first l)))) but that's not quite it |
| 19:24 | duncanm | i tried (assert (= l (cycle [(first l)]))) too |
| 19:24 | amalloy | duncanm: you want to test an infinite number of pairs? |
| 19:25 | duncanm | amalloy: l is finite, right? |
| 19:25 | amalloy | ah. you mean it should consist of the same pair repeated N times, for some finite N? it reads like you meant forever |
| 19:25 | duncanm | right |
| 19:25 | duncanm | it's finite |
| 19:25 | duncanm | sorry |
| 19:26 | technomancy | duncanm: (= 1 (count (set l))) |
| 19:26 | duncanm | technomancy: cute! |
| 19:27 | amalloy | (apply = l (cycle (take 2 l))) looks good |
| 19:27 | amalloy | technomancy: that tests that it's a single item N times. i thought he meant [a b a b], not [[a b] [a b]] |
| 19:28 | amalloy | i guess my version needs a (take (count l)) around the cycle |
| 19:28 | technomancy | will = short-circuit on a lazy seq once it detects a different element? |
| 19:28 | amalloy | technomancy: yeah, it will |
| 19:28 | technomancy | ,(java.util.Date. 0) |
| 19:28 | clojurebot | java.lang.IllegalArgumentException: No matching ctor found for class java.util.Date |
| 19:29 | technomancy | huh; coulda sworn... |
| 19:29 | amalloy | &(java.util.Date. (long 0)) |
| 19:29 | sexpbot | ⟹ #<Date Wed Dec 31 16:00:00 PST 1969> |
| 19:29 | technomancy | *facepalm* |
| 19:33 | technomancy | if you did they wouldn't be so achingly stupid. |
| 19:34 | amalloy | technomancy: tell me about it. i've been dealing with java.util.Date/Calendar/UUID for weeks at work |
| 19:44 | hiredman | ping? |
| 19:44 | clojurebot | PONG! |
| 20:20 | defn_ | amalloy: defprotocol, no? |
| 20:20 | amalloy | defn_: what? |
| 20:21 | defn_ | isn't fixing java.util.Date a defprotocol away? |
| 20:22 | amalloy | i...don't really understand what you're saying, but i'm working with them in java anyway, not clojure |
| 20:24 | defn_ | oh...nevermind... |
| 20:24 | defn_ | I just saw a talk on using defprotocol to make java's Date and Time sane. |
| 20:24 | defn_ | sean devlin gave it. |
| 20:33 | hiredman | defn_: I doubt the ability of protocols to do that |
| 20:33 | hiredman | it might miake them less painful |
| 20:35 | technomancy | sane is a strong word |
| 20:35 | defn_ | i must be wearing orthopedic shoes |
| 20:35 | defn_ | because i stand corrected |
| 20:38 | gfrlog | (defn map-from-fn [f ks] (zipmap ks (map f ks))) |
| 20:38 | gfrlog | if that were in clojure.core I would use it all the time |
| 20:38 | amalloy | gfrlog: it's in clojure.contrib.generic.functor |
| 20:38 | gfrlog | I knew it must be somewhere |
| 20:39 | gfrlog | thx |
| 20:39 | amalloy | or wait, is it? i'm thinking of fmap, which i guess is different |
| 20:39 | gfrlog | yeah that looks different |
| 20:40 | gfrlog | my idea would be even cooler if it was lazy. but that would probably require a different underlying map class |
| 20:40 | amalloy | gfrlog: when i was learning clojure and proposed adding this, someone (hiredman? laujensen?) said that it's usually a bad idea |
| 20:40 | gfrlog | I can imagine the argument that you should just use the function 'f' instead of the map |
| 20:40 | gfrlog | but that doesn't work all the time |
| 20:41 | gfrlog | I'm not sure why else it would be a bad idea... |
| 20:41 | amalloy | another neat impl is (into {} (map (juxt identity f) x)) |
| 20:41 | gfrlog | yeah |
| 20:41 | gfrlog | but that's only because using juxt is always clever :) |
| 20:42 | amalloy | it's also basically the same as memoize |
| 20:42 | gfrlog | oh? is into lazy? |
| 20:42 | gfrlog | ,(doc into) |
| 20:42 | clojurebot | "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined." |
| 20:42 | amalloy | nono, i mean the whole notion |
| 20:42 | gfrlog | well not quite |
| 20:42 | gfrlog | you can pass a map somewhere, and the advantage is that it takes the keys with it |
| 20:43 | gfrlog | try passing a memoized function to (json-str) |
| 20:46 | gfrlog | map-from-fn is a terrible name though |
| 20:53 | xiackok | hi everyone |
| 20:54 | gfrlog | can any function definition be expressed as a combination of higher-order functions? |
| 20:55 | xiackok | i trying to get slime working with clojure for 6 hours. now i eating my brain |
| 20:56 | cky | gfrlog: Sure! (define cadadr (compose car cdr car cdr)). :-P |
| 20:56 | cky | gfrlog: (That's not Clojure, but you get the gist of that.) |
| 20:56 | gfrlog | what about #(% %) |
| 20:56 | xiackok | can anyone help pls |
| 20:58 | gfrlog | I suppose (apply x [x]) would work |
| 20:58 | gfrlog | no wait |
| 20:58 | gfrlog | that doesn't return a function...:( |
| 20:58 | hiredman | gfrlog: SKI says so |
| 20:59 | gfrlog | hiredman: given your name was brought up in my conversation from 5 minutes ago, I'm not sure if you're referring to that or my current mumblings |
| 21:01 | gfrlog | ooh |
| 21:01 | gfrlog | looked up SKI |
| 21:01 | gfrlog | think I have it all sorted out now |
| 21:01 | gfrlog | still working on #(% %) |
| 21:29 | duncanm | is there a way to generate a pom.xml from a lein project? |
| 21:32 | duncanm | sigh, i did a lein pom and netbeans still can't see it |
| 21:38 | duck1123 | Hey guys |
| 21:40 | bhenry | hi duck1123 |
| 21:40 | duck1123 | There was a thread on the list today about binding and lazytest, and stuarts suggestion was to use do-it, but my problem is that I can't put multiple exects inside the do-it and make the story work |
| 21:40 | duck1123 | any heavy BDD-types around? |
| 21:42 | duck1123 | would it be possible to hook the 'it' function so that I could wrap it with with-database |
| 21:54 | duck1123 | is there a version of every? that fails if the collection is empty? |
| 21:56 | dnolen | I never remember, is apply lazy? |
| 21:57 | dnolen | I would imagine not. |
| 21:57 | amalloy | dnolen: i think it's lazy enough to not realize all &rest params |
| 21:57 | amalloy | &(apply + (range 1e4)) |
| 21:57 | sexpbot | ⟹ 49995000 |
| 21:58 | dnolen | amalloy: ah great. |
| 21:59 | defn_ | anyone here intimately familiar with the innerworkings of Dylan? |
| 22:00 | defn_ | I am interested in the fact they seemed to keep s-expressions even though they switched to a more algol-style syntax |
| 22:00 | amalloy | defn_: mumble rhythmically while music plays |
| 22:00 | defn_ | hahaha |
| 22:00 | defn_ | I think it's an interesting language |
| 22:00 | defn_ | Dylan seems like the last effort to "bridge the gap" |
| 22:02 | defn_ | the algol-style syntax -- it seems actually quite a lot like Ruby in some ways -- I wonder what tradeoffs there were in that decision |
| 22:03 | amalloy | defn_: have you asked in #dylan? |
| 22:04 | amalloy | it seems like they'd know more than we do |
| 22:14 | dnolen | are rest vars allowed in protocol signatures ? |
| 22:14 | amalloy | dnolen: i don't think so |
| 22:14 | dnolen | grrr |
| 22:15 | amalloy | dnolen: protocols are for low-level impl stuff. define your protocol to take a seq as its last argument, and then provide the &rest sugar in the library layered over the protocol |
| 22:17 | dnolen | amalloy: I don't consider protocols very 'low-level'. I'm looking forward to that getting fixed. |
| 22:18 | amalloy | getting what fixed? i doubt you'll get rest args; the point of protocols is fast java interop, and the two won't play nice |
| 22:18 | amalloy | if you want fancier stuff, you probably want an interface or a multimethod |
| 22:21 | dnolen | amalloy: interfaces are less fancy then protocols |
| 22:21 | dnolen | amalloy: I recall rhickey mentioned rest vars, destructuring missing from protocols. |
| 22:22 | hiredman | dnolen: you should look at protocols in core like internal reduce |
| 22:23 | hiredman | the use doesn't call the functions defined in internal reduce |
| 22:23 | hiredman | the user calls reduce |
| 22:24 | hiredman | the point is protocols are an extender/implementer interface, with a set of functions built on top that the consumer of the library uses |
| 22:25 | dnolen | hiredman: that's useful. Holy crap ... I had no idea that nil could be used as protocol. |
| 22:25 | hiredman | the set of functions that operate on sequences can be view like this |
| 22:26 | dnolen | I'm happy to say that in my use case at least going from TCO code to lazy sequences isn't any slower, and I don't get any stack overflows. |
| 22:26 | hiredman | seq being a protocol, reduce/map/filter being what the consumer normally uses |
| 23:20 | amalloy | given an ascii/utf number (eg 10), how do i get a char (eg \newline)? |
| 23:22 | amalloy | update: i'm an idiot, it's just (char 10) and i had a bug elsewhere |