#clojure logs

2012-06-09

00:09muhooeslick_: thoughtworks is the only big shop i know of that does clojure in the bay, but there may be others
01:17johnmn3what does it mean that "Can only recur from the tail position" ??
01:17lazybotjohnmn3: Uh, no. Why would you even ask?
01:17johnmn3The recur is the last expression within the scope of the doseq
01:20hiredmandoseq has no return value, it has no tail
01:20johnmn3ah
01:20johnmn3yea, I'm trying loop now
01:21hiredmanyou cannot recur across loops
01:21johnmn3oh?
01:21hiredmanhow would recur know which loop to recur to?
01:22hiredman(loop [] (loop [] (recur)))
01:23johnmn3well, I'm not nesting two loops
02:09johnmn3I'm currently doing a (.read on an input stream, which gets sent to (.write on a FileOutputStream.
02:09johnmn3Now, I want to instead write that to a datastructure
02:16Sgeo_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:04amalloySgeo_: you can always choose to rely instead on a library like clojure.math that provides a layer of indirection to the underlying libraries
03:12borkdudecan I see which libraries on clojars use netty?
03:12borkdudeand how?
03:12brehauthttp://clojuresphere.herokuapp.com/netty
03:13borkdudebrehaut great tnx ;)
04:35tomojis there a nicer way to do (fn [sep & args] (join sep args)) ?
04:35tomojI feel like it should be obvious..
04:38borkdudejust use join?
04:38AimHerejoin takes a seperator and a list of string
04:38AimHere*strings
04:38borkdudeah
04:38AimHereHe wants just a list of stuff, the first one being the seperator
04:39borkdudeof course
04:39amalloyi don't think so, tomoj
04:39amalloyyou can generalize, though, and then use your general tool
04:39borkdudethere is no ~@ in functions ;-)
04:39AimHereWell you can just give that fn up there a name, then it's the generalization
04:40tomojstrange
04:40tomojit doesn't already have a name?
04:41borkdudewait ~@ has nothing to do with it ;; I'm still sleepy...
04:41tomojhmm
04:41tomojI guess it doesn't generalize well
04:41ejacksontomoj: interpose ?
04:41amalloy((fn listify [f arity] (fn [& args] (apply f `(~@(take arity args) ~(drop arity args))))) join 1)
04:42tomojseems weird though
04:42ejackson,(apply str (interpose ":" ["Hello" "My" "Honey"]))
04:43clojurebot"Hello:My:Honey"
04:43amalloyejackson: that's just join
04:43amalloy&(((fn listify [f arity] (fn [& args] (apply f `(~@(take arity args) ~(drop arity args))))) clojure.string/join 1) "," 1 2 3 4)
04:43lazybot⇒ "1,2,3,4"
04:43amalloynow listify is the general case, and you can easily apply it to join
04:43ejacksonand so it is
04:46tomojwhat does that do with arity 0?
04:46amalloyit's probably just (f args)
04:46amalloyor rather (comp f list)
04:47tomojyeah
05:00ejacksonis there a function for: (#(assoc % :key (f %)) map) ?
05:00ejacksonlike update-in, but taking the whole map, rather than a particular key as argument ?
05:04tomojno. (assoc map :key (f map)) is shorter than that though..
05:05tomojdepends on what the map is named I guess :)
05:06ejacksonejackson's-baroquely-named-mega-map, for instance ?
05:08ejacksonagreed, its in that form as I'm mapping it over a seq of maps (I do this a lot)
05:52notsonerdysunnywhile 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:52notsonerdysunnyI am able to successfully do lein jar
05:52notsonerdysunnyor lein uberjar
05:52notsonerdysunnyor lein run
05:53notsonerdysunnyjust unable to work with it using slime..
06:06PKHGhallo, good morning form (NL) (just 2 minutes left ;-) ).... how can I display the conten of jar from out a REPL?
06:14PKHGlazybot: how to ping all listeners?
06:14PKHG&"how to ping several people"
06:14lazybot⇒ "how to ping several people"
06:15PKHG&(* 1234567 88986868686868)
06:15lazybotjava.lang.ArithmeticException: integer overflow
06:15PKHG&(* 1234567 88)
06:15lazybot⇒ 108641896
06:16borkdude&(*' 1234567 88986868686868)
06:16lazybot⇒ 109860251514140566156N
06:17borkdude,(doc *')
06:17clojurebot"([] [x] [x y] [x y & more]); Returns the product of nums. (*) returns 1. Supports arbitrary precision. See also: *"
06:19PKHGborkdude: how to look at the conten of a *.jar from within a repl?
06:19PKHGoh and hallo to you ;-)
06:19borkdudePKHG 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:19PKHGthanks will look now ;-)
06:20borkdudePKHG if you are familiar with the Java API for doing this, you can work it out probabl
06:20PKHGborkdude: lovely complicated for a newbie
06:20PKHGJava was last century for me ;-(
06:20borkdudePKHG I don't have a ready answer, just some pointers on how to get started maybe ;)
06:21PKHGwill look at the script ...
06:21PKHGtrying to use it ..
06:23borkdudePKHG maybe this answer on StackOverflow also contains some useful pointer: http://stackoverflow.com/questions/5171957/access-file-in-jar-file
06:23PKHGyes the last example ... trying too ;-)
06:27PKHGthanks .. have to leave ..
08:39cshellSaturday, the best day to do all of your at-home development!
09:41clj_newbHi, any suggestion on how to read large files ? is duck-stream the best cho? Or go straight to a BufferedReader?
09:43ejacksonclj_newb: http://richhickey.github.com/clojure/clojure.java.io-api.html is a good choice.
09:43lazybotNooooo, 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:43ejacksonsorry lazybot
09:43clj_newbthank you ejackson
09:43clj_newbno offense if I go to where the bot suggest hehe
09:44ejacksonyes, I pasted before I looked
10:00Crackneckhello 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:02AimHereCrackneck, 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:02Crackneckim just goiing throug the clojure learning tool koans
10:02Crackneckit's one of their questions
10:02Cracknecknow i could just copy that code
10:02AimHereWhat 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:02Crackneckbut that would be stupid =)
10:03mthvedtthe recur syntax is like a function call, except instead of calling a function you jump to the nearest recursion point
10:03AimHereSo if you recurse heavily, your stack might grow too big, which might use up vast amounts of memory
10:05AimHereIf 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:05Crackneckmthvedt ok, and the recursion point in that example is the loop?
10:06mthvedtyup
10:06AimHereRight, it's either the enclosing 'loop' or the enclosing function call
10:07Crackneckok, and the "tail" position is the line with only " acc "
10:07AimHerenah, the tail position is the call to 'recur'
10:07mthvedtmultiple positions in a form can be "tail"
10:08babilenHi 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:08mthvedttail position only means the compiler can wrap up all computation before executing the recur
10:09AimHereCrackneck > 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:09Crackneckthat helped AimHere, thanks
10:10Cracknecknot being sarcastic
10:10Cracknecki guess I just got confused by the big words
10:11Cracknecktail and recursion point
10:11Crackneckboth new stuff to me
10:11AimHereEssentially it's just rewriting functions in a funny way because it means they don't eat up lots of memory
10:12Hali_303hi! is there a built-in average function?
10:12Crackneckyes i am familiar with the concept, just not the clojuresk implementation
10:13babilenHali_303: Not AFAIK, but it is easy to implement it as https://www.refheap.com/paste/3066
10:13Hali_303babilen: yeah I know, I just see no point in everybody implementing it..
10:15babilenAny ideas concerning https://www.refheap.com/paste/3065 ? -- I am really not sure where to start :-/
10:17cshellbabilen: Just create a map with the values in your vector as thte keys
10:17cshelland always use the (first) for the value?
10:19babilencshell: 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:21cshellbabilen: Right, so a basic function will be switching them around into key value
10:21cshellthen you can call that for each sequence and take the result and merge it into a map that counts
10:22babilencshell: Ok, I am currently working on an approach that just creates tuples (patN, relN) from the input. Any better idea for the switching?
10:24cshellI think that could work as well and then just count all the tuples, right?
10:26babilenWell, group-by first and then count the tuples that have been grouped together. Strikes me as not very elegant, but meh ..
10:34AimHereCouldn't you just have a frequency table of [relN patN]?
10:55tmciverCould someone tell me what the '[&] here means: https://github.com/cgrand/moustache/blob/master/src/net/cgrand/moustache.clj#L120 ?
11:00raektmciver: that's a part of the moustache route syntax.
11:00raek["foo" &] matches all urls that begin with /foo/
11:01raekit is explained in the moustache github readme
11:01tmciverraek: yes, but is that syntax meaningful outside of moustache? ##((apply array-map [:a 1 :b 2]) '[&])
11:01lazybot⇒ nil
11:02raektmciver: what does 'forms' look like there?
11:03raekit has no special meaning in clojure
11:03tmciverraek: Ah, I think I'm getting it. One of the keys in the resulting array-map may be [&].
11:03raekit just means look up the value for the key which is a vector of the symbol &
11:03tmciverOK, it makes sense to me now. Thanks for helping me to think straight.
11:04tmciver##((apply array-map [[&] "hello" :a 1]) '[&])
11:04lazybotjava.lang.RuntimeException: Unable to resolve symbol: & in this context
11:05tmciverhmm, maybe not.
11:05raek&((apply array-map ['[&] "hello", :a 1]) '[&])
11:05lazybot⇒ "hello"
11:05raek&((apply array-map [[(symbol "&")] "hello", :a 1]) '[&])
11:05lazybot⇒ "hello"
11:06tmciveryes
11:06raeksymbols are treated as variables when evaluated
11:06tmciveror ##((apply array-map ['[&] "hello" :a 1]) '[&])
11:06lazybot⇒ "hello"
11:06babilenAimHere: 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:06tmciverraek: thanks again.
11:43babilencshell: 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:43horofoxHi guys, I want to know why does "(= (:a :b :c :d :e) (cons :a '(:b :c :d :e)))" raise IllegalArgumentException?
11:43horofoxI'm doing the clojure koans
11:44babilenhorofox: Try " (= '(:a :b :c :d :e) (cons :a '(:b :c :d :e)))" (you missed a ' for the first list)
11:44babilenhorofox: 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:45horofoxbabilen: IllegalArgumentException Wrong number of args passed to keyword: :a clojure.lang.Keyword.throwArity (Keyword.java:85)
11:45horofoxbabilen: I'm still getting the same error
11:45horofox;/
11:45babilen&(= '(:a :b :c :d :e) (cons :a '(:b :c :d :e)))
11:45lazybot⇒ true
11:46babilenNote "(= '(:a" vs "(= (:a"
11:46horofoxoh lol
11:46horofoxi'm so dumb
11:46babilenI'd argue that you are rather blind than dumb :-þ
11:46horofox:P
11:47horofoxwhat are good uses of clojure?
11:47babilenThose errors are always horrible and hard to track down.
11:47horofoxI'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:48cshellhorofox: concurrency, general programming, etc
11:48horofoxcshell: projects that use it?
11:48cshellhorofox: the ' just tells it not to evaluate the form - without it it thinks you're making a function call
11:48horofoxbabilen: with hadoop?
11:48thmzltbabilen: have some of that code to show?
11:49cshellhorofox: Websites, some financial industry code, various others - all the work that relevance does I think
11:49babilenthmzlt: Nothing public yet
11:49horofoxcshell: oh, so it's not a abbreviation to list? i wouldn't know if you didn't tell me, thanks!
11:49antares_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:49horofoxcshell: which website is made in clojure?
11:50horofoxantares_: oh i see
11:50cshellhorofox: correct, it tells the reader to just read in whatever follows instead of trying to evaluate
11:51cshellhorofox: 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:51rlbhorofox: '(foo) is shorthand for (quote (foo))
11:52rlbAnd lists have to be quoted so that they're not evaluated as a function call (as mentioned above).
11:52horofoxcshell: 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:53antares_horofox: http://webnoir.org
11:54cshellhorofox: that's what i use, noir
11:54antares_Noir is a bit more towards Django in some design decisions and it definitely is "lower level", like Sinatra
11:54horofoxantares_: is it very fast?
11:54horofoxantares_: would it fit well for say, an API?
11:55antares_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:55cshellhorofox: not much of an api needed - just defpage and defpartial
11:55antares_horofox: JSON API is its sweet spot
11:55cshellI use enlive as templating over hiccup
11:55antares_cshell: noir.response/json is probably what most people would try first for APIs (just saying)
11:55antares_horofox: as for performance, it is very low level and runs on JVM app servers
11:56antares_a small Noir app without any optimizations does 10K+ requests per second on 100 MBit/s and 4 core machine
11:56cshellah, got it
11:57horofoxnice
11:57antares_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:58antares_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:58horofoxantares_: oh, i've seen this post. this looks good
11:59antares_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:59antares_as for templating, there are several Clojure-based templating languages but I use Mustache (with Stencil or Clostache)
12:00horofoxantares_: cool, so there's a ecosystem in clojure for web development it seens :P
12:00antares_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:00antares_horofox: honestly, a lot of Clojure projects need good docs
12:01horofoxantares_: i wanted to join the "data crunching" crowd, i think in the following years it's going to be big.
12:01antares_but good maturing projects are certainly there and JVM ecosystem gets you a ton of good stuff almost for free
12:02antares_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:02horofoxantares_: so you are some months ahead of me hehe :)
12:03antares_horofox: oh, and there's also http://immutant.org
12:03horofoxantares_: I wanted to try some nlp with clojure also :P
12:03antares_much like TorqueBox for Ruby
12:03horofoxthats cool... 0.1.0 hehe
12:04antares_there are 1-2 year old projects that are still 0.2.0 or so in Clojure
12:05antares_for some reason people are very conservative about numbering
12:05antares_we start with 1.0.0-alpha1 for http://clojurewerkz.org and announce things at about rc1
12:05horofoxhehe
12:05antares_but none of that 0.1.0 or 0.0.1 stuff
12:05antares_there are awesome libraries that are at 0.0.9
12:05antares_I mean, come on, plenty of people use them, they are several months old
12:05antares_and at 0.0.x
12:07horofoxi see hehe!
12:07horofoxi just want to see how i'm going to get used to fp :P
12:08horofoxantares_: how long have you been studying clojure?
12:08horofoxor fp
12:09antares_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:09antares_horofox: I used Scala prior to Clojure for ~ 1 year
12:09antares_and now almost 1 year with Clojure
12:10antares_picked up some erlang and haskell along the way, too
12:10antares_I think in 2-3 months you will be comfortable enough to notice what works better and learn from other people's code
12:11antares_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:11horofoxantares_: yea, that's what i want. I'm doing the koans and then I'm going to start with the clojure book.
12:11horofoxantares_:
12:11horofoxantares_: woops, hehe.
12:12antares_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:12antares_horofox: I've never done koans but I heard good things about them
12:12antares_also, 4clojure.com
12:13antares_I jumped into Clojure by developing a couple of libraries I needed when I decided I've had enough CRuby scaling pain
12:15horofoxantares_: i see. i'm going to check 4clojure out
12:31eslickAnyone have a sense of tradeoffs in using regular maps vs. records when pulling records from a document DB?
12:32eslickI have a web app which pulls data from mongodb, does some modest transformations on it, then pushes it over HTTP to the client
12:32eslickI use a :type field to dispatch various common methods on all those objects today
12:33eslickI like the documentation benefits of clearly defining protocols over types, but it didn't seem worth the performance overhead.
13:23clj_newbHi, 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:25morphling,(doc get)
13:25clojurebot"([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."
13:25hoeckclj_newb: of course you can: (:c {} 'foo)
13:29clj_newbthank you
14:28clj_newb,(doc if-let)
14:28clojurebot"([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:15Sgeo_Hmm.
15:15Sgeo_Auto-gensyms are implementable in CL, right?
15:17VinzentSgeo_, I guess so
15:19cmajor7how do I call this from clojurescript (with jayq): $("[rel=tooltip]").tooltip({placement: 'bottom'}); ?
15:19cmajor7this does not work: (.tooltip ($ "[rel=tooltip]") "{placement: 'bottom'}")
15:24bobrycmajor7: you can use js-obj function, (.tooltip ($ "[rel=tooltip]") (js-obj "placement" "bottom"))
15:26raekI haven't used clojurescript much yet, but I think you need to access global js functions via the js "pseudo namespace": (js/$ ...)
15:26cmajor7bobry: 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:26bobryraek: i think it's a function from jayq, not a global jQuery function
15:26bobryah, then raek's advice is relevant
15:27bobryhmm, js-obj didn't work, this is weird
15:27bobryit should've been compiled as {placement: "bottom"}, which version of cljs this is?
15:28cmajor7well "call" itself on the $ does not cause the problem
15:28cmajor7jayq.core.$.call(null, "[rel=tooltip]").tooltip(); works
15:28bobryyup, it's js-obj
15:28cmajor7clojurescript-0.0-993.jar
15:28bobryweird thing is '(js-obj "foo" "bar")' works for me in the repl
15:29bobrybut it's the latest clojurescript from maven repo
15:29bobrycan you update to 1236?
15:30cmajor7just updated to "clojurescript-0.0-1011.jar", I am going through noir-cljs
15:31cmajor7let me try to update noir-cljs to the latest alpha
15:33Sgeo_Does CLR (not necessarily ClojureCLR) support TCO?
15:34cmajor7bobry: 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:35bobrycmajor7: i use 'cljsbuild' plugin https://github.com/emezeske/lein-cljsbuild
15:35bobryand then start the repl with 'repl-rhino' subcommand
15:36bobrybut frankly, this repl is pretty much useless -- no auto completion, no readline, hangs on exceptions etc
15:36bobryit's okay to try a one liner though
15:41cmajor7you mean: "lein trampoline cljsbuild repl-rhino" ?
15:43eggsbySgeo_: not sure about .net and tail call optimization, generally clojure tends towards tail call elimination via loop/recur
15:45Sgeo_Has SICP for Clojure gotten anywhere?
15:45Sgeo_Or should I just use the Scheme version
15:48bobrycmajor7: yup
15:50cmajor7bobry: thx. I added ":plugins" and ran "lein deps" but it does not see those task past trampoline, anything obvious I missed?
15:51bobrycmajor7: not sure, is cljsbuild in .lein-plugins directory?
15:52cmajor7nope..
15:53cmajor7ok.. trying manually: lein plugin install lein-cljsbuild 0.2.1
15:54cmajor7seemed to work => ""ClojureScript:cljs.user>
15:54bobrygood :)
15:55cmajor7ClojureScript:cljs.user> (js-obj "foo" "bar")
15:55cmajor7(js-obj "foo" "bar")
15:55cmajor7did that mean it works in REPL?
15:55bobrywhat did it output?
15:55bobryalso, why don't you try lein2? it's much-much nicer
15:55cmajor7the input :)
15:55bobryhmmm, not sure :)
15:55bobryI have [Object ...]
15:55cmajor7what does it output in your repl?
15:56bobrytry (.-foo (js-obj "foo" "bar")), it should output "bar"
15:58diki_hey everyone
15:58diki_just a quick sanity check, if you don:
15:58ldopais http://dev.clojure.org/jira/browse/LOGIC-8 back in core.logic 0.7.4 or do i not understand how tabling works?
15:59diki_just a quick sanity check, if you don't mind:
15:59diki_(ns sanity-check.core
15:59diki_ (:use [quil.core :exclude [noise]]))
15:59diki_should not complain if i try do defn noise, should it?
16:05cmajor7bobry: yep, it did indeed
16:05bobrythen I guess it works :)
16:06cmajor7but "(.tooltip ($ "[rel=tooltip]") (js-obj "placement" "bottom"))" still fails
16:06bobrywith the same error message?
16:06cmajor7yep: ""EcmaError: TypeError: Cannot call method "call" of undefined (<cljs repl>#4)
16:07bobrywell, no wonder it fails in the repl, it's not a 'browser-connected repl'
16:07bobryso it doesn't know about $ and .tooltip method
16:08raekif $ is a js function (jquery or not) I still think you need js/$
16:08bobryraek: https://github.com/ibdknox/jayq
16:09cmajor7bobry: it fails in the browser too, I just tried it in REPL as well
16:10cmajor7jayq.core.$.call(null, "[rel=tooltip]").tooltip(jayq.core.js_obj.call(null, "placement", "bottom"));
16:10cmajor7TypeError: Cannot call method 'call' of undefined
16:12bobryhmm, does jayq.core.$ return a jQuery object?
16:12raekoh.
16:12bobryoh
16:12bobryjs_obj is still resolved incorrectly
16:14cmajor7bobry: jayq.core.$ returns a function
16:14cmajor7(and it does work)
16:15cmajor7it is the last part (e.g. with {placement: 'bottome'}) that does not
16:15cmajor7*bottom
16:15bobryyes, it *is* the last part, because js-obj call should've been expanded to {"placement": "bottom"} during compilation
16:15bobryi wonder why it wasn't
16:31zakahow 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:31AimHere&(reduce + (values {:a 1 :b 2 :c 5}))
16:31lazybotjava.lang.RuntimeException: Unable to resolve symbol: values in this context
16:31Sgeo_zaka, I think there's a function to... okh
16:31AimHere&(reduce + (vals {:a 1 :b 2 :c 5}))
16:31lazybot⇒ 8
16:32Sgeo_AimHere, reduce is pretty much Haskell's foldl1?
16:32AimHerePretty much
16:32Sgeo_&(reduce (list))
16:32Iceland_jackSgeo_: reduce is foldl and fold
16:32lazybotclojure.lang.ArityException: Wrong number of args (1) passed to: core$reduce
16:32AimHereYou could use 'apply' instead if you like
16:32Sgeo_&(reduce + (list))
16:32lazybot⇒ 0
16:32lpvbfoldl'?
16:32Sgeo_&(reduce cons (list))
16:32lazybotclojure.lang.ArityException: Wrong number of args (0) passed to: core$cons
16:33Sgeo_Ah, I see how it behaves with empty sequences, I.. think
16:33AimHere&(reduce conj '() '(1 2 3 4))
16:33lazybot⇒ (4 3 2 1)
16:33Iceland_jack&(doc reduce)
16:33lazybot⇒ "([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:33Iceland_jackIt can take 2 or 3 parameters
16:34Jayunit100hmm so we are finding that clojurescript isn't interpreted ?
16:35Jayunit100i.e., its not interpreted in the browser.
16:35aduyou mean speed-wise?
16:35Jayunit100well ….. was trying to interpret some simple clojure, in the browser
16:36Sgeo_How does ClojureScript development compare to http://amber-lang.net/ ?
16:37Sgeo_As in, are there nice ClojureScript REPLs that run on the webpage and result in savable Javascript?
16:38Jayunit100yeah -- that's what i thought i could use clojurescript for
16:38zakathanks everybody!
16:42Jayunit100how is the IRC interpreter secured ?
16:43Jayunit100,(print "security?")
16:43clojurebotsecurity?
16:44metellusI think it uses clojail https://github.com/flatland/clojail
16:45Sgeo_What's the difference between , and &?
16:45Sgeo_With the bot
16:45hiredman~sandbox
16:45clojurebotsandbox is http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html
16:45metellusthey trigger different bots
16:45hiredman~source
16:45clojurebotsource is http://github.com/hiredman/clojurebot/tree/master
16:45Raynesclojurebot uses a different sandbox.
16:45Rayneslazybot uses clojail
16:45RaynesWhich is also what tryclj and 4clojure use.
16:46RaynesAnd the difference between then is that they're entirely different bots.
16:47Sgeo_Ah
16:47Sgeo_Why two bots?
16:48amalloySgeo_: why not?
16:50Sgeo_Are there restrictions to how hot-swappable Clojure can be?
16:50Sgeo_I've heard about this ClassLoader thing but don't know anything about it :
16:50Sgeo_:/
16:53RaynesSgeo_: 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:53Raynesbored*
16:54RaynesAnd two bots means that if one goes down, there is always a backup. :)
17:15cmajor7"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:20zomgIs 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:20hiredman;; is for block comments (on their own line)
17:21hiredman(+ 1 2) ; is for comments that follow code
17:21clojurebot3
17:21zomgAh I see
17:21hiredmanand that is how it has been since the dawn of time
17:21RaynesYou *can* use ; for block comments, but I'll find you if you do.
17:22zomgRaynes: yeah I noticed it works like that too so was just wondering :D
17:22zomgI guess it's just a coding style thing
17:30amalloyhttp://www.gnu.org/software/emacs/manual/html_node/elisp/Comment-Tips.html
19:41horofoxhow do i do this koan?
19:41horofox"But they are often better written using the names of functions"
19:41horofox(= 25 (___ square)))
19:42ohpauleezhorofox: is square def'd to 5?
19:43horofoxyep
19:43horofoxohpauleez: yep
19:43AimHereSo can't you just insert a function that turns 5 into 25?
19:44horofoxWell, could do (= 25 25)
19:44horofoxI could do*
19:44horofoxbut I'm not learning that way, hehe
19:44ohpauleez#(* % 2)
19:44horofoxI need to fix the __
19:44raekhorofox: so in this case you want the __ function to return its argument unchanged?
19:45ohpauleezgah - #(* % square)
19:45horofoxI don't know what I want, this is the koan.
19:45ohpauleezSo it's hinting to you
19:45ohpauleezFunctions can be anonymous - without names
19:45raekhorofox: is "square" 5 or 25?
19:46ohpauleez(fn [arg] (* arg arg))
19:46ohpauleezor shorthnd #(* % %)
19:46horofoxoh, square is: (defn square [n] (* n n))
19:46horofoxI just need to fill the blanks
19:47ohpauleezIf that's what square is, then the blank has to do with the threading macro
19:47ohpauleez->
19:47raekok, so your task is to write a function that takes a function (let's call it f) and applies it to 5
19:47horofoxGiven (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:47horofoxno, my task is to fill the blanks :P
19:47horofoxthe __
19:47raek(fn [f] (f 5))
19:48horofoxraek: why your answer is correct? :P
19:48raekif you call that with square, you get ((fn [f] (f 5)) square) → (square 5) → 25
19:48horofoxmy head exploded
19:48horofox:(
19:49ohpauleez(= 25 (-> 5 square))
19:49raekany part of an expression can be a variable, including the function
19:49ohpauleezor rake's solution
19:49ohpauleezwhich was the first suggestion
19:49ohpauleezraek**
19:51raekI still don't understand what they mean by "But they are often better written using the names of functions" though... :)
19:51horofoxSame :(
19:51ohpauleezRight, that made more sense when I assumed square was 5
19:51horofoxwhere did you guys learn functions?
19:51ohpauleeznot a function
19:52horofoxI still can't get it right
19:52ohpauleezhorofox: what language are you coming from, or is this your first?
19:52horofoxoh I've been coding for 12 years but never got into fp
19:52horofox(= 25 (fn [f](f 5) square)))
19:52horofoxwhy is that wrong?
19:53ohpauleezyou're missing some parens
19:53horofoxwhere?
19:53clojurebotwhere is your source code
19:53ohpauleez(= 25 (#(% 5) square))
19:53zomgHm, 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:53horofox(defn square [n] (* n n)) and (= 25 (fn [f](f 5) square)))
19:54zomgShould I just use an anonymous function eg #(Math/sqrt %) ?
19:54ohpauleez(= 25 ((fn [f] (f 5)) square))
19:54raekhorofox: 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:54zomgComing 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:54tmciverzomg: ,(map #(Math/sqrt %) [1 2 3])
19:55zomgOkay, as I thought then. Thanks!
19:55tmciverzomg: ##(map #(Math/sqrt %) [1 2 3])
19:55lazybot⇒ (1.0 1.4142135623730951 1.7320508075688772)
19:55metellushorofox: you need "fn [f] (f 5)" inside parens
19:55metellus,(= 25 ((fn [f](f 5)) square))
19:55clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: square in this context, compiling:(NO_SOURCE_PATH:0)>
19:55raekhorofox: 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:56AimHerezomg > 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:56horofoxhorofox: wait, trying to understand :P
19:57zomgAimHere: Right, so it would work if it was a Clojure function? I see
19:57horofoxraek: I still didn't
19:57AimHereWell what you initially wrote put the function in parentheses, which would evaluate the function with no arguments
19:57horofoxraek: do you have any article?
19:57zomgAimHere: yeah :) And omitting them would cause an error for static field
19:58ohpauleezhorofox: In clojure (and other languages), functions are first-class - like ints, doubles, strings, etc
19:58AimHereThat's just a piece of ugliness caused by clojure sitting on top of Java
19:58ohpauleezyou can pass them around, return them, apply them
19:59ohpauleezthis koan is trying to show you (in a rather silly way) how that happens
19:59horofoxohpauleez: i see, but I don't think I really got it so I can move on :P
19:59ohpauleezin Clojure, the first thing in a paren is always a function *[except in the ns macro]
20:00AimHereWell it might be a macro or a special form
20:00amalloyohpauleez: if you're going to make an exception, i don't know why you would choose the ns macro
20:00ohpauleezAimHere: true, but for the stage he's at, we can get by with a sweeping generalization to solidify the point
20:00horofoxohpauleez: Ok I got it...
20:01ohpauleezamalloy: because it's commonly seen
20:01horofoxohpauleez: It's throwing a function inside another function that solves that thrown function?
20:01horofoxwhich solves*
20:02horofoxohpauleez: is there a name for this kind of pattern so I can research more about it?
20:02ohpauleezhorofox: first-class functions
20:03ohpauleezalso anonymous functions, lambda functions
20:03raekhorofox: higher order functions
20:03ohpauleezalso that
20:03raek(i.e. functions that take functions as parameters or return functions)
20:04raekhorofox: this is a good book where you can learn more: http://mitpress.mit.edu/sicp/full-text/book/book.html
20:04ohpauleezhorofox: And here's an article http://www.ibm.com/developerworks/java/library/j-ft1/index.html
20:04zomgMan the JS generated by ClojureScript is pretty darn messy :P
20:04AimHereThe main trouble with sicp is that you have to get familiar with another Lisp
20:05zomgAdmittedly the clojure code is more concise than the equivalent JS code
20:05raekhorofox: or more specifically: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-12.html#%_sec_1.3
20:05ohpauleezzomg: What do you mean? It's coming out of an optimizing compiler, it's not a 1-to-1 transpolar like CoffeeScript
20:05AimHereI don't mind the js being messy, what I hate is that I get js errors instead of clojure ones
20:05ohpauleeztranspiler*
20:06raekthis book uses scheme, but it is similar enough to clojure for learning basic functional programming patterns you can use in clojure, I think
20:06AimHereYeah, it's transferable
20:06AimHereMostly
20:07zomgYeah with CS the output is at least more what you'd write yourself
20:07zomgBut obviously CS is more 1 to 1 with JS than Clojure is so perhaps it's not a reasonable expectations with this case
20:07zomgBut things like this: var x__48689 = cljs.core.nth.call(null, vec__48687__48688, 0, null);
20:08zomgGuh. =)
20:08zomgFor starters what's with the .call there.. Completely unnecesary as far as I can tell.
20:09zomgI'm just nitpicking since I'm primarily someone who writes JS along some other stuff so it's just bugging me a bit =)
20:15amalloyzomg: do you worry about the assembly code your C compiler writes? why does it matter what javasript the cljs compiler outputs?
20:16zomgSometimes you're going to need to look at it to figure out why it isn't working
20:16zomgBut yeah it's not that big of a deal
21:34devn,(range 0 -10 -1)
21:34clojurebot(0 -1 -2 -3 -4 ...)
21:34devn,(range 0 -10 0)
21:34clojurebot(0 0 0 0 0 ...)
21:34devn,(range 0 10 0)
21:34clojurebot()
21:34devnThis bothers me.
21:34devn,(range 0 0 0)
21:34clojurebot()
21:41hacliffHey, anyone here use sublimetext for their editor? Trying to replicate emacs C-c C-e for eval
21:52zomgMan it feels like I'm probably completely mis-using atoms and mutation...
21:52zomg=)
21:53zomgI'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:55zomgThere'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:56devnzomg: you have a value, like 1, and you need it to change, but you dont want it to change for subsequent callees?
21:57devnzomg: oh, nvm
21:58devnzomg: could you just use loop/recur or (for... or something? does this process go on forever? Is it a lazy seq?
21:58zomghttp://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:59devn'([1 :x] [2 :y] [3 :z], [1 :b] [2 :c] [3 :d], ...) for instance
21:59zomgon the last line of load there are two lambdas, the first one is called when dragging, the second when dragging starts
22:00zomgwhen 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:00zomgThe code works but it doesn't seem to be the correct way to go about doing this =)
22:02zomgIt 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:03devnzomg: that was sort of my initial thought
22:07zomgdevn: good, then it seems I'm not totally lost =) thanks
22:09devnzomg: 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:09devnthen again you might be overthinking it :)
22:09zomgPossibly
22:09devnanyway, im off, godspeed
22:09zomgTypically 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:10zomgBut thought I might as well use Clojure for this as a challenge and a learning experience =)
22:16Sgeo_"In OO languages, another purpose of encapsulation is to prevent object A from modifying or corrupting the private data used by object B.
22:16Sgeo_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:16Sgeo_http://thinkrelevance.com/blog/2009/08/12/rifle-oriented-programming-with-clojure-2
22:17Sgeo_What about when something is an implementation detail, and you want to prevent consumers from relying on it being there
22:17Sgeo_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:17nDuffSgeo_: both convention and documentation work for that
22:17Sgeo_Can't break the object, but it would break the client.
22:17nDuffSgeo_: that's true of Clojure itself, for that matter
22:18Sgeo_Hmm, what convention?
22:18nDuffSgeo_: ...more of Clojure's internals are exposed than are documented, but any user relying on undocumented behavior is on thin ice
22:18nDuff...there actually _is_ support for marking vars (with ^:private or defn-)
22:18nDufferr, marking vars private
22:19Sgeo_What about marking keys on a map?
22:19Sgeo_er, key-value pairs I guess
22:19nDuffnamespacing keys acts as a hint that their values are considered internal
22:19nDuffso ::mykey rather than :mykey
22:19Sgeo_Ah, cool
22:20nDuff(which evaluates to :my-ns/mykey)
22:21kovasbcan one somehow reify an already-instantiated java object?
22:22kovasbvanilla reify will create an object from scratch, but I want to take an object and just add some protocols to it
22:22Sgeo_Is there a particular reason that argument lists use vectors and not lists?
22:23kovasbSgeo_: the convention in clojure is to reserve () to indicate function falls
22:23kovasbcalls
22:23Sgeo_Ah
22:23amalloySgeo_: 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:24amalloykovasb: no, you can't. java doesn't have mixins
22:24kovasbamalloy: bummer. what about in clojurescript?
22:25Sgeo_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:25Sgeo_erm, declare
22:25amalloykovasb: i dunno. probably not, since its protocols are stored in the prototype chain
22:26Sgeo_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:26kovasbamalloy: thnx
22:27amalloySgeo_: i don't understand what you're asking, but the answer is no. not mentioning arguments never issues a warning
22:27Sgeo_Hmm, bleh
22:28amalloyjust 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:30amalloy$heval let _ = 1 in _
22:30lazybot⇒ Pattern syntax in expression context: _
22:31amalloyhuh, apparently not
22:31Sgeo_$heval let f _ _ = 5 in f (1/0) 2
22:31lazybot⇒ 5
22:31Sgeo_$heval let f a a = 5 in f (1/0) 2
22:31lazybot⇒ Conflicting definitions for `a'Bound at: <interactive>:1:6 <interactive>:1:8
22:32johnmn3evenin'
22:32Sgeo_Hi
22:36Sgeo_If I start learning Clojure, how much Java/about the Java ecosystem will I need to learn?
22:39kovasbSgeo_: depends on the kind of program you want to write
22:39devnSgeo_: you'll pick up what you need to know as you go
22:39kovasbSgeo_: and what the available clojure-only library there are in that domain
22:40Sgeo_Any libraries to act as a C FFI?
22:40Sgeo_Besides just using the JNI
22:40kovasbSgeo_: in general the "worst" that will happen is needing to look up some javadoc to find some methods
22:41kovasbSgeo_: 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:42devnSgeo_: dated, but maybe https://github.com/bagucode/clj-nativ
22:42devnhttps://github.com/bagucode/clj-native
22:42devnIt could be updated without too much work I think...
22:44devnSgeo_: https://github.com/Chouser/clojure-jna
22:45Sgeo_Would it make sense to, as a Clojure project, try rewriting a small Haskell thing in it?
22:46devnSgeo_: sure, if you feel like it, just dont doThisSortOfThing ;)
22:54Sgeo_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:54Sgeo_I know (my-obj :x) would be doable of course... although an answer that ties both together would be more elegant
22:56Sgeo_Doing similar with assoc would be even more perfectly, really
22:59amalloySgeo_: implement Associative and IPersistentMap
22:59amalloymaybe ILookup? i forget the exact classes
23:00amalloy&(supers (class {}))
23:00lazybot⇒ #{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:00Sgeo_AFn?
23:00technomancyIPersistentMap might be too specific
23:00technomancyILookup and IFn I believe
23:01technomancyIWishItWereClearerWhatToDoHere
23:01frozenlockI've got a weird error... Wrong number of args (1) passed to: helperfn$make-trend-log-graph$fn
23:01frozenlock [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:01amalloytechnomancy: IPM is the one the specifies assoc
23:02amalloyno, i guess Associative
23:02Sgeo_I guess it's not a very common thing to do
23:03Sgeo_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:03Sgeo_map
23:03kovasbSgeo_: you can use defrecord and get those protocols for free
23:04Sgeo_kovasb, and I could override for certain "keys"?
23:04kovasbSgeo_: what would the override do?
23:04Sgeo_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:05Sgeo_I guess I'm somewhat thinking of Haskell lenses
23:05kovasbSgeo_: if its a function, why not define it as such?
23:05Sgeo_Because for simple things, it sounds like people often use maps
23:05Sgeo_And just put stuff in keys
23:06Sgeo_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:06kovasbi see
23:09kovasbyeah, that kind of thing is not a stock datatype, would need to implement yourself
23:10Sgeo_I feel like this is sort of a violation of encapsulation :/
23:11Sgeo_Hmm.... I feel like maybe this is a project I should take on... although admittedly doesn't seem to large
23:11Sgeo_too
23:11kovasbyou want polymorphism on the content of the argument
23:11kovasbnot a lot of languages give you that
23:12kovasbinteresting problem tho
23:13Sgeo_Haskell has polymorphism on the return type =P
23:13Sgeo_</random>
23:13kovasbi mean, its pretty easy to implement what you want from scratch
23:14kovasbjust use a multi method in the implementation of ILookup
23:15kovasbor just a conditional if you are fine with baking the logic in
23:23lynaghk`Does anyone know if datomic supports a workflow to and from regular clojure maps? E.g., query, assoc new key/values, transact?
23:24lynaghk`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:25kovasblynaghk`: https://groups.google.com/forum/#!topic/datomic/fKKz_tg9Bos
23:25kovasblynaghk`: i think thats the extent of general knowledge
23:25lynaghk`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:25lynaghk`kovasb: I saw that (it's easy to read all 60 messages in Datomics mailing list, unfortunately)
23:26kovasblol
23:26lynaghk`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:27kovasbi see
23:28Sgeo_kovasb, I guess I just need to figure out what the API for making these things would look like
23:28Sgeo_Because I now want to make some sort of easy-to-use library
23:34Sgeo_Hmm, I guess there could be code that expects a normal map... hmm, actually, so what
23:34kovasb(my-thing associative-base {:special-key the-function …})
23:34Sgeo_getter would not cause any issues
23:36Sgeo_Actually, client might not expect one key to change just because it "changed" another
23:36kovasbof course, if the-function returns different values at different times, there could be complications
23:36kovasbalso, calling assoc on your thing could be problematic :)
23:38kovasbif you want to implement lenses, best to just run with that and base the whole thing on reference types
23:38Sgeo_reference types?
23:38kovasbref, atom
23:39kovasbidentities that have values which change over time
23:39Sgeo_...why?
23:39Sgeo_As in, why not stick with immutable data?
23:39kovasbif you thing is changing, then its not immutable
23:39Sgeo_"changing" the same way maps "change"
23:40Sgeo_i.e. just returning an altered copy
23:40kovasbright, but a lens alters multiple things at once
23:41Sgeo_Do we have the same notion of lens?
23:41kovasbby definition there are at least 2 data structures involved right
23:41Sgeo_I don't... think so?
23:42kovasblens transforms between two datastructures
23:43Sgeo_Well, hmm, the "setter" portion of a lens still only "modifies" one thing
23:45kovasbwhat is the purpose of the lens then?
23:45kovasbat least in the papers, its all about shuffling edits between 2 or more datastructures
23:46Sgeo_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:46kovasbyou are talking about lens in haskell?
23:46Sgeo_http://hackage.haskell.org/packages/archive/data-lens/2.10.0/doc/html/Data-Lens-Common.html
23:46Sgeo_That's pretty much what I'm referring to
23:47kovasbunfortunately i can't read haskell
23:48kovasbare there examples of actual invocations together with ouput?
23:48nDuffCould 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:49kovasbthe thing i'm referring to as lenses is stuff like this http://dmwit.com/papers/201107EL.pdf
23:50Sgeo_getL fstLens (1,2)
23:50Sgeo_Would return 1
23:50kovasbtheres definitely a few implementations of this kind of thing in haskell, but its hard to see exactly what they do
23:50kovasbok
23:50Sgeo_setL fstLens 5 (1,2) returns (5,2)
23:50kovasbok
23:51Sgeo_Let's say I do
23:51Sgeo_Hmm
23:52Sgeo_I could define fstLens like so:
23:53amalloylast 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:53amalloy(assoc-in {:left 1 :right 2} [:left] 5)
23:54Sgeo_fstLens = lens fst (\pair item -> (item, snd pair))
23:54Sgeo_-- fst gets the first element of a pair, snd gets the second element of a pair
23:54Sgeo_amalloy, well, I could have different lenses to get and update in different ways
23:56Sgeo_Although, might make more sense to tie it in with the datastructure in question
23:56kovasbthere is some kind of function composition that happens which is different
23:56Sgeo_Actually, hmm.... I see what I want to do
23:56Sgeo_Instead of keywords for assoc-in and friends, it would make sense to use lenses
23:57Sgeo_The thing I linked has mapLens, but that's not a lens
23:57Sgeo_Instead, it's a function that takes a key, and gives a lens
23:58Sgeo_Should I make an example?
23:58kovasbyes :)
23:59Sgeo_let myMap = Data.Map.fromList [("a", 1), ("b", 2), ("c", 3)]
23:59Sgeo_let aLens = mapLens "a"