2012-06-09
| 00:09 | muhoo | eslick_: thoughtworks is the only big shop i know of that does clojure in the bay, but there may be others |
| 01:17 | johnmn3 | what does it mean that "Can only recur from the tail position" ?? |
| 01:17 | lazybot | johnmn3: Uh, no. Why would you even ask? |
| 01:17 | johnmn3 | The recur is the last expression within the scope of the doseq |
| 01:20 | hiredman | doseq has no return value, it has no tail |
| 01:20 | johnmn3 | ah |
| 01:20 | johnmn3 | yea, I'm trying loop now |
| 01:21 | hiredman | you cannot recur across loops |
| 01:21 | johnmn3 | oh? |
| 01:21 | hiredman | how would recur know which loop to recur to? |
| 01:22 | hiredman | (loop [] (loop [] (recur))) |
| 01:23 | johnmn3 | well, I'm not nesting two loops |
| 02:09 | johnmn3 | I'm currently doing a (.read on an input stream, which gets sent to (.write on a FileOutputStream. |
| 02:09 | johnmn3 | Now, I want to instead write that to a datastructure |
| 02:16 | Sgeo_ | If basic math things such as sin rely on interop, does this reduce the number of libraries that work both on Clojure and ClojureCLR? |
| 03:04 | amalloy | Sgeo_: you can always choose to rely instead on a library like clojure.math that provides a layer of indirection to the underlying libraries |
| 03:12 | borkdude | can I see which libraries on clojars use netty? |
| 03:12 | borkdude | and how? |
| 03:12 | brehaut | http://clojuresphere.herokuapp.com/netty |
| 03:13 | borkdude | brehaut great tnx ;) |
| 04:35 | tomoj | is there a nicer way to do (fn [sep & args] (join sep args)) ? |
| 04:35 | tomoj | I feel like it should be obvious.. |
| 04:38 | borkdude | just use join? |
| 04:38 | AimHere | join takes a seperator and a list of string |
| 04:38 | AimHere | *strings |
| 04:38 | borkdude | ah |
| 04:38 | AimHere | He wants just a list of stuff, the first one being the seperator |
| 04:39 | borkdude | of course |
| 04:39 | amalloy | i don't think so, tomoj |
| 04:39 | amalloy | you can generalize, though, and then use your general tool |
| 04:39 | borkdude | there is no ~@ in functions ;-) |
| 04:39 | AimHere | Well you can just give that fn up there a name, then it's the generalization |
| 04:40 | tomoj | strange |
| 04:40 | tomoj | it doesn't already have a name? |
| 04:41 | borkdude | wait ~@ has nothing to do with it ;; I'm still sleepy... |
| 04:41 | tomoj | hmm |
| 04:41 | tomoj | I guess it doesn't generalize well |
| 04:41 | ejackson | tomoj: interpose ? |
| 04:41 | amalloy | ((fn listify [f arity] (fn [& args] (apply f `(~@(take arity args) ~(drop arity args))))) join 1) |
| 04:42 | tomoj | seems weird though |
| 04:42 | ejackson | ,(apply str (interpose ":" ["Hello" "My" "Honey"])) |
| 04:43 | clojurebot | "Hello:My:Honey" |
| 04:43 | amalloy | ejackson: that's just join |
| 04:43 | amalloy | &(((fn listify [f arity] (fn [& args] (apply f `(~@(take arity args) ~(drop arity args))))) clojure.string/join 1) "," 1 2 3 4) |
| 04:43 | lazybot | ⇒ "1,2,3,4" |
| 04:43 | amalloy | now listify is the general case, and you can easily apply it to join |
| 04:43 | ejackson | and so it is |
| 04:46 | tomoj | what does that do with arity 0? |
| 04:46 | amalloy | it's probably just (f args) |
| 04:46 | amalloy | or rather (comp f list) |
| 04:47 | tomoj | yeah |
| 05:00 | ejackson | is there a function for: (#(assoc % :key (f %)) map) ? |
| 05:00 | ejackson | like update-in, but taking the whole map, rather than a particular key as argument ? |
| 05:04 | tomoj | no. (assoc map :key (f map)) is shorter than that though.. |
| 05:05 | tomoj | depends on what the map is named I guess :) |
| 05:06 | ejackson | ejackson's-baroquely-named-mega-map, for instance ? |
| 05:08 | ejackson | agreed, its in that form as I'm mapping it over a seq of maps (I do this a lot) |
| 05:52 | notsonerdysunny | while I am able to run clj project that imports a java-class file.. I am having trouble getting it to work with slime .. it keeps reporting that it cannot find the class file when I try to compile the file using C-c C-k does any of you have a suggestion |
| 05:52 | notsonerdysunny | I am able to successfully do lein jar |
| 05:52 | notsonerdysunny | or lein uberjar |
| 05:52 | notsonerdysunny | or lein run |
| 05:53 | notsonerdysunny | just unable to work with it using slime.. |
| 06:06 | PKHG | hallo, good morning form (NL) (just 2 minutes left ;-) ).... how can I display the conten of jar from out a REPL? |
| 06:14 | PKHG | lazybot: how to ping all listeners? |
| 06:14 | PKHG | &"how to ping several people" |
| 06:14 | lazybot | ⇒ "how to ping several people" |
| 06:15 | PKHG | &(* 1234567 88986868686868) |
| 06:15 | lazybot | java.lang.ArithmeticException: integer overflow |
| 06:15 | PKHG | &(* 1234567 88) |
| 06:15 | lazybot | ⇒ 108641896 |
| 06:16 | borkdude | &(*' 1234567 88986868686868) |
| 06:16 | lazybot | ⇒ 109860251514140566156N |
| 06:17 | borkdude | ,(doc *') |
| 06:17 | clojurebot | "([] [x] [x y] [x y & more]); Returns the product of nums. (*) returns 1. Supports arbitrary precision. See also: *" |
| 06:19 | PKHG | borkdude: how to look at the conten of a *.jar from within a repl? |
| 06:19 | PKHG | oh and hallo to you ;-) |
| 06:19 | borkdude | PKHG maybe take a look at this library: https://github.com/Raynes/bultitude/blob/master/src/bultitude/core.clj which lists the namespaces from a jar file |
| 06:19 | PKHG | thanks will look now ;-) |
| 06:20 | borkdude | PKHG if you are familiar with the Java API for doing this, you can work it out probabl |
| 06:20 | PKHG | borkdude: lovely complicated for a newbie |
| 06:20 | PKHG | Java was last century for me ;-( |
| 06:20 | borkdude | PKHG I don't have a ready answer, just some pointers on how to get started maybe ;) |
| 06:21 | PKHG | will look at the script ... |
| 06:21 | PKHG | trying to use it .. |
| 06:23 | borkdude | PKHG maybe this answer on StackOverflow also contains some useful pointer: http://stackoverflow.com/questions/5171957/access-file-in-jar-file |
| 06:23 | PKHG | yes the last example ... trying too ;-) |
| 06:27 | PKHG | thanks .. have to leave .. |
| 08:39 | cshell | Saturday, the best day to do all of your at-home development! |
| 09:41 | clj_newb | Hi, any suggestion on how to read large files ? is duck-stream the best cho? Or go straight to a BufferedReader? |
| 09:43 | ejackson | clj_newb: http://richhickey.github.com/clojure/clojure.java.io-api.html is a good choice. |
| 09:43 | lazybot | Nooooo, that's so out of date! Please see instead http://clojure.github.com/clojure/clojure.java.io-api.html and try to stop linking to rich's repo. |
| 09:43 | ejackson | sorry lazybot |
| 09:43 | clj_newb | thank you ejackson |
| 09:43 | clj_newb | no offense if I go to where the bot suggest hehe |
| 09:44 | ejackson | yes, I pasted before I looked |
| 10:00 | Crackneck | hello can someone please help a noob understand the recur exprs* (http://clojure.org/special_forms#Special%20Forms--(recur%20exprs*) I not sure how to read that function so that i makes sense |
| 10:02 | AimHere | Crackneck, it's not something you really need to know THAT much about if you're a complete noob, in that it's just an optimization |
| 10:02 | Crackneck | im just goiing throug the clojure learning tool koans |
| 10:02 | Crackneck | it's one of their questions |
| 10:02 | Crackneck | now i could just copy that code |
| 10:02 | AimHere | What it is is that when you're call a function, arguments get pushed onto the stack and the return value gets popped when you return |
| 10:02 | Crackneck | but that would be stupid =) |
| 10:03 | mthvedt | the recur syntax is like a function call, except instead of calling a function you jump to the nearest recursion point |
| 10:03 | AimHere | So if you recurse heavily, your stack might grow too big, which might use up vast amounts of memory |
| 10:05 | AimHere | If you can write your function so that the return value is in the 'tail position' (i.e., it's not being changed after the recursion call) then you can skip past all this pushing and popping |
| 10:05 | Crackneck | mthvedt ok, and the recursion point in that example is the loop? |
| 10:06 | mthvedt | yup |
| 10:06 | AimHere | Right, it's either the enclosing 'loop' or the enclosing function call |
| 10:07 | Crackneck | ok, and the "tail" position is the line with only " acc " |
| 10:07 | AimHere | nah, the tail position is the call to 'recur' |
| 10:07 | mthvedt | multiple positions in a form can be "tail" |
| 10:08 | babilen | Hi all -- I need some help with a most likely quite trivial data-transformation. I've detailed it on https://www.refheap.com/paste/3065 and would be greateful for any pointers. |
| 10:08 | mthvedt | tail position only means the compiler can wrap up all computation before executing the recur |
| 10:09 | AimHere | Crackneck > You can think of it as (defn f [cnt acc] (if (zero? cnt) acc (f (dec cnt) (* acc cnt))) as a factorial function of n, called with (f n 1) |
| 10:09 | Crackneck | that helped AimHere, thanks |
| 10:10 | Crackneck | not being sarcastic |
| 10:10 | Crackneck | i guess I just got confused by the big words |
| 10:11 | Crackneck | tail and recursion point |
| 10:11 | Crackneck | both new stuff to me |
| 10:11 | AimHere | Essentially it's just rewriting functions in a funny way because it means they don't eat up lots of memory |
| 10:12 | Hali_303 | hi! is there a built-in average function? |
| 10:12 | Crackneck | yes i am familiar with the concept, just not the clojuresk implementation |
| 10:13 | babilen | Hali_303: Not AFAIK, but it is easy to implement it as https://www.refheap.com/paste/3066 |
| 10:13 | Hali_303 | babilen: yeah I know, I just see no point in everybody implementing it.. |
| 10:15 | babilen | Any ideas concerning https://www.refheap.com/paste/3065 ? -- I am really not sure where to start :-/ |
| 10:17 | cshell | babilen: Just create a map with the values in your vector as thte keys |
| 10:17 | cshell | and always use the (first) for the value? |
| 10:19 | babilen | cshell: Well essentially I want to count how often "relN" co-occurs with "patN" and have both number easily accessible in two maps. One that maps { rel → { pat → #occurrences}} and the other { pat → {rel → #occurrences}} |
| 10:21 | cshell | babilen: Right, so a basic function will be switching them around into key value |
| 10:21 | cshell | then you can call that for each sequence and take the result and merge it into a map that counts |
| 10:22 | babilen | cshell: Ok, I am currently working on an approach that just creates tuples (patN, relN) from the input. Any better idea for the switching? |
| 10:24 | cshell | I think that could work as well and then just count all the tuples, right? |
| 10:26 | babilen | Well, group-by first and then count the tuples that have been grouped together. Strikes me as not very elegant, but meh .. |
| 10:34 | AimHere | Couldn't you just have a frequency table of [relN patN]? |
| 10:55 | tmciver | Could someone tell me what the '[&] here means: https://github.com/cgrand/moustache/blob/master/src/net/cgrand/moustache.clj#L120 ? |
| 11:00 | raek | tmciver: that's a part of the moustache route syntax. |
| 11:00 | raek | ["foo" &] matches all urls that begin with /foo/ |
| 11:01 | raek | it is explained in the moustache github readme |
| 11:01 | tmciver | raek: yes, but is that syntax meaningful outside of moustache? ##((apply array-map [:a 1 :b 2]) '[&]) |
| 11:01 | lazybot | ⇒ nil |
| 11:02 | raek | tmciver: what does 'forms' look like there? |
| 11:03 | raek | it has no special meaning in clojure |
| 11:03 | tmciver | raek: Ah, I think I'm getting it. One of the keys in the resulting array-map may be [&]. |
| 11:03 | raek | it just means look up the value for the key which is a vector of the symbol & |
| 11:03 | tmciver | OK, it makes sense to me now. Thanks for helping me to think straight. |
| 11:04 | tmciver | ##((apply array-map [[&] "hello" :a 1]) '[&]) |
| 11:04 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: & in this context |
| 11:05 | tmciver | hmm, maybe not. |
| 11:05 | raek | &((apply array-map ['[&] "hello", :a 1]) '[&]) |
| 11:05 | lazybot | ⇒ "hello" |
| 11:05 | raek | &((apply array-map [[(symbol "&")] "hello", :a 1]) '[&]) |
| 11:05 | lazybot | ⇒ "hello" |
| 11:06 | tmciver | yes |
| 11:06 | raek | symbols are treated as variables when evaluated |
| 11:06 | tmciver | or ##((apply array-map ['[&] "hello" :a 1]) '[&]) |
| 11:06 | lazybot | ⇒ "hello" |
| 11:06 | babilen | AimHere: I was thinking about that as well. The problem is that I also would like to be able (without much computational overhead) to know which pats co-occur with which rels and vice versa. The datastructures that I have in mind just allow me to use (keys (get pat FOO {})) to get that and I can still easily have the frequency as well. |
| 11:06 | tmciver | raek: thanks again. |
| 11:43 | babilen | cshell: I am using https://www.refheap.com/paste/3067 but find it overly complicated. What was your initial intuition regarding the switching key <-> values? |
| 11:43 | horofox | Hi guys, I want to know why does "(= (:a :b :c :d :e) (cons :a '(:b :c :d :e)))" raise IllegalArgumentException? |
| 11:43 | horofox | I'm doing the clojure koans |
| 11:44 | babilen | horofox: Try " (= '(:a :b :c :d :e) (cons :a '(:b :c :d :e)))" (you missed a ' for the first list) |
| 11:44 | babilen | horofox: It also makes sense to read the complete error, which would have been "IllegalArgumentException Wrong number of args passed to keyword: :a ..." -- It is clear that :a is called as a function here, which you obviously don't want. |
| 11:45 | horofox | babilen: IllegalArgumentException Wrong number of args passed to keyword: :a clojure.lang.Keyword.throwArity (Keyword.java:85) |
| 11:45 | horofox | babilen: I'm still getting the same error |
| 11:45 | horofox | ;/ |
| 11:45 | babilen | &(= '(:a :b :c :d :e) (cons :a '(:b :c :d :e))) |
| 11:45 | lazybot | ⇒ true |
| 11:46 | babilen | Note "(= '(:a" vs "(= (:a" |
| 11:46 | horofox | oh lol |
| 11:46 | horofox | i'm so dumb |
| 11:46 | babilen | I'd argue that you are rather blind than dumb :-þ |
| 11:46 | horofox | :P |
| 11:47 | horofox | what are good uses of clojure? |
| 11:47 | babilen | Those errors are always horrible and hard to track down. |
| 11:47 | horofox | I'm not really used to fp and using ' to construct lists so like... i don't have the "eye" to this kind of stuff yet |
| 11:48 | cshell | horofox: concurrency, general programming, etc |
| 11:48 | horofox | cshell: projects that use it? |
| 11:48 | cshell | horofox: the ' just tells it not to evaluate the form - without it it thinks you're making a function call |
| 11:48 | horofox | babilen: with hadoop? |
| 11:48 | thmzlt | babilen: have some of that code to show? |
| 11:49 | cshell | horofox: Websites, some financial industry code, various others - all the work that relevance does I think |
| 11:49 | babilen | thmzlt: Nothing public yet |
| 11:49 | horofox | cshell: oh, so it's not a abbreviation to list? i wouldn't know if you didn't tell me, thanks! |
| 11:49 | antares_ | horofox: Twitter Storm is a distributed data crunching framework, much like hadoop. There are also cascalog (Cascading + Datalog, a query language) by the same authors, I think. They have been using Clojure with Hadoop for years. |
| 11:49 | horofox | cshell: which website is made in clojure? |
| 11:50 | horofox | antares_: oh i see |
| 11:50 | cshell | horofox: correct, it tells the reader to just read in whatever follows instead of trying to evaluate |
| 11:51 | cshell | horofox: Some other people can better answer that, but a clojure website is no different than any other website from the browser perspective - I've written some websites in Clojure |
| 11:51 | rlb | horofox: '(foo) is shorthand for (quote (foo)) |
| 11:52 | rlb | And lists have to be quoted so that they're not evaluated as a function call (as mentioned above). |
| 11:52 | horofox | cshell: I do a lot of web development and work with it atm(i work on a startup with rails). Does clojure have anything that speeds up web development or can scale/is fast? |
| 11:53 | antares_ | horofox: http://webnoir.org |
| 11:54 | cshell | horofox: that's what i use, noir |
| 11:54 | antares_ | Noir is a bit more towards Django in some design decisions and it definitely is "lower level", like Sinatra |
| 11:54 | horofox | antares_: is it very fast? |
| 11:54 | horofox | antares_: would it fit well for say, an API? |
| 11:55 | antares_ | for example, you don't need any "engines", it supports loading views (actions) + templates and stuff from a .jar, so you can create embeddable Web apps |
| 11:55 | cshell | horofox: not much of an api needed - just defpage and defpartial |
| 11:55 | antares_ | horofox: JSON API is its sweet spot |
| 11:55 | cshell | I use enlive as templating over hiccup |
| 11:55 | antares_ | cshell: noir.response/json is probably what most people would try first for APIs (just saying) |
| 11:55 | antares_ | horofox: as for performance, it is very low level and runs on JVM app servers |
| 11:56 | antares_ | a small Noir app without any optimizations does 10K+ requests per second on 100 MBit/s and 4 core machine |
| 11:56 | cshell | ah, got it |
| 11:57 | horofox | nice |
| 11:57 | antares_ | horofox: I am not trying to make any "Ruby cannot scale" kind of claims but check out this: http://blog.beanstalkapp.com/post/23998022427?acd86ee0, after using Ruby since 2006 or so, I can confirm that you generally see this kind of difference once you get around writing decent Clojure code HotSpot can optimize |
| 11:58 | antares_ | horofox: so Noir and Clojure are probably as close to Sinatra/Ruby as it gets, if you don't take Python (same category as Ruby) or JRuby into account |
| 11:58 | horofox | antares_: oh, i've seen this post. this looks good |
| 11:59 | antares_ | horofox: if you are looking for data store clients, clojure.java.jdbc, http://sqlkorma.com, Carmine (for Redis) and http://clojurewerkz.org libraries have you covered |
| 11:59 | antares_ | as for templating, there are several Clojure-based templating languages but I use Mustache (with Stencil or Clostache) |
| 12:00 | horofox | antares_: cool, so there's a ecosystem in clojure for web development it seens :P |
| 12:00 | antares_ | while I use Clojure primarily for non-Webapp services, I have been using Noir with Mustache for 2 days straight now and really enjoy testability and minimalism |
| 12:00 | antares_ | horofox: honestly, a lot of Clojure projects need good docs |
| 12:01 | horofox | antares_: i wanted to join the "data crunching" crowd, i think in the following years it's going to be big. |
| 12:01 | antares_ | but good maturing projects are certainly there and JVM ecosystem gets you a ton of good stuff almost for free |
| 12:02 | antares_ | horofox: I can't say I am doing that much data crunching. Primarily NLP, Web crawlers, "background" services. But we will soon start a new project where the Web part will be in Clojure, too (after 6 years of using Ruby) |
| 12:02 | horofox | antares_: so you are some months ahead of me hehe :) |
| 12:03 | antares_ | horofox: oh, and there's also http://immutant.org |
| 12:03 | horofox | antares_: I wanted to try some nlp with clojure also :P |
| 12:03 | antares_ | much like TorqueBox for Ruby |
| 12:03 | horofox | thats cool... 0.1.0 hehe |
| 12:04 | antares_ | there are 1-2 year old projects that are still 0.2.0 or so in Clojure |
| 12:05 | antares_ | for some reason people are very conservative about numbering |
| 12:05 | antares_ | we start with 1.0.0-alpha1 for http://clojurewerkz.org and announce things at about rc1 |
| 12:05 | horofox | hehe |
| 12:05 | antares_ | but none of that 0.1.0 or 0.0.1 stuff |
| 12:05 | antares_ | there are awesome libraries that are at 0.0.9 |
| 12:05 | antares_ | I mean, come on, plenty of people use them, they are several months old |
| 12:05 | antares_ | and at 0.0.x |
| 12:07 | horofox | i see hehe! |
| 12:07 | horofox | i just want to see how i'm going to get used to fp :P |
| 12:08 | horofox | antares_: how long have you been studying clojure? |
| 12:08 | horofox | or fp |
| 12:09 | antares_ | Clojure is not as strict as Haskell, for example. If you want to do I/O semi-randomly, go for it, just don't use it inside STM transactions. TheJust as example. Monads and all ther CS theory stuff is entirely optional, too. |
| 12:09 | antares_ | horofox: I used Scala prior to Clojure for ~ 1 year |
| 12:09 | antares_ | and now almost 1 year with Clojure |
| 12:10 | antares_ | picked up some erlang and haskell along the way, too |
| 12:10 | antares_ | I think in 2-3 months you will be comfortable enough to notice what works better and learn from other people's code |
| 12:11 | antares_ | it may be just 4-5 weeks if you have someone experienced around to help you and point out what you are doing wrong or where you can just use a core library function instead of writing your own thing |
| 12:11 | horofox | antares_: yea, that's what i want. I'm doing the koans and then I'm going to start with the clojure book. |
| 12:11 | horofox | antares_: |
| 12:11 | horofox | antares_: woops, hehe. |
| 12:12 | antares_ | but I may be an exception, I never worried about prog lang syntax and FP in general fits my brain well (I find it easier than all that OO patterns stuff that keeps layering abstractions upon abstractions) |
| 12:12 | antares_ | horofox: I've never done koans but I heard good things about them |
| 12:12 | antares_ | also, 4clojure.com |
| 12:13 | antares_ | I jumped into Clojure by developing a couple of libraries I needed when I decided I've had enough CRuby scaling pain |
| 12:15 | horofox | antares_: i see. i'm going to check 4clojure out |
| 12:31 | eslick | Anyone have a sense of tradeoffs in using regular maps vs. records when pulling records from a document DB? |
| 12:32 | eslick | I have a web app which pulls data from mongodb, does some modest transformations on it, then pushes it over HTTP to the client |
| 12:32 | eslick | I use a :type field to dispatch various common methods on all those objects today |
| 12:33 | eslick | I like the documentation benefits of clearly defining protocols over types, but it didn't seem worth the performance overhead. |
| 13:23 | clj_newb | Hi, can I retrieve a default value when nil from a map I mean (def n {:a 1 :b 7}) and when (:c n) since it'll return nil assign a number |
| 13:25 | morphling | ,(doc get) |
| 13:25 | clojurebot | "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present." |
| 13:25 | hoeck | clj_newb: of course you can: (:c {} 'foo) |
| 13:29 | clj_newb | thank you |
| 14:28 | clj_newb | ,(doc if-let) |
| 14:28 | clojurebot | "([bindings then] [bindings then else & oldform]); bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else" |
| 15:15 | Sgeo_ | Hmm. |
| 15:15 | Sgeo_ | Auto-gensyms are implementable in CL, right? |
| 15:17 | Vinzent | Sgeo_, I guess so |
| 15:19 | cmajor7 | how do I call this from clojurescript (with jayq): $("[rel=tooltip]").tooltip({placement: 'bottom'}); ? |
| 15:19 | cmajor7 | this does not work: (.tooltip ($ "[rel=tooltip]") "{placement: 'bottom'}") |
| 15:24 | bobry | cmajor7: you can use js-obj function, (.tooltip ($ "[rel=tooltip]") (js-obj "placement" "bottom")) |
| 15:26 | raek | I haven't used clojurescript much yet, but I think you need to access global js functions via the js "pseudo namespace": (js/$ ...) |
| 15:26 | cmajor7 | bobry: thanks. that compiles as: "jayq.core.$.call(null, "[rel=tooltip]").tooltip(jayq.core.js_obj.call(null, "placement", "bottom"));" and gives "TypeError: Cannot call method 'call' of undefined" |
| 15:26 | bobry | raek: i think it's a function from jayq, not a global jQuery function |
| 15:26 | bobry | ah, then raek's advice is relevant |
| 15:27 | bobry | hmm, js-obj didn't work, this is weird |
| 15:27 | bobry | it should've been compiled as {placement: "bottom"}, which version of cljs this is? |
| 15:28 | cmajor7 | well "call" itself on the $ does not cause the problem |
| 15:28 | cmajor7 | jayq.core.$.call(null, "[rel=tooltip]").tooltip(); works |
| 15:28 | bobry | yup, it's js-obj |
| 15:28 | cmajor7 | clojurescript-0.0-993.jar |
| 15:28 | bobry | weird thing is '(js-obj "foo" "bar")' works for me in the repl |
| 15:29 | bobry | but it's the latest clojurescript from maven repo |
| 15:29 | bobry | can you update to 1236? |
| 15:30 | cmajor7 | just updated to "clojurescript-0.0-1011.jar", I am going through noir-cljs |
| 15:31 | cmajor7 | let me try to update noir-cljs to the latest alpha |
| 15:33 | Sgeo_ | Does CLR (not necessarily ClojureCLR) support TCO? |
| 15:34 | cmajor7 | bobry: how do I start a repl to be in sync with all the server deps, so I can try '(js-obj "foo" "bar")'? I am just "lein repl" it in the root, but the deps are not loaded into repl |
| 15:35 | bobry | cmajor7: i use 'cljsbuild' plugin https://github.com/emezeske/lein-cljsbuild |
| 15:35 | bobry | and then start the repl with 'repl-rhino' subcommand |
| 15:36 | bobry | but frankly, this repl is pretty much useless -- no auto completion, no readline, hangs on exceptions etc |
| 15:36 | bobry | it's okay to try a one liner though |
| 15:41 | cmajor7 | you mean: "lein trampoline cljsbuild repl-rhino" ? |
| 15:43 | eggsby | Sgeo_: not sure about .net and tail call optimization, generally clojure tends towards tail call elimination via loop/recur |
| 15:45 | Sgeo_ | Has SICP for Clojure gotten anywhere? |
| 15:45 | Sgeo_ | Or should I just use the Scheme version |
| 15:48 | bobry | cmajor7: yup |
| 15:50 | cmajor7 | bobry: thx. I added ":plugins" and ran "lein deps" but it does not see those task past trampoline, anything obvious I missed? |
| 15:51 | bobry | cmajor7: not sure, is cljsbuild in .lein-plugins directory? |
| 15:52 | cmajor7 | nope.. |
| 15:53 | cmajor7 | ok.. trying manually: lein plugin install lein-cljsbuild 0.2.1 |
| 15:54 | cmajor7 | seemed to work => ""ClojureScript:cljs.user> |
| 15:54 | bobry | good :) |
| 15:55 | cmajor7 | ClojureScript:cljs.user> (js-obj "foo" "bar") |
| 15:55 | cmajor7 | (js-obj "foo" "bar") |
| 15:55 | cmajor7 | did that mean it works in REPL? |
| 15:55 | bobry | what did it output? |
| 15:55 | bobry | also, why don't you try lein2? it's much-much nicer |
| 15:55 | cmajor7 | the input :) |
| 15:55 | bobry | hmmm, not sure :) |
| 15:55 | bobry | I have [Object ...] |
| 15:55 | cmajor7 | what does it output in your repl? |
| 15:56 | bobry | try (.-foo (js-obj "foo" "bar")), it should output "bar" |
| 15:58 | diki_ | hey everyone |
| 15:58 | diki_ | just a quick sanity check, if you don: |
| 15:58 | ldopa | is http://dev.clojure.org/jira/browse/LOGIC-8 back in core.logic 0.7.4 or do i not understand how tabling works? |
| 15:59 | diki_ | just a quick sanity check, if you don't mind: |
| 15:59 | diki_ | (ns sanity-check.core |
| 15:59 | diki_ | (:use [quil.core :exclude [noise]])) |
| 15:59 | diki_ | should not complain if i try do defn noise, should it? |
| 16:05 | cmajor7 | bobry: yep, it did indeed |
| 16:05 | bobry | then I guess it works :) |
| 16:06 | cmajor7 | but "(.tooltip ($ "[rel=tooltip]") (js-obj "placement" "bottom"))" still fails |
| 16:06 | bobry | with the same error message? |
| 16:06 | cmajor7 | yep: ""EcmaError: TypeError: Cannot call method "call" of undefined (<cljs repl>#4) |
| 16:07 | bobry | well, no wonder it fails in the repl, it's not a 'browser-connected repl' |
| 16:07 | bobry | so it doesn't know about $ and .tooltip method |
| 16:08 | raek | if $ is a js function (jquery or not) I still think you need js/$ |
| 16:08 | bobry | raek: https://github.com/ibdknox/jayq |
| 16:09 | cmajor7 | bobry: it fails in the browser too, I just tried it in REPL as well |
| 16:10 | cmajor7 | jayq.core.$.call(null, "[rel=tooltip]").tooltip(jayq.core.js_obj.call(null, "placement", "bottom")); |
| 16:10 | cmajor7 | TypeError: Cannot call method 'call' of undefined |
| 16:12 | bobry | hmm, does jayq.core.$ return a jQuery object? |
| 16:12 | raek | oh. |
| 16:12 | bobry | oh |
| 16:12 | bobry | js_obj is still resolved incorrectly |
| 16:14 | cmajor7 | bobry: jayq.core.$ returns a function |
| 16:14 | cmajor7 | (and it does work) |
| 16:15 | cmajor7 | it is the last part (e.g. with {placement: 'bottome'}) that does not |
| 16:15 | cmajor7 | *bottom |
| 16:15 | bobry | yes, it *is* the last part, because js-obj call should've been expanded to {"placement": "bottom"} during compilation |
| 16:15 | bobry | i wonder why it wasn't |
| 16:31 | zaka | how can i count all the values of a map to eachother? For example i have the map {:a 1 :b 2 :c 5} then I want the answer to be 8 |
| 16:31 | AimHere | &(reduce + (values {:a 1 :b 2 :c 5})) |
| 16:31 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: values in this context |
| 16:31 | Sgeo_ | zaka, I think there's a function to... okh |
| 16:31 | AimHere | &(reduce + (vals {:a 1 :b 2 :c 5})) |
| 16:31 | lazybot | ⇒ 8 |
| 16:32 | Sgeo_ | AimHere, reduce is pretty much Haskell's foldl1? |
| 16:32 | AimHere | Pretty much |
| 16:32 | Sgeo_ | &(reduce (list)) |
| 16:32 | Iceland_jack | Sgeo_: reduce is foldl and fold |
| 16:32 | lazybot | clojure.lang.ArityException: Wrong number of args (1) passed to: core$reduce |
| 16:32 | AimHere | You could use 'apply' instead if you like |
| 16:32 | Sgeo_ | &(reduce + (list)) |
| 16:32 | lazybot | ⇒ 0 |
| 16:32 | lpvb | foldl'? |
| 16:32 | Sgeo_ | &(reduce cons (list)) |
| 16:32 | lazybot | clojure.lang.ArityException: Wrong number of args (0) passed to: core$cons |
| 16:33 | Sgeo_ | Ah, I see how it behaves with empty sequences, I.. think |
| 16:33 | AimHere | &(reduce conj '() '(1 2 3 4)) |
| 16:33 | lazybot | ⇒ (4 3 2 1) |
| 16:33 | Iceland_jack | &(doc reduce) |
| 16:33 | lazybot | ⇒ "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as... https://www.refheap.com/paste/3070 |
| 16:33 | Iceland_jack | It can take 2 or 3 parameters |
| 16:34 | Jayunit100 | hmm so we are finding that clojurescript isn't interpreted ? |
| 16:35 | Jayunit100 | i.e., its not interpreted in the browser. |
| 16:35 | adu | you mean speed-wise? |
| 16:35 | Jayunit100 | well ….. was trying to interpret some simple clojure, in the browser |
| 16:36 | Sgeo_ | How does ClojureScript development compare to http://amber-lang.net/ ? |
| 16:37 | Sgeo_ | As in, are there nice ClojureScript REPLs that run on the webpage and result in savable Javascript? |
| 16:38 | Jayunit100 | yeah -- that's what i thought i could use clojurescript for |
| 16:38 | zaka | thanks everybody! |
| 16:42 | Jayunit100 | how is the IRC interpreter secured ? |
| 16:43 | Jayunit100 | ,(print "security?") |
| 16:43 | clojurebot | security? |
| 16:44 | metellus | I think it uses clojail https://github.com/flatland/clojail |
| 16:45 | Sgeo_ | What's the difference between , and &? |
| 16:45 | Sgeo_ | With the bot |
| 16:45 | hiredman | ~sandbox |
| 16:45 | clojurebot | sandbox is http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html |
| 16:45 | metellus | they trigger different bots |
| 16:45 | hiredman | ~source |
| 16:45 | clojurebot | source is http://github.com/hiredman/clojurebot/tree/master |
| 16:45 | Raynes | clojurebot uses a different sandbox. |
| 16:45 | Raynes | lazybot uses clojail |
| 16:45 | Raynes | Which is also what tryclj and 4clojure use. |
| 16:46 | Raynes | And the difference between then is that they're entirely different bots. |
| 16:47 | Sgeo_ | Ah |
| 16:47 | Sgeo_ | Why two bots? |
| 16:48 | amalloy | Sgeo_: why not? |
| 16:50 | Sgeo_ | Are there restrictions to how hot-swappable Clojure can be? |
| 16:50 | Sgeo_ | I've heard about this ClassLoader thing but don't know anything about it : |
| 16:50 | Sgeo_ | :/ |
| 16:53 | Raynes | Sgeo_: Because I got board a couple of years ago and wrote a bot and it happened to end up with features that clojurebot doesn't have that some people like. |
| 16:53 | Raynes | bored* |
| 16:54 | Raynes | And two bots means that if one goes down, there is always a backup. :) |
| 17:15 | cmajor7 | "Could not locate crate/def_macros__init.class or crate/def_macros.clj on classpath" => seems to be a dependency issue between "noir-cljs" and "crate". anybody knows what is the latest working version combination? |
| 17:20 | zomg | Is there some meaning to using ;; as comments as opposed to just a single ; ? I see ;; occasionally but not sure why use it if ; works too |
| 17:20 | hiredman | ;; is for block comments (on their own line) |
| 17:21 | hiredman | (+ 1 2) ; is for comments that follow code |
| 17:21 | clojurebot | 3 |
| 17:21 | zomg | Ah I see |
| 17:21 | hiredman | and that is how it has been since the dawn of time |
| 17:21 | Raynes | You *can* use ; for block comments, but I'll find you if you do. |
| 17:22 | zomg | Raynes: yeah I noticed it works like that too so was just wondering :D |
| 17:22 | zomg | I guess it's just a coding style thing |
| 17:30 | amalloy | http://www.gnu.org/software/emacs/manual/html_node/elisp/Comment-Tips.html |
| 19:41 | horofox | how do i do this koan? |
| 19:41 | horofox | "But they are often better written using the names of functions" |
| 19:41 | horofox | (= 25 (___ square))) |
| 19:42 | ohpauleez | horofox: is square def'd to 5? |
| 19:43 | horofox | yep |
| 19:43 | horofox | ohpauleez: yep |
| 19:43 | AimHere | So can't you just insert a function that turns 5 into 25? |
| 19:44 | horofox | Well, could do (= 25 25) |
| 19:44 | horofox | I could do* |
| 19:44 | horofox | but I'm not learning that way, hehe |
| 19:44 | ohpauleez | #(* % 2) |
| 19:44 | horofox | I need to fix the __ |
| 19:44 | raek | horofox: so in this case you want the __ function to return its argument unchanged? |
| 19:45 | ohpauleez | gah - #(* % square) |
| 19:45 | horofox | I don't know what I want, this is the koan. |
| 19:45 | ohpauleez | So it's hinting to you |
| 19:45 | ohpauleez | Functions can be anonymous - without names |
| 19:45 | raek | horofox: is "square" 5 or 25? |
| 19:46 | ohpauleez | (fn [arg] (* arg arg)) |
| 19:46 | ohpauleez | or shorthnd #(* % %) |
| 19:46 | horofox | oh, square is: (defn square [n] (* n n)) |
| 19:46 | horofox | I just need to fill the blanks |
| 19:47 | ohpauleez | If that's what square is, then the blank has to do with the threading macro |
| 19:47 | ohpauleez | -> |
| 19:47 | raek | ok, so your task is to write a function that takes a function (let's call it f) and applies it to 5 |
| 19:47 | horofox | Given (defn square [n] (* n n)) and "But they are often better written using the names of functions" and (= 25 (___ square))) and I need to fill the blank |
| 19:47 | horofox | no, my task is to fill the blanks :P |
| 19:47 | horofox | the __ |
| 19:47 | raek | (fn [f] (f 5)) |
| 19:48 | horofox | raek: why your answer is correct? :P |
| 19:48 | raek | if you call that with square, you get ((fn [f] (f 5)) square) → (square 5) → 25 |
| 19:48 | horofox | my head exploded |
| 19:48 | horofox | :( |
| 19:49 | ohpauleez | (= 25 (-> 5 square)) |
| 19:49 | raek | any part of an expression can be a variable, including the function |
| 19:49 | ohpauleez | or rake's solution |
| 19:49 | ohpauleez | which was the first suggestion |
| 19:49 | ohpauleez | raek** |
| 19:51 | raek | I still don't understand what they mean by "But they are often better written using the names of functions" though... :) |
| 19:51 | horofox | Same :( |
| 19:51 | ohpauleez | Right, that made more sense when I assumed square was 5 |
| 19:51 | horofox | where did you guys learn functions? |
| 19:51 | ohpauleez | not a function |
| 19:52 | horofox | I still can't get it right |
| 19:52 | ohpauleez | horofox: what language are you coming from, or is this your first? |
| 19:52 | horofox | oh I've been coding for 12 years but never got into fp |
| 19:52 | horofox | (= 25 (fn [f](f 5) square))) |
| 19:52 | horofox | why is that wrong? |
| 19:53 | ohpauleez | you're missing some parens |
| 19:53 | horofox | where? |
| 19:53 | clojurebot | where is your source code |
| 19:53 | ohpauleez | (= 25 (#(% 5) square)) |
| 19:53 | zomg | Hm, what is the correct way to call a function multiple times with different args, and collect the results as a list? Eg. (map (Math/sqrt) [1 2 3]) which obviously does not work |
| 19:53 | horofox | (defn square [n] (* n n)) and (= 25 (fn [f](f 5) square))) |
| 19:54 | zomg | Should I just use an anonymous function eg #(Math/sqrt %) ? |
| 19:54 | ohpauleez | (= 25 ((fn [f] (f 5)) square)) |
| 19:54 | raek | horofox: but functions are so simple. to evaluate a function call, like (defn g [a b] (+ a b)) (g 1 2), you replace the call with the function body, substuting the actual parameters (1 and 2) for the formal parameters (a and b): (+ 1 2) |
| 19:54 | zomg | Coming mostly from a Haskell background where you can just toss functions into map like that and it works without making it a lambda or such =) |
| 19:54 | tmciver | zomg: ,(map #(Math/sqrt %) [1 2 3]) |
| 19:55 | zomg | Okay, as I thought then. Thanks! |
| 19:55 | tmciver | zomg: ##(map #(Math/sqrt %) [1 2 3]) |
| 19:55 | lazybot | ⇒ (1.0 1.4142135623730951 1.7320508075688772) |
| 19:55 | metellus | horofox: you need "fn [f] (f 5)" inside parens |
| 19:55 | metellus | ,(= 25 ((fn [f](f 5)) square)) |
| 19:55 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: square in this context, compiling:(NO_SOURCE_PATH:0)> |
| 19:55 | raek | horofox: does it make more sense if I write it like this? (defn square [n] (* n n)) (defn call-with-five [f] (f 5)) (= 25 (call-with-five square)) |
| 19:56 | AimHere | zomg > most of the time, you'd have something like (map sqrt [1 2 3]). Math/sqrt is just some java function instead of a clojure one, so it's not really a first class citizen |
| 19:56 | horofox | horofox: wait, trying to understand :P |
| 19:57 | zomg | AimHere: Right, so it would work if it was a Clojure function? I see |
| 19:57 | horofox | raek: I still didn't |
| 19:57 | AimHere | Well what you initially wrote put the function in parentheses, which would evaluate the function with no arguments |
| 19:57 | horofox | raek: do you have any article? |
| 19:57 | zomg | AimHere: yeah :) And omitting them would cause an error for static field |
| 19:58 | ohpauleez | horofox: In clojure (and other languages), functions are first-class - like ints, doubles, strings, etc |
| 19:58 | AimHere | That's just a piece of ugliness caused by clojure sitting on top of Java |
| 19:58 | ohpauleez | you can pass them around, return them, apply them |
| 19:59 | ohpauleez | this koan is trying to show you (in a rather silly way) how that happens |
| 19:59 | horofox | ohpauleez: i see, but I don't think I really got it so I can move on :P |
| 19:59 | ohpauleez | in Clojure, the first thing in a paren is always a function *[except in the ns macro] |
| 20:00 | AimHere | Well it might be a macro or a special form |
| 20:00 | amalloy | ohpauleez: if you're going to make an exception, i don't know why you would choose the ns macro |
| 20:00 | ohpauleez | AimHere: true, but for the stage he's at, we can get by with a sweeping generalization to solidify the point |
| 20:00 | horofox | ohpauleez: Ok I got it... |
| 20:01 | ohpauleez | amalloy: because it's commonly seen |
| 20:01 | horofox | ohpauleez: It's throwing a function inside another function that solves that thrown function? |
| 20:01 | horofox | which solves* |
| 20:02 | horofox | ohpauleez: is there a name for this kind of pattern so I can research more about it? |
| 20:02 | ohpauleez | horofox: first-class functions |
| 20:03 | ohpauleez | also anonymous functions, lambda functions |
| 20:03 | raek | horofox: higher order functions |
| 20:03 | ohpauleez | also that |
| 20:03 | raek | (i.e. functions that take functions as parameters or return functions) |
| 20:04 | raek | horofox: this is a good book where you can learn more: http://mitpress.mit.edu/sicp/full-text/book/book.html |
| 20:04 | ohpauleez | horofox: And here's an article http://www.ibm.com/developerworks/java/library/j-ft1/index.html |
| 20:04 | zomg | Man the JS generated by ClojureScript is pretty darn messy :P |
| 20:04 | AimHere | The main trouble with sicp is that you have to get familiar with another Lisp |
| 20:05 | zomg | Admittedly the clojure code is more concise than the equivalent JS code |
| 20:05 | raek | horofox: or more specifically: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-12.html#%_sec_1.3 |
| 20:05 | ohpauleez | zomg: What do you mean? It's coming out of an optimizing compiler, it's not a 1-to-1 transpolar like CoffeeScript |
| 20:05 | AimHere | I don't mind the js being messy, what I hate is that I get js errors instead of clojure ones |
| 20:05 | ohpauleez | transpiler* |
| 20:06 | raek | this book uses scheme, but it is similar enough to clojure for learning basic functional programming patterns you can use in clojure, I think |
| 20:06 | AimHere | Yeah, it's transferable |
| 20:06 | AimHere | Mostly |
| 20:07 | zomg | Yeah with CS the output is at least more what you'd write yourself |
| 20:07 | zomg | But obviously CS is more 1 to 1 with JS than Clojure is so perhaps it's not a reasonable expectations with this case |
| 20:07 | zomg | But things like this: var x__48689 = cljs.core.nth.call(null, vec__48687__48688, 0, null); |
| 20:08 | zomg | Guh. =) |
| 20:08 | zomg | For starters what's with the .call there.. Completely unnecesary as far as I can tell. |
| 20:09 | zomg | I'm just nitpicking since I'm primarily someone who writes JS along some other stuff so it's just bugging me a bit =) |
| 20:15 | amalloy | zomg: do you worry about the assembly code your C compiler writes? why does it matter what javasript the cljs compiler outputs? |
| 20:16 | zomg | Sometimes you're going to need to look at it to figure out why it isn't working |
| 20:16 | zomg | But yeah it's not that big of a deal |
| 21:34 | devn | ,(range 0 -10 -1) |
| 21:34 | clojurebot | (0 -1 -2 -3 -4 ...) |
| 21:34 | devn | ,(range 0 -10 0) |
| 21:34 | clojurebot | (0 0 0 0 0 ...) |
| 21:34 | devn | ,(range 0 10 0) |
| 21:34 | clojurebot | () |
| 21:34 | devn | This bothers me. |
| 21:34 | devn | ,(range 0 0 0) |
| 21:34 | clojurebot | () |
| 21:41 | hacliff | Hey, anyone here use sublimetext for their editor? Trying to replicate emacs C-c C-e for eval |
| 21:52 | zomg | Man it feels like I'm probably completely mis-using atoms and mutation... |
| 21:52 | zomg | =) |
| 21:53 | zomg | I've got a value which needs to be changed from a function call as it will affect the subsequent calls, but it also must sometimes get reset to 0... so I've def'd an atom which gets reset! into the values it needs |
| 21:55 | zomg | There's all this bindings and whatever else there is but this seemed like the most straightforward way to go about it :P In Haskell I probably would've used a State monad or something |
| 21:56 | devn | zomg: you have a value, like 1, and you need it to change, but you dont want it to change for subsequent callees? |
| 21:57 | devn | zomg: oh, nvm |
| 21:58 | devn | zomg: could you just use loop/recur or (for... or something? does this process go on forever? Is it a lazy seq? |
| 21:58 | zomg | http://jjh.fi:8080/~jani/editor-cljs/src-cljs/editor/core.cljs <- this is the mess I have, the relevant functions are load and handle-drag |
| 21:59 | devn | '([1 :x] [2 :y] [3 :z], [1 :b] [2 :c] [3 :d], ...) for instance |
| 21:59 | zomg | on the last line of load there are two lambdas, the first one is called when dragging, the second when dragging starts |
| 22:00 | zomg | when dragging starts, the value needs to be reset to 0, and then it later gets changed when the handle-drag function gets called while the drag is being performed |
| 22:00 | zomg | The code works but it doesn't seem to be the correct way to go about doing this =) |
| 22:02 | zomg | It seems like using binding might be a better way for it since I think def is making 'sx' a global... at least in the generated JavaScript code it is marked into editor.core.sx |
| 22:03 | devn | zomg: that was sort of my initial thought |
| 22:07 | zomg | devn: good, then it seems I'm not totally lost =) thanks |
| 22:09 | devn | zomg: wish i could offer more. i see your dilema, but it sure feels like some information is being propagated using the atom that doesnt need to be |
| 22:09 | devn | then again you might be overthinking it :) |
| 22:09 | zomg | Possibly |
| 22:09 | devn | anyway, im off, godspeed |
| 22:09 | zomg | Typically with JS I'd just stick it into a variable which is shoved into a closure with the rest of the junk accessing it |
| 22:10 | zomg | But thought I might as well use Clojure for this as a challenge and a learning experience =) |
| 22:16 | Sgeo_ | "In OO languages, another purpose of encapsulation is to prevent object A from modifying or corrupting the private data used by object B. |
| 22:16 | Sgeo_ | In Clojure, this problem does not exist. Data structures are immutable. They cannot possibly be corrupted, or changed in any way, period. You can write query functions that return “private” state, without any fear of data corruption." |
| 22:16 | Sgeo_ | http://thinkrelevance.com/blog/2009/08/12/rifle-oriented-programming-with-clojure-2 |
| 22:17 | Sgeo_ | What about when something is an implementation detail, and you want to prevent consumers from relying on it being there |
| 22:17 | Sgeo_ | You wouldn't want it to be readable (easily), because if it was, someone might rely on it and it might not work in the future |
| 22:17 | nDuff | Sgeo_: both convention and documentation work for that |
| 22:17 | Sgeo_ | Can't break the object, but it would break the client. |
| 22:17 | nDuff | Sgeo_: that's true of Clojure itself, for that matter |
| 22:18 | Sgeo_ | Hmm, what convention? |
| 22:18 | nDuff | Sgeo_: ...more of Clojure's internals are exposed than are documented, but any user relying on undocumented behavior is on thin ice |
| 22:18 | nDuff | ...there actually _is_ support for marking vars (with ^:private or defn-) |
| 22:18 | nDuff | err, marking vars private |
| 22:19 | Sgeo_ | What about marking keys on a map? |
| 22:19 | Sgeo_ | er, key-value pairs I guess |
| 22:19 | nDuff | namespacing keys acts as a hint that their values are considered internal |
| 22:19 | nDuff | so ::mykey rather than :mykey |
| 22:19 | Sgeo_ | Ah, cool |
| 22:20 | nDuff | (which evaluates to :my-ns/mykey) |
| 22:21 | kovasb | can one somehow reify an already-instantiated java object? |
| 22:22 | kovasb | vanilla reify will create an object from scratch, but I want to take an object and just add some protocols to it |
| 22:22 | Sgeo_ | Is there a particular reason that argument lists use vectors and not lists? |
| 22:23 | kovasb | Sgeo_: the convention in clojure is to reserve () to indicate function falls |
| 22:23 | kovasb | calls |
| 22:23 | Sgeo_ | Ah |
| 22:23 | amalloy | Sgeo_: rich's general stance on encapsulation, i believe, is that it's more important to enable good code than to prevent bad code. if someone's not supposed to rely on a particular field, just say so; if they do and then break, that's their problem |
| 22:24 | amalloy | kovasb: no, you can't. java doesn't have mixins |
| 22:24 | kovasb | amalloy: bummer. what about in clojurescript? |
| 22:25 | Sgeo_ | I don't know whether to be glad that Clojure uses _ for ignored arguments over CL's (define (ignore blah)), or just react normally since that's what Haskell does |
| 22:25 | Sgeo_ | erm, declare |
| 22:25 | amalloy | kovasb: i dunno. probably not, since its protocols are stored in the prototype chain |
| 22:26 | Sgeo_ | Does Clojure have something like (declare (ignorable)), so that macros can emit code that depending on circumstance may or may not mention the argument, and either way not trigger a warning? |
| 22:26 | kovasb | amalloy: thnx |
| 22:27 | amalloy | Sgeo_: i don't understand what you're asking, but the answer is no. not mentioning arguments never issues a warning |
| 22:27 | Sgeo_ | Hmm, bleh |
| 22:28 | amalloy | just like in haskell (i think?), _ meaning "ignored" is just a convention. it's a perfectly legal variable name that you can access if you want |
| 22:30 | amalloy | $heval let _ = 1 in _ |
| 22:30 | lazybot | ⇒ Pattern syntax in expression context: _ |
| 22:31 | amalloy | huh, apparently not |
| 22:31 | Sgeo_ | $heval let f _ _ = 5 in f (1/0) 2 |
| 22:31 | lazybot | ⇒ 5 |
| 22:31 | Sgeo_ | $heval let f a a = 5 in f (1/0) 2 |
| 22:31 | lazybot | ⇒ Conflicting definitions for `a'Bound at: <interactive>:1:6 <interactive>:1:8 |
| 22:32 | johnmn3 | evenin' |
| 22:32 | Sgeo_ | Hi |
| 22:36 | Sgeo_ | If I start learning Clojure, how much Java/about the Java ecosystem will I need to learn? |
| 22:39 | kovasb | Sgeo_: depends on the kind of program you want to write |
| 22:39 | devn | Sgeo_: you'll pick up what you need to know as you go |
| 22:39 | kovasb | Sgeo_: and what the available clojure-only library there are in that domain |
| 22:40 | Sgeo_ | Any libraries to act as a C FFI? |
| 22:40 | Sgeo_ | Besides just using the JNI |
| 22:40 | kovasb | Sgeo_: in general the "worst" that will happen is needing to look up some javadoc to find some methods |
| 22:41 | kovasb | Sgeo_: possible, do some github searching .. :) also there is a project to have a Lua backend for clojurescript, so that should have good c ffi |
| 22:42 | devn | Sgeo_: dated, but maybe https://github.com/bagucode/clj-nativ |
| 22:42 | devn | https://github.com/bagucode/clj-native |
| 22:42 | devn | It could be updated without too much work I think... |
| 22:44 | devn | Sgeo_: https://github.com/Chouser/clojure-jna |
| 22:45 | Sgeo_ | Would it make sense to, as a Clojure project, try rewriting a small Haskell thing in it? |
| 22:46 | devn | Sgeo_: sure, if you feel like it, just dont doThisSortOfThing ;) |
| 22:54 | Sgeo_ | Suppose I want to make an object such that (:x my-obj) runs my own code, i.e., I'm pretending to be a map |
| 22:54 | Sgeo_ | I know (my-obj :x) would be doable of course... although an answer that ties both together would be more elegant |
| 22:56 | Sgeo_ | Doing similar with assoc would be even more perfectly, really |
| 22:59 | amalloy | Sgeo_: implement Associative and IPersistentMap |
| 22:59 | amalloy | maybe ILookup? i forget the exact classes |
| 23:00 | amalloy | &(supers (class {})) |
| 23:00 | lazybot | ⇒ #{clojure.lang.IFn clojure.lang.Associative clojure.lang.IEditableCollection clojure.lang.Seqable clojure.lang.APersistentMap clojure.lang.IObj clojure.lang.AFn clojure.lang.IHashEq java.lang.Runnable clojure.lang.Counted clojure.lang.IMeta clojure.lang.IPersist... https://www.refheap.com/paste/3073 |
| 23:00 | Sgeo_ | AFn? |
| 23:00 | technomancy | IPersistentMap might be too specific |
| 23:00 | technomancy | ILookup and IFn I believe |
| 23:01 | technomancy | IWishItWereClearerWhatToDoHere |
| 23:01 | frozenlock | I've got a weird error... Wrong number of args (1) passed to: helperfn$make-trend-log-graph$fn |
| 23:01 | frozenlock | [Thrown class clojure.lang.ArityException]. Usually I would say "of course!" and add the missing argument, but in this case I know I have exactly 3 arguments (VS 1 as in the error message). Any idea on what might be causing this? |
| 23:01 | amalloy | technomancy: IPM is the one the specifies assoc |
| 23:02 | amalloy | no, i guess Associative |
| 23:02 | Sgeo_ | I guess it's not a very common thing to do |
| 23:03 | Sgeo_ | Which kind of saddens me -- to my mind it sort of makes sense, to have a sort of getter that is independent of implementation, whether or not it's as a mpa |
| 23:03 | Sgeo_ | map |
| 23:03 | kovasb | Sgeo_: you can use defrecord and get those protocols for free |
| 23:04 | Sgeo_ | kovasb, and I could override for certain "keys"? |
| 23:04 | kovasb | Sgeo_: what would the override do? |
| 23:04 | Sgeo_ | kovasb, perhaps generate a value based on a function of the values of other keys, when I try to look up on that specific key |
| 23:05 | Sgeo_ | I guess I'm somewhat thinking of Haskell lenses |
| 23:05 | kovasb | Sgeo_: if its a function, why not define it as such? |
| 23:05 | Sgeo_ | Because for simple things, it sounds like people often use maps |
| 23:05 | Sgeo_ | And just put stuff in keys |
| 23:06 | Sgeo_ | So if I were to switch from, say, storing something in a key to it being dynamically generated, I have to change from key to function, meaning that due to an implementation details, client code has to change |
| 23:06 | kovasb | i see |
| 23:09 | kovasb | yeah, that kind of thing is not a stock datatype, would need to implement yourself |
| 23:10 | Sgeo_ | I feel like this is sort of a violation of encapsulation :/ |
| 23:11 | Sgeo_ | Hmm.... I feel like maybe this is a project I should take on... although admittedly doesn't seem to large |
| 23:11 | Sgeo_ | too |
| 23:11 | kovasb | you want polymorphism on the content of the argument |
| 23:11 | kovasb | not a lot of languages give you that |
| 23:12 | kovasb | interesting problem tho |
| 23:13 | Sgeo_ | Haskell has polymorphism on the return type =P |
| 23:13 | Sgeo_ | </random> |
| 23:13 | kovasb | i mean, its pretty easy to implement what you want from scratch |
| 23:14 | kovasb | just use a multi method in the implementation of ILookup |
| 23:15 | kovasb | or just a conditional if you are fine with baking the logic in |
| 23:23 | lynaghk` | Does anyone know if datomic supports a workflow to and from regular clojure maps? E.g., query, assoc new key/values, transact? |
| 23:24 | lynaghk` | From what I can tell, datomic entities don't support assoc, and the best I can do is manually coerce them into hashmaps (making the :db/id an explicit key) and then manipulate and transact that |
| 23:25 | kovasb | lynaghk`: https://groups.google.com/forum/#!topic/datomic/fKKz_tg9Bos |
| 23:25 | kovasb | lynaghk`: i think thats the extent of general knowledge |
| 23:25 | lynaghk` | That feels like too much fighting (especially then special-case ignoring :db/id in all map comprehensions through the rest of my code), so I wonder if I'm missing something |
| 23:25 | lynaghk` | kovasb: I saw that (it's easy to read all 60 messages in Datomics mailing list, unfortunately) |
| 23:26 | kovasb | lol |
| 23:26 | lynaghk` | kovasb: I'm not trying to do anything with arbitrary maps. I just want to manipulate what I've already defined in the schema in a more natural way than juggling vectors of facts manually |
| 23:27 | kovasb | i see |
| 23:28 | Sgeo_ | kovasb, I guess I just need to figure out what the API for making these things would look like |
| 23:28 | Sgeo_ | Because I now want to make some sort of easy-to-use library |
| 23:34 | Sgeo_ | Hmm, I guess there could be code that expects a normal map... hmm, actually, so what |
| 23:34 | kovasb | (my-thing associative-base {:special-key the-function …}) |
| 23:34 | Sgeo_ | getter would not cause any issues |
| 23:36 | Sgeo_ | Actually, client might not expect one key to change just because it "changed" another |
| 23:36 | kovasb | of course, if the-function returns different values at different times, there could be complications |
| 23:36 | kovasb | also, calling assoc on your thing could be problematic :) |
| 23:38 | kovasb | if you want to implement lenses, best to just run with that and base the whole thing on reference types |
| 23:38 | Sgeo_ | reference types? |
| 23:38 | kovasb | ref, atom |
| 23:39 | kovasb | identities that have values which change over time |
| 23:39 | Sgeo_ | ...why? |
| 23:39 | Sgeo_ | As in, why not stick with immutable data? |
| 23:39 | kovasb | if you thing is changing, then its not immutable |
| 23:39 | Sgeo_ | "changing" the same way maps "change" |
| 23:40 | Sgeo_ | i.e. just returning an altered copy |
| 23:40 | kovasb | right, but a lens alters multiple things at once |
| 23:41 | Sgeo_ | Do we have the same notion of lens? |
| 23:41 | kovasb | by definition there are at least 2 data structures involved right |
| 23:41 | Sgeo_ | I don't... think so? |
| 23:42 | kovasb | lens transforms between two datastructures |
| 23:43 | Sgeo_ | Well, hmm, the "setter" portion of a lens still only "modifies" one thing |
| 23:45 | kovasb | what is the purpose of the lens then? |
| 23:45 | kovasb | at least in the papers, its all about shuffling edits between 2 or more datastructures |
| 23:46 | Sgeo_ | I don't know if we're referring to different things, or to the same thing and I'm not at that level of understanding |
| 23:46 | kovasb | you are talking about lens in haskell? |
| 23:46 | Sgeo_ | http://hackage.haskell.org/packages/archive/data-lens/2.10.0/doc/html/Data-Lens-Common.html |
| 23:46 | Sgeo_ | That's pretty much what I'm referring to |
| 23:47 | kovasb | unfortunately i can't read haskell |
| 23:48 | kovasb | are there examples of actual invocations together with ouput? |
| 23:48 | nDuff | Could be talking out my rear here (very much unfamiliar with Haskell concepts), but it smells to me like the sort of thing that might be done with zippers in this world. |
| 23:49 | kovasb | the thing i'm referring to as lenses is stuff like this http://dmwit.com/papers/201107EL.pdf |
| 23:50 | Sgeo_ | getL fstLens (1,2) |
| 23:50 | Sgeo_ | Would return 1 |
| 23:50 | kovasb | theres definitely a few implementations of this kind of thing in haskell, but its hard to see exactly what they do |
| 23:50 | kovasb | ok |
| 23:50 | Sgeo_ | setL fstLens 5 (1,2) returns (5,2) |
| 23:50 | kovasb | ok |
| 23:51 | Sgeo_ | Let's say I do |
| 23:51 | Sgeo_ | Hmm |
| 23:52 | Sgeo_ | I could define fstLens like so: |
| 23:53 | amalloy | last time i heard about lenses (and this setL example reinforces), it seems like they're just a way to implement get-in/assoc-in/update-in in a typesafe way. what's the point of doing them in clojure? |
| 23:53 | amalloy | (assoc-in {:left 1 :right 2} [:left] 5) |
| 23:54 | Sgeo_ | fstLens = lens fst (\pair item -> (item, snd pair)) |
| 23:54 | Sgeo_ | -- fst gets the first element of a pair, snd gets the second element of a pair |
| 23:54 | Sgeo_ | amalloy, well, I could have different lenses to get and update in different ways |
| 23:56 | Sgeo_ | Although, might make more sense to tie it in with the datastructure in question |
| 23:56 | kovasb | there is some kind of function composition that happens which is different |
| 23:56 | Sgeo_ | Actually, hmm.... I see what I want to do |
| 23:56 | Sgeo_ | Instead of keywords for assoc-in and friends, it would make sense to use lenses |
| 23:57 | Sgeo_ | The thing I linked has mapLens, but that's not a lens |
| 23:57 | Sgeo_ | Instead, it's a function that takes a key, and gives a lens |
| 23:58 | Sgeo_ | Should I make an example? |
| 23:58 | kovasb | yes :) |
| 23:59 | Sgeo_ | let myMap = Data.Map.fromList [("a", 1), ("b", 2), ("c", 3)] |
| 23:59 | Sgeo_ | let aLens = mapLens "a" |