2011-07-11
| 01:19 | jonasen | Does records support metadata? |
| 01:21 | sean_corfield | vars support metadata |
| 01:22 | sean_corfield | so a var that's an instance of a record can have metadata |
| 01:22 | sean_corfield | is that what you mean? |
| 01:23 | hiredman | sean_corfield: a var is a var |
| 01:23 | seancorfield_ | hiredman: thank you for that :) |
| 01:23 | seancorfield_ | jonasen: could you clarify your question? |
| 01:23 | jonasen | not really, maps can hold metadata as in (meta ^{:a :b} {}) |
| 01:24 | hiredman | seancorfield_: just saying "so a var that's an instance of a record can have metadata" is nonsense |
| 01:24 | hiredman | vars are never instances of a record |
| 01:24 | seancorfield_ | ok, sloppy terminology |
| 01:25 | hiredman | (nonsense) |
| 01:25 | chouser | records support metadata |
| 01:25 | seancorfield_ | which is why i asked jonasen to clarify the question |
| 01:25 | jonasen | So I would have guessed that records could too |
| 01:25 | chouser | jonasen: yes, they can. |
| 01:25 | chouser | do |
| 01:25 | hiredman | jonasen: what does ^{:a 1} do? |
| 01:25 | hiredman | vs. with-meta |
| 01:26 | seancorfield_ | chouser: so you can declare metadata with a record type and then add to it when you have a var bound to an instance of that type? i guess i'm having a hard time envisaging it without an example |
| 01:27 | jonasen | oh, I thought ^{:a :b} was shorthand for (with-meta ...) |
| 01:27 | hiredman | the follow up equestion is: why would with-meta and ^ appear to behave differently for records but the same for maps |
| 01:27 | hiredman | seancorfield_: do you understand how metadata works? |
| 01:28 | seancorfield_ | hiredman: do you understand how sarcastic you sound? there are ways to explain things without being so condescending |
| 01:28 | chouser | (defrecord R [a b]) (meta (with-meta (R. 1 2) {:foo :bar})) ;=> {:foo :bar} |
| 01:29 | hiredman | there are two ways to support metadata in clojure, mutable and immutable |
| 01:29 | hiredman | seancorfield_: and? |
| 01:30 | jonasen | chouser: If I understand http://clojure.org/reader correctly, (meta ^{:foo :bar} (R. 1 2)) should work too? |
| 01:30 | hiredman | jonasen: does (meta ^{:foo :bar} (hash-map :a :b)) work? |
| 01:31 | jonasen | so ^{..} only works for literals. |
| 01:32 | chouser | ^{} is metadata that is applied to the *form* at *read time* |
| 01:32 | hiredman | ^ is for reader metadata |
| 01:32 | jonasen | ok, I think I got it now. Thanks all! |
| 01:32 | chouser | some things then take that metadata from their form and apply it to an object available at runtime. The data literals do this. |
| 01:34 | seancorfield_ | ,(meta (with-meta (hash-map :a :b) {:foo :bar})) |
| 01:34 | clojurebot | {:foo :bar} |
| 01:35 | ibdknox | seancorfield_: sadly some people feel the need to be an ass :( Gotta just shrug it off. |
| 01:40 | seancorfield_ | (def ^{:foo :bar} v (R. 1 2)) (meta #'v) => {:ns #<Namespace user>, :name v, :file "NO_SOURCE_PATH", :line 12, :foo :bar} |
| 01:41 | hiredman | and? |
| 01:41 | amalloy | seancorfield_: getting vars involved clouds the picture for no clear purpose |
| 01:41 | amalloy | def (and defn) take the metadata of the symbol (which ^{...} applies at read time) and applies it to the var at evaluation time |
| 01:42 | amalloy | this is a convenience for attaching metadata to vars, which is otherwise difficult, and should not be confused with adding metadata to *values*, like a record |
| 01:43 | seancorfield_ | right, and i wasn't sure from jonasen's question which he was asking about |
| 01:43 | jonasen | seancorfield_: I was asking about metadata on values (specifically maps and records) |
| 01:44 | seancorfield_ | 'k... so we have the answer to both then |
| 01:48 | seancorfield_ | so what values can have metadata? IObj? |
| 01:51 | amalloy | seancorfield_: or IMeta, depending on what you mean by "have" |
| 01:53 | jonasen | seancorfield_: symbols and collections according to http://clojure.org/metadata |
| 01:53 | seancorfield_ | IObj extends IMeta? (sorry, my screen is very small and Clojure Atlas's info doesn't fully fit |
| 01:54 | amalloy | &(supers clojure.lang.IObj) |
| 01:54 | sexpbot | ⟹ #{clojure.lang.IMeta} |
| 01:54 | seancorfield_ | &(supers clojure.lang.IReference) |
| 01:54 | sexpbot | ⟹ #{clojure.lang.IMeta} |
| 02:01 | amalloy | &(let [m {:x 1}] (meta (reify clojure.lang.IMeta (meta [this] m)))) |
| 02:01 | sexpbot | java.lang.ClassFormatError: Duplicate method name&signature in class file sandbox21497$eval23915$reify__23916 |
| 02:01 | amalloy | huh |
| 02:02 | jonasen | Now I don't understand metadata anymore :). In addition to collections and symbols, all reference types support metadata. Correct? |
| 02:02 | seancorfield_ | this little discussion has helped me understand (def ^{:foo 1} v ^{:bar 2} {:a :b}) |
| 02:02 | seancorfield_ | and why (meta v) and (meta #'v) are different |
| 02:02 | amalloy | jonasen: anything that implements IObj can support metadata |
| 02:03 | amalloy | usually it's easiest to avoid working with metadata on reference types, except for what gets added to vars when you def them |
| 02:05 | amalloy | hiredman, chouser: it looks like the compiler automatically imlements IObj for you when you reify an object. is there some reason for that? |
| 02:13 | jonasen | I think what I find confusing is that (def ^{:foo :bar} a) puts metadata on the Var, not the symbol 'a. But something like (with-meta #'a {:foo :bar}) doesn't work |
| 02:14 | hiredman | with-meta is for the immutable metadata interface |
| 02:14 | hiredman | ,(doc alter-meta) |
| 02:14 | clojurebot | Gabh mo leithscéal? |
| 02:14 | hiredman | ,(doc alter-meta!) |
| 02:14 | clojurebot | "([iref f & args]); Atomically sets the metadata for a namespace/var/ref/agent/atom to be: (apply f its-current-meta args) f must be free of side-effects" |
| 02:15 | hiredman | ^- is what you use for the mutable metadata interface (which is what the reference types use) |
| 02:15 | amalloy | ~source alter-meta! |
| 02:17 | jonasen | So what are the semantic differences for metadata on values vs. reference types? |
| 02:18 | hiredman | ,(let [a {}] (identical? a (with-meta a {:foo 1}))) |
| 02:18 | clojurebot | false |
| 02:18 | amalloy | welllll, reference types mutate their metadata in-place |
| 02:19 | hiredman | ,(let [a (ref 1)] (identical? a (alter-meta! a assoc :foo 1))) |
| 02:19 | clojurebot | false |
| 02:19 | hiredman | uh |
| 02:19 | hiredman | right |
| 02:19 | hiredman | ,(let [a (ref 1)] (identical? a (do (alter-meta! a assoc :foo 1) a))) |
| 02:19 | clojurebot | true |
| 02:19 | jonasen | amalloy: and with values a new value is returned with different metadata |
| 02:23 | seancorfield_ | nice example that with-meta can't be used with (ref 1) but alter-meta! can |
| 02:36 | amalloy | seancorfield_: an interesting exercise to make sure you know what's going on is to implement clojure.contrib.def/defalias |
| 02:37 | amalloy | defining an alias for a macro, with all the correct metadata copied, is harder than it looks |
| 02:43 | ihodes | coming into this way late; the meta hashmap on a Var is just a field in the instance of the var, right? |
| 03:00 | seancorfield__ | amalloy: yes, congomongo used defalias and we just dropped that when moving it to clojure 1.3 since that macro has not been promoted to new contrib |
| 03:01 | seancorfield__ | i'm not sure i really understand why defalias is all that useful |
| 03:01 | seancorfield__ | enlightenment? |
| 03:01 | amalloy | ihodes: yes |
| 03:01 | amalloy | but it's an implementation detail that could change, etc etc |
| 03:03 | amalloy | seancorfield__: it's not really useful, but it can be convenient. eg, if you like to use complement the long name is a pain, and you might choose to call it ! instead. or you want to re-export some var from another namespace into yours (though this usage has some pitfalls) |
| 03:07 | seancorfield__ | so, like exporting foo* from an internal namespace to foo in the main namespace? |
| 03:08 | amalloy | something like that |
| 03:09 | amalloy | of course you can just (def ! complement), but then you don't get the metadata like :arglists for slime, and it won't work for macros |
| 03:10 | seancorfield__ | 'k good to know the downside |
| 03:22 | ihodes | IFn.java has really grown hasn't it? whew. |
| 03:23 | amalloy | (defmacro defalias [dst src] `(let [v# (var ~src)] (doto (def ~dst @v#) (alter-meta! (constantly (meta v#)))))) is more or less what you need, if anyone is curious |
| 03:23 | ihodes | let's throw in type hinting for ints and floats while we're at it. and support at least arity of 6. i mean, come on, that file can stand to grow some more ;) |
| 03:31 | ihodes | what does RT stand for? in clojure.lang |
| 03:36 | amalloy | runtime |
| 03:50 | ihodes | amalloy: ah, thanks. of course. |
| 06:08 | bulters | anyone here happens to get slimv working with macvim? |
| 07:28 | bsod1_ | how can Clojure supports adding different types in a java data structure like hashmap or arraylist? |
| 08:10 | peteriserins | how to see if two lists are the same object? |
| 08:23 | peteriserins | ok it was identical? that I needed |
| 09:02 | chouser | peteriserins: Under normal circumstances you shouldn't need to know that about lists. What are you doing? |
| 09:06 | gfrlog | man using defrecord makes my lein workflow different |
| 09:22 | chouser | gfrlog: really? |
| 09:27 | ffailla | /join #thortech yorktown |
| 10:52 | bpr | ping technomancy |
| 11:08 | gfrlog | chouser: yeah, I had issues with stale record definitions that required "lein clean", which I almost never have to do otherwise |
| 11:08 | chouser | bleh |
| 11:13 | gfrlog | chouser: in lein's defense, I had an older version (though I don't know which one) |
| 11:14 | chouser | I think it's Clojure's fault, not lein's |
| 11:15 | chouser | But maybe nothing can be done |
| 11:16 | chouser | if you have an instance of an old defrecord around, re-running defrecord has to create a new class and the old instaces won't act the same as the new ones |
| 11:17 | cemerick | yeah, not a lot that can be done there |
| 12:11 | Scripiology | about time :p |
| 12:11 | cemerick | ;-) |
| 12:13 | Scripiology | noooooo |
| 12:31 | tibbe | cemerick: I want to see it too so I can follow up with this year's Haskell survey ;) |
| 12:45 | Scripiology | yay, ideas I'm learning from Clojure seem to carry over with reasonable efficiency to PHP |
| 12:45 | Scripiology | actually, never mind |
| 12:46 | chouser | ha! |
| 12:50 | pyr | any pallet users ? |
| 12:50 | pyr | around i mean :) |
| 12:51 | __name__ | pyr: http://upload.wikimedia.org/wikipedia/commons/7/74/Wooden_pallet_with_glove.jpg that? |
| 12:51 | __name__ | Not the glove … |
| 12:55 | pyr | nope, https://github.com/hugoduncan/pallet that :) |
| 12:55 | sritchie | pyr: yes, but you may have more luck in #pallet |
| 12:55 | pyr | ah, nice to know it exists :) will head off there |
| 12:55 | sritchie | see you there! |
| 13:55 | shintaku | how should i install clojure on mac os x so that the repl doesn't suck in iTerm2? should i use rlwrap? or should i try clojure out with one of the newer jline versions out there, such as the one used for scala? |
| 13:55 | amalloy | jline is terrible. use rlwrap |
| 13:56 | hiredman | I suggest using the repl that comes with your editor |
| 13:56 | shintaku | actually, the jline that ships with scala is not so bad |
| 13:56 | shintaku | with scala 2.9+ |
| 13:56 | shintaku | hiredman: you obviously haven't tried using clj in iTerm2 |
| 13:57 | shintaku | ohh |
| 13:57 | shintaku | you said editor |
| 13:57 | shintaku | my mistake |
| 13:57 | hiredman | I have yet to see a decent shell launcher script for clojure |
| 13:58 | mdeboard | emacs++ |
| 13:58 | hiredman | I think people are only interested in having one for about the first month or so using clojure and after that there is no strong desire to have one, so the onse out there are junk |
| 13:58 | shintaku | i googled for rlwrap and clojure and was told to download a bunch of scripts so i stopped |
| 13:58 | shintaku | they were all outdated too: http://trac.macports.org/browser/trunk/dports/lang/clojure/files/ |
| 13:58 | hiredman | ugh |
| 13:58 | hiredman | no |
| 13:59 | hiredman | anytime you are using the jvm and you say something like "I used my systems package manager to ..." you are doing it wrong |
| 13:59 | shintaku | pretty much. i was just downloading those files separately |
| 14:00 | mdeboard | hiredman: ...to install OpenJDK? Serious question, can you explain? |
| 14:00 | scgilardi | "lein repl" works and uses rlwrap if present. |
| 14:01 | hiredman | mdeboard: well no, not the jvm itsself, but in almsot all cases installing jars via the system package manager is the wrong thing to do |
| 14:01 | mdeboard | Why? I mean, is there a reason apart from the general awfulness of most package managers? |
| 14:02 | hiredman | mdeboard: they assume they way your language works is a global code space (see C, and C language conventions) which is not what the jvm has |
| 14:02 | hiredman | the way |
| 14:03 | scgilardi | maven (and maven-compatible tools) do a better job of retrieving current versions of jars than system package managers. |
| 14:05 | hiredman | each running jvm is a different virtual machine and gets a different classpath (like every application getting a unique LD_LIBRARY_PATH), there is no shared /usr/lib, etc |
| 14:05 | hiredman | different world from what package managers are written for |
| 14:05 | technomancy | debian at least is strongly geared towards packaging up applications for end users. if you're a developer, that model is unhelpful because you need things like multiple versions of the same library to co-exist on a single machine |
| 14:06 | technomancy | so if you just want to use hudson or whatever, that usually works. if you want to use lucene, apt-get is not going to be helpful. |
| 14:06 | technomancy | err--I mean jenkins. sheesh. |
| 14:11 | mdeboard | Yeah lein reminds me a lot, at least superficially, of RVM for Ruby |
| 14:11 | technomancy | that's funny since I quit using ruby right before rvm was written |
| 14:11 | kumarshantanu | can anybody tell why does this throw FileNotFoundException — (clojure.java.io/reader "file:///tmp") |
| 14:12 | amalloy | you can't read characters from a directory |
| 14:12 | hiredman | kumarshantanu: reader may not expect a file url |
| 14:12 | hiredman | "/tmp" |
| 14:13 | amalloy | hiredman: it's happy to take URLs |
| 14:13 | amalloy | it just can't read directories. you have to open them as File objects and then list them |
| 14:13 | technomancy | yeah, not really sure what you're expecting from that |
| 14:14 | mdeboard | technomancy: I'm a big-time beginner with Clojure (ergo Lein) and a novice iwth Ruby, but rvm is great, and I really prefer it to virtualenv for Python. |
| 14:14 | kumarshantanu | hmm, so it should not say "No such file or directory" in the exception then — just "No such file" |
| 14:15 | amalloy | kumarshantanu: blame your OS |
| 14:15 | amalloy | mine says: /tmp (Is a directory) |
| 14:16 | technomancy | "no such file or directory" is also the exception you get when you try to run a 32-bit executable on a 64-bit OS. it's just JDK nonsense. |
| 14:17 | kumarshantanu | using the default JDK (1.6.0_26) on 64-bit Snow Leopard |
| 14:18 | kumarshantanu | okay |
| 14:24 | brettkromkamp | good afternoon |
| 14:25 | brettkromkamp | clojure n00b |
| 14:25 | brettkromkamp | on the block :-) |
| 14:25 | tufflax | ni |
| 14:25 | tufflax | hi |
| 14:25 | brettkromkamp | hi |
| 14:26 | brettkromkamp | well... when i say clojure noob, probably functional programming noob is a better description |
| 14:26 | tufflax | state of clojure 2011 results are not up yet, right? |
| 14:26 | Scripiology | tufflax: I think he's working on them today |
| 14:26 | tufflax | oh nice |
| 14:26 | Scripiology | or at least some time this week |
| 14:26 | mdeboard | Wait, what? |
| 14:26 | brettkromkamp | i hope i have come to the right place to ask some really beginners questions |
| 14:26 | tufflax | mdeboard ? |
| 14:26 | Scripiology | brettkromkamp: go for it! |
| 14:27 | mdeboard | State of Clojure? What a pointless speech. Clojure's state never changes. |
| 14:27 | brettkromkamp | i've installed emacs |
| 14:27 | mdeboard | badum-pshhhhh |
| 14:27 | brettkromkamp | installed clojure mode |
| 14:27 | brettkromkamp | installed swank and slime |
| 14:27 | mdeboard | stop |
| 14:27 | mdeboard | brettkromkamp: |
| 14:27 | mdeboard | uninstall swank and slime |
| 14:27 | brettkromkamp | got some clojure books |
| 14:27 | brettkromkamp | everything seems to be working |
| 14:27 | brettkromkamp | repl responding |
| 14:27 | mdeboard | which repl? |
| 14:27 | brettkromkamp | no apparent problems there |
| 14:28 | brettkromkamp | no... my questions are bigger than configuration/installation issues |
| 14:28 | brettkromkamp | mdeboard: clojure repl |
| 14:28 | brettkromkamp | clojure 1.2.1 |
| 14:28 | brettkromkamp | all working fin |
| 14:28 | brettkromkamp | *fine |
| 14:29 | brettkromkamp | goto start on my version of "hello world" |
| 14:29 | brettkromkamp | which is: http://www.quesucede.com/page/show/id/python_tree_implementation |
| 14:29 | mdeboard | this is a very lengthy setup |
| 14:30 | brettkromkamp | implementing a tree structure |
| 14:30 | brettkromkamp | in clojure |
| 14:30 | brettkromkamp | i know |
| 14:30 | brettkromkamp | by all means, bail out if you get board with me/it :-) |
| 14:30 | brettkromkamp | trying to make the jump from imperative programmer to functional programmer |
| 14:30 | mdeboard | Well, I just started teaching myself Clojure Friday so I thought I might have some help for you, just waiting for the question |
| 14:31 | brettkromkamp | ok... here goes |
| 14:31 | brettkromkamp | in python, my tree structure is stored in a list |
| 14:31 | brettkromkamp | and i append 'nodes' to the list |
| 14:31 | brettkromkamp | but in clojre |
| 14:31 | brettkromkamp | *clojure |
| 14:31 | brettkromkamp | everything is supposed to be immutable |
| 14:31 | brettkromkamp | so... when i apped a node to this list |
| 14:32 | brettkromkamp | what is actually happening? |
| 14:32 | Scripiology | using something like conj/cons? |
| 14:32 | brettkromkamp | am i getting a *new* copy of the list with the appended node? |
| 14:32 | brettkromkamp | yep |
| 14:32 | tufflax | you get a new list, that shares structure with the old one |
| 14:32 | Scripiology | it will create a new list with the new node prepended to the old list |
| 14:32 | brettkromkamp | ah |
| 14:32 | Scripiology | but the original list is unchanged, of course |
| 14:32 | brettkromkamp | so that doesn't mean that for each newly appended node |
| 14:33 | tufflax | sharing structure makes it fast, and it is safe because they are immutable |
| 14:33 | brettkromkamp | i get a completely new list back |
| 14:33 | brettkromkamp | ? |
| 14:33 | Scripiology | yes |
| 14:33 | mdeboard | yep |
| 14:33 | brettkromkamp | say i append 100 nodes |
| 14:33 | brettkromkamp | do i have 100 list structures floating around |
| 14:33 | brettkromkamp | in memory |
| 14:33 | brettkromkamp | ? |
| 14:33 | Scripiology | brettkromkamp: note what tufflax said |
| 14:33 | mdeboard | Joy of Clojure has an amazing explanation of immutable state, if that's one of your books |
| 14:33 | dnolen | brettkromkamp: garbage collection |
| 14:33 | tufflax | for a list (linked list) you get a 100 long list, but 100 different pointers into it |
| 14:33 | brettkromkamp | mdeboard |
| 14:34 | brettkromkamp | mdeboard: it is |
| 14:34 | mdeboard | brettkromkamp: section 1.4.1 |
| 14:34 | mdeboard | go read it :) |
| 14:34 | Scripiology | dnolen: I think he meant doing a 100 conses in a row and storing that, so gc wouldn't have come in yet |
| 14:34 | mdeboard | It's so good I memorized the section |
| 14:34 | brettkromkamp | i do |
| 14:34 | brettkromkamp | checking it now |
| 14:35 | Scripiology | brettkromkamp: you know how a linked list works? Clojure's list is similar, except that the sequence abstraction lets you think of each node in the linked list as a list of its own |
| 14:35 | brettkromkamp | scripiology: linked list? yes... i know how they are implemented (in high-level terms) |
| 14:36 | Scripiology | cool, let's start from the beginning, say you have a list of one item: '(3) |
| 14:36 | brettkromkamp | ok |
| 14:37 | brettkromkamp | said list also represents a given 'state' right? |
| 14:37 | Scripiology | inside the Clojure runtime this equates to having one object of class PersistentList (and an empty list object at the end of that, but that's not relevant right now) |
| 14:37 | brettkromkamp | ok |
| 14:37 | Scripiology | yep, a list can be considered a 'state', but we can cover that later |
| 14:37 | brettkromkamp | ok |
| 14:37 | Scripiology | so, say you do (cons 2 '(3)) |
| 14:37 | brettkromkamp | ok |
| 14:38 | Scripiology | this creates a new list that's the same as '(2 3), however, what Clojure does is create a new object of PersistentList which stores 2, and also stores a pointer to the original PersistentList that stores 3 |
| 14:39 | jonabbey | it's one of the coolest things about clojure, actually |
| 14:39 | Scripiology | when you call (first '(2 3) |
| 14:39 | Scripiology | ) |
| 14:39 | brettkromkamp | ok |
| 14:39 | mdeboard | oh, awesome |
| 14:39 | mdeboard | did not know that |
| 14:39 | tufflax | So if you do (def a '(3)) then (def b (cons 2 a)), the '(3) part of b is = to a |
| 14:40 | Scripiology | what happens is you call first on a PersistentList object that stores 2 and also happens to store a pointer to the list that just contains 3 |
| 14:40 | tufflax | well, not just = in the clojure sense |
| 14:40 | Scripiology | and that call to first() returns 2 |
| 14:40 | mdeboard | Huh |
| 14:40 | Scripiology | when you call (rest '(2 3)) Clojure follows a pointer to that original list and returns that |
| 14:40 | brettkromkamp | ok... that makes sense |
| 14:40 | brettkromkamp | proper linked-list |
| 14:41 | Scripiology | so if you do (first (rest '(2 3))) it gets that original list and calls first on it, which returns 3 |
| 14:41 | mdeboard | so if you've got '(2 3 4 5 6), and call (rest '(2 3 4 5 6)), it's only going to retrieve that next pointer |
| 14:41 | mdeboard | or rather, that next List object |
| 14:41 | Scripiology | mdeboard: exactly! |
| 14:41 | mdeboard | Huh |
| 14:41 | mdeboard | mind:blown |
| 14:41 | brettkromkamp | btw... what about performance considerations? |
| 14:41 | brettkromkamp | with increasingly longer and longer lists |
| 14:41 | tufflax | what about them |
| 14:41 | Scripiology | which considerations specificlly? |
| 14:42 | Scripiology | a list of length 1000 is stored in memory as 1000 PersistentList objects |
| 14:42 | tufflax | Btw the other data structures also share structure but it is a litte more complicated |
| 14:42 | Scripiology | nothing more |
| 14:42 | brettkromkamp | does clojure transverse a list from beginning to end if for example i 'access' the last item in a list? |
| 14:42 | Scripiology | yep, PersistentVector is a bit less efficient than PersistentList in terms of memory storage, but that's because it's optimized for appending to the end and random access |
| 14:42 | tufflax | brettkromkamp yes |
| 14:43 | Scripiology | brettkromkamp: for lists, yes |
| 14:43 | Scripiology | brettkromkamp: so if you know you'll do that, it's best to use a vector |
| 14:43 | mdeboard | vectors aren't hashed then? |
| 14:43 | brettkromkamp | ok... so does list lookups perform better for items at the beginning of a list as opposed to items at the end of a list |
| 14:43 | brettkromkamp | ? |
| 14:43 | Scripiology | which has O(log32(n) speed |
| 14:43 | Scripiology | for accessing values inside the array |
| 14:44 | Scripiology | brettkromkamp: for lists, yes, because it's in linear time, but like I mentioned above for vectors it's logarithmic time |
| 14:44 | tufflax | mdeboard no, they are trees, just like hash maps, but instead on a hash they use the index to index into it |
| 14:44 | Scripiology | mdeboard: check out http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/ |
| 14:44 | tufflax | of* |
| 14:44 | mdeboard | trees? Having trouble figuring that out. A tree where every node is an edge? |
| 14:45 | Scripiology | great explanation of PersistentVector |
| 14:45 | brettkromkamp | ok... making sense, guys :-) |
| 14:45 | brettkromkamp | so... big question |
| 14:45 | mdeboard | brettkromkamp: I really suggest if you're using clojure mode to also use the slime-repl inside emacs. Makes life very easy |
| 14:45 | brettkromkamp | mdeboard: doing just that - absolutely love it |
| 14:45 | jimi_hendrix | is there something like the rest function that returns a string? |
| 14:46 | mdeboard | then why did you install slime and swank :( |
| 14:46 | jimi_hendrix | (rest "foo") -> "oo" |
| 14:46 | technomancy | ,(subs "foo" 1) |
| 14:46 | clojurebot | "oo" |
| 14:46 | jimi_hendrix | thanks |
| 14:46 | brettkromkamp | mdeboard: for swank i'm using leiningen |
| 14:46 | mdeboard | ,(str (rest '(1 2 3))) |
| 14:46 | tufflax | jimi_hendrix not quite |
| 14:46 | clojurebot | "(2 3)" |
| 14:46 | jonabbey | i'm still trying to figure out lein/slime/swank, etc. |
| 14:46 | brettkromkamp | sorry if i didn't explain myself properly |
| 14:46 | tufflax | ,(rest "foo") |
| 14:46 | clojurebot | (\o \o) |
| 14:47 | Scripiology | yea, rest calls seq() on its argument, and for strings it returns a character array |
| 14:47 | technomancy | clojurebot: quit starin at me; you're creeping me out |
| 14:47 | clojurebot | Cool story bro. |
| 14:47 | brettkromkamp | big question for you guys [well, it is big for me] |
| 14:47 | S11001001 | ) |
| 14:48 | brettkromkamp | really grokking functional programming if you come from imperative programming [like the majority of us, i suppose]... how did you guys go about that? |
| 14:48 | jonabbey | you just get your hands dirty with it |
| 14:48 | hodapp | first, you find all the people who tell you you should write in C++ |
| 14:48 | brettkromkamp | java, python, etc... all about objects with mutable state |
| 14:48 | hodapp | then you hit them with a clue-by-four repeatedly |
| 14:49 | technomancy | you have to write code. it may be embarrassing to you later, but it's the best way to get your brain in gear |
| 14:49 | Scriptor | brettkromkamp: I read a bit of LearnYouAHaskell and tried to implement some of the functions it introduced without looking at the source for them |
| 14:49 | brettkromkamp | ok |
| 14:49 | mdeboard | Scriptor: oof |
| 14:49 | mdeboard | Haskell was way, way, way hairier for me |
| 14:49 | brettkromkamp | but haskell is too much of a brain-fuck [pardon my language] :-) |
| 14:50 | hodapp | well, at least it's not C++ |
| 14:50 | tufflax | brettkromkamp I used python before clojure, and in python I was pretty fond of map, filter and reduce. I guess I was just progressing towards fp |
| 14:50 | mdeboard | brettkromkamp: My background is in Python & JS. Like technomancy said you just have to write code. I rewrote a Python app I did a long while ago in Clojure this weekend and learned a ton. |
| 14:50 | brettkromkamp | but did any of you guys have a 'aha' moment when it just clicked? and, if yes, what made it click? |
| 14:50 | Scriptor | brettkromkamp: heh, for functional programming it's not too bad once you get past the first couple of hurdles |
| 14:50 | mdeboard | tufflax: tsk tsk |
| 14:50 | Scriptor | definitely |
| 14:50 | mdeboard | brettkromkamp: I have had several aha moments reading Joy of Clojure |
| 14:50 | Scriptor | though I needed several aha moments |
| 14:51 | brettkromkamp | ok |
| 14:51 | Scriptor | brettkromkamp: start simple, like implementing a count function to return the length of a list |
| 14:51 | brettkromkamp | so... just take an existing algorithm or app in an imperative language and convert to clojure? |
| 14:51 | mdeboard | brettkromkamp: That's been a big help for me. |
| 14:51 | mdeboard | brettkromkamp: And seriously, read Joy of Clojure |
| 14:51 | mdeboard | like, right now :P |
| 14:51 | tufflax | mdeboard brettkromkamp try this http://4clojure.com/ |
| 14:52 | mdeboard | clojurians |
| 14:52 | brettkromkamp | and just hit my head against the wall until i get it [or have brain a brain concussion :-)] |
| 14:52 | mdeboard | yeah |
| 14:52 | hodapp | I should be writing these books down. I've messed with Lisp a bit, but not Clojure, yet |
| 14:52 | mdeboard | once I got my app rewritten last night I turned off the computer and went to bed |
| 14:52 | mdeboard | completely wore me out, felt like I gave birth |
| 14:52 | hodapp | lol |
| 14:53 | brettkromkamp | mdeboard: lol |
| 14:53 | hodapp | was it Paul Graham who said that writing a program was the closest thing to giving birth that males could do? |
| 14:53 | mdeboard | then woke up at 9p and read JoC for 2 hours :( |
| 14:53 | brettkromkamp | tufflax: thanks - am checking it out as we speak |
| 14:53 | amalloy | tufflax: whew, just finished reading the scrollback and was worried i'd have to advertise 4clojure myself. now i can just be subtle and let you do it |
| 14:53 | mdeboard | spent the entire weekend working on it. |
| 14:53 | jimi_hendrix | mdeboard, JoC? |
| 14:53 | tufflax | :) |
| 14:53 | jonabbey | the first time i studied lisp, it wound up getting into my head so much that i found myself in bed with my girlfriend, and everything she said my brain was permuting into prefix order |
| 14:53 | Scriptor | I still have to write a major clojure app...:/ |
| 14:54 | Scriptor | just browse through some of the source every now and then |
| 14:54 | jonabbey | ooh, 4clojure, nice |
| 14:54 | brettkromkamp | scriptor: that brings me to another question... who has written a major clojure app? and what kind of app is it? |
| 14:55 | brettkromkamp | just to get a feel for the kind of problems that are being solved in clojure |
| 14:55 | tufflax | brettkromkamp im trying, im working on a online rpg :p |
| 14:55 | amalloy | clojurebot: source? |
| 14:55 | clojurebot | source is http://github.com/hiredman/clojurebot/tree/master |
| 14:55 | tufflax | an* |
| 14:55 | Scriptor | brettkromkamp: lots of people have writtens decent-sized clojure codebases, as in more than toys |
| 14:55 | amalloy | $whatis source |
| 14:55 | sexpbot | source is http://github.com/cognitivedissonance/sexpbot |
| 14:55 | hiredman | http://dev.clojure.org/display/community/Clojure+Success+Stories |
| 14:55 | Scriptor | hiredman: thanks, was about to hunt for that :) |
| 14:55 | amalloy | brettkromkamp: you can look at the source for #clojure's bots as examples |
| 14:55 | mdeboard | jimi_hendrix: Joy of Clojure |
| 14:55 | jimi_hendrix | ah |
| 14:56 | tufflax | brettkromkamp http://cemerick.com/2010/06/07/results-from-the-state-of-clojure-summer-2010-survey/ the 2011 should be up soon too |
| 14:56 | brettkromkamp | thx guys - you are being really helpful |
| 14:56 | dnolen | brettkromkamp: Twitter's using Clojure now |
| 14:56 | Scriptor | dnolen: they're using both clojure and scala? |
| 14:56 | brettkromkamp | dnolen: is it? i though they had migrated to scala |
| 14:56 | amalloy | brettkromkamp: well, they bought backtype |
| 14:56 | dnolen | Scriptor: Twitter bought BackType, BackType is and will continue to build out their Clojure code base. |
| 14:56 | symbole | Scriptor: Write an Emacs killer. Put this putty to sleep already. |
| 14:56 | mdeboard | I feel like, "State of Clojure every year? Why? Clojure's state is immutable!" is an A+ pun. |
| 14:56 | symbole | puppy* |
| 14:57 | brettkromkamp | ;-) |
| 14:57 | amalloy | mdeboard: c'mon, clojure lets you *manage* state |
| 14:57 | cemerick | mdeboard: well done :-) |
| 14:57 | mdeboard | I said it earlier to crickets :( |
| 14:57 | amalloy | mdeboard: i applauded while i was reading the scrollback |
| 14:57 | mdeboard | Anyway brettkromkamp #clojure is a great channel. Unwashed masses haven't started showing up yet. |
| 14:57 | mdeboard | #python is kind of a cesspool, for example. |
| 14:58 | Scriptor | symbole: I know someone in another channel who was doing a vim clone in clojure |
| 14:58 | Scriptor | mdeboard: have you checked out ##php? |
| 14:58 | hiredman | there was a lot of talk at one point about "oh, clojure as functional dynamic language will be good for the frontend and because of scala's static nature and types it will be good for the backend" but the majority of stacks I know of are clojure on the backend and rails on the frontend |
| 14:58 | jimi_hendrix | mdeboard, i love how "lol" is banned in #python |
| 14:59 | jimi_hendrix | also, #d is the worst language channel i have seen |
| 14:59 | mdeboard | Scriptor: no |
| 14:59 | Scriptor | mdeboard: lucky |
| 15:00 | brettkromkamp | so... using clojure to build a combined marketing intelligence and scenario planning system makes sense? :-) |
| 15:00 | brettkromkamp | that's why i am looking into it... |
| 15:00 | brettkromkamp | it => clojure |
| 15:00 | tufflax | using clojure to build just aboul anything makes sense, the using clojure part |
| 15:00 | tufflax | at least |
| 15:01 | Scriptor | how suitable would clojure be to writing a VM? |
| 15:01 | Scriptor | since it's entirely based on mutating |
| 15:01 | amalloy | brettkromkamp: ∀x, using clojure to build x makes sense |
| 15:01 | jimi_hendrix | just curious, how is clojure speed wise? how does it compare to normal java? |
| 15:01 | brettkromkamp | ok |
| 15:02 | dnolen | jimi_hendrix: you can get Java speed if you write nasty code. |
| 15:02 | jimi_hendrix | lol |
| 15:02 | brettkromkamp | dnolen: but clojure isn't 'slow' is it? |
| 15:02 | tufflax | amalloy is shows up as a back square for me, your qualifier :p |
| 15:02 | jimi_hendrix | thus defeating the point |
| 15:02 | clojurebot | the point of moby dick is "be yourself" |
| 15:02 | Scriptor | brettkromkamp: nope, it's very nice speed-wise |
| 15:02 | dnolen | brettkromkamp: no, it's quite fast. |
| 15:03 | brettkromkamp | not like python or ruby? |
| 15:03 | amalloy | tufflax: sad. fix your unicode support? |
| 15:03 | amalloy | jimi_hendrix: not at all! just write nasty code in the places where you really have to |
| 15:03 | tufflax | maybe :p |
| 15:03 | jimi_hendrix | brettkromkamp, even those can be quite fast if you use the right interpreter |
| 15:03 | brettkromkamp | python -> cpython and ruby -> mri |
| 15:03 | brettkromkamp | that's what i'm using and i sometimes feel the pain |
| 15:04 | dnolen | jimi_hendrix: was being a bit facetious of course. what amalloy said is closer to the truth. |
| 15:04 | jimi_hendrix | brettkromkamp, i know the EVE online servers use stackless python for all their processing |
| 15:04 | jonabbey | the ability of clojure code to be neatly paralellized is very exciting |
| 15:05 | dnolen | brettkromkamp: big draw to me for Clojure was that you didn't have leave the language to write low level fast stuff when you want/need it. |
| 15:05 | jonabbey | write in a functional manner, and then spread those functions out across all your processing resources |
| 15:05 | brettkromkamp | jimi_hendrix: yeah... i heard... but although i like python it does seem like from an evolution point of view... it is at a dead end |
| 15:05 | brettkromkamp | don't know why it gives me that impression, but it does |
| 15:06 | Scriptor | brettkromkamp: pypy's doing some pretty good work on the speed end, but language-design wise you might be right |
| 15:06 | brettkromkamp | clojure gives me the impression that we haven't seen nothing yet - despite the fact that it is slow in terms of version updates |
| 15:06 | brettkromkamp | slow version updates does not mean a bad thing |
| 15:07 | mdeboard | Yeah agree about Python plateauing. But its ease of use and multiparadigm design will make sure it's around forever. |
| 15:07 | brettkromkamp | if i was going on a trip to mars |
| 15:08 | brettkromkamp | would i take clojure or would i take python [if i was only allowed one language]... it would be clojure... without a doubt and i don't even know the language yet |
| 15:08 | brettkromkamp | and i *really* do know python |
| 15:08 | hodapp | I am a fan of Python. |
| 15:08 | brettkromkamp | so am i |
| 15:08 | tufflax | brettkromkamp about having seen nothing yet: lisps have been around for quite some time :p |
| 15:08 | Scriptor | might be hard sending new clojure versions to mars :p |
| 15:09 | hodapp | although it can be tough to write in Python after having written in C++, MATLAB, and so on for awhile, because you tend to choose harder ways to solve things before realizing Python has a one-line answer |
| 15:09 | brettkromkamp | tufflax you are right - but i mean clojure specific -> concurrency, specifically |
| 15:10 | brettkromkamp | anyway... thanks guys |
| 15:10 | brettkromkamp | you have pointed me in the right direction -> rtfm :-) |
| 15:10 | tufflax | thanks for making the clojure community bigger :p |
| 15:10 | brettkromkamp | the manual being "the joy of clojure" |
| 15:10 | tufflax | brettkromkamp and clojure.org! |
| 15:11 | brettkromkamp | will do |
| 15:11 | brettkromkamp | already have it as my home page :-) |
| 15:11 | tufflax | hehe |
| 15:12 | brettkromkamp | talk to you guys later - and again... thanks for all your advice |
| 15:12 | Scriptor | no prob! |
| 15:13 | babilen | brettkromkamp: I wouldn't necessarily start with "The Joy of Clojure" but with "Practical Clojure" -- Read tjoc afterwards. :) |
| 15:14 | mdeboard | babilen: Why's that? I'm new to FP in general and find JoC *extremely* accessible. |
| 15:15 | babilen | mdeboard: I found JoC to be better suited after you have at least a little experience and quite liked PC -- Although the "List of api calls"-Chapters in PC are bad. |
| 15:16 | mdeboard | I dunno, maybe. But as a beginner to Clojure, the JVM and FP in general Joy of Clojure is amazing and eye-opening. First tech book I've ever been excited to get back to after work. |
| 15:16 | babilen | mdeboard: I am not saying that JoC is bad or so, it is a wonderful book, but *I* started with "Programming Clojure" and couldn't quite get into it, then switched over to PC. |
| 15:17 | babilen | mdeboard: Indeed, it is great. I am curious what Programming Clojure 2nd Edition will be like. |
| 15:17 | flazz | i created a project with lein, how do i play with functions in the repl? |
| 15:17 | amalloy | (inc mdeboard) |
| 15:17 | sexpbot | ⟹ 1 |
| 15:18 | amalloy | i read JoC first |
| 15:18 | babilen | But I am by no means a veteran in Clojure and there might also be technical or style-wise reasons to prefer one book over the other. I just had the impression that PC + JoC is a very good combination. |
| 15:18 | amalloy | no previous functional experience |
| 15:18 | babilen | I can not really comment on reading JoC first as I have never done that. |
| 15:19 | amalloy | flazz: cd myproj && lein repl? |
| 15:19 | brettkromkamp | ok... |
| 15:20 | brettkromkamp | just to make sure i've understood you guys [i'm slow on the uptake] |
| 15:20 | flazz | amalloy: right, got there; how do i load/run code i wrote in the lib dir in the repl? |
| 15:20 | amalloy | blerg. don't write code in the lib dir |
| 15:20 | brettkromkamp | it's ok in clojure to use a list as the container for the 'nodes' for my tree implementation? |
| 15:21 | brettkromkamp | appending/cons-ing nodes to a list is not 'bad' clojure practice |
| 15:21 | brettkromkamp | or is it? |
| 15:21 | mdeboard | vectors are specifically designed for appending |
| 15:21 | Scriptor | brettkromkamp: depends, appending is faster for vectors |
| 15:21 | mdeboard | s/designed/optimized |
| 15:21 | sexpbot | <mdeboard> vectors are specifically optimized for appending |
| 15:21 | brettkromkamp | ok |
| 15:21 | mdeboard | lol, nice bot. |
| 15:21 | Scriptor | brettkromkamp: you'd normally use conj insted of cons, actually |
| 15:22 | Scriptor | conj prepends to lists and appends to vectors |
| 15:22 | brettkromkamp | regardless of the actual underlying data structure |
| 15:22 | brettkromkamp | from a fp point of view |
| 15:22 | Scriptor | actually, conj calls the equivalent method on the list object it's given |
| 15:22 | Scriptor | equivalent meaning the object's own conj method |
| 15:22 | brettkromkamp | there is nothing wrong with using a list/vector as the container for a data structure and updating said data structure |
| 15:22 | brettkromkamp | ? |
| 15:22 | Chousuke | it's fine to use any data structure that provides the operations you need :) |
| 15:23 | amalloy | just avoid *mutating* data structures if you can help it |
| 15:23 | brettkromkamp | i'm just trying to wrap my head around this whole 'immutable' state thing |
| 15:23 | Chousuke | every clojure data structure is persistent and so good to use |
| 15:23 | flazz | amalloy: sorry src dir |
| 15:24 | brettkromkamp | amalloy: that's exactly what i mean - what do you mean with "just avoid mutating data structures" how do i work with them if i don't mutate them??? |
| 15:24 | Chousuke | brettkromkamp: it's not that difficult in the end; instead of "changing" something you transform it |
| 15:24 | Chousuke | brettkromkamp: and end up with both the original and the transformed version |
| 15:24 | brettkromkamp | chousuke: isn't that horribly inefficient |
| 15:24 | brettkromkamp | ? |
| 15:24 | Chousuke | brettkromkamp: no |
| 15:24 | jonabbey | clojure's data structures are designed to work that way |
| 15:24 | Chousuke | brettkromkamp: clojure data structures do structural sharing |
| 15:25 | brettkromkamp | so when i cons or conj - what am i doing? mutating? or transforming? |
| 15:25 | Chousuke | transforming |
| 15:25 | Scriptor | brettkromkamp: remember how each PersistentList I mentioned before pointed to the next one? That's how lists share structure |
| 15:25 | brettkromkamp | perhaps it is just the semantics that i am not understanding |
| 15:25 | Scriptor | transforming |
| 15:25 | jonabbey | if you do a transformation that shrinkis a data structure and then just keep a reference to the shrunken transformed structure, gc will get rid of the unnecessary pieces |
| 15:25 | amalloy | ugh transform is not a word with clear meaning here |
| 15:26 | amalloy | you are creating a new version of the list/vector/whatever |
| 15:26 | Chousuke | brettkromkamp: it is slightly less efficient than mutating things, but it's worth the benefits:) |
| 15:26 | jonabbey | but if you have a var or a thread that is still referencing the old (larger) version of the structure, it will be kept around as needed |
| 15:26 | mdeboard | 15:26 <amalloy> you are creating a new version of the list/vector/whatever |
| 15:26 | amalloy | &(let [x [1 2], newx (conj x 3)] [x newx]) |
| 15:26 | sexpbot | ⟹ [[1 2] [1 2 3]] |
| 15:26 | mdeboard | this |
| 15:26 | brettkromkamp | ok... this is the real head-fuck with regards to clojure |
| 15:26 | jonabbey | by transform, read the output of a function that returns a modified version of a structure |
| 15:26 | amalloy | here i conjed onto a vector, and the old and new versions are both still in existence |
| 15:26 | Chousuke | brettkromkamp: note that most programs do need mutable state. But clojure handles that with another mechanism |
| 15:26 | Chousuke | brettkromkamp: ie. with reference types |
| 15:27 | brettkromkamp | ok |
| 15:27 | jonabbey | or by simply calling methods on java objects, if you like that sort of thing |
| 15:27 | amalloy | Chousuke: no programs *need* mutable state. but often it's easier to write/model them if you use some |
| 15:27 | Chousuke | brettkromkamp: references mutate, but the data structures that they refer to do not |
| 15:27 | mdeboard | brettkromkamp: It need not be a headfuck. Every time you change something about a collection, you get a new item back. |
| 15:27 | brettkromkamp | i *think* i understand what you guys are saying - but it really does require a different way of thinking about program design |
| 15:27 | jonabbey | it does |
| 15:27 | hiredman | amalloy: *ahem* |
| 15:27 | mdeboard | Chousuke's explanation is muddying the water a bit I think |
| 15:28 | Scriptor | mdeboard: it's just explaining how the new item still shares memory with the original that's hard to explain :) |
| 15:28 | mdeboard | It's all pointers right? |
| 15:28 | jonabbey | references, yes |
| 15:28 | mdeboard | So there you go :) |
| 15:29 | Scriptor | brettkromkamp: maybe this'll clarify it for you: say you conj onto a vector. In Clojure terms this returns a new vector that's separate from the old one |
| 15:29 | brettkromkamp | ok |
| 15:29 | Scriptor | but in implementation terms, since the new vector is almost exactly the same as the old one except for one new item, you don't need to copy the old one |
| 15:30 | dnolen | brettkromkamp: but really you shouldn't even think about it like that since this all implementation-centric |
| 15:30 | amalloy | hiredman: am i wrong? it seems to me you can write any program as a function which takes "the universe" as input and returns a new universe, in conjunction with a loop that iterates over this, possibly doing some i/o |
| 15:30 | dnolen | 1 + 1 - > 2 |
| 15:30 | Chousuke | ,(let [a '(a list) r (atom a)] (swap! a conj 'something) [a @r r]) |
| 15:30 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Atom |
| 15:30 | brettkromkamp | so... under the hood clojure is inmutable but from a programming point of view... it's business as usual? |
| 15:30 | Scriptor | brettkromkamp: so the new vector actually tries to share as many objects as it can with the old one without copying them |
| 15:30 | dnolen | you have values and operations on values, you can't change 1 or 2 |
| 15:30 | Chousuke | wait |
| 15:30 | Chousuke | ,(let [a '(a list) r (atom a)] (swap! r conj 'something) [a @r r]) |
| 15:30 | clojurebot | [(a list) (something a list) #<Atom@199682f: (something a list)>] |
| 15:31 | jonabbey | it's business as usual from a functional point of view |
| 15:31 | dnolen | you should see (conj {} 'a) should think, that just like (+ 0 1) etc |
| 15:32 | jonabbey | i.e., you write functions which take data and return results. clojure's data structures are designed under the covers to make that as efficient as possible for operations on lists, vectors, etc. |
| 15:32 | mdeboard | brettkromkamp: For our purposes right now, in answer to your "business as usual" question, yes. |
| 15:32 | brettkromkamp | mdeboard i will read the joy of clojure - sorry about this |
| 15:32 | jonabbey | and clojure's persistent ("immutable") data structures have unique benefits when you're running multithreaded |
| 15:33 | mdeboard | You can write a million lines of operational code in Python without ever understanding the concept of state mutability |
| 15:33 | mdeboard | it will augment your ability for sure |
| 15:33 | brettkromkamp | me -> off to read the first chapters of the joy of clojure |
| 15:33 | mdeboard | I'm p sure it's like that in clojure too. |
| 15:33 | brettkromkamp | sorry guys |
| 15:33 | Chousuke | brettkromkamp: no need to apologise for asking questions |
| 15:33 | mdeboard | ^ |
| 15:34 | mdeboard | I'm at work writing python or I'd be asking them myself |
| 15:34 | Chousuke | brettkromkamp: what you're asking might seem simple or "stupid" but it really isn't. |
| 15:34 | brettkromkamp | well... i must admit... i do feel a bit stupid |
| 15:35 | brettkromkamp | i've been developing for 10 years now |
| 15:35 | brettkromkamp | that's why i just wanted to talk to other devs |
| 15:35 | Chousuke | brettkromkamp: that might be precisely why clojure's concepts are difficult for you |
| 15:35 | brettkromkamp | in the company i work for... the other devs just aren't interested in other languages |
| 15:35 | brettkromkamp | let alone fp... oo is everything to them |
| 15:35 | Chousuke | it's easier to learn something new when you have no expectations of how things work |
| 15:36 | Cozey | is it possible to call a static method of a class, when I have this class as a value ? |
| 15:36 | brettkromkamp | true |
| 15:36 | jonabbey | learning functional programming / lisp is almost like learning a new human language.. it takes some time to get your brain to think in it |
| 15:36 | Chousuke | yeah, but once you get it, it will affect the way you think about all programming |
| 15:36 | brettkromkamp | i'll get there [cross fingers] :-D |
| 15:36 | Cozey | like: (let [i Integer] (.valueOf i "123" ) ) ? |
| 15:36 | technomancy | brettkromkamp: it might be too theoretical, but if you're interested in an explanation for how programs can work without modifying state I recommend reading Out of the Tarpit |
| 15:37 | technomancy | you'll definitely want to read it eventually |
| 15:37 | brettkromkamp | out of the tarpit? |
| 15:37 | technomancy | http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.93.8928&rep=rep1&type=pdf |
| 15:37 | jonabbey | nice ref |
| 15:37 | technomancy | a short paper on FP; pretty accessible |
| 15:37 | amalloy | Cozey: it's possible, but it might need reflection? |
| 15:37 | brettkromkamp | what you say... how programs can work without modifying state -> that is hitting the proverbial nail on the head |
| 15:38 | jonabbey | for 'state', read 'heap |
| 15:38 | Cozey | amalloy: mhm.. so maybe there's another way to serialize an Enum ? |
| 15:38 | brettkromkamp | that is exactly what i am looking for |
| 15:38 | jonabbey | functional code involves modifying state, but it's state that is thread-private and restricted to active function stack |
| 15:38 | technomancy | brettkromkamp: it has a great proof that storing internal state is necessary solely for optimization (called "accidental complexity") |
| 15:39 | brettkromkamp | out of the tarpit -> copying to my kindle as we speak :-) |
| 15:39 | hiredman | amalloy: seems rather disingenuous to discount the io loop as part of the process |
| 15:39 | jonabbey | fun / neat languages to learn: clojure, erlang, prolog |
| 15:39 | Chousuke | brettkromkamp: I think most programs need some sort of state, but most of the *code* doesn't. It's possible to separate "stateful" code from code that does things with immutable values. |
| 15:40 | technomancy | brettkromkamp: the second half is not as relevant fwiw |
| 15:40 | brettkromkamp | technomancy :-D |
| 15:40 | Cozey | ah there's a (Enum/valueOf BlaBla "NAME") |
| 15:41 | technomancy | clojurebot: Out of the Tarpit is a short, accessible paper on FP and reducing complexity by identifying and minimising state: http://ben.moseley.name/frp/paper-v1_01.pdf |
| 15:41 | clojurebot | In Ordnung |
| 15:41 | amalloy | Cozey: hah, wish i knew about that when i was serializing enums a while ago |
| 15:41 | brettkromkamp | thanks guys -> i'm off to do some reading |
| 15:42 | mdeboard | brettkromkamp: So look, instead of feeling stupid, you really need to feel smart as hell in here because Clojure is a very big deal. As a friend of mine says, the consumer Internet has been aruond for ten years. There's no possible way that Python or Ruby is the end-all, be-all of web development. Clojure has undeniable benefits in concurrency and speed that imperative langs, and even multiparadigm langs e.g. py/rb, |
| 15:42 | mdeboard | will not be able to match. I'm not saying Clojure is "the next big thing", it probably isn't, but I think the next generation of impure FP langs will be the big ones. |
| 15:42 | amalloy | though i think i wanted to serialize to a byte rather than a string |
| 15:42 | Chousuke | brettkromkamp: for example, you might have a function that removes all vowels from text. that obviously can be done with a non-stateful function. then you might have an UI with an input field where you want to apply this transition; it requires state, but that is a separate problem... The main logic is still a stateless function. |
| 15:42 | Cozey | amalloy: i want to pass mine through a html form |
| 15:44 | dnolen | mdeboard: I don't see any serious competitors for the future FP goto langs beyond Scala & Clojure. Scala from the static typing side, Clojure from the dynamic typing side. |
| 15:45 | mdeboard | dnolen: Well, I think the thought patterns of FP will keep Clojure & Scala from reaching widescale adoption. OOP is pretty entrenched |
| 15:46 | jonabbey | a generation is being trained to a broader point of view already with python, ruby, and javascript |
| 15:46 | mdeboard | ture that |
| 15:46 | mdeboard | true* |
| 15:46 | dnolen | mdeboard: I don't mean FP will replace OOP anytime soon, but I think the adoption of FP will be quite dramatic in the next few years. |
| 15:47 | mdeboard | dnolen: That's what everyone thought in the 70s and early 80s too |
| 15:47 | dnolen | mdeboard: except there were very few *production* oriented FP langs. |
| 15:47 | mdeboard | also true |
| 15:48 | dnolen | Clojure & Scala are both squarely aimed at working programmers. |
| 15:48 | jonabbey | with massive pre-existing libary and tooling support |
| 15:48 | jonabbey | i remember doing CLOS coding back in the early 90's.. talk about a wasteland |
| 15:49 | hodapp | You say "replace OOP" like we currently use OOP... |
| 15:49 | jonabbey | i remember when Apple was pushing Dylan hard, too |
| 15:49 | hodapp | but the dominant implementations are pretty lacking in terms of actually meeting what Alan Kay had in mind in proposing the term |
| 15:50 | jonabbey | isn't Objective C supposed to be pretty decent? |
| 15:50 | hodapp | I've heard it is. |
| 15:50 | hodapp | It's closer to Smalltalk |
| 15:51 | jonabbey | it supports dynamic method dispatch the way python does |
| 15:51 | jonabbey | message oriented |
| 15:51 | hodapp | yeah |
| 15:52 | hodapp | I am much a fan of Python's duck typing |
| 15:53 | jonabbey | is clojure-contrib 1.2 the latest version, or is there a newer version for use with clojure 1.3.0 beta? |
| 15:54 | jweiss_ | anyone know of a lib that would let me jump into code the way you do in emacs with M-. but generating HTML with links instead? |
| 15:57 | mdeboard | jweiss_: I don't understand the question |
| 15:57 | jweiss_ | mdeboard: you know what i'm referring to with the emacs M-., right? |
| 15:57 | mdeboard | yeah |
| 15:57 | mdeboard | it's the "but" clause I don't understand. |
| 15:57 | technomancy | jonabbey: individual libraries may have been upgraded to work with 1.3; depends what you want |
| 15:58 | jweiss_ | mdeboard: i want to take my set of source files, and output html so taht the fn calls are links to the functions they actually call |
| 15:58 | jonabbey | okay |
| 15:58 | mdeboard | ahh |
| 15:58 | brettkromkamp | technomancy, mdeboard, chousuke... thanks guys |
| 15:58 | jonabbey | i'll just clone clojure-contrib from github/clojure and go with that |
| 15:58 | brettkromkamp | i hope to come back somewhat more enlightened |
| 15:58 | jweiss_ | mdeboard: obviously, you need some kind of runtime to do that, you can't do it just with the source, but i'm ok with that |
| 15:59 | cemerick | well, that took waaaay too long |
| 15:59 | cemerick | State of Clojure 2011 results: http://wp.me/p10OJi-9L |
| 15:59 | amalloy | cemerick: you got it done before 2012, anyway |
| 16:00 | tufflax | brettkromkamp you might like this http://blip.tv/clojure/clojure-for-java-programmers-1-of-2-989128 |
| 16:00 | tufflax | cemerick nice :) |
| 16:01 | cemerick | mdeboard: your pun has been immortalized :-P |
| 16:01 | mdeboard | cemerick: How's that |
| 16:02 | cemerick | mdeboard: OH'ed on twitter |
| 16:02 | mdeboard | cemerick: lol |
| 16:02 | mdeboard | shit you could've @'d me at least, mattdeboard |
| 16:02 | mdeboard | (jk obv) |
| 16:03 | mdeboard | s/sh*t/darn |
| 16:03 | cemerick | mdeboard: well, see, you should've tweeted it, and then I'd give you a RT |
| 16:03 | mdeboard | I don't use twitter anymore, G+ |
| 16:03 | cemerick | *shrug* |
| 16:03 | mdeboard | lol but I'm honored, thanks :) |
| 16:04 | cemerick | My G+ profile will likely languish, just like my FB account. |
| 16:04 | dnolen | cemerick: it's interesting that people come to Clojure from dynamic langs but would switch to a static lang if Clojure didn't exist. |
| 16:04 | cemerick | dnolen: true. I don't think static/dynamic is as much of a divide as it's put up to be. |
| 16:04 | cemerick | imperative vs. functional, though, that's a biggie |
| 16:12 | dnolen | cemerick: great stuff, thanks for putting it together. |
| 16:15 | paraseba | Is anybody using clj-time with clojure 1.3.0-beta1? |
| 16:28 | cemerick | dnolen: Thanks, and np :-) |
| 16:28 | mdeboard | cemerick: I can't see it at work :( |
| 16:29 | cemerick | really! |
| 16:29 | cemerick | mdeboard: do they just block all of wordpress.com? |
| 16:29 | mdeboard | cemerick: probs |
| 16:29 | cemerick | bogus |
| 16:31 | Scriptor | mdeboard: google cache: http://goo.gl/XbUvl |
| 16:31 | Scriptor | hopefully that works |
| 16:31 | Scriptor | wait, nvm |
| 16:31 | Scriptor | that's the announcement of the end of the survey |
| 16:32 | cemerick | I was going to say, no way it's cached already |
| 16:32 | mdeboard | it did thanks Scriptor |
| 16:32 | mdeboard | oh |
| 16:32 | mdeboard | I was like "where's the survey" |
| 16:40 | amalloy | cemerick: google caches stuff like mad |
| 16:40 | amalloy | even with some fairly minor SEO you get cached within the hour, iirc |
| 16:41 | Scriptor | amalloy: all the more reason why g+ running out of disk space was a serious wtf |
| 16:41 | kumarshantanu | hi, need some help with regex-fu — can anybody verify that this (below) is correct? |
| 16:41 | kumarshantanu | ,(re-find (re-matcher #"(.+)\-([\d\.]+)\.(\w+)" "foo-bar-1.0.6.jar")) |
| 16:41 | clojurebot | ["foo-bar-1.0.6.jar" "foo-bar" "1.0.6" "jar"] |
| 16:41 | amalloy | shoulda headed over to facebook to borrow a cup of sugar |
| 16:42 | kumarshantanu | trying to split up arbitrary maven artifact filenames into tokens — artifactId and version |
| 16:42 | Scriptor | kumarshantanu: seems to work from what clojurebot printed out |
| 16:42 | hiredman | not going to happen |
| 16:42 | amalloy | kumarshantanu: fwiw, - doesn't need to be escaped, and nor does . inside of [] |
| 16:43 | hiredman | jars don't have the groupid in the filename |
| 16:43 | kumarshantanu | hiredman: right, i am just trying to get artifact-id and version |
| 16:43 | hiredman | I'm not actualyl sure that the artifactId is always in the jar name, could just be most of the time |
| 16:43 | hiredman | actually |
| 16:43 | hiredman | cemerick: ? |
| 16:44 | cemerick | hrm? |
| 16:44 | cemerick | oh |
| 16:45 | cemerick | Not having the artifactId in the artifact filename would be *very* rare, but can happen. |
| 16:46 | kumarshantanu | amalloy: thanks, yes - and . need not be escaped in [] |
| 16:46 | cemerick | IIRC, you can attach any file to an install/deploy, with any filename. |
| 16:46 | cemerick | kumarshantanu: do you not have the pom's for these artifacts right next door? |
| 16:47 | hugod | there are also classifiers - test, sources, etc |
| 16:47 | kumarshantanu | cemerick: hiredman: i am only trying to guess the artifact-id and version |
| 16:47 | kumarshantanu | cemerick: am trying to do a lein plugin…so it'll be user-assisted |
| 16:47 | kumarshantanu | this is for local JARs |
| 16:48 | cemerick | kumarshantanu: well, just know that you're in murky territory. |
| 16:49 | kumarshantanu | cemerick: true :) |
| 16:50 | cemerick | kumarshantanu: also know that, as long as you're working with local jars, you're working with jars that aren't in a repo, and the build process you're attempting to support will be unrepeatable by default |
| 16:50 | cemerick | :-) |
| 16:53 | kumarshantanu | cemerick: right…am wondering if it can be streamlined a bit — (1) store local JARs in "local" dir, (2) run this lein plugin to install to local-repo, (3) lein deps, (4) lein jar |
| 16:53 | kumarshantanu | checking in JARs in version control is another can of worms though |
| 16:53 | hiredman | kumarshantanu: there is a local repo, ~/.m2 |
| 16:54 | kumarshantanu | hiredman: installing JARs to ~/.m2 is a chore, which is what i am trying to get rid of |
| 16:54 | cemerick | kumarshantanu: I don't know what you're attempting to do, and I've never written any lein-related code, I don't really want to say anything unhelpful. But if anything you're doing involves jars into version control systems, please don't. |
| 16:54 | hiredman | kumarshantanu: I think you would be better serverd by taking the time to get your jars into a repo |
| 16:55 | hiredman | infact, if you specify an unknown jar in your project.clj, lein will spit out the command needed to install it into the repo |
| 16:56 | cemerick | hiredman: can it do it itself, or is it still a mvn incantation? |
| 16:56 | hiredman | cemerick: it is an mvn command |
| 16:56 | hiredman | for random jars, lein can install and deploy the artifacts it produces |
| 16:57 | cemerick | There was a guy around here a year ago or so that was thinking of starting a mvn repo hosting service. I wonder where he went off to. |
| 16:58 | hiredman | *shrug* maven repos are dirt simple, dunno how you could make money doing it |
| 16:58 | hiredman | you need GET and PUT and you're done |
| 16:59 | cemerick | hiredman: same goes for e.g. gitosis, yet people pay for hosted git repos. |
| 17:00 | cemerick | My mvn-repo-in-github hack is consistently one of my most popular posts, surprisingly. http://cemerick.com/2010/08/24/hosting-maven-repos-on-github/ |
| 17:01 | hiredman | cemerick: yeah, but the host github repos are git + other features you want anyway, how much is there to build on top of GET and PUT for a maven repo? |
| 17:02 | cemerick | There's nothing to build at all — you can just use nexus or artifactory, and have lots more than GET and PUT for free. |
| 17:03 | cemerick | I think it's fundamentally a matter of admin overhead (or not). |
| 17:03 | hiredman | mmm |
| 17:18 | paraseba | right now, clojure.contrib.condition is broken for clojure 1.3.0, it's not using :dynamic. How is this project going to be maintained? should I send a patch to contrib? should I help to migrate it to its own project? |
| 17:20 | technomancy | paraseba: it's in its own project already, actually |
| 17:21 | technomancy | clojurebot: slingshot? |
| 17:21 | clojurebot | It's greek to me. |
| 17:21 | technomancy | clojurebot: lise |
| 17:21 | clojurebot | excusez-moi |
| 17:21 | technomancy | I mean lies. |
| 17:21 | technomancy | whatever |
| 17:21 | technomancy | clojurebot: slingshot is the successor to clojure.contrib.condition: https://github.com/scgilardi/slingshot |
| 17:21 | clojurebot | Ok. |
| 17:22 | paraseba | technomancy: Oh, didn't know about that. Thanks |
| 17:23 | paraseba | technomancy: but, don't you think this kind of problem will slow 1.3.0 adoption? |
| 17:29 | ibdknox | do you think clojure/core would be interested in a redesign of clojure.org? |
| 17:37 | technomancy | paraseba: yeah, but people need to move off contrib anyway |
| 17:38 | technomancy | it's a left-over from back when the answer to "how do I make it easy for people to use this code" wasn't "publish it somewhere that makes sense" |
| 17:38 | paraseba | I agree, but it's hard to know where to move to |
| 17:39 | paraseba | maybe adding some alternative options in contrib modules documentation |
| 17:39 | technomancy | slingshot is different because the author wants it to see more internal usage before making a big announcement |
| 17:40 | technomancy | I personally haven't seen many useful old-style contrib libraries that don't have modular replacements |
| 17:40 | technomancy | slingshot was kind of the last missing piece |
| 17:41 | paraseba | c.c.def has an alternative? |
| 17:43 | amalloy | i think it's fair to say that c.c.def isn't "useful" |
| 17:43 | replaca | technomancy: hmmm, an issue with lein repl, lein swank, etc.: if I need a big JVM and I set JAVA_OPTS=-Xmx1024m, the setting applies to both lein *and* the jvm it spins up to run the repl/swank client |
| 17:43 | technomancy | defalias hovers on the edge of being justified |
| 17:44 | technomancy | replaca: good point; that's not terribly useful |
| 17:44 | replaca | technomancy: I'm not sure if this really matter (the resident set size of lein is quite small) but I could imagine probs for very large virtual sizes |
| 17:44 | technomancy | do you know about :jvm-opts in project.clj? |
| 17:44 | replaca | ahh, no. That's probably what I want. |
| 17:44 | replaca | works in both those scenarios? |
| 17:44 | technomancy | it applies to the project JVM only |
| 17:45 | technomancy | but if you could open an issue to separate out JVM_OPTS and LEIN_JVM_OPTS that would be super |
| 17:45 | replaca | right, but both with swank or repl? |
| 17:45 | technomancy | since it's not always appropriate to edit project.clj |
| 17:45 | technomancy | yes, every project JVM |
| 17:45 | replaca | yup (in my case it is, though) |
| 17:45 | technomancy | all code that needs to run in the context of the project |
| 17:45 | replaca | technomancy: issue on the way, thx |
| 17:45 | technomancy | cool |
| 17:49 | paraseba | technomancy: I agree, the problem is there are lots of libraries depending on c.c.def and others. If all they had to do to move to 1.3.0 was change a namespace, it would be faster |
| 17:49 | paraseba | but also ... it wouldn't help moving out of c.c . So, probably the pain is justified |
| 17:50 | amalloy | technomancy: "We have a policy of releasing entire Java packages in which every single class, interface and method is deprecated right out of the box, starting at version 1.0." -- http://steve-yegge.blogspot.com/2010/07/wikileaks-to-leak-5000-open-source-java.html |
| 17:51 | amalloy | not really relevant, i suppose, unless that's why you like defdeprecated |
| 18:07 | technomancy | deprecation happens |
| 18:40 | dRbiG | right, i have (sort-by (fn [x] (.length (new File path x))) files) - i'd like to make a macro/fn/whatever out of it where i can substitute .length with a string (i check if the string actually is a proper .method before, so no need to worry) |
| 18:41 | dRbiG | and this is giving me a headache :S |
| 18:45 | ataggart | dRbiG: is there a question? |
| 18:45 | dRbiG | ataggart: there is, implicitly, "how would you do it?" |
| 18:46 | ataggart | invoke a method on an object using the method's string name? |
| 18:46 | ibdknox | does it have to be a string? |
| 18:47 | ibdknox | not that it really matters |
| 18:47 | ibdknox | &(symbol ".length") |
| 18:47 | sexpbot | ⟹ .length |
| 18:49 | cemerick | or just use the lower-level form so you don't have to bother with the concatenation: (. (new File path x) length) |
| 18:50 | ibdknox | even better |
| 18:50 | ataggart | smells like an xy problem |
| 18:50 | dRbiG | cemerick: nope, |
| 18:51 | ataggart | xy? |
| 18:51 | clojurebot | xy is http://mywiki.wooledge.org/XyProblem |
| 18:52 | dRbiG | indeed |
| 18:52 | dnolen | dRbiG: methods are not first class, they are statically determined. |
| 18:53 | dnolen | ,(doc memfn) |
| 18:53 | clojurebot | "([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn." |
| 18:53 | dnolen | dRbiG: is there any reason to use a string and not a function ? |
| 18:54 | cemerick | ataggart: probably right, but that wiki page is unfortunate. |
| 18:55 | terom | Are there any good examples of memfn use somewhere? |
| 18:56 | amalloy | &(map (memfn length) ["test" "strings" "are" "long"]) :P |
| 18:56 | sexpbot | ⟹ (4 7 3 4) |
| 18:56 | ataggart | largely replaced with the anonymous fn synta |
| 18:56 | dnolen | http://clojuredocs.org/clojure_core/clojure.core/memfn |
| 18:56 | ataggart | x |
| 18:56 | dRbiG | http://en.wikibooks.org/wiki/Clojure_Programming/Examples#Invoking_Java_method_through_method_name_as_a_String |
| 18:56 | dRbiG | this does it |
| 18:57 | amalloy | sigh. yes, reflection will solve many such problems, but as ataggart says they're usually only problems because you've done something wrong already |
| 18:57 | ibdknox | dRbiG: but you have to ask yourself if this is really necessary, resorting to reflection is a sad thing |
| 18:59 | dRbiG | maybe as i iterate i'll see better way to do it |
| 18:59 | dnolen | dRbiG: what advantage do you see in using strings over functions ? |
| 19:01 | dRbiG | query string will have ?sort=length, or ?sort=lastModified etc. - so i just want to invoke that inside sort-by; as a chceck against stuff like sort=delete i'll check if the given str is in a predefined list of what's allowed |
| 19:01 | ataggart | BTW, the dot is a special form, so you could avoid reflection via a macro |
| 19:01 | ataggart | e.g.: (defmacro invoke-method-name [method target & args] `(. ~target ~(symbol method) ~@args)) |
| 19:02 | dRbiG | that's the approach i'd take with ruby/io/anything that has nice member? and send |
| 19:02 | dRbiG | i guess there's better way to do it here :) |
| 19:03 | dnolen | dRbiG: if you're going to check against a predefined list, why not just have map that stores str -> fn |
| 19:03 | ataggart | dnolen: nah, just use eval. ;) |
| 19:03 | ibdknox | lol |
| 19:05 | mdeboard` | Man, 4clojure.com is slow |
| 19:06 | mdeboard` | Not a random gripe by the way; I'm curious why it's slow. Holy cow look at the source, I assme this is auto-generated by Clojure? |
| 19:06 | amalloy | mdeboard`: it is fast as lightning for me |
| 19:07 | amalloy | and yes, hiccup generates the html every time |
| 19:07 | mdeboard` | amalloy: page load times are intermittently horrendous and acceptable |
| 19:08 | amalloy | mdeboard`: we serve some big javascript files, but we carefully mark them as cacheable |
| 19:08 | mdeboard` | Maybe that'swhy |
| 19:08 | Raynes | mdeboard`: We don't talk about 4clojure's performance. You're new here, so I'm going to let this slide. |
| 19:08 | mdeboard` | It's my first visit |
| 19:08 | amalloy | my browser shows a bunch of 304 Not Modified |
| 19:08 | mdeboard` | Raynes: Thanks |
| 19:08 | Raynes | ;) |
| 19:09 | mdeboard` | You know I could rewrite this in Python on top of Flask if you'd like! :D |
| 19:09 | mdeboard` | I'm kidding of course |
| 19:09 | ibdknox | hehehe |
| 19:10 | amalloy | mdeboard`: if you're looking for a small project and you think the html is ugly, you could write a wrapper that pretty-prints the generated html if the url has a ?debug=true |
| 19:11 | ibdknox | or just use a DOM inspector, which all modern browsers have :) |
| 19:11 | ibdknox | amalloy: a winner is you ;) |
| 19:11 | mdeboard` | ibdknox: Dom inspectors are good for honing in on a particular bit of content but it is often helpful to me to then view source and Ctrl-F for that bit of content to get context |
| 19:12 | ibdknox | hm, you can search the DOM too? |
| 19:12 | ibdknox | not sure I understand the distinction |
| 19:13 | ibdknox | the only real difference between a pretty printed version of the HTML and what you would get in firebug or webkit's inspection tools is that the JS will have run |
| 19:13 | ibdknox | which I would think you'd want |
| 19:13 | mdeboard` | Plus I don't have to futz about with resizing the window and can navigate entirely by keyboard without tabbing a million times |
| 19:14 | mdeboard` | Just personal preferences, not syaying my way is better at all. |
| 19:14 | mdeboard` | or superior in some way |
| 19:14 | mdeboard` | It's superior to me because that's how I like doing i t:) |
| 19:14 | ibdknox | mdeboard`: yep yep :) |
| 19:19 | ndimiduk | ,(contains? [1 2 3] 2) |
| 19:19 | clojurebot | true |
| 19:19 | amalloy | clojurebot: contains? |
| 19:19 | ndimiduk | ,(contains? '(1 2 3) 2) |
| 19:19 | clojurebot | false |
| 19:19 | clojurebot | contains? is for checking whether a collection has a value for a given key. If you want to find out whether a value exists in a Collection (in linear time!), use clojure.core/some or the java method .contains |
| 19:20 | amalloy | ninja'd |
| 19:20 | mdeboard` | lol |
| 19:21 | ndimiduk | amalloy: why does this not work on seqs? |
| 19:21 | amalloy | for the same reason that (= 5 '(1 2 3)) doesn't return 2. it does a different thing |
| 19:22 | Scriptor | ,('(0 1 2) 2) |
| 19:22 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn |
| 19:24 | mdeboard` | ,(closure.set/intersection #{:a :b :c} #{:b :c :d}) |
| 19:24 | clojurebot | java.lang.ClassNotFoundException: closure.set |
| 19:24 | mdeboard` | wow |
| 19:25 | mdeboard` | ,(clojure.set/intersection #{:a :b :c} #{:b :c :d}) |
| 19:25 | clojurebot | #{:c :b} |
| 19:31 | leeda | Hi, I'm trying to understand binding... why doesn't this work: (binding [x 1] (println x))? |
| 19:33 | hiredman | ,(doc binding) |
| 19:33 | clojurebot | "([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before. The new bindings are made in parallel (unlike let); all init-exprs are evaluated before the vars are bound to their new values." |
| 19:34 | gfrlog | leeda: binding works with vars, which are normally created with (def) |
| 19:34 | mdeboard` | Hrm why is (fn [x] (+ x x)) not a valid answer to http://4clojure.com/problem/15 ? |
| 19:35 | amalloy | mdeboard`: it is. you must be typoing somewhere? i jsut copy/pasted that and it works |
| 19:35 | gfrlog | mdeboard`: it tells me it's valid |
| 19:35 | mdeboard` | hm not working for me, I have it on four lines. |
| 19:35 | leeda | gfrlog: I see, thanks. So if I do (def x 1), how can I get a per-thread binding for x? |
| 19:35 | mdeboard` | :\ if there's four blanks shouldn't it accept four answers? |
| 19:35 | gfrlog | leeda: after you've def'd it you can (binding [x ...] ...) |
| 19:36 | amalloy | uh. no, you supply an answer, and it uses it in all the blanks |
| 19:36 | leeda | gfrlog: ok, I see, thanks! |
| 19:36 | gfrlog | leeda: note that in clojure 1.3 you have to add the ^:dynamic metadata to the var |
| 19:36 | mdeboard` | amalloy: Hm it works in previous answers |
| 19:36 | amalloy | coincidence |
| 19:36 | mdeboard` | lol |
| 19:36 | leeda | gfrlog: ah ok, I'll look that up |
| 19:36 | mdeboard` | amalloy: Kind of like gist's random coloration? |
| 19:36 | amalloy | mdeboard`: yeah srsly though |
| 19:38 | mdeboard` | I mean for new people inconsistent behavior from the UI is goingto be pretty frustrating |
| 19:38 | amalloy | mdeboard`: it's not inconsistent |
| 19:38 | mdeboard` | How not |
| 19:38 | amalloy | i literally mean that, by coincidence, supplying an answer N times happens to work |
| 19:38 | amalloy | because (= 3 3 3 3) is true |
| 19:38 | amalloy | on, eg, http://4clojure.com/problem/12 |
| 19:40 | amalloy | if you supply "3 3 3" as your answer, it splices that string into each __ and then runs all the tests |
| 19:40 | mdeboard` | From the perspective of a user, that is 100% inconsistent behavior |
| 19:40 | mdeboard` | It doesn't matter if mechanically behidn the scenes it's expected behavior |
| 19:40 | mdeboard` | To the user it's nonsensical |
| 19:41 | amalloy | you are the first user to have encountered this "nonsense", perhaps because you didn't read http://4clojure.com/directions? |
| 19:46 | mdeboard` | amalloy: Before I say anything else I wanna make clear that I'm not griping about the site (which I infer you maintain?). It's awesome and I'm using it. I just think that something as straightforward as fill-in-the-blank shouldn't require reading instructions. I mean, the only reason I care is because I'd hate for someone to get turned off by unpredictable behavior. If you give a human four problems and the ability t |
| 19:46 | mdeboard` | o enter in four solutions, I'd wager a lot will do that. I assumed every line was being evaluated individually against its corresponding form. If you like it that way, then cool. Now that I know, I know. |
| 19:47 | Scriptor | does anyone know if anyone has written a netflix lib for clojure? |
| 19:47 | amalloy | mdeboard`: i don't think a lot of people have thought of it as four problems. it's one problem, with four test cases |
| 19:47 | chitsubr | rich hickey's wiki page is nominated for deletion - http://en.wikipedia.org/wiki/Wikipedia:Articles_for_deletion/Rich_Hickey. sheer madness |
| 19:48 | mdeboard` | amalloy: Alright. |
| 19:48 | amalloy | if you have a suggestion for a good way to improve the UI, or to put into a readme somewhere, i can make it happen |
| 19:48 | Scriptor | "Clojure may be notable but its creator may be not" wow |
| 19:49 | gfrlog | This feels a lot like Horton Hears a Who. I think we need to start banging pots so the kangaroo can hear us. |
| 19:50 | mdeboard` | Nah, I'm probably just being a dummy. Long day at work. |
| 19:50 | Scriptor | so...no netflix lib? I has a project! |
| 19:50 | amalloy | Scriptor: first go find a java lib for it |
| 19:51 | Scriptor | amalloy: but then I won't has a project :p |
| 19:52 | Scriptor | ah, http://www.blueleftistconstructor.com/projects/nfjc/current/ |
| 19:53 | mdeboard` | Wow, that Artem Karimov fella really, really has a stick somewhere about Clojure. |
| 19:53 | mdeboard` | re: wikipedia |
| 19:54 | technomancy | pretty typical of the deletionists crew |
| 19:55 | technomancy | that said, the article isn't terribly informative |
| 19:56 | Scriptor | heh, he's an 18-year old kid from moscow |
| 19:56 | mdeboard` | I wonder why, say, Guido van Rossum is notable but not Rich Hickey? |
| 19:56 | mdeboard` | Anywya. |
| 19:57 | amalloy | mdeboard`: because he has rabies re: TCO |
| 19:58 | amalloy | and reference counting |
| 19:58 | amalloy | that is basically the one things i know about him: he has terrible ideas about TCO and reference counting |
| 19:59 | zodiak | actually, I wonder what mascot clojure would have .. you know.. a nice friendly little thing to put on t-shirts, stickers, etc |
| 19:59 | zodiak | it's all about propaganda ;) |
| 19:59 | Scriptor | a lamb? |
| 19:59 | mdeboard` | A lamb riding a dragon |
| 19:59 | Scriptor | a lamb saying "yes" in Russian :p |
| 19:59 | zodiak | I was thinking single cell organism; you know, sort of the building block of life ;) |
| 20:00 | mdeboard` | ಠ_ಠ |
| 20:00 | ibdknox | why did Clojure go with a mailing list instead of a forum? |
| 20:00 | Scriptor | most languages do |
| 20:01 | Scriptor | I've also seen very little spam on the mailing list, maybe it's harder to manage on a forum? |
| 20:01 | ibdknox | I would think the exact opposite |
| 20:01 | mdeboard` | old people love mailing list |
| 20:01 | mdeboard` | s |
| 20:01 | ibdknox | you can moderate a forum |
| 20:01 | amalloy | i would have been happy with usenet |
| 20:02 | hiredman | mdeboard`: old people? |
| 20:02 | Scriptor | ibdknox: also, the google groups website itself acts almost like a forum |
| 20:03 | mdeboard` | hiredman: Yeah, you know, everyone older than the person using the term "old people". (I'm in my 30s) |
| 20:03 | ibdknox | Scriptor: it's close, but the lack of true moderation makes that less useful I would think |
| 20:03 | ibdknox | Scriptor: also, the interface could be greatly improved |
| 20:03 | Scriptor | ibdknox: hmm, it allows some moderation |
| 20:03 | ibdknox | like having code highlighting and such |
| 20:03 | Scriptor | but eh, a lot of programmers like their email clients, I think, |
| 20:03 | amalloy | Scriptor: or news clients |
| 20:04 | ibdknox | indeed |
| 20:04 | hiredman | ibdknox: could be argued you need a better email client |
| 20:04 | Scriptor | the only project I can think of off the top of my head with a forum is a PHP web framework |
| 20:04 | ibdknox | hiredman: haha one that auto-syntax-highlights code? :) |
| 20:05 | mdeboard` | ibdknox: emacs mail |
| 20:05 | Scriptor | emacs os. ftfy |
| 20:05 | ibdknox | lol |
| 20:05 | mdeboard` | srs |
| 20:05 | mdeboard` | :) |
| 20:06 | Scriptor | hmm, so there is a java netflix lib, but that means now I have to learn interop |
| 20:06 | technomancy | that's one of the most annoying things about Android developers; they seem to use PHPbb un-ironically |
| 20:06 | mdeboard` | Scriptor: Why? |
| 20:06 | amalloy | Scriptor: that's gotta be easier than writing it yourself |
| 20:07 | mdeboard` | I ask that question assuming two things: 1. There's a public API for Netflix 2. it's possible to craft HTTP requests in Clojure in such a way that exploits the API |
| 20:07 | Scriptor | mdeboard`: I figured a netflix app would be a good first project |
| 20:07 | mdeboard` | Scriptor: Oh, I meant using Java interop |
| 20:07 | mdeboard` | That is a p cool first project |
| 20:08 | Scriptor | mdeboard`: oh, because the lib is pure java, so I'd need to use the Java interop to call it from Clojure |
| 20:08 | Scriptor | amalloy: I never take the easy route when learning :p |
| 20:11 | mdeboard` | Scriptor: Yeah the Java lib is almost certainly the best move in the long run but if you were really averse to it, the Netflix API is pretty straightforward from what I can tell in a 20-sec gloss over. |
| 20:15 | gfrlog | Scriptor: write your own and make it somehow enable me to watch streaming video on linux |
| 20:20 | mdeboard` | gfrlog: Netflix allegedly has something in the works for that? |
| 20:21 | gfrlog | mdeboard`: I'll believe it when somebody tells me it a second time |
| 20:21 | mdeboard` | gfrlog: Netflix allegedly has something in the works for that? |
| 20:21 | Scriptor | gfrlog: what he said |
| 20:21 | gfrlog | ah, I see |
| 20:21 | gfrlog | well here's hopin |
| 20:22 | hopin | Hey everyone! |
| 20:22 | gfrlog | hi hopin |
| 20:22 | hopin | Thanks for the intro, gfrlog |
| 20:22 | gfrlog | I do what I can |
| 20:22 | Scriptor | what |
| 20:22 | Scriptor | ah |
| 20:25 | Scriptor | hmm, have to apply for a key for each application |
| 20:26 | chitsubr | so is lein help supposed to take 5+ minutes to run? |
| 20:26 | chitsubr | I downloaded the lein script, chmod +x'ed it and typed lein help, and it is taking forever to run |
| 20:26 | mdeboard | chitsubr: It's slow, but not that slow. |
| 20:26 | amalloy | lein self-install first |
| 20:27 | chitsubr | amalloy: ah so thats what I missed, thx |
| 20:27 | amalloy | but it should cope better if you've missed that step, i would think |
| 20:29 | Scriptor | when people interop with java libs, what do they do to keep the code from basically becoming java with parentheses, since wrapper functions are discouraged? |
| 20:30 | gfrlog | Scriptor: moan and wail |
| 20:31 | Scriptor | gfrlog: that's what #clojure's for! |
| 20:32 | ataggart | Scriptor: wrapper functions like (defn size [coll] (.size coll)) are discouraged. It really depends on the api one is working with. |
| 20:32 | mdeboard | amalloy: How did you say to suggest UI changes for 4clojure? |
| 20:33 | amalloy | uh, i didn't really specify. you can mention them here, or open an issue at https://github.com/dbyrne/4clojure/issues |
| 20:34 | Scriptor | ataggart: makes sense, I guess I'll write a wrapper when it gets too imperative for my taste |
| 20:35 | ataggart | Scriptor: also note that even "java with parentheses" ends up having fewer parens than straight java (e.g., the .. and doto macros) |
| 20:36 | mdeboard | amalloy: 1. Put a listener for Ctrl+Return (or whatever) on your "Run" button; since I can't tab out of the REPL box I have to use my mouse to click Run <firstworldproblems> 2. The "Now try %s!" element keeps suggesting the last unfinished problem; I think it would be a bit better if it either automatically suggested the next problem in the list of problems OR if there was a NEXT PROBLEM button. |
| 20:37 | Scriptor | ataggart: I know, just using it as a figurative way of saying imperative code that happens to be written in a lisp :) |
| 20:37 | amalloy | mdeboard: yeah, the Ace codebox annoys me no end |
| 20:37 | amalloy | stealing all the keystrokes |
| 20:40 | amalloy | mdeboard: for (2), why don't you try forking it yourself? i wrote that feature and iirc it would be pretty trivial to make it link to both of those |
| 20:40 | mdeboard | amalloy: I'm not that confident in my clojure-foo |
| 20:46 | mdeboard | amalloy: What the hey, I'll give it a go. |
| 20:47 | amalloy | mdeboard: sweet. good luck |
| 20:48 | amalloy | you'll feel great when you actually get something done, that's visible in a public clojure project |
| 20:50 | Scriptor | heh, just found out *jure names aren't allowed |
| 20:51 | hiredman | wuh-pow! |
| 20:58 | cemerick | I thought that had been pulled lately? |
| 21:00 | mdeboard | How will anyone make an RPG if they can't have names like Abjure and Conjuure? |
| 21:00 | mdeboard | Conjure* |
| 21:00 | mdeboard | Wait what about Compojure |
| 21:01 | Scriptor | mdeboard: I guess it was the original |
| 21:01 | Scriptor | and they don't want anything competing with it name-wise? |
| 21:03 | technomancy | it's just a restriction on new project generation |
| 21:03 | technomancy | you can work with existing projects just fine |
| 21:03 | amalloy | wut. is this an actual thing? someone is saying not to use names ending with jure? |
| 21:04 | Scriptor | amalloy: it's built-in to lein, at least |
| 21:06 | chouser | just lein, I believe. |
| 21:09 | Scriptor | what does it mean when something is 'grandfathered' in? |
| 21:10 | mdeboard | Scriptor: A thing being granted an exception to a rule, on the basis that the attribute of the thing that is now forbidden by the rule predated the inception of the rule. |
| 21:10 | ibdknox | http://en.wikipedia.org/wiki/Grandfather_clause |
| 21:10 | mdeboard | Or yeah. |
| 21:12 | Scriptor | mdeboard, ibdknox: ah, thanks, was in relation to https://github.com/pjstadig/leiningen/commit/f4e4c1958d9f9d07d46f7e1c2d3ea11f6b660f72 |
| 21:12 | mdeboard | amalloy: I'm getting an error while trying to load localhost:8080: "java.util.concurrent.RejectedExecutionException"... I'm operating under the assumption I've left something undone with clojail .java.policy |
| 21:13 | mdeboard | amalloy: Or am I missing something. |
| 21:14 | ibdknox | Scriptor: yeah, that's just saying that *jure names are no longer allowed, with the exception of compojure |
| 21:14 | amalloy | mdeboard: hm. is it possible you just don't have mongodb running? that causes all kinds of weird not-obviously-related exceptions |
| 21:14 | mdeboard | Hm I do have it running in a separate term window |
| 21:15 | mdeboard | amalloy: And shows several connections/disconnections as I start/stop the dev server |
| 21:15 | amalloy | well, that should be fine then. it shouldn't be related to java.policy, but sounds more like an agent issue |
| 21:17 | amalloy | mdeboard: what command are you using to start things up? |
| 21:17 | mdeboard | `lein run` in 4clojure/ |
| 21:17 | mdeboard | and it is starting up ko |
| 21:17 | mdeboard | ok |
| 21:17 | mdeboard | 2011-07-11 16:17:38.572:INFO::Started SocketConnector@0.0.0.0:8080 |
| 21:18 | mdeboard | but when I try to connect |
| 21:18 | mdeboard | that's when it errors out |
| 21:19 | amalloy | what if you load a different page, like localhost:8080/problems |
| 21:19 | mdeboard | amalloy: same |
| 21:22 | mdeboard | wow ps aux|grep mongo yields... interesting results |
| 21:23 | amalloy | i don't know what would cause a rejectedexecutionexception |
| 21:23 | chouser | iirc, stopping the agents and then trying to use them does that |
| 21:25 | amalloy | i wonder if that's related to some issues technomancy had with lein and shutdown-agents, then? i'm using some git checkout of lein from a while ago |
| 21:28 | gfrlog | is there a standard way to keep db-auth data in a non-versioned file? |
| 21:30 | gfrlog | (such that it is easy to load from clojure) |
| 21:30 | amalloy | gfrlog: just add it to .gitignore? |
| 21:31 | gfrlog | amalloy: I guess I meant more the easy-to-load-from-clojure part. I.e., would you make it just another source file? or some kind of java properties thing? |
| 21:31 | mdeboard | amalloy: Would the ful stack trace help at all? :-\ |
| 21:36 | technomancy | amalloy: yeah, you can't rely on the agent thread pool to keep the process alive anymore; you need to block if you want to keep non-daemon threads running |
| 21:36 | technomancy | due to Clojure not providing tools for dealing with the agent thread pool correctly |
| 21:37 | technomancy | I have a half-drafted message to the mailing list explaining this that I really should finish |
| 21:39 | technomancy | otherwise a single use of clojure.java.shell/sh will cause the process never to exit (!) |
| 21:40 | technomancy | puredanger has a good explanation of the problem: http://tech.puredanger.com/2010/06/08/clojure-agent-thread-pools/ |
| 21:41 | mdeboard | technomancy: Hrm I tried out the link, blank page. |
| 21:42 | mdeboard | cached http://webcache.googleusercontent.com/search?q=cache:YlxRVd5mJVsJ:tech.puredanger.com/2010/06/08/clojure-agent-thread-pools/+clojure+agent+thread+pools&cd=1&hl=en&ct=clnk&gl=us&source=www.google.com |
| 21:48 | cesDave | Hey, does anyone feel like answering a project euler question? |
| 21:48 | cesDave | Should be an easy one... |
| 21:49 | hiredman | the answer is "yes it is solvable" |
| 21:50 | cesDave | Not the question, question is, why would someone take (range 1 (floor (sqrt n))) when trying to find the factors of n? couldn't there be a factor of n larger than sqrt n? |
| 21:51 | cesDave | guess more of a math question |
| 21:51 | mdeboard | project euler is 100% math questions, not programming |
| 21:52 | Scriptor | cesDave: think about it, if you have n = 100, pick a number greater than the square root of it that's a factor of 100 |
| 21:52 | cesDave | 50 |
| 21:52 | Scriptor | what's 100/50? :) |
| 21:52 | jweiss_ | is there a function that 'composes' predicates using either and/or? |
| 21:52 | cesDave | 2, but 50 is still a factor of n greater than root n |
| 21:52 | Scriptor | sure |
| 21:53 | Scriptor | but as soon as you know 2 is a factor of 100 you immediately know 50 is as well |
| 21:53 | mdeboard | what |
| 21:53 | cesDave | true enough |
| 21:54 | jweiss_ | if you're lookign for primes, once you know one factor, you don't care about the other |
| 21:54 | jweiss_ | so the smaller one will do |
| 21:54 | hiredman | clojurebot: sieve? |
| 21:54 | clojurebot | see the genuine sieve of eratosthenes |
| 21:55 | hiredman | clojurebot: the genuine sieve of eratosthenes |
| 21:55 | clojurebot | the genuine sieve of eratosthenes is http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf |
| 21:55 | cesDave | mkay, i'll check it out. thanks! |
| 21:55 | cesDave | sorry for slightly off-topic. |
| 21:55 | hiredman | (may include ML) |
| 22:00 | chitsubr | if x * y = N, then one of x or y will be less than root(n), since if both were greater than root(n), their product would be greater than n |
| 22:00 | scottj | jweiss_: every-pred and maybe some-pred, in clojure 1.3 |
| 22:01 | Scriptor | chitsubr: right, there's a one-to-one mapping of x<sqrt(n) to factors>n, at least in the natural numbers |
| 22:02 | chitsubr | cesDave.. replace less than with "less than or equals" |
| 22:04 | cesDave | chitsubr: Yeah, I see that. I'll give that more consideration in terms of the problem I'm looking at. You may have guessed I'm working on project euler 3. |
| 22:04 | ataggart | technomancy: did you see any problem with using a shutdown hook to deal with the agent pools? |
| 22:05 | cesDave | chitsubr: I'm new to clojure and don't have a math degree so I've got a couple challenges in that regard. |
| 22:09 | jweiss_ | scottj: thanks - still on 1.2, so i'll just use 'and' :) |
| 22:09 | jweiss_ | or #(and ...) rather |
| 22:10 | jweiss_ | or maybe i'll try every? and juxt |
| 22:12 | chitsubr | cesDave - right. I wonder if there is a companion site to project Euler that provides some math help for each of the problems. |
| 22:28 | Scriptor | man, just adding a jar I downloaded to my lein project seems to require a bunch of hoops |
| 22:28 | hiredman | stop downloading jars |
| 22:28 | Scriptor | ok :( |
| 22:29 | hiredman | find the groupid/artifactid and version, add it to your project.clj |
| 22:29 | mdeboard | sigh, I feel as though I'm missing something re: lein again. Once I do "lein new <foo>", when I go into foo/, every lein command I execute is in the 'foo' context, right? e.g. if I do `lein swank` in foo/, when I connect to that connection, all the project's dependencies will be available to me, right? (assuming I did `lein deps`) |
| 22:29 | hiredman | let lein download it |
| 22:29 | hiredman | mdeboard: yes |
| 22:31 | hiredman | Scriptor: generally what I do is google "<projectname> maven" to find that info |
| 22:32 | mdeboard | hiredman: I have (require 'clojure.contrib.strint) which introduces the `<<` symbol for string interpolation in the src for this project. I have clojure-contrib 1.2.0 in my project.clj. However when i go to my project directory and run e.g. `lein repl` it gives me an "Unable to resolve symbol: << in this context" error message. Am I doing something wrong? |
| 22:33 | hiredman | mdeboard: did you load the file that has the require? |
| 22:34 | vkurup | \q |
| 22:34 | mdeboard | hiredman: I was under the impression it was loaded by lein when I fired up the repl, since it was apparently parsing the file |
| 22:35 | Scriptor | hiredman: the repository the jar is hosted on isn't part of the default ones lein looks under, is there a way I can manually edit the pom file or do I need to fiddle with maven? |
| 22:35 | hiredman | mdeboard: it wasn't |
| 22:35 | hiredman | Scriptor: have you read the lein readme and looked at the sample project.clj? |
| 22:35 | hiredman | I suggest you do |
| 22:36 | technomancy | ataggart: I haven't looked into it enough |
| 22:37 | technomancy | mdeboard: if you want to "land" in a given namespace for every lein repl invocation, set it as :repl-init in project.clj |
| 22:37 | mdeboard | hiredman: I see. When I do (use 'change), it returns the same message again |
| 22:37 | technomancy | maybe that could be part of the default project skeleton in a future version |
| 22:37 | mdeboard | technomancy: I see, i.e. :repl-init foo |
| 22:37 | ataggart | technomancy: ok. I added a question to Rich about why the pools use non-daemon threads. Hopefully once we know the full reasoning, we can resolve this. http://dev.clojure.org/jira/browse/CLJ-124 |
| 22:37 | technomancy | mdeboard: foo.core hopefully |
| 22:37 | mdeboard | oh |
| 22:38 | technomancy | ataggart: never going to be resolved for 1.2 unfortunately and likely not for 1.3 either =\ |
| 22:38 | technomancy | so the hacks and workarounds will be with us forever |
| 22:38 | technomancy | aw geez; that issue has been around since google code days? |
| 22:38 | hiredman | ~namespaces |
| 22:38 | clojurebot | namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it |
| 22:39 | technomancy | ಠ_ಠ |
| 22:39 | hiredman | mdeboard: don't get into a habbit of using single segment namespaces |
| 22:39 | mdeboard | ಠ_ಠ |
| 22:40 | mdeboard | hiredman: So for package 'change', with change.clj being in ~/change/src/ , for example, I should do :repl-init change.change |
| 22:40 | ataggart | technomancy: it might make it into 1.3 if the change I have in mind gets accepted. It wouldn't change any actual behaviour, other than obviating the need to ever call shutdown-agents |
| 22:40 | technomancy | ataggart: your optimism is refreshing |
| 22:40 | hiredman | mdeboard: no |
| 22:41 | hiredman | there is a reason `lein new` created src/change/core.clj for you |
| 22:41 | ataggart | technomancy: it comes back to me when I stop trying to help for a while. |
| 22:41 | mdeboard | hiredman: Right, I figured that, but when that dir isn't on my classpath. So I assume di was doing it wrong. |
| 22:42 | hiredman | mdeboard: how do you know it is not on your classpath? |
| 22:42 | mdeboard | I did `lein classpath` |
| 22:42 | hiredman | and 'src' was not on the classpath? |
| 22:43 | hiredman | please picture me here with an eyebrow raised |
| 22:43 | mdeboard | src/ yes, but not src/change |
| 22:43 | mdeboard | haha |
| 22:43 | mdeboard | Cnsider itpictured |
| 22:43 | technomancy | hiredman: o_O works well for that |
| 22:43 | hiredman | so you (use 'change.core) |
| 22:43 | mdeboard | DIdn't seem like classpath was recursive since every change/ subdr was on classpath |
| 22:43 | technomancy | mdeboard: each classpath entry should be considered a "root" |
| 22:44 | hiredman | technomancy: far too goofy looking, you've seen my eyebrows, they are serious business |
| 22:44 | mdeboard | I see |
| 22:44 | technomancy | hiredman: true; further exploration of the unicode plane is in order |
| 22:44 | mdeboard | hiredman: So, should the code I have in src/change/change.clj go in core instead? core.clj is empty. |
| 22:45 | hiredman | mdeboard: change/change.clj (relative to a classpath root) should have a namespace like change.change and can be loaded like (require 'change.change) or (use change.change) or … |
| 22:47 | mdeboard | I see |
| 22:49 | mdeboard | I've clearly done somehting wrong here, because things which were working last night no longer work :) |
| 22:50 | mdeboard | me am no good computer |
| 22:50 | Scriptor | hiredman: thanks for the tip, though I'd browsed it enough, :repositories was what I needed (duh) |
| 23:32 | ihodes | hiredman: ಠ_ಠ is what you're looking for |
| 23:34 | amalloy | i think his eyebrows are likely a lot more formidable than that |