2009-11-30
| 00:01 | _ato | ,(re-pattern (str "hello" "world")) |
| 00:01 | clojurebot | #"helloworld" |
| 00:01 | _ato | :-P |
| 00:01 | _mst | even better :) |
| 00:02 | qed | ah so I should just (let [regex-pattern (re-pattern s)]) |
| 00:02 | qed | thanks |
| 00:04 | qed | if i have some list of strings |
| 00:05 | qed | how can i search that list of strings for a regex |
| 00:05 | qed | (filter #"text" coll)? |
| 00:07 | _ato | ,(filter #(re-matches #"a.*") ["apple" "cat" "dog"]) |
| 00:07 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--7967$fn |
| 00:07 | _ato | ,(filter #(re-matches #"a.*" %) ["apple" "cat" "dog"]) |
| 00:07 | clojurebot | ("apple") |
| 00:07 | _ato | ,(filter #(re-find #"a.*" %) ["apple" "cat" "dog"]) |
| 00:07 | clojurebot | ("apple" "cat") |
| 00:07 | _ato | depending on what kind of matching you need |
| 00:09 | qed | thanks _ato :) |
| 00:11 | qed | _ato: nullpointer exception |
| 00:11 | qed | anyway to avoid that? |
| 00:14 | qed | http://gist.github.com/245271 |
| 00:14 | qed | what am i doin wrong there? |
| 00:16 | _ato | what line are you getting the NPE on? |
| 00:16 | qed | (i should add (search-text "test" (tweet-text 100))) |
| 00:16 | _ato | (if SLIME is giving you some no-source file rubbish, use C-c C-k to compile) |
| 00:16 | qed | when i run (search-text "test" (twett-text 100)) |
| 00:17 | qed | i get an NPE |
| 00:17 | _ato | right, but in the stack trace, where's the NPE |
| 00:17 | _ato | or you mean it's on that line? |
| 00:17 | qed | im in a repl |
| 00:17 | qed | not sure how to find the line |
| 00:18 | _ato | it should say in the stack trace |
| 00:18 | _ato | it should at least tell you what function it's in |
| 00:18 | _ato | even if it doesn't have the line |
| 00:18 | qed | 17: user$eval__2442.invoke(NO_SOURCE_FILE) |
| 00:18 | qed | that line i hilighted |
| 00:18 | _ato | huh... that doesn't sound right :/ |
| 00:18 | qed | 0: clojure.lang.LazySeq.sval(LazySeq.java:47) |
| 00:19 | _ato | can you pastebin the whole stack trace? |
| 00:19 | qed | sure |
| 00:20 | qed | http://gist.github.com/245274 |
| 00:20 | _ato | ah |
| 00:20 | _ato | press "1" |
| 00:21 | konr | Is there any recipe to turn [1 10 100 1000] into [9 90 900]? |
| 00:21 | _ato | debugging Clojure 101: keep pressing "1" until pressing "1" is not an option. ;-) |
| 00:21 | _ato | then you'll get a more useful stack trace |
| 00:22 | _ato | 1: [CAUSE] Throw cause of this exception |
| 00:22 | _ato | ^ I mean until that line isn't there anymore |
| 00:23 | qed | 0: java.util.regex.Matcher.getTextLength(Matcher.java:1140) |
| 00:23 | _ato | right |
| 00:23 | _ato | so it sounds like you're trying to run the regex on a null string |
| 00:23 | _mst | ,(map #(apply - (reverse %)) (partition 2 1 [1 10 100 1000])) |
| 00:23 | clojurebot | (9 90 900) |
| 00:24 | rzezeski | ,(into [] (take 3 (map #(* 9 %) [1 10 100 1000]))) |
| 00:24 | clojurebot | [9 90 900] |
| 00:24 | _ato | qed: I'd guess (tweet-text) is not always returning a string |
| 00:24 | _mst | *laughs* |
| 00:24 | qed | _ato: yeah that's true |
| 00:24 | _mst | we may need more information :) |
| 00:24 | qed | is there anyway to get rid of nils before i run it |
| 00:25 | _ato | (filter #(re-find regex-pattern %) (remove nil? coll)) |
| 00:25 | qed | nice |
| 00:25 | qed | thanks _ato |
| 00:26 | _ato | ,(next (map #(* 9/10 %) [1 10 100 1000])) |
| 00:26 | clojurebot | (9 90 900) |
| 00:27 | _mst | ,(list 9 90 900) |
| 00:27 | clojurebot | (9 90 900) |
| 00:27 | _mst | maybe the input was just a decoy :) |
| 00:27 | konr | oops, I forgot to say what it was supposed to mean. I want [n1 n2 n3 n4] turned into [(- n2 -n1) (- n3 n2)] etc |
| 00:28 | _mst | this is good news for my first attempt :) |
| 00:28 | konr | ah-ha, I think _mst's answer is right |
| 00:28 | qed | ah yes, searching 10,000 tweets for "fuck" |
| 00:28 | konr | thanks! |
| 00:28 | qed | so classy |
| 00:29 | qed | thank god we have computers to let us search for curse words |
| 00:32 | qed | now i need to do something more interesting |
| 00:35 | qed | wow. people who use "fuck" in their tweets are generally trashy |
| 00:35 | qed | either trashy or emo |
| 00:41 | qed | anyone know where i can find r. hickey's jvm language summit video in full? |
| 00:44 | _ato | qed: it's on infoq.com |
| 00:44 | _ato | http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey |
| 00:44 | _ato | or do you mean there's something missing from that? |
| 00:45 | qed | found it |
| 00:45 | qed | thanks |
| 00:45 | qed | _ato: do you teach IRL? |
| 00:46 | qed | _ato: if you dont you should consider it, you are one of the most supremely patient people ive met in any community |
| 00:46 | qed | you seem passionate when it comes to showing others how things work |
| 00:47 | _ato | thanks. :-) |
| 00:48 | _ato | and no I don't teach IRL, in fact I haven't finished undergrad yet (I'm thinking of switching to a shorter degree and just graduating though, I'm getting sick of uni, so not always so patient :-P) |
| 00:48 | qed | i keep failing out |
| 00:49 | qed | i take a course and it gets me interested in some dark corner where i work and learn, not getting credit for it |
| 00:49 | qed | oh well |
| 00:49 | qed | the things i have learned which i have received no formal credit for |
| 00:49 | qed | are the most important things ive learned to-date |
| 00:52 | _ato | Yeah, I have that problem as well. Purely theoretical stuff (like proofs of correctness and such) just bore me. That's part of the reason I'm considering changing degrees, I don't think I'm really suited to academic-style research, I like research by tinkering not research by formalism. ;-) |
| 00:54 | _ato | I definitely think the CS degree was worthwhile starting with though, it meant I could skip all the zaney software engineering courses and did teach me a lot of useful stuff I wouldn't have otherwise encountered (compiler theory, automata/turing machines, lambda calculus etc) |
| 00:56 | rzezeski | can anyone point me to a function that acts like partition but doesn't truncate the remaining items? |
| 00:57 | _ato | rzezeski: sure, it's called 'partition' ;-) |
| 00:57 | _ato | ,(doc partition) |
| 00:57 | clojurebot | "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items." |
| 00:58 | _ato | give it an empty "pad" argument |
| 00:58 | rzezeski | I guess that's not in 1.0.0? |
| 00:58 | technomancy | rzezeski: maybe partition-all from seq-utils in contrib |
| 01:00 | _ato | ,(partition 3 3 [] [1 2 3 4 5]) |
| 01:00 | clojurebot | ((1 2 3) (4 5)) |
| 01:00 | _ato | ,(partition-all 3 [1 2 3 4 5]) |
| 01:00 | clojurebot | ((1 2 3) (4 5)) |
| 01:01 | _ato | looks like that does the trick for 1.0 |
| 01:03 | cgordon | I'm trying to use Leiningen, so I downloaded the latest "lein" script and ran "lein self-install". That put a jar file in ~/.m2/..., but when I run "lein new some-name", I get: Exception in thread "main" java.io.FileNotFoundException: Could not locate leiningen/new__init.class or leiningen/new.clj on classpath |
| 01:04 | cgordon | If I do a "jar tvf ..." on the lein jar file, there is no leiningen/new.clj |
| 01:05 | _ato | cgordon: lein new doesn't exist in 0.5.0 (the latest stable release) |
| 01:05 | cgordon | _ato: ah, that would explain it :) |
| 01:05 | cgordon | are there instructions somewhere for using lein with swank/slime from Emacs? |
| 01:06 | rzezeski | that'll do it, thx guys |
| 01:07 | _ato | cgordon: you don't need to do anything special with slime. Create a file project.clj with your dependencies (there's an example in the lein README). Create a directory "src" for your code. Run "lein deps" to grab dependencies and chuck them into "lib". Fire up emacs and hit M-x swank-clojure-project and give your project's directory path |
| 01:08 | cgordon | I don't seem to have a swank-clojure-project command in emacs, is that bundled with a new version of swank-clojure, or is that part of lein? |
| 01:08 | _ato | it's in a new swank-clojure |
| 01:08 | cgordon | also, where is lein getting dependencies from? Clojars? What about regular Java jar dependencies? |
| 01:09 | _ato | it checks maven central, clojars and build.clojure.org/snapshots |
| 01:09 | cgordon | _ato: thanks! |
| 01:09 | _ato | you can search maven central here: http://www.jarvana.com/ |
| 01:31 | G0SUB | I am trying to design a very simple object store using a vector where objects expire after a while and the store is replenished with new objects. |
| 01:31 | G0SUB | any idea how to manage the expiration of objects? |
| 01:41 | G0SUB | Is clojure.org down? |
| 01:46 | tomoj | doesn't seem to be |
| 02:00 | G0SUB | tomoj: hmm, it's up now. |
| 02:29 | tomoj | is there a way to get the arity of a fn? |
| 02:30 | tomoj | c.c.repl-utils/show suggests not |
| 02:33 | _ato | ,^#'inc |
| 02:33 | clojurebot | {:ns #<Namespace clojure.core>, :name inc, :file "clojure/core.clj", :line 618, :arglists ([x]), :inline #<core$fn__4729 clojure.core$fn__4729@1b0b0c1>, :doc "Returns a number one greater than num."} |
| 02:33 | _ato | hmm |
| 02:34 | tomoj | seems defn gives you :arglists |
| 02:34 | tomoj | but not on anonymous fns of course |
| 02:34 | tomoj | anyway I think I've realized I don't actually need to this anyway :) |
| 02:35 | _ato | ~count arities |
| 02:35 | clojurebot | count arities is http://groups.google.com/group/clojure/msg/fb9930ba2a25d2dd |
| 02:36 | tomoj | cool |
| 04:36 | angerman | I have a seq of line-no of a file. I want to extract. how would I do that in a memory friendly way? |
| 04:49 | AWizzArd | angerman: are you lazily reading the lines from your file? For example using duck-streams read-lines? |
| 04:49 | angerman | AWizzArd: that's what I'm trying |
| 04:51 | konr | It's my first GUI application, how can I make it not look like crap? Take a look: http://scorciapino.com/pub/fotos/peso.jpg |
| 04:54 | AWizzArd | angerman: well, then it sounds that you are already on the right path. You can use (I think from Contribs seq-utils) the function indexed and then run filter over it. This would give you all those lines you want |
| 04:55 | hiredman | http://java.sun.com/j2se/1.5.0/docs/api/java/io/RandomAccessFile.html |
| 04:57 | AWizzArd | Or maybe this is also ok for you: (filter (fn [[i line]] (when (your-set-of-lines-you-want i) line)) (read-lines "some-file")) |
| 04:58 | AWizzArd | uhm, (indexed (read-lines ...)) |
| 04:58 | _ato | angerman: if your list of line numbers is also too big to fit into memory and is sorted, you could do something like this: http://gist.github.com/245377 |
| 05:02 | noidi | konr, you could use qt4 :) |
| 05:02 | hoeck | konr: maybe use another gui toolkit, for example http://incubator.apache.org/pivot/ :) |
| 05:03 | noidi | http://qt.nokia.com/doc/qtjambi-4.4/html/com/trolltech/qt/qtjambi-index.html |
| 05:03 | konr | interesting, guys... |
| 05:04 | konr | haha |
| 05:04 | konr | http://qt.nokia.com/doc/qtjambi-4.4/html/com/trolltech/qt/qtjambi-pathstroke.html <- This certainly looks better |
| 05:05 | _ato | there's also alternative widget sets for swing: http://code.google.com/p/macwidgets/ |
| 05:10 | konr | Does QT work flawlessly in Windows XP/Vista/7? |
| 05:13 | _ato | also try: (javax.swing.UIManager/setLookAndFeel (javax.swing.UIManager/getSystemLookAndFeelClassName)) |
| 05:19 | Chousuke | konr: well, nothing ever works flawlessly, but... with the disclaimer, yes. |
| 05:20 | Chousuke | I guess there always are gotchas when writing crossplatform UIs but Qt is pretty good. |
| 05:27 | noidi | konr, one caveat regarding qt jambi: http://qt.nokia.com/about/news/preview-of-final-qt-jambi-release-available |
| 05:28 | noidi | it is no longer developed by qt software, and they will end support for it next year |
| 05:29 | noidi | I haven't followed the project so I don't know whether an open source community has taken over the maintenance or not |
| 05:32 | noidi | apparently there is already a port of Jambi for the next QT release http://qt.gitorious.org/qt-jambi/community-port-to-4_6 |
| 06:23 | AWizzArd | Chousuke: funny, what you said is impossible I think. I mean your rule/law "nothing ever works flawlessly". If this rule were true then the nothing also points to itself. So the truth of your statement leads to its untruth :) |
| 06:34 | AWizzArd | ,java.io.File/separator |
| 06:34 | clojurebot | "/" |
| 06:35 | AWizzArd | is there something like this for determine line endings on the given system, such as "\n" for Unix and Gnu, "\r\n" for Windows and "\r" for OSX? |
| 06:37 | AWizzArd | ,(System/getProperty "line.separator") |
| 06:37 | clojurebot | java.security.AccessControlException: access denied (java.util.PropertyPermission line.separator read) |
| 07:55 | AWizzArd | rhickey: Is this a new exception? java.lang.VerifyError: (class: my/namespace/program$my_fun__2984, method: invoke signature: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;) Expecting to find integer on stack |
| 07:56 | rhickey_ | AWizzArd: verify errors are my bad - what's the code/Clojure version? |
| 07:56 | AWizzArd | I get this in a loop where I have (loop [n (foo xyz)] ...) and where foo is (defn #^int foo [x] ...) |
| 07:56 | AWizzArd | When I remove the #^int return value type hint this error goes away. |
| 07:57 | AWizzArd | It is {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}, from the New branch from Thursday (Nov. 26) |
| 07:58 | rhickey_ | AWizzArd: no Clojure fn can return an int primitive |
| 07:58 | rhickey_ | your type hint is a lie |
| 07:59 | AWizzArd | ah okay, I und |
| 08:01 | chouser | rhickey_: it would be pretty easy (and apparently desirable to dysinger and other maven consumers) to use the :qualifier for the branch name. |
| 08:03 | chouser | rhickey_: just a one-line patch to each branch that seems worth naming (I was thinking master and new) |
| 08:03 | rhickey_ | chouser: fine by me |
| 08:06 | chouser | ok, thanks. I'll coordinate with dysinger |
| 08:36 | AWizzArd | Is it already possible to type hint deftypes? |
| 08:36 | AWizzArd | (deftype person [a b c]) (defn #^person foo [] ...) |
| 08:38 | chouser | AWizzArd: shouldn't be necessary |
| 08:39 | chouser | (:a (foo)) should give you field-access speed without type hints. |
| 08:40 | AWizzArd | How would it be known at compile time that foo returns a person? |
| 08:42 | rhickey | AWizzArd: what code need to know that or could leverage it? Also, person is not a class |
| 08:42 | rhickey | at least not yet :) |
| 08:51 | cemerick | rhickey: does that mean finding classes loaded in sibling classloaders? (surely not?) |
| 08:51 | rhickey | yup |
| 08:51 | rhickey | just the dynamic ones |
| 08:52 | cemerick | oh, this is only intra-clojure |
| 08:52 | rhickey | also, no-op reload of identical class, load new version of class with same name |
| 08:52 | rhickey | cemerick: yes, just for Clojure stuff |
| 08:52 | cemerick | rhickey: OK, right. Thought you were really changing the rules on us somehow. :-) |
| 08:53 | rhickey | cemerick: well, it should enable new features |
| 08:54 | rhickey | right now I'm focusing on the underpinnings of protocols/defclass, but this could e.g. support dynamic definterface |
| 08:55 | rhickey | er, deftype |
| 08:55 | rhickey | not defclass |
| 08:56 | AWizzArd | I just liked the idea to document my code with type hints. |
| 08:56 | cemerick | defclass is gone for good, right? |
| 08:56 | AWizzArd | instead (defn foo [string] ...) I prefer (defn foo [#^String s] ...) |
| 08:57 | rhickey | cemerick: it's a naming thing, certainly there's no reason for 2, deftype covers both use cases. But it looks like deftype might be able to generate what feels like a named class even in the dynamic case, including across redefs |
| 08:57 | AWizzArd | Without type hints lispers sometimes are tempted to name a var after its type. |
| 08:58 | chouser | AWizzArd: I see that in fully statically-typed code too |
| 08:58 | cemerick | rhickey: That's good, if only so that some of that naming real estate is available for people building object systems. |
| 08:58 | rhickey | AWizzArd: using type hints that way is a bad idea |
| 08:58 | chouser | AWizzArd: either with hungarian or something less formal |
| 08:59 | rhickey | cemerick: the only question would be which to choose - if types no longer need the IDynamicType stucc, i.e. are classes, is defclass the better name? |
| 09:00 | rhickey | AWizzArd: becasue type hints mean something, they are not just comments |
| 09:00 | AWizzArd | Yes, and I would only pass in the right types. |
| 09:00 | cemerick | rhickey: the weaker the construct's support for all of the trappings of jvm/clr classes, the more I'd lean towards deftype |
| 09:00 | cemerick | ...regardless of the underlying impl, I mean. |
| 09:00 | rhickey | cemerick: that's my inclination as well |
| 09:01 | AWizzArd | rhickey: what is the lateral class resolution to DynamicClassLoader good for? I mean, what are your grand plans? :) |
| 09:01 | rhickey | anyway, seems like a clear path now to protocols/deftype/reify with no reference even to interfaces, reify of protocols |
| 09:01 | rhickey | reify of interfaces and deftype implementing interfaces just about interop |
| 09:04 | rhickey | AWizzArd: lateral class resolution means I can dynamically generate named classes, and find them in other dynamic classloaders, without trying to insert them in some shared root in the hierarchy (an impossible task given modular classloaders, context classloaders etc) |
| 09:04 | chouser | how do the lateral class loaders find each other? |
| 09:04 | rhickey | lifts a prior restriction on named things being static only |
| 09:05 | rhickey | chouser: they don't see each other, but see the dynamic classes of all, in a shared cache |
| 09:05 | rhickey | now named things need be static only for other static things |
| 09:05 | AWizzArd | And if you use a dynamic classloader, does this then mean you can gc those named classes? |
| 09:05 | rhickey | the cache holds the classes in weak refs |
| 09:06 | rhickey | but it also allows for no op redefs, caches the hash of the bytecode |
| 09:06 | rhickey | if same, just returns existing class |
| 09:07 | rhickey | so you could intermix definterface or deftypes in a file with code, reload won't invalidate unchanged classes |
| 09:08 | rhickey | this also means that both deftype and reify can implement protocols based on interfaces always, not just when AOTed |
| 09:08 | rhickey | chouser: this is what weak refs are for, canonic caches |
| 09:10 | rhickey | the upside is huge |
| 09:11 | rhickey | definterface (formerly gen-and-load-interface), no problem, including redefs |
| 09:11 | rhickey | deftypes could gen named classes, with same name, all the time |
| 09:11 | rhickey | protocols can always gen a corresponding interface, not just AOT |
| 09:12 | rhickey | reify can easily implement protocols |
| 09:12 | chouser | yeah, that's a bit stunning |
| 09:13 | rhickey | the only hitch will be a true (altering) redef of a type will require a reload of client code to work with new instances, but no JVM restart ever |
| 09:14 | rhickey | I basically decided following the tree design was simply too restrictive, was never intended to cover these cases, and hell, why should these modularity systems have all the fun - they do this kind of thing all the time |
| 09:15 | chouser | heh |
| 09:15 | rhickey | it's still early, but I'm quite hopeful |
| 09:17 | rhickey | so, when protocols generate interfaces I want to cover 2 things: |
| 09:17 | rhickey | first, there needs to be name munging, as the protocols fns will become interface methods |
| 09:17 | rhickey | I can hide this munging so deftype and reify use the clojure names |
| 09:18 | rhickey | the second thing I want to do is allow for multiple protocols to have the same named functions, without merging or clashes |
| 09:18 | rhickey | this will require that the method names in the interface have something about the protocol as a prefix or suffix |
| 09:19 | rhickey | again, as with munging, deftype and reify will hide this |
| 09:19 | rhickey | but, should you want to extend the protocol from JAva, you will see these names |
| 09:20 | chouser | these would be multiple protocols each in their own namespace with the same unqualified method names? |
| 09:20 | rhickey | yes |
| 09:20 | rhickey | right now that is a weakness of interfaces - the names merge |
| 09:20 | rhickey | and can conflict if, say, only return types differ |
| 09:21 | rhickey | never mind any semantic conflicts |
| 09:22 | rhickey | so, if protocols Bar and Baz both define foo, would become methods: Bar__foo(), Baz__foo(), or foo__Bar(), foo__Baz() |
| 09:22 | chouser | semantic conflicts that could actually cause an extend to want different functionality for two methods with the same name (and args and even return type) from different protocols |
| 09:23 | rhickey | yes, definitely, the functions in separate namespaces mean different things |
| 09:24 | rhickey | CLR doesn't do merging anyway, it is a broken part of Java |
| 09:24 | rhickey | also a broken part of most open-class OO systems |
| 09:24 | rhickey | classes make lousy namespaces |
| 09:24 | chouser | CLR languages provide extra syntax to disambiguate on method calls? |
| 09:25 | rhickey | so, the question is, would those pre/suffixes be bad |
| 09:25 | rhickey | chouser: yes, both on calls and definitions, you can define overrides for Bar::foo and Baz::foo in the same class |
| 09:25 | cemerick | rhickey: pretty cringe-inducing *shrug* |
| 09:26 | rhickey | which makes sense, because when calling you will be using the Bar or Baz interfaces |
| 09:26 | cemerick | not sure what a good alternative would be |
| 09:26 | rhickey | just like in Clojure you will be using the Bar or Baz namespaces |
| 09:26 | rhickey | cemerick: right, alternatives welcome |
| 09:27 | cemerick | rhickey: how about defining inner interfaces? |
| 09:27 | chouser | any chance of also generating prefix-less methods that just call the real one? |
| 09:27 | rhickey | chouser: when there is only one? |
| 09:28 | rhickey | cemerick: the problem is the method name, not the class structure |
| 09:28 | chouser | rhickey: right, for the probably common case of there being only one. Dunno if there's an appropriate moment to hook in order to leave it out on multiple. |
| 09:28 | rhickey | two interfaces both have a foo method, with different semantics, and you want to implement both |
| 09:29 | rhickey | chouser: the problem there is that, should you in the future implement another interface with an overlap, that redirector will disappear |
| 09:29 | rhickey | breaking clients |
| 09:29 | chouser | yeah, I guess my idea won't work, since both would produce the prefix-less methods, and would just have a conflict the moment some Java code tried to implement both. |
| 09:30 | chouser | yeah, that too. :-( |
| 09:30 | rhickey | also, the clients will be using the interfaces, not the concrete class |
| 09:30 | chouser | ah, right -- no redirect code allowed in interfaces. |
| 09:30 | chouser | broken on so many levels! oh well. |
| 09:30 | rhickey | so, protocol Baz looking for foo will be looking for foo_Baz |
| 09:31 | rhickey | this aspect of JAva is broken, and I'd prefer not to have protocols be broken too. Right now the story is, same function name in different namespaces ok |
| 09:32 | rhickey | and use of interfaces for speed under protocols is an implementation detail |
| 09:32 | chouser | always using a prefix/suffix would dissallow the kind of "transparent" client use by Java code I'm using right now. |
| 09:34 | rhickey | chouser: there are slightly different requirements at play here. There, the Java interface is driving, it won't be the primary interface to the protocol |
| 09:34 | rhickey | I'm thinking about designs where some substantial facility has been built in clojure on protocols, how to write new Java to work with it |
| 09:35 | chouser | I have Java clients doing things like RPC.newChannel("target").send(myMessage), where RPC is gen-class with static methods, and the Channel interface is from gen-interface. 'send' is implemented via proxy |
| 09:35 | rhickey | JAva code can't presume all implementors of protocol implement some interface - that will never be true, since extends lets protocols reach classes with no derivation requirement |
| 09:36 | rhickey | chouser: so for that you might still want definterface + deftype/reify |
| 09:36 | cemerick | rhickey: FWIW, in that use case, I'd say that a Java-friendly API should be written using genclass or a regular interface + deftype/reify. |
| 09:36 | cemerick | heh |
| 09:37 | chouser | right. I'm fine with Java code that's aware of Clojure having to stretch a bit (munging in prefixes or whatever) to get at things that weren't intentionally made Java-friendly. |
| 09:37 | rhickey | if protocols are to be clojure-like, they will have name munging too |
| 09:37 | octe | i was thinking about creating a http loadtest program, as an exercise... make x requests using y concurrent clients |
| 09:37 | octe | would it be a good idea to use agents for that? |
| 09:37 | rhickey | but, it could be possible, if you used compatible names and didn't get a prefix, to get a nice-looking interface from defprotocol... |
| 09:37 | chouser | ...as long as I can still do what I'm doing as well. |
| 09:38 | cemerick | my point being, I think any general solution to making clojure callable from Java will be less than what a real user would want. |
| 09:38 | chouser | octe: yep, probably. |
| 09:38 | octe | i was thinking you could create Y agents with a request-coutner as a value and keep sending of request requests to them until their total count reaches X |
| 09:38 | rhickey | cemerick: by regular interface above do you mean JAva-defined? |
| 09:39 | cemerick | rhickey: yes. If you're writing Java code anyway, and you want to call some clojure lib, I think it's totally reasonable to say that the work and shape of that integration falls on the integrator, not the language. |
| 09:40 | rhickey | the biggest problem of declaring 'no prefix' at the protocol side is that the clashes occur in client code doing ad-hoc extension |
| 09:40 | cemerick | someone in that position will likely be doing something you're not going to anticipate anyway, so punting to interface+reify/genclass will be the rule more than the exception, I'd wager. |
| 09:40 | rhickey | You can't be both a j.u.Map and a j.u.Collection, for example, due to this problem |
| 09:41 | rhickey | one thing that is key is that if you have a protocol-driven design, and want to make it reach another, more Java friendly interface, you always can |
| 09:42 | rhickey | but the protocol-specific interface gets a perf benefit that can't be gotten otherwise |
| 09:44 | rhickey | I guess if I leave in :on, you could make protocols where a definterface drives that, but :on is really ugly, puts a discussion of interfaces up front, has name-mapping and other required knobs... |
| 09:45 | rhickey | but it is a key question - are there many cases where a pre-existing interface should be the basis for a protocol? |
| 09:46 | chouser | my code is already partitioned into core functions vs. clojure api (which includes macros) vs. java api (public interfaces, static factory methods, etc.) ...so I have no problem with internal clojure stuff that might look "ugly" to Java, as long as I can still wrap it up in stuff that looks pretty in Java without actually writing any Java. :-) |
| 09:47 | rhickey | (definterface Pretty ...) (extend Pretty MyProtocol ...) |
| 09:47 | chouser | rhickey: do clojure's java.util-extending classes not fit that description? |
| 09:49 | rhickey | chouser: no, the primary consumption on the Clojure side is via Clojure's interfaces, which will become protocols. deftypes will implement the j.util stuff so they can be passed across |
| 09:49 | rhickey | usually protocolizing a java interface won't help JAva, since you can;t make a Java String a Java Collection |
| 09:50 | rhickey | protocols break free from the derivation requirement |
| 09:51 | Chousuke | rhickey: you haven't added a seq1 function (for "unchunking" a seq) yet, have you? I suppose it would be good to have in 1.1 if people need it :/ |
| 09:52 | rhickey | the other route is to do name-munging only, people can easily avoid munging by using compatible names. You would be precluded from implementing protocols with overlapping functions in the same deftype, but could still reach the other protocol with an extend-type |
| 09:53 | rhickey | Chousuke: that's definitely something we need to look at pre 1.1, yes |
| 09:54 | rhickey | so, no merging |
| 09:54 | rhickey | but no prefixes |
| 09:54 | rhickey | never stuck due to extend-type |
| 09:54 | rhickey | have to pick which protocol you want 'fast' |
| 09:55 | rhickey | that's not so bad |
| 09:56 | rhickey | if protocol is my.ns/Protocol, interface is my.ns.Protocol? |
| 09:56 | rhickey | I'm trying to avoid knobs |
| 09:57 | doublindirection | hello #clojure |
| 10:06 | cemerick | rhickey: sounds like a perfectly reasonable approach that (most importantly, IMO) doesn't try to be a general solution. |
| 10:21 | konr | (-> f .getName .toLowerCase (.endsWith ".jpg")) |
| 10:21 | konr | -> is so awesome. |
| 10:22 | angerman | is there a math (arrays) lib from clojure? |
| 10:29 | angerman | looks like the incater matrix is pretty ncie |
| 10:39 | cemerick | Looks like I need to rebind a multimethod with one that temporarily contains an additional set of methods. Is there a better way to do this, short of using defmethod before (binding...) and remove-method in a finally? (Thankfully, I'm not worried about race conditions in this case.) |
| 10:41 | patrkris | Is there a video available of the Clojure Experience talk (http://tinyurl.com/ygb5t8m)? |
| 10:41 | patrkris | Couldn't seem to find one |
| 10:42 | chouser | cemerick: the same defmultis, but for additional types? |
| 10:42 | cemerick | chouser: right |
| 10:42 | chouser | weird. and it's no good to just leave them in place all the time? |
| 10:44 | cemerick | there's an outside chance that leaving them in place all the time will cause strange bleed-through of behaviour from one lib to another, depending on load order |
| 10:44 | rhickey | patrkris: not as far as I know. It was a talk I gave recently at MIT CSAIL, and it was videotaped |
| 10:44 | patrkris | rhickey: ok, would love to watch it |
| 10:45 | chouser | it looks like the standard clojure intro, but updated post JVM lang summit. |
| 10:45 | cemerick | actually, any naming collision of the keywords used as args to the multimethod will cause problems, so I definitely wouldn't want to leave in method impls |
| 10:46 | rhickey | the intro stuff went by quickly. many in the audience had seen both my Boston talk (3 hrs) and ILC tutorial (5 hrs) |
| 10:46 | cemerick | (this calls for a persistent MultiFn impl :-P) |
| 10:49 | octe | hmm, probably somethings stupid but.. http://paste.lisp.org/display/91271 <- why does this code end up making 25 requests? |
| 10:50 | chouser | cemerick: add/remove is the only way I can think of, but I suppose I can imagine each methodtable living in, say, an atom in a var so that the var could get thread-local bindings. |
| 10:50 | chouser | cemerick: still seems pretty weird to me. :-P |
| 10:51 | chouser | would mess with the caching |
| 10:54 | cemerick | eh, dispatch table caching is not a cost relative to the rest of the app |
| 10:54 | cemerick | chouser: the specific situation is an indexing system where documents are {:name "val" :name2 "val"}, and different callers need to have control over how the values are indexed (tokenized or not and how, stored or not, etc). If document type A has a field :foo that should be tokenized, and document type B has a field :foo that shouldn't be tokenized, this has to be controlled in a context-sensitive way. |
| 10:55 | cemerick | I guess I could use a two-stage approach. |
| 10:55 | chouser | and multimethods have been a good fit up to this point? |
| 10:55 | cemerick | no, this is a new addition -- so far, indexing params have been hardcoded based on the type of the value |
| 10:56 | chouser | rhickey: I think at least 3 books on the way: one from APress, two from Manning |
| 10:56 | rhickey | should be interesting to see how they differ |
| 10:56 | chouser | indeed |
| 10:58 | chouser | my vague understanding is that the prag, apress, and "in action" from manning are essentially meant to be head-to-head competition, while we're making ours try to come at things from a slightly different angle. |
| 10:59 | rhickey | chouser: lucky you! |
| 10:59 | chouser | heh |
| 10:59 | chouser | we'll see. :-) |
| 10:59 | cemerick | chouser: yeah, a 2-stage approach is better in general -- multimethod dispatching on document type returning a fn (or var that can be rebound as desired) that provides the actual configuration |
| 11:00 | cemerick | although the method-table-in-an-atom idea is a good thought :-) |
| 11:02 | G0SUB | what is a nice way to emulate expiration of data after some time? |
| 11:03 | G0SUB | I have some access tokens which expire after 1 hour and need to be renewed. |
| 11:03 | G0SUB | a thread monitoring the tokens periodically is one way. |
| 11:04 | chouser | G0SUB: you want renewal triggered by time, or by attempted usage after a time limit? |
| 11:04 | G0SUB | chouser: the latter is OK with me. |
| 11:05 | G0SUB | I am fine with both, actually. |
| 11:05 | chouser | for the latter, you can just timestamp the object. Maybe in metadata, depending on other usage. |
| 11:05 | G0SUB | I get the tokens from an external system, and I have 3 api calls to create, destroy and validate the tokens |
| 11:06 | G0SUB | hmm |
| 11:17 | AlexStoddard | I have large data where I expect different instances to share a lot of structure (genetic variation in humans - representable as a vector or sequence). Clojure's structural sharing is mostly explained in terms of changes over time not changes between individuals. Any suggestions on how I might leverage structural sharing in Clojure to efficiently represent the data? |
| 11:22 | Chousuke | AlexStoddard: can't you just model your data as a progression of individuals instead of as progression of time? :/ |
| 11:23 | Chousuke | AlexStoddard: if you make a "modification" to a vector, it would represent a new individual, but the structure would be shared with the parent individual. |
| 11:26 | AlexStoddard | Chousuke: That is what I am thinking, the abstraction makes sense. What I am unsure about is how to "attach" an individual to each given state of the vector. |
| 11:27 | Chousuke | Each state *is* an individual. but you could have a ref to point to one of the individuals (changing over time) and call it pinnacle-of-evolution or something. Or you could have sets containing these individuals, or whatever |
| 11:28 | chouser | AlexStoddard: the structural sharing is pretty invisible. Just hang onto one version of a thing, do some 'assoc', 'dissoc', etc. to get to your next object, then hang onto that as well. |
| 11:30 | Chousuke | if genetic change can happen within one individual then you need to model them as time-dependent. eg. you need a ref to give an identity to the individual, or if that's too granular, a whole population (which "progresses" synchronously) |
| 11:34 | AlexStoddard | chouser: So it would be as simple as (def ind1 (load-genetic-vector)) (def ind2 (mutate ind1)) and ind1 and ind2 share structure? |
| 11:36 | liebke | AlexStoddard: yes, ind1 and ind2 will share structure |
| 11:36 | mattrepl | chouser: how should one choose bugs in assembla to work on? it's not clear what fields like "approved" mean. I'd like to help out, but not sure what's higher priority |
| 11:37 | chouser | mattrepl: yeah, it's a bit confusing. I started on a flow chart once... ... |
| 11:37 | chouser | mattrepl: it's generally pretty flat. "approved" is only when there's a patch attached that rhickey has examined and agrees is ready to be committed. |
| 11:38 | chouser | "test" means someone has submitted a patch but rhickey hasn't approved it yet. |
| 11:39 | rhickey | mattrepl: something useful right now would be to go through the existing tickets and set any missing Types |
| 11:39 | rhickey | bug vs enhancement |
| 11:40 | mattrepl | chouser: thanks, that makes sense |
| 11:40 | rhickey | http://twitter.com/neal4d/status/6189294802 |
| 11:40 | mattrepl | rhickey: sure thing |
| 11:41 | chouser | everything else is fair game for writing patches -- I guess "milestone" gives a sense of priority |
| 11:41 | mattrepl | are tickets in the backlog ok to work on or do they need to be reviewed for relevancy? |
| 11:41 | AlexStoddard | liebke et al: Thanks, persistent vectors for genetics, here I come... |
| 11:42 | rhickey | yes, there were a whole bunch of things slated for next release that got ignored, while others from backlog got worked on, so didn't seem to make much sense to me to keep trying to do that, but the approved backlog are things I think are more important |
| 11:42 | chouser | mattrepl: if they exist at all it's ok to work on them, though they might need more design discussion or might not make it in anytime soon. |
| 11:43 | mattrepl | ok, thanks |
| 11:45 | rhickey | wow, this instant interface thing will be game changing: |
| 11:45 | rhickey | (defprotocol P (foo [x]) (bar ([x] [x y]))) |
| 11:45 | rhickey | (defn baz [x] (bar x)) |
| 11:45 | rhickey | (baz (reify [user.P] (.bar [] 42))) |
| 11:45 | rhickey | ;will become (baz (reify [P (bar [] 42)]))? |
| 11:46 | rhickey | does beg the implicit this question again... |
| 11:47 | cemerick | rhickey: one thing stuck out for me in those slides that are making the rounds this morning: "composability of independent decisions e.g. thread pool sizing". That's developing into a big issue for our UIs -- e.g. running a pmap in a UI app simply kills the entire system. Definitely good utilization, but being able to say "this pmap/send/future/etc should go into this low-priority/N-thread/etc threadpool/executor" woul |
| 11:47 | cemerick | incredibly useful. |
| 11:47 | rhickey | I hate to see all those unused thises |
| 11:47 | Chousuke | rhickey: I'm fine with either choice as long as its applied consistently :) |
| 11:48 | Chousuke | proxy already has implicit this so that's one argument for it, I suppose. |
| 11:48 | rhickey | Chousuke: what's consistent though? - interface sigs are declared without this, protocol fns have an arg for it, and both may appear together in a single deftype |
| 11:49 | rhickey | you are bound to have one mismatch |
| 11:49 | Chousuke | hmm, right. Java complicating things again :P |
| 11:50 | rhickey | cemerick: definitely want to have more pool options, but still leaves basic questions unanswered - how do independent decisions interact> |
| 11:50 | rhickey | there is implicit scope already in play in deftype - unqualified access to fields |
| 11:57 | notallama | cemerick: i wrote a different version of future the other day that uses a daemon thread pool (http://paste.lisp.org/display/91277). that's something you can hack together yourself, if you want. for send, i think you have to change Agent.java (i didn't see another way to do it) |
| 11:57 | cemerick | rhickey: absolutely. The brute-force approach leads to insanity. Further, I presume that the way j.u.concurrent does things is not suitable for .NET or cocoa or js or..., so I suppose clojure needs a higher-level set of levers than all of the fiddly bits that j.u.c provides. |
| 11:58 | rhickey | cemerick: I think you miss my point - I consider this an unsolved problem |
| 11:58 | rhickey | i.e. for which I don't yet have an answer |
| 12:03 | cemerick | Well, I'd think a first step of having bindable vars for the executors in Agent (as notallama's impl points towards) would be a good 80% solution. |
| 12:03 | cemerick | Certainly leads to proliferation with various libs potentially keeping their own pools around, but that's what thread schedulers are for. |
| 12:04 | rhickey | cemerick: meh, I think at least moving towards ForkJoin work-stealing. |
| 12:05 | cemerick | rhickey: well, that's JDK7 only, no? |
| 12:05 | rhickey | works with JDK 6 |
| 12:05 | rhickey | but not 5 :( |
| 12:05 | cemerick | oh, that's interesting. Isn't there a native component, though? |
| 12:05 | rhickey | no, just JSR166y.jar |
| 12:06 | rhickey | see par branch |
| 12:06 | rhickey | works today on 6 |
| 12:06 | cemerick | huh, I never looked at that at all because I had it in my head that it was JDK 7-only |
| 12:06 | rhickey | has a fjtask, like future, but joins any enclosing fjtask |
| 12:38 | arohner | is there a way to introspect a deftype to get the number and order of the args in the constructor? |
| 12:38 | arohner | I'd like to pass a map literal to make a deftype instance. if I could introspect, I could write the fn to do it |
| 12:39 | djork | hmm, every time I try this failing 'use' expression in my repl, it increments the line number associated with the error |
| 12:39 | djork | is that a bug? |
| 12:40 | djork | like, it starts at line 1, then just goes up by one each time |
| 12:40 | chouser | arohner: you can use the arglists of the factory fn pretty safely I think. |
| 12:41 | arohner | chouser: aha, thanks |
| 13:03 | rhickey | hmm, clojure.contrib.pprint.PrettyWriter has an illegal method name: col-write |
| 13:06 | qed | heh that was fun, i ran a search for 250,000 incoming tweets for clojure |
| 13:06 | qed | w/ clojure of course |
| 13:07 | qed | i wonder how many tweets there are in a day |
| 13:12 | qed | look like ~25 million per day |
| 13:12 | tmountain | qed: according to this guy's blog, 27.3 million - http://www.briansolis.com/2009/11/guess-how-many-tweets-fly-across-twitter-each-day/ |
| 13:12 | qed | http://popacular.com/gigatweet/ |
| 13:13 | tmountain | too bad they use scala :-p |
| 13:13 | qed | hehe |
| 13:13 | qed | im gonna grab a day of tweets and see what I can do with it |
| 13:20 | rhickey | so I'm left with the conflict between the name of a protocol and its implicit interface - user/P and user.P |
| 13:23 | Chousuke | rhickey: would it be too ugly to just prefix the interface name with P or something? |
| 13:23 | rhickey | Chousuke: yes |
| 13:41 | rhickey | ok, protocols gen interfaces is up! |
| 13:42 | noidi | how can I drop every second item from a seq? |
| 13:43 | Chousuke | ,(let [x (atom false)] (filter #(swap! x not) [1 2 3 4 5 6])) |
| 13:43 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--8041$fn |
| 13:43 | Chousuke | hmm |
| 13:43 | Chousuke | oops |
| 13:44 | Chousuke | ,(let [x (atom false)] (filter (fn [_] (swap! x not)) [1 2 3 4 5 6])) |
| 13:44 | clojurebot | (1 3 5) |
| 13:44 | noidi | thanks |
| 13:44 | Chousuke | there's probably a better way, but... |
| 13:44 | noidi | that works but the atom is not too pretty |
| 13:45 | the-kenny | Chousuke: That was my first idea too.. But I'm sure there is a better way |
| 13:45 | the-kenny | maybe seq-utils/indexed + for or something |
| 13:45 | noidi | ah, indexed |
| 13:45 | noidi | that was the thing I was looking for, but I couldn't remember the name |
| 13:46 | the-kenny | noidi: It's in clojure.contrib.seq-utils. |
| 13:46 | noidi | thanks |
| 13:46 | noidi | that + filter odd? should probably do the trick |
| 13:46 | Chousuke | indexes :( |
| 13:47 | esj | or (map first (partition 1 2 '(1 2 3 4 5 6))) ? |
| 13:48 | noidi | esj, of course! brilliant! :) |
| 13:48 | noidi | thanks |
| 13:49 | esj | noidi: don't take my word for it, i'm habitually wrong. |
| 13:50 | noidi | ,(map first (partition 2 (range 10))) |
| 13:50 | clojurebot | (0 2 4 6 8) |
| 13:51 | noidi | ,(map second (partition 2 (range 10))) |
| 13:51 | clojurebot | (1 3 5 7 9) |
| 13:51 | noidi | nice and simple :) |
| 13:54 | esj | cool. |
| 13:55 | noidi | weird, I can load the triangles of a 3D mesh from a COLLADA file in 13 lines of clojure |
| 13:56 | noidi | coming from an imperative/OO programming, functional code feels amazingly dense |
| 13:56 | the-kenny | noidi: That's true |
| 13:56 | noidi | dense as in little fluff, not dense as in difficult to read |
| 13:57 | polypus | niodi, yeah i'm rewriting a genetic programming project from ruby and it is an order of magnitude smaller |
| 13:57 | polypus | noidi* |
| 13:58 | polypus | hey do you guys know if there is any audio/video available anywhere of rhickey's semantic web talks? |
| 13:59 | technomancy | I wish I understood more than 20% of this, but it's a good read nonetheless: http://blogs.sun.com/jrose/entry/tailcalls_meet_invokedynamic |
| 14:03 | esj | anybody knows if json.write has gone away ? |
| 14:03 | esj | (use 'clojure.contrib.json.write) doesn't seem to work |
| 14:03 | esj | ? |
| 14:07 | rhickey | noidi: (take-nth 2 (range 10)) |
| 14:07 | rhickey | ,(take-nth 2 (range 10)) |
| 14:07 | clojurebot | (0 2 4 6 8) |
| 14:07 | esj | rhickey: nice. |
| 14:07 | rhickey | Chousuke: shame on you for that atom stuff! |
| 14:08 | noidi | rhickey, you win :) |
| 14:09 | esj | he has an unfair advantage... and not just that he's super clever :) |
| 14:11 | cemerick | are tail-calls really on the table for JDK 7 now? |
| 14:11 | rhickey | cemerick: not as far as I know |
| 14:12 | technomancy | cemerick: according to John Rose it's a matter of manpower |
| 14:12 | cemerick | that's what I thought, though I see the post that technomancy just linked to, and there was a java.net post about first-class continuations in JDK 7 over the weekend, so I thought maybe something was afoot |
| 14:13 | cemerick | technomancy: IMO: http://twitter.com/cemerick/status/5868285825 |
| 14:13 | rhickey | If all this stuff is going to be in JDK7, then JDK7 is a long way away |
| 14:13 | cemerick | from a selfish user standpoint, of course ;-) |
| 14:17 | shr3kst3r | change java 7 to java dnf |
| 14:52 | technomancy | cemerick: I guess the guy working with Rose on that was doing it for his Ph.D thesis, but then he graduated. =( |
| 14:53 | cemerick | bah |
| 14:53 | cemerick | and there's a small squad of folks puttering away building the javafx stack. Awesome. |
| 14:57 | djork | does anybody else worry about the future of Sun's JDK? |
| 14:57 | djork | like, that they will be around at all? |
| 14:57 | djork | are they financially sound at all? |
| 14:57 | rsynnott | couldn't people just use the open-source version? |
| 14:57 | rsynnott | djork: well, Oracle is supposedly buying them |
| 14:57 | djork | oh great |
| 14:57 | rsynnott | (assuming that the EC can be satisfied) |
| 14:58 | djork | I wonder how Oracle will treat the JDK |
| 14:58 | djork | err, JVM |
| 14:58 | djork | will they further its development or hinder it |
| 14:59 | rsynnott | probably won't hinder it |
| 14:59 | rsynnott | they're pretty java-dependent |
| 14:59 | djork | yeah, I suppose so |
| 14:59 | rsynnott | of course, they may not be allowed to buy sun |
| 14:59 | djork | right |
| 15:00 | rsynnott | they will, of course, put it on a website of remarkable awfulness and make it harder to install |
| 15:00 | rsynnott | (that's pretty much Oracle's job) |
| 15:00 | djork | yeah I can't wait for Oracle Java 9-16R Enterprise Edition |
| 15:01 | lisppaste8 | rhickey pasted "protocols gen interfaces" at http://paste.lisp.org/display/91296 |
| 15:04 | chouser | bar-me takes either 1 or 2 args? |
| 15:04 | rhickey | right |
| 15:04 | chouser | I was sure for several moments that it was taking 1 arg and returning a vector length 2, and was trying to figure out where y was coming from. |
| 15:06 | rhickey | so you can implement protocols in deftype, and reify protocols |
| 15:06 | rhickey | all of this is dynamic |
| 15:07 | chouser | that's really seamless |
| 15:07 | rhickey | munging occurs on the names in deftype and reify |
| 15:08 | rhickey | still not sure about (.foo [] ...) vs (foo [this] ...) |
| 15:08 | rhickey | I know the crowd here wanted explicit this |
| 15:09 | Chousuke | the argument lists in deftype managed to throw me off somewhat already. |
| 15:10 | rhickey | right now deftype and reify don't know or care that P is a protocol |
| 15:11 | rhickey | whatever happens should be the same for interfaces and protocols (really, there are only interfaces in deftype and reify) |
| 15:11 | rhickey | explicit this would align better with protocols, and less well with interfaces coming from JAva |
| 15:12 | rhickey | the leading dot also seems weird if you are working only with protocols and deftype |
| 15:15 | lisppaste8 | rhickey annotated #91296 "w/explicit this" at http://paste.lisp.org/display/91296#1 |
| 15:16 | rhickey | explicit this, no dots |
| 15:16 | rhickey | seems a better match for protocols |
| 15:16 | LauJensen | rhickey, so both explicit and mandatory for each method? |
| 15:17 | rhickey | LauJensen: whatever it is would be the same story for all methods, from interfaces and protocols |
| 15:17 | Chousuke | yeah, I like that better. it's more functional in style anyway |
| 15:17 | rhickey | you don't have to call it this, you could do [_] when you don't use it |
| 15:17 | rhickey | or call it me or self or whatever |
| 15:18 | Chousuke | or it could be "handler" or whatever the object actually represents :P |
| 15:18 | LauJensen | rhickey, I think implicit this would be much more elegantly and feel quite natural in the jvm |
| 15:18 | Chousuke | LauJensen: looking at the previous example, I have to disagree with that :/ |
| 15:19 | LauJensen | oh ok, np. good to have more views :) |
| 15:19 | Chousuke | it fits the java way where you have objects and "this" anyway, but it looks like magic in Clojure core. :P |
| 15:19 | Chousuke | code' |
| 15:19 | arbscht | I look forward to using clojure outside of the jvm. explicit would be nice ;) |
| 15:19 | rhickey | basic interface use of reify would be: (reify [ActionListener] (actionPerformed [this evt] ...)) |
| 15:20 | LauJensen | Chousuke, I think ritually repeated the first argument which is a fixed ref to fixed is just ceremony in some regard |
| 15:20 | Chousuke | LauJensen: you don't have to always call it this. |
| 15:20 | LauJensen | I know |
| 15:21 | Chousuke | But especially off-putting is the mismatch between defprotocol definitions and deftype definitions in the implicit this example :/ |
| 15:21 | Chousuke | I'd rather have some ceremony than that. |
| 15:21 | rhickey | I was very much in favor of implicit this when it was just about interfaces, now with protocols, alignment with protocols is primary concern |
| 15:22 | rhickey | people can use protocols, reify and deftype and never know about interfaces |
| 15:22 | LauJensen | Sure, I didn't consider that. Consistency is supremely important |
| 15:22 | LauJensen | Which reminds me, doesn't it seem odd that nth doesn't take the idx as its first arg? Or is that just a gut feeling? |
| 15:24 | dnolen | rhickey: interesting so do the latest changes allow you to create Java interfaces on the fly? |
| 15:25 | rhickey | dnolen: right now, only with defprotocol, still thinking about what definterface should look like |
| 15:25 | rhickey | but the machinery is in place |
| 15:26 | dnolen | rhickey: crazee cool :D |
| 15:28 | rhickey | what about the parens-mean-calls folks? the leading dot seemed to ease that somewhat, without it do reify and deftype get hard to parse? |
| 15:29 | LauJensen | rhickey, not sure Im following, parens-mean-calls? |
| 15:29 | chouser | reify no worse than proxy. defprotocol and deftype somewhat better because of being rooted at the top level. |
| 15:30 | rhickey | chouser: I presume you like the explicit this? |
| 15:30 | chouser | I think 'case' is my new favorite punching bag on that front. |
| 15:30 | rhickey | the dots really bother me when implementing protocols |
| 15:31 | chouser | yeah, I won't disagree with you there. I liked it when the only way you would call it was also with a dot, but defining with a dot and calling without just makes no sense. |
| 15:31 | chouser | for explicit this, I was going to check the logs to make sure I didn't disagree with myself... |
| 15:32 | rhickey | two other niggles are - in defprotocol, multiple arity goes in same form, in reify/deftype, multiple forms |
| 15:32 | notallama | with explicit this, you could destructure it, yes? |
| 15:32 | chouser | notallama: nice!! |
| 15:33 | rhickey | and, my.ns/Protocol (the protocol itself) my.ns.Protocol (the interface we don't want to talk about but need to name in reify/deftype) |
| 15:34 | rhickey | notallama: not right now, no |
| 15:34 | chouser | I guess you'd only be destructuring fields that you already have direct access to, right? |
| 15:34 | chouser | or ... wait, I'm confused. do we have direct access in all contexts? |
| 15:34 | rhickey | chouser: yes |
| 15:35 | rhickey | but bigger issue is these methods are not fns, don't have any destructuring of any args yet |
| 15:37 | chouser | I'm just not keeping up. |
| 15:37 | chouser | but that's ok. It's not as if me keeping up helps anyone. :-) |
| 15:38 | rhickey | chouser: not true! |
| 15:38 | rhickey | what's unclear? |
| 15:38 | chouser | I'll catch up eventually. |
| 15:39 | chouser | my mental construct is a fragile collection of various versions of various of these pieces. stop thinking about it for a holiday weekend and I've got hardly anything left. |
| 15:39 | rhickey | :) |
| 15:40 | rhickey | well, if I can iron out these few details I'll finish up and modify the docs to align |
| 15:40 | rhickey | seems like few people would want the dot given protocols |
| 15:40 | rhickey | andfew would want implicit this either |
| 15:41 | rhickey | I guess people will have to use it a bit to see if my.ns/Protocol (the protocol itself) vs my.ns.Protocol (the interface) poses a problem |
| 15:42 | rhickey | destructuring support would be nice, would need to make reify a macro |
| 15:44 | chouser | extend still takes maps of real fns, right? so destructuring and closures are there. |
| 15:45 | rhickey | chouser: yes, all that is the same |
| 15:45 | chouser | reify now works on protocols because each protocol has a matching interface. |
| 15:45 | rhickey | new today is defprotocol gens interface, opening up existing interface impl support in deftype and reify to protocols |
| 15:46 | chouser | I forget if reify does closures |
| 15:46 | rhickey | reify is a closure essentially |
| 15:46 | notallama | man. this was already my favourite type system about a week ago (when i tried new). and it keeps getting better |
| 15:47 | rhickey | see x in the paste |
| 15:47 | chouser | ok, right. the fields of the reify class are the closed-overs |
| 15:47 | rhickey | right |
| 15:48 | chouser | the methods of the reify class have direct access to its fields in the same way any closure does. But it also has methods as allowed by the interface as always but now also protocols. |
| 15:49 | chouser | deftype has been about interfaces, but now can do protocols as well. Does it just use the interface? Does that mean it's not splitting its body into deftype/extend? |
| 15:49 | rhickey | chouser: right, but the trick is to come up with the story from the other direction - imagine you don't know Java, and have been shown protocols and deftype. You can etend a type to a protocol externally or internally |
| 15:50 | solussd | could somebody explain the difference between send and send-off? |
| 15:51 | rhickey | externally with extend or extend-type, internally by putting ____ (called my.ns.Protocol) in square brackets and the definitions inline. The inline definitions have direct access to your fields, but are not closures over surrounding lexical scope (usually none) |
| 15:51 | rhickey | additionally, you can do one-off implementations of a protocol with reify |
| 15:51 | notallama | solussd: send uses a fixed-size thread pool, send-off uses a variable-sized one. so, send can get clogged if you have slow/blocking functions, basically. |
| 15:51 | SergeyDidenko | Solussd, http://clojure.org/agents |
| 15:52 | rhickey | note the absence of 'interface' in the above description |
| 15:52 | rhickey | perhaps interface must unavoidably go in ____ above |
| 15:52 | polypus | rhickey. was there any audio/video of your semantic talks ever released. google aint giving me anything. any plans for other talks on same subject? |
| 15:53 | solussd | thanks, http://clojure.org/agents doesn't explain the implementation difference, only usage scenarios. |
| 15:53 | rhickey | polypus: not as far as I know |
| 15:53 | chouser | not just "protocol name" for the ____? |
| 15:53 | polypus | rhickey: thx |
| 15:54 | rhickey | chouser: yeah, the trouble is my.ns/Protocol also names the protocol object |
| 15:54 | rhickey | which is what you'll need for extend* |
| 15:54 | chouser | oh, I see. |
| 15:54 | SergeyDidenko | solussd, indeed. I thought I saw it there. |
| 15:55 | rhickey | chouser: that's one of the current niggles |
| 15:56 | SergeyDidenko | solussd, http://java.ociweb.com/mark/clojure/article.html#Concurrency see "Agents" section |
| 15:56 | chouser | surely anything that expects a protocol object my.ns/Protocol can figure out the interface name? |
| 15:56 | SergeyDidenko | solussd, it's a great artcile BTW |
| 15:56 | solussd | SergeyDidenko: excellent, thanks. I'll read it |
| 15:57 | rhickey | chouser: right now deftype and reify don't know about protocols |
| 15:57 | SergeyDidenko | Is the simplest way to translate '(n1 n2 n3 ...) into ((1 n1) (1 n2) (1 n3) ...) is to use "(partition 2 (interleave (repeat 1) '(n1 n2 n3 ...)))" ? |
| 15:57 | rhickey | but yes, given a protocol instance P the interface name is (:on P) |
| 15:59 | chouser | ,(map #(list 1 %) '(n1 n2 n3 ...)) |
| 15:59 | clojurebot | ((1 n1) (1 n2) (1 n3) (1 ...)) |
| 15:59 | rhickey | ,(map list (repeat 1) [2 3 4 5]) |
| 15:59 | clojurebot | ((1 2) (1 3) (1 4) (1 5)) |
| 16:00 | SergeyDidenko | Oh, I completely forgot about map :) Thank you |
| 16:01 | rhickey | we'd need to yank some innards from fn to enable destructuring in deftype and reify |
| 16:01 | chouser | rhickey: ok, I see. So either deftype and reify have to be taught (a little) about protocols, or users need to know about the two names for the protocol and when to use each. |
| 16:07 | alexyk | anybody here using clojure maven plugin? |
| 16:07 | konr | Is there a parser generator for clojure? |
| 16:08 | cark | konr : fnparse |
| 16:09 | hiredman | that is a parser, not a parser generator, innit? |
| 16:10 | cark | hum, at the end that's doing the same thing no ? |
| 16:13 | alexyk | any nice wrappers around joda time? |
| 16:15 | chouser | alexyk: I think the consensus has been it doesn't really need a wrapper. |
| 16:16 | alexyk | chouser: Scala adds things like < operator |
| 16:16 | alexyk | can you redefine < for DateTime in clojure? |
| 16:17 | alexyk | or, define |
| 16:17 | chouser | no |
| 16:17 | alexyk | hi mattrepl! I was just looking at your neo4j wrappers yesterday |
| 16:17 | alexyk | chouser: makes it easier :) |
| 16:18 | cemerick | mmm, operator overloading. |
| 16:18 | chouser | alexyk: I can see that. I dunno if we'll get a protocol for < or not. |
| 16:18 | cemerick | 154227134 < some-date-obj, yay ;-P |
| 16:18 | mattrepl | hey alexyk, cool! they don't do much but hope they were useful |
| 16:19 | alexyk | mattrepl: I was just poking around... found several. Yours is just one file, right? |
| 16:20 | alexyk | chouser: protocol is the OO parlance, right? |
| 16:20 | chouser | protocol is a Clojure feature in the "new" branch |
| 16:20 | chouser | But I guess I'm referring to a future beyond that: clojure-in-clojure |
| 16:21 | mattrepl | alexyk: yup |
| 16:22 | alexyk | how do I translate this Java into Clojure: DateTimeFormat.forPattern("<fmt>")? |
| 16:22 | chouser | alexyk: (DateTimeFormat/forPattern "<fmt>") |
| 16:22 | chouser | alexyk: that's the pattern for static method calls. |
| 16:22 | alexyk | ah right. I was trying (.forPattern DateTimeFormat.forPattern "...") and it was not finding it. |
| 16:23 | twbray | While you guys were Thanksgiving-ing, I was pounding away on Clojure with big data: http://www.tbray.org/ongoing/When/200x/2009/11/26/No-Free-Lunch |
| 16:23 | alexyk | I mean (.method Class "param") |
| 16:24 | alexyk | twbray: nice! I was an eager collector of the Wide Finders scripts back in the day! Are you still running any? |
| 16:24 | chouser | alexyk: right, that would be treating DateTimeFormat like an instance of the Class class, looking for a method Class::forPattern or something. |
| 16:25 | bitbckt | "back in the day"... has it been that long, already? |
| 16:25 | twbray | alexyk: Yep, technology moves along. |
| 16:25 | alexyk | twbray: the Perl lead was mindboggling |
| 16:26 | alexyk | twbray: we need a Scala/Clojure shootout with agents vs actors |
| 16:26 | rhickey | chouser: ok, that's better, so now after doing (defprotocol P ...) you can just do (deftype Foo [a b c] [P] ...) |
| 16:27 | alexyk | twbray: how about a JVM-only Wide Finder? |
| 16:28 | alexyk | twbray: tweak your GC's, do whatever. Same Sun JDK; or may be OpenJDK and others, too. |
| 16:28 | twbray | alexyk: JVM is crippled on this problem compared to systems that don't have to turn texts into UTF-16 :(. |
| 16:28 | chouser | rhickey: deftype will take either an interface or a protocol object? |
| 16:29 | alexyk | twbray: then some other problem with juicy concurrency :) |
| 16:29 | hiredman | you just need a regex engine that takes bytes |
| 16:29 | alexyk | regex there was a weak link allowing a perl lead even |
| 16:29 | twbray | hiredman: Trying to make it *easy* for programmers. They just want to see strings. |
| 16:30 | chouser | hiredman: that's a good point. is there no string/regex lib for java that uses utf8 internally instead of 16? |
| 16:31 | alexyk | twbray: UTF-16 will work on Chinese web logs :) |
| 16:31 | twbray | chouser: There might be, but irrelevant. You wanna live in the java ecosystem, you got to live with Java strings :( |
| 16:32 | chouser | hmmm |
| 16:32 | twbray | Anyhow, not really relevant. The fact that Java burns CPU on this means that concurrency should be *more* valuable on a many-core system, deal the computing out. |
| 16:35 | cemerick | I'm a similar position as a few commenters on that post: does it matter at all, as long as wall-clock time is what it should be? |
| 16:35 | alexyk | Dmitriy talks of teams of 10 employers doing work in 1 day, very post-modern :) |
| 16:35 | cemerick | (outside of wattage burned, perhaps?) |
| 16:37 | twbray | cemeric: I'm not really sure whether or not the amount of CPU burned is significant. But it's still surprising. Anyhow, a speedup factor of four based on straightforward use of Clojure primitives without too much voodoo is obviously good. |
| 16:38 | cemerick | twbray: I guess my confusion is around what exactly a cpu cycle is, if not a corollary to a unit of time. |
| 16:39 | twbray | cemerick: In practical terms, what it means is, how many of the machines cores are in use & not available for other work. |
| 16:39 | twbray | On this computer, for every unit of time, there are 16 units of integer computing potentially available. |
| 16:39 | chouser | seems like it might matter a lot in a world of on-demand provisioned virtual machines billed by number of comuter-hours used. |
| 16:39 | alexyk | twbray: a bit offtopic, but perhaps you can shed the light. I got a box with 8 quad-core CPUs, but top never shows loads more than 800% CPU. In such setups, is it because 100% CPU is counted per each quad-core? It's a Barcelona Intel x86_64 each. Can such a system run 32 threads at once? |
| 16:40 | cemerick | chouser: thus my wattage remark. Thankfully a world I've no involvement in. |
| 16:40 | rhickey | chouser: yes, interface or protocol designators |
| 16:40 | twbray | alxyk: Don't know, depends on details of processor architecture & how it reports CPU time to the OS and how the OS reports to you. |
| 16:46 | tmountain | alxyk: make a shell script, and put one of these per line, per core - while [ 1 ]; do :; done & |
| 16:47 | tmountain | alxyk: go into top after that, and you should easily be able to tell what your system reports when it's maxed out |
| 16:50 | the-kenny | I have a file with little-endian utf16-text. How can I read the file in clojure? |
| 16:50 | bitbckt | heh |
| 16:50 | SergeyDidenko | the-kenny, play with *default-encoding* ? |
| 16:51 | twbray | the-kenny: (def decoder java.nio.charset.Charset forName "UTF-8") newDecoder)) |
| 16:51 | twbray | Oops, that UTF-8 should be UTF-16LE for you |
| 16:51 | twbray | the-kenny: Then you can call (. decoder decode) on a buffer |
| 16:52 | Chousuke | (.newDecoder (java.nio.charset.Charset/forName "UTF-16LE")) would be more idiomatic. :) |
| 16:52 | alexyk | is there any shorthand for the following two imports: (import [org.joda.time DateTime]) (import [org.joda.time.format DateTimeFormat]) -- or they have to stay separate? |
| 16:53 | the-kenny | twbray, Chousuke: Thanks, I'll try that :) |
| 16:53 | Chousuke | also (.decode decoder args) (assuming it's an instance method) |
| 16:54 | Chousuke | I will never stop trying to wean people away from using . directly. :) |
| 16:56 | Chousuke | It is, after all, in my best insterest to have people write code that I find readable :P |
| 16:56 | Chousuke | but I digress. |
| 16:57 | alexyk | Chousuke: is there any alternaive to, e.g.: (.parseDateTime dtFmt "2009-06-15 04:01:00") ; ? |
| 16:57 | Chousuke | that's the proper sugared form I think. |
| 16:58 | alexyk | Chousuke: ah, you mean (. <space> ...) |
| 16:58 | Chousuke | yeah. |
| 16:58 | Chousuke | also, I don't think there's any way to unify those import statements |
| 16:59 | Chousuke | though usually you'd have them in the ns declaration |
| 16:59 | Chousuke | eg. (ns (:import (org.joda.time.format DateTimeFormat) (org.joda.time DateTime))) |
| 16:59 | alexyk | Chousuke: I noticed that both Clojure and Scala abbreviate importing a list from the same package, but not across e.g. nested supbpackages. Is it based on JVM innards for import? |
| 17:00 | Chousuke | alexyk: subpackages and their parents are not actually related in any way, except by name. |
| 17:01 | Chousuke | it is possible to extend the ns macro to support (foo.bar subpackage.Class AnotherClass) but I don't know if that could create ambiguities. |
| 17:02 | alexyk | Chousuke: ah, I forgot it's a lisp and we got macros! would be cut to write a different ns and annoy people :) |
| 17:02 | Chousuke | heh. |
| 17:03 | Chousuke | (my-ns foo.bar (import-my-stuff)) |
| 17:03 | jasapp | is there a better way to do this? |
| 17:03 | Chousuke | yeah, you could do that but you shouldn't :P |
| 17:03 | jasapp | ,(apply hash-map (list 1 2 3 4)) |
| 17:03 | clojurebot | {1 2, 3 4} |
| 17:04 | Chousuke | ,(hash-map 1 2 3 4); like this? |
| 17:04 | clojurebot | {1 2, 3 4} |
| 17:04 | jasapp | well, if the argument has to be a list |
| 17:04 | Chousuke | ah, then no. |
| 17:04 | alexyk | ok, so I see two different ways to interop with Java here: (.parseDateTime dtFmt "2009-06-15 04:01:00") and (. dtFmt parseDateTime "2009-06-15 04:01:00"); but this doesn't work: (dtFmt. parseDateTime "2009-06-15 04:01:00") |
| 17:04 | alexyk | when do you use the form (Class. method ...) ? |
| 17:05 | Chousuke | the Foo. form is short for new Foo |
| 17:05 | jasapp | thanks |
| 17:05 | alexyk | ok |
| 17:05 | Chousuke | About Foo. and new Foo I don't really care which one you use. at least new is an informative operator, unlike . :P |
| 17:07 | alexyk | yeah, Class. method is confusing |
| 17:08 | alexyk | (new Foo) is clearer |
| 17:10 | Chousuke | The Foo. syntax is convenient when you need to wrap things though. |
| 17:10 | the-kenny | hm... looks like the text isn't utf-16.. stupid windows mobile |
| 17:10 | Chousuke | like (BufferedReader. (FileReader. ...)) |
| 17:11 | alexyk | right |
| 17:12 | alexyk | can it be done with .. though? |
| 17:12 | alexyk | or not for nested new's? |
| 17:12 | Chousuke | no. |
| 17:12 | Chousuke | .. is for calling methods |
| 17:12 | Chousuke | though I prefer using -> with .methods :) |
| 17:13 | alexyk | Chousuke: how would that work in my parseDateTime example above |
| 17:13 | alexyk | ? |
| 17:14 | Chousuke | well, it's not very useful in that case |
| 17:14 | Chousuke | but (-> dtFmt (.parseDateTime "2009-06-15 04:01:00")) |
| 17:16 | alexyk | hmm... slightly bigger than (. ...) :) |
| 17:16 | alexyk | can see better :) |
| 17:16 | Chousuke | yeah, but the real use is when you have a pipeline of operations |
| 17:17 | Chousuke | ,(-> "foobar" (subs 2 4) .toUpperCase); especially if you need to mix clojure functions and java methods |
| 17:17 | clojurebot | "OB" |
| 17:18 | alexyk | nice |
| 17:19 | Chousuke | or if you need to look up something in a deep data structure |
| 17:20 | Chousuke | ,(-> {:foo {:bar {:a 3 :b 1}}} :foo :bar :b) |
| 17:20 | clojurebot | 1 |
| 17:20 | alexyk | now that's useful even in clojure-only! |
| 17:23 | Chousuke | it's actually a macro |
| 17:23 | Chousuke | it just reorders the operators a bit |
| 18:50 | defn | hey all |
| 18:54 | defn | I have this silly thing where I'm searching for tweets which contain #"regex" -- I'd like to create two instances of this search, 1000 tweets each, and then combine their state |
| 18:54 | defn | this is something I'd use refs for, yes? |
| 19:00 | defn | nvm |
| 19:39 | rhickey_ | ok - latest deftype/reify implements all discussed - no dots, no implicit this, can use protocol directly in deftype/reify protocol/interface lists, updated docs |
| 19:41 | KirinDave | Is there a special "last result" variable for the clojure repl? |
| 19:41 | KirinDave | I heard there was one, but I honestly can't find it. |
| 19:41 | rhickey_ | *1 |
| 19:41 | rhickey_ | *2 *3 too |
| 19:41 | KirinDave | Thanks. |
| 19:41 | defn | there's also one for errors |
| 19:41 | defn | *e I believe |
| 19:41 | defn | exceptions, rather |
| 19:41 | defn | ,*e |
| 19:41 | clojurebot | java.lang.IllegalStateException: Var clojure.core/*e is unbound. |
| 19:42 | KirinDave | ,*1 |
| 19:42 | clojurebot | java.lang.IllegalStateException: Var clojure.core/*1 is unbound. |
| 19:42 | defn | hehe, not here though :) |
| 19:42 | KirinDave | Heh |
| 19:42 | cemerick | heh, no more dots on method impls, eh? |
| 19:45 | rhickey_ | cemerick: no, they don't match protocols well at all |
| 19:45 | cemerick | ah, consistency. Well, I really liked them while they lasted. :-) |
| 19:45 | rhickey_ | I think they made sense without protocols, but I want protocols to be the primary story, since now it is so good |
| 19:46 | cemerick | yeah, no argument from me |
| 19:47 | KirinDave | Is there a new description for protocols |
| 19:47 | KirinDave | ? |
| 19:47 | KirinDave | Besides the old thread on the list? |
| 19:48 | rhickey_ | KirinDave: I'm tweaking the wiki now, but the inline (doc ...) should all be correct, for reify, deftype, defprotocol etc |
| 19:48 | defn | Is there any ongoing effort to provide real-world examples for the api documentation? |
| 19:49 | KirinDave | rhickey_: I will start fanatically clicking the refresh button in anticipation. :) |
| 19:50 | KirinDave | I'm excited about things that make noun-y programming a bit easier. |
| 19:51 | rhickey_ | KirinDave: I'm not sure this does that |
| 19:52 | defn | I'm interested in building an expanded documentation project that adds some real world examples to the api documentation. |
| 19:52 | defn | (where appropriate) |
| 19:52 | defn | For things like (ns) it could be nice to have somewhere to document that sort of thing |
| 19:52 | KirinDave | rhickey_: My use case is very banal. I've been bugging people here about a foosball scoring webapp. |
| 19:53 | KirinDave | rhickey_: And I find it kind of tedious to have to write things like make-player and make-team. |
| 19:53 | rhickey_ | defn: there is this: http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Cookbook |
| 19:53 | _mst | defn: how about http://en.wikibooks.org/wiki/Clojure_Programming? |
| 19:55 | defn | That's pretty nice, I guess I would like to see something like ruby-doc.org/core |
| 19:55 | rhickey_ | defn: not trying to discourage you, contributions welcome |
| 19:56 | defn | rhickey_: would it make sense to start a new project, or to submit to you additions to the current api documentation? |
| 19:56 | rhickey_ | defn: the api doc is reference-style and is likely to stay that way |
| 19:58 | KirinDave | is clojure.contrib.seq-utils open for suggestions? |
| 19:59 | KirinDave | Just via the normal github process maybe? |
| 20:00 | rhickey_ | KirinDave: there is the ggroup and contrib assembla |
| 20:17 | rhickey_ | https://www.assembla.com/wiki/show/clojure/Datatypes and https://www.assembla.com/wiki/show/clojure/Protocols updated, feedback welcome |
| 20:18 | rhickey_ | this all feels good to me now, please try it out |
| 20:23 | bitbckt | I don't think I've seen this asked, but forgive me if it has been... |
| 20:23 | bitbckt | "resulting functions dispatch on the type of their first argument"... why only the first? |
| 20:24 | rhickey_ | bitbckt: there are multimethods if you want to do other than that |
| 20:24 | rhickey_ | protocols let you reach the highest level of polymorphism perf available on the platform |
| 20:25 | bitbckt | I see. Multimethods are still to be preferred for multiple dispatch, then. |
| 20:25 | rhickey_ | bitbckt: no other choice for that |
| 20:26 | bitbckt | Okay. Thanks. :) |
| 21:14 | arohner | I have a protocol. I have a deftype that implements a method on the protocol's interface. In my deftype declaration, I'm getting clojure.lang.Var cannot be cast to java.lang.Class |
| 21:14 | arohner | lisppaste8: url? |
| 21:14 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 21:15 | chouser | rhickey_: what about allowing (defprotocol P (bar [x] [x y])) for multiple args, rather than (bar ([x] [x y])) ? |
| 21:15 | lisppaste8 | arohner pasted "deftype" at http://paste.lisp.org/display/91318 |
| 21:15 | rhickey_ | chouser: maybe, where do docs go? |
| 21:16 | rhickey_ | I agree the grouping is unintuitive |
| 21:16 | chouser | hm, at the end I guess, where they do now. |
| 21:17 | chouser | name, vectors, then a string. |
| 21:18 | lisppaste8 | rhickey annotated #91318 "deftype for latest" at http://paste.lisp.org/display/91318#1 |
| 21:18 | chouser | arohner: your deftype doesn't look quite right |
| 21:18 | rhickey_ | see annotation ^ |
| 21:19 | rhickey_ | no dots anymore, no [] around methods |
| 21:19 | arohner | my checkout is probably a week old. I'll update. |
| 21:21 | rhickey_ | arohner: yeah, the version you are using doesn't support protocols in deftype |
| 21:21 | arohner | ah! that would be a problem. thanks |
| 21:22 | chouser | heh. This error message seems like it ought to be informative enough. |
| 21:22 | chouser | No single method: foo of interface: user.Foo found for function: foo of protocol: Foo |
| 21:23 | hiredman | ouch |
| 21:23 | chouser | maybe if I used names better than "foo" it would help :-P |
| 21:26 | rhickey_ | chouser: what were you doing? |
| 21:27 | chouser | ooh, I can use 'show' to see the protocol methods implemented directly by a deftype |
| 21:27 | chouser | rhickey_: just playing at the repl |
| 21:27 | chouser | ...and I see what I did wrong. |
| 21:28 | chouser | so methods defined inline in a deftype get real methods in the resulting class, right? |
| 21:28 | rhickey_ | yes |
| 21:28 | chouser | but anything added via extend doesn't? |
| 21:29 | rhickey_ | right, can't, class is baked |
| 21:29 | chouser | right, makes sense. |
| 21:31 | arohner | so where do methods added via extend go? |
| 21:32 | rhickey_ | they are fns in maps |
| 21:33 | rhickey_ | stored in protocol itself |
| 21:34 | chouser | so, faster than multimethods but not as fast as a case or direct method call? |
| 21:35 | rhickey_ | as fast as call through var, given caching. Doesn't lookup every time |
| 21:36 | chouser | ok, nice. |
| 21:36 | dnolen | rhickey_: so I saw that you mean somewhere that the inclusion of deftype will remove the need for type metadata pattern? or am I dreaming that up andi it's still useful? :) |
| 21:37 | dnolen | mean -> mention |
| 21:37 | chouser | (deftype Foo [a b c] [] (foo [this] <<here>>)) ; at <<here>>, 'a' is the same as '(:a this)'? |
| 21:37 | rhickey_ | dnolen: well, protocols won't use type metadata, so I expect it to fall by the wayside |
| 21:38 | rhickey_ | chouser: there a is the same as (.a this) |
| 21:38 | hiredman | chouser: did you see my fn minus |
| 21:39 | rhickey_ | looks like external protocol defs are broken, aargh |
| 21:39 | chouser | hiredman: no I didn't. |
| 21:40 | dnolen | rhickey_: so you expect that people that really want to define a type, will just use deftype over map plus metadata? |
| 21:40 | rhickey_ | dnolen: yes |
| 21:41 | hiredman | http://paste.lisp.org/display/91148#1 this was more or less sitting in my head when I woke up thanksgiving morning |
| 21:41 | dnolen | rhickey_: duh, I forgot that deftype creates a type tag for you. It's so magical! :) |
| 21:44 | chouser | hiredman: did you just toss together a little tree-walking macro!? |
| 21:44 | hiredman | oh, it just uses tree-seq |
| 21:45 | hiredman | very simple, which is why I called it fn minus, I was just kind of tickled by how easy it just falls out |
| 21:46 | chouser | so that's an implementation of fn in terms of deftype. |
| 21:46 | chouser | ? |
| 21:46 | hiredman | well AFn needs to be a protocol |
| 21:47 | hiredman | hmmm |
| 21:47 | efarrar | is there a mechanism to override/overload java methods from clojure? I'd sure love it if javax.swing.JContainer#setPreferredSize() took a height and a width, and not a java.awt.Dimension |
| 21:47 | hiredman | IFn would be the protocol and AFn would just be a map of functions you can mix in |
| 21:48 | JAS415 | efarrar: proxy? |
| 21:48 | efarrar | i'll check it out |
| 21:48 | efarrar | thanks |
| 21:48 | hiredman | chouser: so yes then |
| 21:49 | efarrar | i thought that was just for interfaces |
| 21:49 | hiredman | proxy doesn't let you create new methods |
| 21:50 | hiredman | efarrar: just write a function |
| 21:51 | hiredman | (defn set-prefered-size [jcontainer height width] (.setPreferedSize jcontainer (Dimension. width height))) |
| 21:53 | efarrar | fair enough |
| 22:01 | rhickey_ | ok, all fixed, grab latest if playing with new branch |
| 22:08 | arohner | hrm, github is lying. |
| 22:09 | arohner | git pull says I'm up-to-date, but the commit id doesn't match the github UI |
| 22:09 | hiredman | have to wait for the latest commit to replicate out |
| 22:10 | arohner | this time it worked |
| 22:13 | Base | Hi |
| 22:15 | rhickey_ | Hi |
| 22:21 | arohner | is there a way to specify a default method for a protocol? |
| 22:22 | arohner | for all types |
| 22:22 | rhickey_ | extend to Object |
| 22:22 | hiredman | maybe extend the protocol on Object? |
| 22:23 | hiredman | ahem |
| 22:23 | hiredman | extend to |
| 22:23 | rhickey_ | will cover everything except nil |
| 22:23 | rhickey_ | you can also extend to nil |
| 22:23 | arohner | thanks |
| 22:25 | dnolen | rhickey: can extend be used to add metadata support to fns? |
| 22:25 | rhickey_ | dnolen: no |
| 22:36 | dnolen | technomancy: do you have to run lein install in the lein-swank directory first? |
| 23:10 | JAS415 | hmm |
| 23:10 | JAS415 | i'm having trouble with the pprint package |
| 23:10 | JAS415 | ,(clojure.contrib.pprint/cl-format nil "~s" 1) |
| 23:11 | clojurebot | java.lang.ClassNotFoundException: clojure.contrib.pprint |
| 23:11 | alexyk | is there any BitSet wrapper in clojure, or just JDK BitSet? |
| 23:13 | The-Kennz | JAS415: have you clojure-contrib.jar in your classpath? |
| 23:14 | technomancy | dnolen-rec: I pushed out lein-swank under the leiningen group |
| 23:14 | dnolen | technomancy: just now? |
| 23:14 | JAS415 | yup |
| 23:14 | JAS415 | been using all of the other contrib stuff |
| 23:14 | technomancy | dnolen: no, a few days ago |
| 23:15 | dnolen | technomancy: so here's the deal, lein swank only works for me from the lein-swank folder in the leiningen checkout directory |
| 23:15 | dnolen | technomancy: i can't get it to work at all outside that directory. |
| 23:16 | technomancy | dnolen: have you declared it as a dev dependency of the project you want to use it on? |
| 23:16 | dnolen | technomancy: yup |
| 23:16 | technomancy | can you paste your project.clj? |
| 23:16 | dnolen | :dev-dependencies [[leiningen/lein-swank "1.0.0-SNAPSHOT"]] |
| 23:16 | dnolen | https://gist.github.com/4cefd43eca404c351f22 |
| 23:17 | dnolen | I added the swank-clojure dependency as a debug shot in the dark, I don't think that's required |
| 23:17 | technomancy | no, it should get pulled in automatically |
| 23:17 | technomancy | ah, did you run lein deps to pull in all the dependencies? |
| 23:18 | dnolen | technomancy: here's the stack trace when I run lein deps |
| 23:18 | dnolen | http://gist.github.com/246047 |
| 23:19 | The-Kennz | Woho, I love lein-swank |
| 23:19 | technomancy | wow; crazy. I'll clear it out of my local repo and try again |
| 23:19 | dnolen | technomancy: should I do that as well? |
| 23:19 | technomancy | you could try it. |
| 23:19 | dnolen | like erase everything out of ~/.m2 ? |
| 23:20 | dnolen | technomancy: erase whole directory or just the subdirectories? |
| 23:20 | technomancy | I can't repro. =\ |
| 23:20 | technomancy | ah: "Unable to store local copy of metadata"... |
| 23:20 | technomancy | maybe it's just a permissions thing |
| 23:20 | technomancy | try chowning and chmodding ~/.m2 first |
| 23:22 | dnolen | technomancy: yup permissions |
| 23:22 | dnolen | thx |
| 23:22 | dnolen | lein rulez |
| 23:22 | technomancy | cool; did you previously run lein as sudo or something? |
| 23:23 | dnolen | I probably did nonsensically at some point yes :P |
| 23:23 | technomancy | well if you're used to rubygems or something... =) |
| 23:24 | alexyk | I get an error in maven witrh clojure plugin, when it tries compiling a script which feeds fine into a repl: java.lang.Exception: Unable to resolve symbol: only in this context. Points to a line which is fine in repl, no actual symbol shown... is it normal? |
| 23:24 | dnolen | technomancy: yeah, Python also encourages the overly eager use of sudo. |
| 23:25 | dnolen | technomancy: I started a wiki stub, is lein install necessary from the lein-swank directory at all? |
| 23:25 | dnolen | or does it just get pulled in? |
| 23:28 | technomancy | dnolen: it should be able to pull it from coljars |
| 23:28 | technomancy | *clojars |
| 23:28 | dnolen | technomancy: does lein swank work on the stable branch work, or do you have to be on the master branch? |
| 23:29 | alexyk | how do you replace the first space in a string by a T ? |
| 23:30 | arohner | alexyk: have you see clojure.contrib.str-utils2? |
| 23:31 | alexyk | arohner: not yet! |
| 23:31 | technomancy | dnolen: I think it might work on 0.5.0 but haven't tested it |
| 23:32 | alexyk | where's the standard docs for contrib? in fact, what do you guys have instead of javadoc/scaladoc? :) |
| 23:34 | the-kenny | alexyk: http://richhickey.github.com/clojure-contrib/index.html |
| 23:34 | alexyk | the-kenny: thx! |
| 23:35 | arohner | alexyk: there's also (doc function-name) and (find-doc string) from the repl |
| 23:35 | arohner | ,(doc map) |
| 23:35 | clojurebot | "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments." |
| 23:35 | alexyk | so does clojure have thingies to generate API docs a ;a javadoc? |
| 23:35 | alexyk | a la |
| 23:35 | alexyk | a lá |
| 23:36 | cark | "à la" =) |
| 23:36 | arohner | or (find-doc "replace") |
| 23:37 | alexyk | cark: finally my wrong pattern is corrected by a Francophone! :) |
| 23:38 | cark | =) |
| 23:38 | alexyk | cark: or should I say a Walloon? :) |
| 23:38 | cark | indeed |
| 23:40 | alexyk | so how did rhickey generate those docs? |
| 23:41 | cark | you mean the docs from (doc some-function) ? |
| 23:41 | cark | or a la javadoc ? |
| 23:42 | alexyk | cark: the docs on the website, http://richhickey.github.com/clojure-contrib/str-utils2-api.html -- or is it just a concatenation of the doc strings from the defn's? |
| 23:42 | arohner | alexyk: those are just the doc strings on the defns |
| 23:43 | alexyk | arohner: ok |
| 23:43 | arohner | and on the namespace |
| 23:46 | alexyk | how do I import just that replace from a repl, not from ns macro? |
| 23:46 | alexyk | repl complains about: (use 'clojure.contrib.str-utils2 :only [replace]) |
| 23:48 | The-Kennz | alexyk: alexyk There's already a replace in clojure.core |
| 23:48 | alexyk | and if I want to import str-utils2 as a whole, I get: repeat already refers to: #'clojure.core/repeat in namespace: user |
| 23:48 | alexyk | is it predefined in core too? |
| 23:48 | The-Kennz | alexyk: You have to import like this: (use '[clojure.core.str-utils2 :as strut]) and use like this: (strut/replace ...) |
| 23:49 | KirinDave | The-Kennz: You mean require, right? |
| 23:49 | The-Kennz | alexyk: But that's mentioned in the doc for str-utils2 |
| 23:49 | alexyk | ah ok |
| 23:49 | The-Kennz | KirinDave: Yes.. I always forget when I have to use which one ;) |
| 23:50 | The-Kennz | alexyk: (require '[clojure.contrib.str-utils2 :as s]) says the doc |
| 23:50 | alexyk | btw, (doc clojure.contrib.str-utils2) is nil |
| 23:51 | The-Kennz | alexyk: doc prints the meta-description for a var, clojure.contrib.str-utils2 isn't a var |
| 23:51 | The-Kennz | ,(doc doc) |
| 23:51 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 23:51 | alexyk | ah ok |
| 23:53 | alexyk | so if I have a Java BitSet as state, do I have to wrap it in any refs or atoms? |
| 23:55 | tomoj | clojure concurrency won't help you there |
| 23:56 | alexyk | tomoj: I wonder if I need any by law :) |
| 23:57 | hiredman | alexyk: refs, atoms, agents, etc, are designed to hold immutable things |
| 23:57 | alexyk | what is defn- ? |
| 23:57 | notallama | private defn |
| 23:57 | alexyk | notallama: what's the private scope? |
| 23:58 | the-kenny | alexyk: Functions defined by defn- don't get exported from its namespace |
| 23:58 | tomoj | I suppose if you wanted to just have a bitset as state which gets replaced with an entirely new bitset but is never changed itself, you could use refs/etc |
| 23:59 | technomancy | dnolen: did you send that github message before you got everything sorted out? |
| 23:59 | alexyk | tomoj: I need a map with millions of keys with small bitsets hanging off the leaves... The map may be worked in parallel, but the leaves must be updated atomically |