#clojure log - Dec 24 2014

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:27 crispin: hey, I want to use an externs in cljs

0:27 that is, NOT bring in the js code to the closure compiler

0:27 I've made my extern js file

0:27 Ive put it in :externs

0:28 (as per instructions)

0:28 but compiling keeps giving me WARNING: No such namespace: PIXI at line 1 src/cljs/cljs_jam/gfx.cljs

0:28 WARNING: Required namespace not provided for PIXI

0:28 SEVERE: /home/crispin/dev/clojure/cljs-jam/resources/public/cljs_jam/gfx.js:4: ERROR - required "PIXI" namespace never provided

0:28 goog.require('PIXI');

0:28 it shouldnt be goog.require()ing it

0:29 its an external!

0:29 oh wait!

0:29 do I need to :use instead of :require it in ns?

0:31 nope that didn't work

0:32 how do I reference external javascript?

0:32 I followed the docs. Doesn't work

0:35 ok got it working

0:35 had cljsbuild auto

0:35 changed my project.clj file

0:35 need to ctrl-c and restart the auto build. It doesnt pickup project.clj changes

0:36 no wait. thats still trying to google closure compile it

0:36 (I added :foreign-libs)

0:37 http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html

0:37 how do I reference external javascript?"

0:37 "Referencing a library outside your compilation"

0:37 doesnt work

0:37 keeps wanting to goog.require() my extern library

0:41 maybe theres a problem with my externs... let me try modifying it a bit

0:41 it is one gripe I have with leiningen

0:41 silences so many errors

0:41 bad path in there somewhere.... crickets


0:44 so frustrating

0:47 eg. put a completely bogus path into externs. no error at all

0:47 just silence

0:49 andyf: You can try filing an issue for Leiningen: https://github.com/technomancy/leiningen/issues

0:50 crispin: ok I think I got it. Errors in the externs

0:51 but yes. will check for a ticket. Because if the path doesn't exist, you get no error

0:51 I had a typo in the path

0:51 now I get: ERROR: JSC_PARSE_ERROR. Parse error. '}' expected at /home/crispin/dev/clojure/cljs-jam/src/js/pixi/externs2.js line 651 : 0

0:51 if the path doesn't exist

0:52 just fails bizarly. Will check the leiningen issues and raise one if theres not one already

0:54 ok fixed all that. still doesnt work :P

0:54 will keep digging

0:58 maxpn: how to split sequence by chuncks?

0:58 [1 2 3 4 5 6] -> [1 2] [3 4] [5 6] ...

0:59 chuncks of n-elements each

0:59 luxbock: ,(doc partition)

0:59 clojurebot: "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."

0:59 maxpn: thank you

1:00 luxbock: there's also partition-by which is handy at times

3:04 Raynes: https://github.com/scopely/sqlquest/issues/16#issuecomment-68034697 I love my coworkers.

3:04 Teasing me about my Clojureness on a Coffeescript project that I wrote :P

3:27 andyf: You should respond and tell him its a Python triple-quoted string thing.

3:28 lxsameer: hey guys, I really confused in a two way situation between clojure and scala, What is the most important advantages of clojure over scala ?

3:29 sg2002: lxsameer: Clojure is a lisp.

3:31 lxsameer: sg2002: ok and how is that an advantage my friend ?

3:33 sg2002: lxsameer: The answer to that would be a long one. Just gonna say that there are people who believe that lisp style languages are better and if you're one of them, that's an advantage of clojure over scala.

3:34 lxsameer: Another specific clojure advantage is it's concurrency model. But again you have to understand it before you know whether you need it.

4:38 ddellacosta: Is there an equivalent to Haskell's flip function in Clojure?

4:40 hellofunk: ddellacosta: interesting we discussed that yesterday, flip exists in a common library for clojure, can't remember which one now

4:40 though it's trivial to write it yourself

4:40 ddellacosta: hellofunk: thanks, yeah, just would be handy if it was already part of core, but ah well

4:40 hellofunk: not in core

4:42 ddellacosta: it is in flatland/useful according to my chat logs

4:42 ddellacosta: hellofunk: cool, thanks

4:42 probably not worth using the lib just for that now, but good to know

4:44 hellofunk: i'll have to take a look at the library to see what else might be "useful", no pun intended

4:50 ddellacosta: i'm curious why flip comes up often, why is it important to rearrange arg order so often?

4:51 SagiCZ1: what about if you want to use threading, and one of 10 functions has a different arg order than the others?

4:51 ddellacosta: hellofunk: I'm still learning Haskell so I can't tell you in general, although pair tuples are a more common type that you run into in Haskell, so that may have something to do with it

4:51 hellofunk: the reason I wanted to use it just now was to flip a sort, basically

4:52 and yeah, in Clojure at least, SagiCZ1's example seems pertinent

4:53 SagiCZ1: i wonder what as-> does.. didnt understand it

4:53 (doc as->)

4:53 clojurebot: "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."

4:54 SagiCZ1: seems like it is for when you have functions with different args order and you want to still use threading

4:55 hellofunk: SagiCZ1: ddellacosta: ah i get it. i rarely use the thread macro so maybe haven't run into that need. i'm still old school leaning on comp and partial a lot

4:55 SagiCZ1: i guess its just a matter of preference..

4:55 ddellacosta: hellofunk: I used to use the threading macro a lot more, and use it less now, as I find (ironically) readability can suffer using it sometimes

4:56 and if I've got a huge stack of functions then probably I'm doing something wrong

4:56 SagiCZ1: i am a beginner so this may be something i am heading towards in the future

4:57 hellofunk: SagiCZ1: i should sit down and memorize the core api some time. little nuggets like this as-> keep popping up and i wish they where in my regular vocab

4:58 for Om, i wish I'd adopted doto a long time ago, would have cleaned up a number of things for me.

4:59 SagiCZ1: i learn it similar to a human language vocabulary.. if i run into a need of some function many times over and over i remember it.. otherwise its not worth my time

4:59 ddellacosta: I've been using Clojure for years now and I still come upon functions I was barely aware of, or new idioms

5:00 also there are some functions I finally have "gotten the hang of" and know when to use

5:00 I couldn't for the life of me figure out why to use juxt for a long time, for example

5:00 still don't think it's that useful actually, haha

5:00 but figured out some uses

5:01 hellofunk: ddellacosta: someone showed a good example of juxt the other day: using it to pull out isolated values from a map, based on just a selection of its keys.

5:02 ddellacosta: hellofunk: yeah, that's what I was thinking of actually...and that's all I've ever been able to do with it!

5:02 maybe I'm not imaginative enough

5:03 also starting to learn Haskell lately, there are a few functions I wish were named differently

5:03 hellofunk: ,((juxt :a :b) {:a 1 :b 2 :c 3 :d 4})

5:03 clojurebot: [1 2]

5:03 hellofunk: in this case i think of it as "just" the keys i want

5:03 ddellacosta: comp seems so unwieldy now, love the simple .

5:03 yeah, that is handy, definitely

5:03 and that + map can be really useful

5:04 hellofunk: you are saying you do or do not like using comp now?

5:04 ddellacosta: &(map (juxt :a :b) [{:a "a" :b "b"}{:a "a1" :b "b1}])

5:04 lazybot: java.lang.RuntimeException: EOF while reading string

5:04 ddellacosta: d'oh

5:04 &(map (juxt :a :b) [{:a "a" :b "b"}{:a "a1" :b "b1"}])

5:04 lazybot: ⇒ (["a" "b"] ["a1" "b1"])

5:04 hellofunk: ddellacosta: almost like an sql query in that case

5:04 ddellacosta: hellofunk: I'm saying I might use comp more if the syntax was simpler, since it's super powerful

5:04 yeah, never thought of it that way

5:05 hellofunk: ddellacosta: i think i will steal that idiom you just shared when i get back results from postgres!

5:05 ddellacosta: ha, yeah, although to be honest I find it of limited utility

5:06 but would be interested in hearing how other people have managed to use juxt

5:06 hellofunk: it comes up a lot when reading others solutions to the 4clojure problems. lots of ingenuity to be learned from that site.

5:06 SagiCZ1: ~juxt

5:06 clojurebot: juxt is pretty metal

5:06 ddellacosta: good point, I need to revisit that site

5:08 hellofunk: ddellacosta: perhaps better for the cljs room but have you done much drag and drop operations in Om? i'm tackling the sortable example today to really grasp it

5:08 ddellacosta: hellofunk: I have done a drag and drop implementation in Om, as a matter of fact

5:08 it was a pain in the ass, but mostly because drag and drop freaking sucks

5:08 hellofunk: ddellacosta: did you model it on the Om example for sortable?

5:09 ddellacosta: er, I don't think so

5:09 sorry. :-(

5:09 hellofunk: ddellacosta: then you must really know JS because it seems to involve a lot of stuff i'd never know without following that example closely

5:10 ddellacosta: I mean, I got to know the drag and drop API pretty well because of it

5:10 but it is really just frustrating to work with, and there are a lot of browser quirks

5:10 hellofunk: using googe closure utilities?

5:10 ddellacosta: I did not use Google Closure, no, that may be one way around the challenges

5:10 but our front-end is too specific to use whatever Google offers in that domain

5:11 and in general I find trying to integrate google closure widgets into Om is a major PITA

5:11 hellofunk: ddellacosta: ok. dnolen's uses closure for a few things in the example

5:11 ddellacosta: it could work, I honestly don't know

5:11 we just have a very specific set of needs

5:12 and certainly there is a lot of utility in the Google Closure library, I think some parts of it are very robust

5:12 I don't love the interface in general, it's super Java-y

5:12 but it handles a lot of browser quirks well

5:12 hellofunk: ddellacosta: its the event handling and stuff that the Om example uses

5:13 ddellacosta: hellofunk: oh, yeah, he falls back on that a lot, which makes sense because otherwise you have to import Dommy or something

5:13 hellofunk: certainly the event handling lib in Google Closure is lightweight enough

5:13 hellofunk: I was more talking about the UI widgets

5:13 Google Closure's lib is huge

5:15 hellofunk: re: drag and drop, I don't feel like the situation has changed much since this was written: http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html

5:15 hellofunk: ddellacosta: he does stuff like this: (doto js/window (events/listen EventType.MOUSEUP mouse-up) (events/listen EventType.MOUSEMOVE mouse-move))

5:15 ddellacosta: (well, it's improved a bit, I used it at least)

5:15 yeah

5:15 that's simple enough, and not much different from how it would look in Dommy

5:16 hellofunk: i've been tasked with a big drag and drop interface and we use Om so i hope it goes well

5:16 ddellacosta: hellofunk: Om is the easy part. Be careful about checking what parts of the api all the browsers support

5:17 hellofunk: ddellacosta: well fortunately we don't support all browsers :)\

5:17 ddellacosta: hellofunk: that is the part that sucks and will make you miserable

5:17 hellofunk: good for you, you're lucky. :-)

5:18 hellofunk: for now, we will be expanding it in the future. hopefully by then we have a real browser expert to take over stuff

5:40 cfleming: hellofunk: My argument wasn't so much that we shouldn't be using text, which I think is actually a pretty good serialisation mechanism, but that tools should understand what that text means

5:41 hellofunk: I'd love to provide a formatting "view" on code, it's something I always wanted in Java, where different formatting styles are much more different than in Clojure

5:42 hellofunk: cfleming: yeah i paraphrased you confusingly perhaps. i think it was about the writing of text and focusing each minutiae like indents, line breaks, parens, etc that gets in the way of "the zone" of expressing ideas

5:42 cfleming: hellofunk: Yeah, I'm definitely a fan of removing all that.

5:43 hellofunk: cfleming: i don't want to have to focus both on my code as well as its display formatting simultaneosly; yet the display formatting affects the ease of writing the code, so it's an annoying feedback loop

5:43 cfleming: hellofunk: I'm actually planning to record where the user has made changes, and automatically reformat the current top level form after a second's inactivity.

5:43 hellofunk: So you

5:43 Ooops

5:44 hellofunk: So you'll modify the code, stop to think for a moment, and it'll format what you've done so far.

5:44 hellofunk: Doing that just for the top-level form should make it interactive-level fast

5:44 hellofunk: cfleming: that would work, as you type new nested forms, it reformats parent forms to "make room" for them on the screen without line wrapping

5:45 and by "reformat" i usually just mean where the line breaks are inserted, since they affects the overall indentiation of deep nested forms

5:46 cfleming: hellofunk: Yeah - that's a little tricky, automatically breaking lines is quite controversial and requires some knowledge of the forms themselves

5:47 hellofunk: I'm experimenting with that right now.

5:47 SagiCZ1: can really imagine how would that work

5:48 whats hard about manually inserting line breaks when you write code?

5:48 hellofunk: cfleming: here is an example: https://www.refheap.com/95377 note how the final arg2 has vastly different indentation despite that both versions here are correct

5:49 cfleming: SagiCZ1: Generally, that different people like to do it in different ways, and doing it interactively often requires the full context which you may not have.

5:49 mi6x3m: hellofunk: i prefer the second :)

5:49 cfleming: SagiCZ1: e.g. a simple example is that I often have (if condition (then-form) (else-form)) on the same line if it's short

5:49 SagiCZ1: i insert them where it makes code more readible.. no strict rules

5:49 yeah

5:50 hellofunk: SagiCZ1: because when you are writing a fn, you don't necessarily know in advance when line wrapping will occur, which is ugly and throws off the readability of the code. having to stop and go back to format your code just so you can continue to work with something readable is a stumbling block in the workflow

5:50 cfleming: SagiCZ1: Exactly, but that's a very difficult heuristic to apply automatically

5:50 SagiCZ1: but you do want to try to implement that heuristic, is that what you are talking about here?

5:51 cfleming: SagiCZ1: I'd love to, but the problem is automatic formatting is infuriating if it doesn't work well.

5:51 hellofunk: to me the issue is not complicated. just add line breaks to parent forms after the fn name when line wrapping occurs.

5:51 SagiCZ1: cfleming: that would be my fear exactly

5:51 mi6x3m: I had the idea of writing an automatic formatter for the clojure style guide using fipp

5:52 mainly test-driven

5:52 hellofunk: mi6x3m: i only like the second when i have to use it to avoid line wrapping. generally i prefer the first but when working with Om which has #js literals and other things, the code can get quite long and then starts wrapping a lot

5:52 * mi6x3m nods

5:53 cfleming: hellofunk: That can be mitigated by allowing functions to indent two spaces, which was one of the focuses of the recent discussions around formatting Clojure code

5:54 hellofunk: cfleming: i don't follow... allow a fn to indent? what does that mean?

5:54 cfleming: If you haven't read it, Steve Yegge's post on implementing an IntelliJ style mode for JS is a really great read: http://steve-yegge.blogspot.co.nz/2008/03/js2-mode-new-javascript-mode-for-emacs.html

5:54 In particular how difficult indentation is.

5:55 hellofunk: Bozhidar feels very strongly that only macros should have body-like indentation of two spaces.

5:55 hellofunk: So functions can only line up in your two styles there.

5:56 hellofunk: Om in particular has a lot of forms that are actually functions but which benefit from macro-style indentation, which is why Cursive allows that.

5:57 hellofunk: hm i must admit i'm still confused what you mean by macro indents vs fn indents. i've never noticed the differences.

5:57 cfleming: See https://github.com/cursiveclojure/cursive/issues/536

5:58 See the difference?

5:58 hellofunk: cfleming: i see. i never noticed that macros do it differently. probably because i don't use too many macros. but you are right that Om would really benefit from this

5:59 cfleming: in fact I became passionate about this "problem" only when I started using Om, but then realized that it applied in general.

5:59 cfleming: hellofunk: There are lots of other examples too. In general I'm not a fan of the one-space indent (the second example in your refheap).

6:00 hellofunk: cfleming: that issues link refers to a "reformat" feature in Cursive, is that right? kinda like a "beautify" ?

6:01 cfleming: hellofunk: Yeah. Currently it doesn't actually break lines, it adjusts the indent and also aligns some things automatically, like map values and (soon) let bindings and the like.

6:01 hellofunk: cfleming: that issue was closed on gh, what was the outcome? is it just for Om fns or in general you can set in Cursive your preferred indent style for any fn?

6:02 cfleming: hellofunk: It's actually capable of breaking lines now too, if only I can get the heuristics right. I'm working on that for EDN first since that's easier - I'll then pretty print REPL results and so on.

6:02 hellofunk: It's also used for the diff view for test results, but that's a hack right now and doesn't use the proper formatting engine.

6:02 hellofunk: It's general, you can set it for any fn.

6:05 hellofunk: well it's just one more reason i need to devote some time to giving Cursive a solid look.

6:05 cfleming: Let me know what you think if you do, for sure - I'm always interested in feedback, good and bad

6:05 SagiCZ1: hellofunk: definitely worth it, i cant imagine coding without it, its super intuitive and just works like a charm

6:06 hellofunk: the irony is that after using emacs for 1 year I'm finally starting to really really get into it. but there are some things for cljs that emacs will never do right until someone write a good syntax parser in the spirit of what Cursive/IntelliJ does

6:06 cfleming: It'll be interesting to see how dnolen's new compiler functionality for cljs.test will help cljs tooling in Emacs

6:08 hellofunk: one thing i liked right away -- the simple things -- when i looked at cursive once was the little vertical line that helps you see where things are lined up. of course, this could also be done in emacs

6:09 SagiCZ1: i think thats an intellij feature though

6:09 hellofunk: SagiCZ1: regardless, it's sweet

6:09 cfleming: Yeah, I got that one for free. It is nice, though.

6:09 SagiCZ1: thats another advantage of cursive though.. that it has a solid and stable intellij to run on

6:10 if it was an eclipse plugin, i would have rather learned emacs :P

6:10 hellofunk: cfleming: and you demoed some things where actual code lines would change and get rewritten automatically, and while cool, i can see a meta form of this where users can add their own little coding tools to do this for various circumstanced.

6:11 cfleming: hellofunk: The refactoring stuff, you mean? Yeah, that's easy to do really nicely - it took a while to get the infrastructure in place, but I can add new things pretty quickly now.

6:11 hellofunk: i mean once you have a great tool like cursive that understands the lanuage syntax, there is a whole new level of tooling that can come from that, the demos just scratch the surface.

6:12 cfleming: hellofunk: Yeah, absolutely, I'm really just at the point now where I'm starting to add functionality based on the infrastructure, which has taken a year or so to get to where it is now.

6:13 hellofunk: cfleming: i can completely see how some day it could be possible that the code you physically type and code that ends up on the screen are quite different, making it possible to get ideas across almost in shorthand. like improvising music. that would be the ultimate realization of what lisp has to offer, i think.

6:13 SagiCZ1: you gotta be lazier than i am if you came up with such ideas

6:13 :D

6:15 hellofunk: well just imagine the power of an interactive programming environment like any good lisp but without the tedious layer of lots of typing in the middle. our ideas are always bigger than the process of typing little keys. FP feels a lot like a gesture-driven or musical process to me, less like a textual one

6:19 cfleming: Yeah, there's lots of potential. In particular I do think some of this kind of functionality can let you sketch out code and then have it be filled in/organised for you.

6:20 I'm also toying with the idea of being able to capture a REPL session and automatically turn it into unit tests.

6:20 Or at least semi-automatically.

6:20 Right, bedtime for me

6:20 hellofunk: oh exactly. i really think that text editing is going to be a smaller part of the future of coding in general.

6:20 cfleming: Happy Christmas, everyone, if you're in a Christmassy sort of place.

6:20 hellofunk: merry xmas!

6:24 tomjack: '(def symbol ^holy-crap! doc-string? init?)

6:26 SagiCZ1: merry christmas to you all guys

6:27 is it the 23 or 24 in the us?

6:27 hellofunk: SagiCZ1: it is the 24th now everywhere in the world

6:27 SagiCZ1: cool.. i never know whether to add or substract to my timezone :-/

6:41 how would you pick random n elements from a collection?

6:42 ,(take 5 (shuffle (range 10)))

6:42 clojurebot: (7 2 5 3 4)

6:42 SagiCZ1: it would be cool if shuffle was lazy

6:43 Bronsa: how would it work

6:43 ?

6:44 SagiCZ1: it would return a random element, and remove it from the collection

6:44 delexi: is there a function/idiom in clojure acting like flip in haskell? As a concrete example: I want to pass the arguments to mod in the reverse ordering. I want to use (mod num div) as (mode div num).

6:44 Bronsa: SagiCZ1: but get a random n element in a coll, you have to resolve that collection until the nth element

6:45 SagiCZ1: Bronsa: i see

6:45 Bronsa: SagiCZ1: and how can you even know how big the collection is without realizing it?

6:45 SagiCZ1: count on vector is O(1) though?

6:45 Bronsa: vectors are not lazy

6:45 SagiCZ1: of course

6:45 sorry i am stupid in the mornings.. thanks

6:46 Bronsa: SagiCZ1: i mean, there can be lazy + O(1) count colls, e.g. range in cljs

6:47 SagiCZ1: but still, there's really no good way to have a shuffle a lazy collection without realizing it

6:48 SagiCZ1: I suppose shuffle *could* produce a lazily shuffled coll, but the issue of having to realize the coll still remains.

6:48 SagiCZ1: so it wouldnt save any time on (take n (shuffle coll))

6:49 tomjack: if the lazy seq is very big, you can do better, I think. not lazier, but more forgetful.

6:50 Bronsa: SagiCZ1: it would save time if n was sufficiently small, realizing coll was sufficiently fast and shuffling the whole coll took a long time

6:50 SagiCZ1: wich I think is an unrealistic scenario

6:51 ctford: I've found something strange while working in a directory with an accented character - using clojure.java.io, (-> "file.txt" io/resource io/reader) fails, due to URL encoding of the path.

6:52 Does anyone know if there's a way to handle this correctly, or is it just a limitation in the Java libraries?

6:54 Bronsa: SagiCZ1: thinking about it it might make sense in the case of, (take small-number (lazy-shuffle (vec (range BIG_NUMBER))))

6:56 ctford: Perhaps using getResourceAsStream() would avoid the problem? I believe it would still be compatible with io/reader.

7:00 SagiCZ1: ,(into {} (map #(vector %1 :x) (range 5)))

7:00 clojurebot: {0 :x, 1 :x, 2 :x, 3 :x, 4 :x}

7:00 SagiCZ1: any way to make this look better?

7:01 mi6x3m: SagiCZ1: define "better"

7:01 SagiCZ1: shorter

7:02 ctford: ,(zipmap (range 5) (repeat :x))

7:02 clojurebot: {4 :x, 3 :x, 2 :x, 1 :x, 0 :x}

7:02 SagiCZ1: ctford: pretty cool, thanks

7:03 ctford: SagiCZ1: no problem.

7:30 Would there be an interest in an io/stream-resource to match io/resource? It would return an InputStream, and thus avoid URL-encoding issues.

7:36 OscarZ-: if i have some client side app that interacts with Clojure server.. i'd like to do some server side validation on the data sent by client.. what do you guys recommend for that sort of task ?

7:36 i guess usually the JSON is converted to clojure maps

7:37 ctford: OscarZ-: What kind of validation? If it's simply checking that the input is of the right format, Prismatic Schema is very handy.

7:37 However, it's designed to either succeed or fail - it won't give you errors back as data that you can format for clients.

7:38 OscarZ-: im thinking stuff like making sure there are no extra fields, the fields that are there are in specified format.. ints, strings, maybe i could use some regexp patterns too

7:38 yeah, i'd like some kind of feedback too

7:40 hmm.. ive been thinking of some simple exercise project for learning Clojure.. maybe i could try to do that myself

7:44 i also ran into EDN data format.. but i guess its not for this sort of thing

7:53 if i have a map, and the map can have other maps inside it (and recursively they might have more maps inside them) .. whats the best way to transform all those nested maps with some function ?

8:04 AimHere: OscarZ-, you looked into zippers?

8:05 Frozenlock: OscarZ-: zippers, walk, even 'for' might be good enough.

8:05 OscarZ-: nope.. ill check them out :)

8:08 "Editing trees in Clojure with clojure.zip" sounds just like the thing im looking for :)

8:10 this is probably something i should be able to program myself

8:12 but with Clojure, as its so data- oriented, if i have some problem with data transformations that sounds "primitive enough", i usually find out its already there :)

8:14 hmm.. zippers seem a bit complex.. maybe they are too flexible for my thing..

8:19 ill try to formulate what i want: given a map, i want everything else but maps to be "copied" as they are.. for maps i'd like to run a some "check" function, if check=true, then the map transformed by some function of my own, if check=false, then it is copied as it is and not recursed

8:20 is this a case for zippers?

8:22 AimHere: You might get away with some recursive function using something like recurse-kv

8:22 reduce-kv rather

8:28 hellofunk: OscarZ-: that kind of validation seems rather simple to send from a browser to a server and then back. unless it depends on data that is on the server, why not just validate client side? and if you cljs client side, this is pretty straightforward

8:35 OscarZ-: AimHere, does that do only one level though ?

8:37 hellofunk, id like a function "layer" in my server side code that if it passes the validation, it is safe to pass it down to save it to database etc..

8:39 hellofunk, i suppose i could do more heavy validation on client side that would provide feedback, but i certainly need some validation on server too for security reasons... and as they are surely overlapping concerns, i wouldnt want to do it twice if possible

8:41 CLJS on client side and Clojure on server it sounds like a library is needed :)

8:43 hellofunk: OscarZ-: well, there are many libraries out there for interop between cljs and clojure. but in your case if the nature of the validation requires information the browser does not have, then of course you'd do that on the server.

8:45 OscarZ-: hellofunk, yeah true, i didnt even think about that.. i could need that too, eg. check if the username exists and that sort of thing

8:47 i guess the way i would like forms on a web page to work needs to have some server side validation too

8:47 AimHere: OscarZ-, it does, but you can put it in a recursive function; there's also 'walk'

8:47 OscarZ-: for example when you type in a username, we need to check if it already exists

8:48 and i need to do that per input field, its not enough to first do client side validation and if it passes, then do server side

8:49 uris77: that sounds like database validation

8:49 OscarZ-: AimHere, ok.. i didnt understand it from the docs

9:03 kl: do you guys throw exceptions, or use another approach for exceptional situations that is referentially transparent?

9:05 ddellacosta: kl: you might want to take a look at dire, if you haven't: https://github.com/MichaelDrogalis/dire

9:06 not exactly referentially transparent, but maybe as close as you're going to get with Java in the mix

9:07 hellofunk: OscarZ-: are you sending down your info to the server for validation via a socket or ajax?

9:07 OscarZ-: hellofunk, ajax

9:07 hellofunk: OscarZ-: are you doing it only on form submit, or constantly monitoring their changes as they type?

9:08 or perhaps doing it in an onBluer

9:08 *onBlur

9:08 OscarZ-: onBlur, i'd like instant feedback as they move out of some input field

9:09 hellofunk: i've been working client side with sockets from a vendor and must admit they are quite nice over ajax. i hope to study the mechanics of getting it all going serverside too, but i think i'd need to switch to http-kit

9:10 by which i mean, nicer than ajax (preferred over ajax)

9:23 kl: ddellacosta: I'm surprised that the maybe/try monads like Scala/Haskell aren't used

9:26 Throwing exceptions is *very* referentially untransparent - not very functional at all

9:26 tcrayford____: kl / ddellacosta : I use that style in my app's API: http://yellerapp.com/posts/2014-06-27-api-error-handling.html

9:28 roll a thing on top of ->> and -> that shortcircuits when an error type is returned from one of the functions

9:30 kl: tcrayford____: I'll have to revisit this when I've got a better understanding of clojure. I've just started

9:31 tcrayford____: yeah. It's just a reimplementation of the `either` monad :)

9:31 kl: Oh. That sounds like what I'd hope for

9:31 tcrayford____: but it's not widely used

9:32 (I mean, the code in there isn't in a library or anything, so it's not too surprising other folk don't)

9:33 kl: I find it a little disappointing that side-effects are common for functions in a language that's meant to be a functional language

9:34 tcrayford____: you mean like, clojure.core has a load of side effecting functions in it?

9:34 Bronsa: kl clojure doesn't enforce purity. But the core language has very few side-effecting functions

9:34 kl: tcrayford____: I mean exceptional cases in functions we use/make seem to be handled by exceptions, which are side-effects

9:36 tcrayford____: are they? they're just control flow things as far as I can tell

9:44 kl: tcrayford____: I don't know whether that's the common clojure line of thought: but I think all Scala/Haskell etc. devs would disagree with that

9:45 tcrayford____: kl: that's coming from a dude who's done ~10k+ lines of production haskell over the past 5 years

9:45 ;)

9:50 kl: tcrayford____: strange. I suppose they are different to "non-local side effects". I'll have to meditate on this one

9:51 tcrayford____: you can sorta imagine it if you wrapped the entire program with an Either monad, it'd come out just like exceptions

10:41 jonathanj: how do things like :dev :prod :test keys get set when using lein?

10:42 can i find out whether my application is running in dev, prod or test myself?

10:42 dnolen_: jonathanj: you can w/ environ https://github.com/weavejester/environ

10:44 jonathanj: dnolen_: well what i'm trying to do is not repeat myself when using joplin: i have to specify the database connection string in the :joplin key (in project.clj) and then in my db-spec that i use in various places in my code; i can't see any clear way to avoid repeating the URL

10:48 dnolen_: jonathanj: sounds solvable w/ environ, a while ago I played around with Stuart Sierra's component model + environ - seemed promising

10:48 jonathanj: dnolen_: hrm, i'm not sure how i would solve it with environ

10:49 dnolen_: jonathanj: have you never done this before w/ Django or Rails, etc?

10:49 jonathanj: dnolen_: or more specifically, i'm not sure how i call an environ function from projuct.clj

10:49 dnolen_: jonathanj: seems the same to me.

10:49 jonathanj: it's not an eviron function, you have dev, staging, prod profiles in project.clj and you can read these via envrion in your program

10:50 jonathanj: i thought environ only read values from the :env key in your project.clj

10:50 dnolen_: jonathanj: each profile can have it's on :env key

10:51 s/on/own

10:52 jonathanj: ah but you're probably saying :joplin is not this flexible

10:52 jonathanj: okay, so if i specify the database-uri to :joplin {:databases {:blah {... :uri URI_GOES_HERE}}}, i have no idea how to avoid repeating that

10:52 but i guess if i put the env and joplin defs next to one another in each profile then it's probably okay

10:53 dnolen_: i'm not really sure how joplin could be made better, in this regard

10:53 dnolen_: sure you could add an external config file but then you kind of still have this problem, maybe it's marginally better

10:53 (i mean, i would contribute to making joplin better if i knew how)

11:02 triss: hey all...

11:03 what's this operator all about #'

11:03 Bronsa: triss: clojure doesn't really have operators, that's a reader macro

11:03 agarman: it is the same as (var ...)

11:04 Bronsa: triss: that reader macro expands to (var ..) e.g. #'+ == (var clojure.core/+)

11:04 ,#'+

11:04 clojurebot: #'clojure.core/+

11:04 Bronsa: ,'#'+

11:04 clojurebot: (var +)

11:04 Bronsa: ,(var +)

11:04 clojurebot: #'clojure.core/+

11:04 triss: now I'm wondering what var does.... of to the docs i go

11:04 cheers chaps!

11:06 Bronsa: ,(doc var)

11:06 clojurebot: I don't understand.

11:06 Bronsa: :<

11:06 $doc var

11:06 &doc var

11:06 lazybot: java.lang.RuntimeException: Can't take value of a macro: #'sandbox11388/doc

11:06 Bronsa: bah

11:06 hellofunk: Bronsa: lol i was going to do the same thing

11:06 Bronsa: &(doc var)

11:06 lazybot: ⇒ "Special: var; The symbol must resolve to a var, and the Var object\nitself (not its value) is returned. The reader macro #'x expands to (var x)."

11:06 Bronsa: there we go

11:07 hellofunk: triss: if you understand what a var actually is, and its difference from what its contents *do*, then you'll understand what (var..) does.. i hope

11:07 Bronsa: triss: if you don't know what a Var is, http://clojure.org/vars

11:09 hellofunk: in the practical world, calling var explicitly (including using the reader macro) is often used in environments where you don't want to recompile the caller to get the callees newly compiled changes.. i.e., in Ring handlers for web servers

11:10 you can usually use the var of a fn in place of the fn itself, since the var will lookup and point to the fn when the var is invoked.

11:10 Bronsa: (inc hellofunk)

11:10 lazybot: ⇒ 1

11:10 hellofunk: $(#'+ 5 6)

11:10 &(#'+ 5 6)

11:10 lazybot: ⇒ 11

11:10 mbac: what's the minimal translation of this clisp code? (defun foo (n) (lambda (i) (incf n i)))

11:10 hellofunk: works just like +

11:11 mbac: is it (defn foo [n] (let [n (atom n)] (fn [i] (swap! n (partial + i)))))

11:12 Bronsa: mbac: clojure strongly discourages mutable state, we don't have an equivalent for incf

11:12 mgaare: what does incf do?

11:12 Bronsa: or for setf, that is

11:12 mgaare: it's +=

11:12 mgaare: ah

11:13 hellofunk: mbac: that would depend on whether you want the atom closed over or recreated every time you call the function

11:13 Bronsa: mbac: the clj code you pasted is not equivalent to the CL one

11:14 hellofunk: mbac: your clj translation really doesn't need atom at all i think

11:15 mbac: and actually your passed in arg of n is ignored when you rebind it via let

11:16 mbac: hellofunk, the atom n shadows the original n, which is the intent

11:17 hellofunk: mbac: i'm sorry i misread the atom form

11:18 mbac: for context, this little toy come sfrom the appendix in http://www.paulgraham.com/icad.html

11:21 hellofunk: mbac: the problem is that in your code, there is a separation from the original n, which remains unchanged, and the n created by foo, which is closed over as a new atom. your original n will not change as you call this function, which i think is the intent of the CL snippet you pasted

11:22 in clojure, you would just make n an atom from the start if you need it to be stateful

11:23 mbac: what problem in my code are you referring to specifically?

11:23 my only complaint is the clisp version is way more succinct :)

11:23 hellofunk: mbac: i assume you are trying to mutate the original n via the final lambda created

11:24 mbac: i disagree. if you make n an atom from the start, the clojure version is just as succinct. your code is adding new features by creating a new stateful n detached from the original n.

11:24 mbac: is the clisp version mutating the original n being passed in?

11:24 hellofunk: mbac: i assume that is the case, it is not?

11:24 mbac: beats me, i don't write clisp :)

11:24 * hellofunk admits he is not a CL guy

11:25 hellofunk: in CL data is not immutable by default, which was my biggest gripe with that language because some fns mutate the arg and others do not, and it wasn't always clear which they were

11:27 jonathanj: what should my main function look like for a ring app?

11:27 `lein ring server` doesn't run the main function (afaict) but `lein ring uberjar` complains i have no main function

11:29 hellofunk: mbac: yes looks like it does mutate, so the translation to clojure is to just make n an atom if that's what you really want: http://dantorop.info/project/emacs-animation/lisp9.html

11:32 mbac: cool

11:36 hellofunk: mbac: there are a number of sites and blog posts from several people about converting Paul Graham's work to Clojure. worth checking out since it's not just syntactic transformation but often conceptual improvements as well since there are big philosophical differences between the languages

11:37 mfikes: distinct claims to be lazy, but embedded inside of it is an eager optimization, causing this to hang: (take 10 (distinct (concat [1 2 3] (repeat 4)))) Wondering what it means to claim laziness...

11:39 jonathanj: according to http://yogthos.net/posts/2013-01-11-One-Ring-to-rule-them-all.html `lein ring uberjar` should generate a main for me?

11:39 hellofunk: mfikes: nice example, but think about how, how could distinct be lazy on an infinite sequence?

11:40 the docs say it is lazy, but i don't see how that is possible

11:40 mfikes: hellofunk: I'm wondering if the recur inside if it is necessary

11:41 hellofunk: mfikes: if you take 1, 2, 3, 4 it works. the problem is it keeps looking and looking and looking once it cannot find a 5th distinct item you have requested. so i see now how it is lazy, though it is easy to get an infinite loop with it, even with take

11:44 mfikes: hellofunk: Right... I see what you are saying. It will hang looking trying to realize the next novel element no matter what solution you employ

11:46 dnolen_: ,(type (distinct '(1 1 2 2 3 3 4 4)))

11:46 clojurebot: clojure.lang.LazySeq

11:47 dnolen_: mfikes: just because it's lazy doesn't it mean it won't hang

11:47 mfikes: hellofunk: Makes me ponder the true meaning of lazy: It doesn't seem to guarantee that take will complete. But, arguably, it is living up to its definition of deferring work until it needs to be done.

11:47 dnolen_: (filter true? (repeat false))

11:47 mfikes: dnolen_: Cool. I learned something new. :)

11:47 dnolen_: call first on that will hang, distinct is not different in this case

12:06 hellofunk: dnolen_: great example. learned something on that one.

12:18 cbryan: what would be the idiomatic way to write the equivalent to this java code? http://hastebin.com/omahoyamus.avrasm I think I did the loop nicely, but I'm not sure how to efficiently and readably do the conditions. http://hastebin.com/tadaxehube.coffee

12:37 hellofunk: cbryan: isn't "for" quite a lot of fun?

12:49 cbryan: hellofunk: indeed, i only recently learned about :when and :let :D

12:50 i just cant get the conditionals to be pretty

13:05 hellofunk: cbryan: i think there is a syntax error in there, where's the final ] ?

13:44 daniel_: what are some techniques for making a library configurable? i want to be able to require it and then define certain constants which it relies on

13:44 justin_smith: $mail cbryan (= x 0) should usually be (zero? x)

13:44 lazybot: Message saved.

13:50 bbloom: cbryan: `for produces a sequence, but it looks like you're trying to return a scalar value

13:50 so the vertexOffset parameter is really like state, so you may want to consider using reduce

13:50 (reduce (fn [vertex-offset i] ...) 0 (for ....))

13:50 cbryan: for that first "..." try cond

14:04 aaelony: in emacs markdown-mode, I get nice element items by starting the line with a dash "-" in an unordered list. Hitting return then takes me to the next line with correct indentation for the next element of the list in my markdown. When I parse the markdown with clj-markdown however, items where I did that don't render the quite right, and I need to replace all the tabs with spaces manually. They don't appear to be actual tabs though, as (cloju

14:04 re.string/replace s #"\t" " ") doesn't remove them. What's the best way to find out what they are and replace them appropriately?

14:10 andyf: aaelony: To find out what they are, debug prints can be very informative

14:11 perhaps after breaking up into lines, if you aren't doing that already.

14:11 wjlroe: with core.logic.pldb, when facts have been defined, how do you do disequality with those facts? If (db-rel grouped x y) - how do I unify 2 values that aren't in that relationship?

14:11 aaelony: andf: indeed, but for whitespace?

14:11 andyf: ,(map int " abc")

14:11 clojurebot: (32 32 97 98 99)

14:12 aaelony: andyf: thanks, I'll try that.

14:16 andyf: thanks for that, I feel stupid as it was simply 4 space characters...

14:18 andyf: no worries. Forgive yourself :-)

14:20 aaelony: ;)

14:56 lxsameer: hey guys, 1) can create a binary executable using clojure ( java independent ) ?

14:57 justin_smith: lxsameer: clojure needs a target platform to run (jvm, or clr, or javascript)

14:57 lxsameer: justin_smith: so answer is no. fair enough

14:57 justin_smith: it doesn't need java though (jdk) just the vm

14:58 lxsameer: justin_smith: jre only, am I right ?

14:58 justin_smith: right, that's what I meant

14:58 lxsameer: 2) Can i use java lib directly in clojure ?

14:58 borkdude: hmm, #<CompilerException java.lang.RuntimeException: No such var: clojure.core.cache/through, compiling:(clojure/core/memoize.clj:52:3)> what?

14:59 justin_smith: lxsameer: yes, all of the jvm is available from clojure

14:59 ie. ##(java.util.Date.)

14:59 lazybot: ⇒ #inst "2014-12-24T19:56:09.925-00:00"

14:59 lxsameer: justin_smith: do I have to write a wrapper or something

14:59 justin_smith: lxsameer: though some things are easier than others (you need ie. gen-class and static compilation to do all the features of concrete inheratence)

15:00 lxsameer: no - what I did above directly instanciated a Date object

15:00 no wrappers

15:00 *instantiated

15:00 lxsameer: justin_smith: cool

15:00 justin_smith: clojure compiles to jvm bytecode, and directly does anything you can do on the jvm (though some things are easier than others)

15:01 lxsameer: 3) can I use OOP along side with functional programming in clojure ?

15:01 borkdude: I get this exception when adding com.cemerick/friend "0.2.1" to my project, weird?

15:01 lxsameer sure https://pbs.twimg.com/media/B3QEKjUIUAEPYtk.jpg:large

15:02 lxsameer: borkdude: I meant the actual code, not the principles

15:02 borkdude: lxsameer you mean interop? not sure what you mean

15:03 lxsameer you don't want to write java classes in clojure, but you can use them

15:03 justin_smith: lxsameer: yeah, you can do OOP with classes / methods etc. But clojure doesn't really encourage concrete inheritence, or make it easy. Which is a good thing imho.

15:03 borkdude: defrecord, fn, defprotocol... these things all generate classes

15:04 borkdude: justin_smith fn also generates a class, that is not important

15:04 lxsameer: justin_smith: borkdude , I know that it's not a good idea, but can I define a class in clojure ?

15:04 justin_smith: yes

15:04 lxsameer: good

15:04 justin_smith: with deftype, or gen-class, or defrecord

15:04 and defprotocol for interfaces

15:05 also, there are reify and proxy for instantiating / extending a java class or interface with an anonymous singleton class instance

15:06 as can be needed sometimes to interoperate with things written in java

15:06 lxsameer: 4) what about using codes which is written in other JVM base langs like JRuby or scala, can I use them clojure

15:07 justin_smith: yes, they all generate classes with methods, and you can instantiate their classes and invoke their methods via clojure without any wrappers needed

15:07 lxsameer: justin_smith: niceeee

15:07 justin_smith: though in some cases a very small "shim" java class, in regular java, can make things easier

15:09 I think the right approach with clojure, as borkdude was hinting also I think, is to stick to immutable collections (hash-maps, vectors, lists, sets) and writing pure functions that use those

15:09 lxsameer: justin_smith: can I use Akka framework of scala in clojure for example ?

15:09 justin_smith: and then do only as much OO as you need to interact with the features you need from other things on the jvm

15:09 borkdude: lxsameer you probably want to use core.async before looking at Akka from clojure

15:09 justin_smith: lxsameer: yeah, there are even some helpers to make that simpler

15:10 lxsameer: borkdude: yeah you right, but I'm looking for some answers in all these stupid questions :P

15:10 justin_smith: awesome

15:10 justin_smith: lxsameer: yeah, in general for anything with message passing / async / threads / state coordination, the normal clojure way will likely be a lot better than bindings to another lang's lib

15:10 lxsameer: borkdude: justin_smith I'm trying to choose between clojure and scala and I messed up :[

15:11 justin_smith: cool, then you can definitely interact with akka :)

15:11 lxsameer: justin_smith: thanks man, you really helped me a lot

15:11 justin_smith: and eventually, you may agree with us about Clojure's superiority and migrate to pure clojure for the async stuff

15:11 ;)

15:11 borkdude: lxsameer I wouldn't worry much about "can I do this feature from my favorite language in clojure", because clojure has indeed it's own way and many things are much simpler than the tangible mess most OO languages are ;P

15:12 justin_smith: borkdude: but he isn't asking about the feature, he is asking about extending code he already has

15:12 which is totally valid imho

15:12 borkdude: justin_smith I missed that part then I think.

15:12 lxsameer: borkdude: thanks man

15:13 I have a huge rails application right now which is run on Torquebox

15:13 borkdude: can someone help me with this exception? #<CompilerException java.lang.RuntimeException: No such var: clojure.core.cache/through, compiling:(clojure/core/memoize.clj:52:3)>

15:13 I got it after adding friend to my project

15:13 cemerick maybe?

15:13 lxsameer: I wanted to re implement several parts of it in an JVM base lang

15:13 justin_smith: borkdude: I remember issues regarding lein and core.cache... wish I remembered the details

15:13 borkdude: lxsameer I'm using JRuby now since 4 weeks and coming from clojure I want to go back iasao ;)

15:14 lxsameer *asap

15:15 lxsameer: borkdude: cool

15:15 justin_smith: lxsameer: my intro to clojure was being hired to work on a ruby web platform replacement (modified rails like thing) with a clojure system (for sanity and performance reasons)

15:15 borkdude: lxsameer although JRuby isn't that bad compared to Java EE :P

15:15 lxsameer: borkdude: but I really like Ruby and ROR

15:15 cemerick: borkdude: probably related to https://github.com/cemerick/friend/issues/116

15:16 lxsameer: justin_smith: really ?

15:16 borkdude: my experience with (J)Ruby is that you get lots of things for free, but that it's hard to track down when something goes wrong and too much magic is happening to my taste

15:16 justin_smith: lxsameer: clojure is really great for things like a web backend where you have very long program running times, and can use as much ram as you need within system limits and just need fast throughput and dynamism

15:16 borkdude: JRuby + RoR I mean

15:16 justin_smith: lxsameer: yup. Caribou project.

15:17 lxsameer: justin_smith: awesome , but How is clojure in matter of resource usage ?

15:17 borkdude: I hope you find it more interesting in the future

15:17 ro_st: it uses them all. but it uses them wisely. :-)

15:17 justin_smith: borkdude: "too much magic is happening" could be both ruby's best motto, and it's worst slur :)

15:18 lxsameer: the baseline is pretty high - but it can keep going for months or years without blowing up (unlike some platforms I can name)

15:18 borkdude: lxsameer I'm sure only a month experience is not a position to give a fair judgement and I do like a lot of stuff of it

15:18 justin_smith: lxsameer: a big part of this is you get the entire clojure compiler, for free, whether you want it or not, as part of your deployed runtime.

15:18 lxsameer: justin_smith: can you name those , For my information :P

15:18 borkdude: it seems that I won't be using friend then for a simple login

15:19 justin_smith: lxsameer: ruby, node, php - good luck getting month long uptimes in one process under any load with any of those

15:19 borkdude: I wish I understood friend.

15:19 borkdude: justin_smith what are you using for authentication?

15:19 lxsameer: justin_smith: interesting

15:20 justin_smith: borkdude thanks guys, you helped me a lot

15:20 justin_smith: borkdude: username + bcrypt hash of password stored in the db, authorized token in session in a server-side in-mem cookie

15:21 borkdude: lxsameer sure thing, welcome to clojure, there is (almost) no way back ;)

15:21 justin_smith: borkdude: plus a very simple middleware that sends you to the login for protected routes (and login checks pw to hashed pw, etc.)

15:21 borkdude: justin_smith do you have some sample code?

15:21 lxsameer: borkdude: :))

15:21 borkdude: thansk buddy

15:21 justin_smith: borkdude: let me check

15:22 borkdude: justin_smith I think I'll go for lib-noir's session thing

15:22 justin_smith unless you offer me something better :)

15:23 justin_smith: https://github.com/caribou/caribou-admin/blob/master/src/caribou/admin/controllers/settings/account.clj#L35 borkdude admittedly not pretty, but here is how we do it in the caribou admin

15:24 come to think of it though, the logic is kind of scattered in different parts of the code (which is one thing friend and lib-noir improve)

15:25 but it's only a few things - retrieving and comparing a hash, routing based on whether the user is authorized

15:25 tucker: hello

15:26 How does (def head-fibo (lay-cat [0N 1N] (map + head-fibo (rest head-fibo))) work

15:26 because it seems to make a recursive call to head-fibo, yet this function isn't set up to take any arguments

15:54 justin_smith: tucker: def does not create a function, it creates a var. It isn't calling itself, it is including itself in the calculation used to create itself

15:54 it's a clever trick, but not neccissarily good style

15:54 ,(def head-fibo (lay-cat [0N 1N] (map + head-fibo (rest head-fibo)))

15:54 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

15:55 justin_smith: ,(def head-fibo (lay-cat [0N 1N] (map + head-fibo (rest head-fibo))))

15:55 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: lay-cat in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:55 justin_smith: ,(def head-fibo (lazy-cat [0N 1N] (map + head-fibo (rest head-fibo))))

15:55 clojurebot: #'sandbox/head-fibo

15:55 justin_smith: ,head-fibo

15:55 clojurebot: (0N 1N 1N 2N 3N ...)

15:56 justin_smith: it relies on the fact that vars are created before they have values assigned (so that they can refer to themselves in the code that constitutes them)

15:56 tucker: so (def head-fibo (lay-cat [0N 1N] (map + head-fibo (rest head-fibo)))

15:56 justin_smith: it's not lay-cat, it's lazy-cat

15:57 tucker: justin_smith: so

15:57 justin_smith: we bind head-fibo to what's inside the parenthesis right?

15:57 justin_smith: we bind it to the result of calling lazy-cat with those args

15:58 so really there are two "tricks" here - the fact that it can refer to itself in its definition, and the fact that lazy-cat only creates elements of the result sequence as you use them

16:00 ,(let [fib-subseq [0 1 1 2 3 5]] (map + fib-subseq (rest fig-subseq)))

16:00 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: fig-subseq in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:00 justin_smith: ,(let [fib-subseq [0 1 1 2 3 5]] (map + fib-subseq (rest fib-subseq)))

16:00 clojurebot: (1 2 3 5 8)

16:00 justin_smith: maybe seeing that helps a little?

16:01 ,(let [fib-subseq [0 1 1 2 3 5]] (map vector fib-subseq (rest fib-subseq))) ; showing pairs of args this time

16:01 clojurebot: ([0 1] [1 1] [1 2] [2 3] [3 5])

16:01 tucker: justin_smith: hmm bare with me. In the REPL, I cannot simply do (+ [0 1] [3 4]), but I can do (map + [0 1] [3 4])

16:01 why?

16:01 clojurebot: http://clojure.org/rationale

16:02 justin_smith: tucker: see what hapens when I map vector in that last call

16:02 ,(map vector [:a :b :c] [:x :y :z])

16:02 clojurebot: ([:a :x] [:b :y] [:c :z])

16:02 tucker: surely (+ [0 1] [3 4]) must be valid for it then to apply map ?

16:02 justin_smith: no

16:02 [0 1] is not a number

16:03 tucker: ,(+ [0 1] [3 4])

16:03 justin_smith: notice that I map vector - then I get a lazy seq of vectors

16:03 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>

16:03 justin_smith: if I map + instead of vector, I get each sum instead of each pair

16:03 tucker: how do you know it's a lazy seq here?

16:03 justin_smith: ,(type (map + [1 2 3] [4 5 6]))

16:03 clojurebot: clojure.lang.LazySeq

16:04 justin_smith: map always returns a lazy-seq

16:09 tucker: justin_smith: I get (let [fib-subseq [0 1 1 2 3 5]] (map vector fib-subseq (rest fib-subseq)))

16:09 justin_smith: but (def head-fibo (lazy-cat [0N 1N] (map + head-fibo (rest head-fibo)))) still eludes me

16:10 justin_smith: ,(let [items '[a b c]] (map list items (rest items))) ; does this help?

16:10 clojurebot: ((a b) (b c))

16:10 justin_smith: hmm, more items would likely help there

16:11 ,(let [items '[a b c d e f g h]] (map list items (rest items))) ; does this help?

16:11 clojurebot: ((a b) (b c) (c d) (d e) (e f) ...)

16:11 tucker: yeah, I see

16:11 justin_smith: see how (map f x (rest x)) operates on each consecutive pair? and isn't that kind of how fib is defined normally?

16:14 tucker: justin_smith: I get it. Awesome. And this is bad for recursion as the head-fibo will hold the entire collection? That is, it will always store every element calculated ?

16:15 justin_smith: yeah, like any infinite lazy-seq defined at the top level, the only way to clear the heap used by the collection is to destructively redefine it

16:15 unless it was closed over - then it isn't freed until those closed-over contexts are freed...

16:17 if instead you defined a generator function, then you could use it inside a let block and if you are careful about scope leakage the clojure compiler and the jvm gc can make sure it is freed when needed

16:18 come to think of it, that's using a function as an "anti-closure" - storing the method of production instead of the result of production

16:42 tucker: justin_smith: Thanks alot. In regards to your closure comment, you said normally the closure pattern stores result of production. Can you expand on this (I use closures all the time in my work, but I wasn't sure what you're getting it)?

16:43 justin_smith: it's a pattern more common to common lisp / scheme (let [x (make-x)] (defn foo [y] (g x y)))

16:43 so it's storing x as part of the function closure

16:44 as opposed to (defn fibs [] (lazy-cat ...)) which would ensure you recreate the lazy-seq on each invocation rather than storing it for later

16:45 tucker: I think I see what you're getting at. g is just some kind of operator, right?

16:47 hellofunk: (inc justin_smith)

16:47 lazybot: ⇒ 162

16:47 justin_smith: tucker: yeah, some function or another, not really important there what it is

16:49 hellofunk: justin_smith: i remain a fan of the idiom (let [x (make-x)] (defn foo [y] (g x y)))

16:50 justin_smith: hellofunk: we even have partial to make it more succinct (def foo (partial g (make-x)))

16:50 hellofunk: nifty

16:50 justin_smith: hellofunk: but in an environment of pervasive immutability, locally hidden state is often worse than global state would be

16:51 hellofunk: nice point.

17:05 munderwo: Hi all. Has anybody had to interop with promises is javascript from clojurescript? Any pointers on how to handle it?

17:09 hellofunk: munderwo: fyi there is also #clojurescript though you might get some pointers here too.

17:10 munderwo: oh, yeah. I always forget to ask there… I’ll cross-ask (?) there and see if anybody has had any luck

17:12 dnolen_: munderwo: interop'ing with promises is just basic JS interop, also pretty straightforward to bridge promises to core.async channels if you need to

17:13 munderwo: ahh ok. I think im still trying to get my head around how they actually work. that and I think Im using a hand rolled version of promises. I gather than the .then function gets called automatically once the promise is realised?

17:31 dnolen_: munderwo: yes same as JS

17:46 makk: hello

17:47 Is there a clojure function similar to map that doesn't collect results? I want to apply a function on elements in a vector without really collection any results (i.e. maybe just return nil)

17:48 SagiCZ1: doseq

17:48 or, if you want map syntax.. you can (doall (map ..))

17:49 ,(doseq [e (range 2)] (println e))

17:49 clojurebot: 0\n1\n

17:49 SagiCZ1: and it does return nil btw

17:50 tomjack: if you want to return nil, dorun instead of doall

17:50 SagiCZ1: yeah sorry.. dorun

17:50 makk: thank you, I'll check out dorun and doseq

17:51 SagiCZ1: dorun is to force evaluation of lazyseq.. its useful in general.. doseq is exactly for calling a function on each element of collection to produce sife-effects

17:57 thheller: clojure 1.7 has (run! some-fn coll) if you are playing with the alpha ;)

18:00 SagiCZ1: thheller: what does that do

18:00 thheller: call (some-fn item) for each item in coll, return nil

18:01 SagiCZ1: is that not doseq?

18:01 thheller: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L7298-L7303

18:01 well (doseq [item coll] (some-fn item)) is a bit longer ;)

18:02 SagiCZ1: and whats up with the exclamation mark.. seems like they are getting too generous with them

18:02 thheller: slight difference that it uses reduce internally

18:03 well its to force side effects, so run! is good

18:03 SagiCZ1: why doseq doesnt have an exclamation mark then?

18:04 thheller: starts with do? don't care honestly ...

19:43 justin_smith: thheller: at one point we talked about adding don't blocks to the useless lib

19:43 like do, except it doesn't

19:44 (defmacro don't [& _] '(do nil))

20:07 rpaulo_: heh

22:25 gfredericks: ,#"(?<=xx*)" ;; okay fine

22:25 clojurebot: #<SecurityException java.lang.SecurityException: denied>

22:25 gfredericks: &#"(?<=xx*)" ;; okay fine

22:25 lazybot: java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 6

22:25 rksm_:

22:25 [Wed Dec 24 2014]

22:25 *** Topic for #clojure: Clojure, the language http://clojure.org | Currently

22:25 at 1.6.0; top analysts expect this to be followed by newer versions with

22:25 still higher numbers:

22:25 https://github.com/clojure/clojure/blob/master/changes.md | discussion:

22:25 gfredericks: &#"(?<=x*)" ;; wat

22:25 lazybot: ⇒ #"(?<=x*)"

22:25 rksm_: http://groups.google.com/group/clojure [18:16]

22:25 *** #clojure: topic set by

22:25 technomancy!~user@ec2-54-244-178-65.us-west-2.compute.amazonaws.com,

22:25 2014-03-26 09:33:15

22:25 *** Users on #clojure: rksm_ sgregory dalzony looper wiggen ztellman n0n3such

22:25 brucehauman apah fivebats yeahnoob ChiralSym cydork m_3 farhaven ka2u pdk

22:25 robustus swgillespie jimduey jumblerg kristof andres-v jasonjckn Jabberz

22:25 namra mumrah hbccbh conan telex andyf astrofog mrcheeks` rksm Kohelet

22:25 seangrove h_ Rhainur1 jareddba rcarey4 TEttinger w4ffles__ MadFunk aka

22:25 meandi jlf dc_ munderwo moisesv_ havenwood ajhager sak supersym lyddonb

22:26 dsantiago nuwanda dopamean_ OlegYch6 wildnux

22:26 *** Users on #clojure: keen__________12 sova gws tucker Atlanis lordB8r

22:26 craigglennie daniel_ drbobbeaty prc danielglauser adamhill_ olivierrr

22:26 mikem mbac klyed2 ticking meoblast001 adamhill newportd carc presto

22:26 charliekilo dnolen_ oscar_toro ivan\ mnemnion Frozenlock fsvehla triss

22:26 vendethiel dakrone robink elarson_ Jellydog nw Intensity rkneufeld_ pfeyz

22:26 mtd_ jconnolly OscarZ- nicferrier sw1nn Javran mrBliss psy_ frkout mee

22:26 malyn dabradley kanobe_ lnostdal razum2um1 gigetoo tobik

22:26 *** Users on #clojure: jweiss sarlalian audaxion mysamdog insamniac srcerer

22:26 mlb- jakecraige wtflem_ DomKM herme5 abhirc skrblr rplaca jlewis jlewis_

22:26 paulweb515 zerokarmaleft wolfes hodlr kephale necronian AimHere Ragnor

22:26 ordnungswidrig Excureo cascada-io daemian _5kg superjudge_ jmccune

22:26 TEttinger2 ibdknox lifenoodles_ rs0 willgorman teejar_ heurist clojurebot

22:26 crazysim Natch rlb TDJACR Raynos ZucchiniZe Xorlev ConstantineXVI Xe Cr8

22:26 Klumben Alina-malina arekinath xpika luxbock uber

22:26 *** Users on #clojure: SegFaultAX PeregrinePDX samflores r4vi boyscared matt_c

22:26 cherwin cYmen_ rtl turbofail hooptw sobel ska-fan ieure neena ryanf

22:26 perplexa kylo eevar FMJaggy abh jcsims magopian twem2 jfojtl vmesons

22:26 spwhitt rowth Kneiva juhani hipsterslapfigh- onthesta1rs oyvinrob

22:26 jackjames scopedTV scttnlsn the-kenny noidi_ gideonite devn Pistahh Kruppe

22:27 msassak greenyouse amontalenti edw spjt _trev TristamWrk icedp Trieste

22:27 jave ngk Lugoues jetlag lvh Adeon tuft godd2 ktsuji

22:27 *** Users on #clojure: luigy stderr wang saurik glitch100 tbaldridge someone

22:27 Mongey Luyt_ broquaint jlpeters d4gg4d jlouis boodle amoe AeroNotix

22:27 sbauer322 cfleming akhudek Rapp 7YUAAPOC8 s_e Orva Shayanjm codelahoma jwm

22:27 [blake| dogonthehorizon jeremyheiler rufoa mattrepl moquist verma LBRapid

22:27 jswanson lfranchi mekaj spectre256 maxmartin jinks_ gko kiwitobes tomjack

22:27 wirrbel ered auganov thecontrarian42 Sorella eristic [Neurotic]

22:27 greghendershott nmashton si14 whodidthis raywillig

22:27 *** Users on #clojure: ipolyzos bjeanes NhanH gluegadget ambrosebs rigalo_

22:27 fuziontech____ Robdor nseger_ mccraig metadaddy andreypopp__ lijnen_

22:27 dzimm_ jonathanj jayne_ reiddraper kzar mcav elsen_ thheller sohum

22:27 sea-gull- arkh divyanshu bodie_ sordina3 soncodi rfv joshhead ThePhoeron

22:27 jcrossley3-away StianE rpaulo ChongLi nickenchuggets relgar Tuna-Fish

22:27 pawnda dysfun clauswitt joshbamboo2 Christmasiumn alandipert arohner

22:27 Glenjamin saltsa Duke- pppppaul engblom npr owengalenjones

22:27 *** Users on #clojure: troydm codeburg ahihi chriswk_____ pgmcgee

22:27 gratimax|away opqdonut nullptr H4ns ggreer sneeu brixen ivan`

22:27 StevePotayTeo chridal itruslove joshskidmore grauwulf pjstadig hakvroot

22:27 LukeWinikates___ jez0990 tcrayford____ fmu yazirian guilleiguaran jdaggett

22:27 swgillespie: ok

22:28 rksm_: yogthos|away ucb__ brianwong anildigital hiredman cdombroski banjiewen

22:28 josephwi_ mjz Mendor|scr joegallo shoky morganastra luisalima maxigas

22:28 troydm: wtf

22:28 rksm_: borkdude justinmcp_ tikotus neektza justin_smith haroldwu fikusz

22:28 *** Users on #clojure: yason awkorama alxlit Sgeo libertas jerseykx

22:28 sova: lol

22:28 rksm_: bencryption igorw matthoffman babilen kryft rovar_ yunfan povilas nikola

22:28 jgmize `brian lhdc_ lobotomy torgeir waf rweir amalloy_ oskarth grandy_

22:28 larme demolithion cosmicexplorer profil tomku kristian_ Guest50300 supki

22:28 jabbslad seubert cursork numberten shem machty jodaro hash averell jlyndon

22:28 karls zph dkua khmer madscientist` aksatac zanes troezen Empperi majoh

22:28 dominiclobue zonpantli algernon pyrtsa orkaa

22:28 *** Users on #clojure: edoloughlin ninjudd janne byaruhaf l1x avdi nexysno

22:28 Raynes Revenrof Guest83413 jamiei ffwacom 32NAARMUJ okic jmolet cantsin

22:28 ekroon marce808 micrypt hguux_ aperiodic zpconn__________ wink l3dx

22:28 mariorz augustl donmullen littleli magnars tbatchelli___ korpse

22:28 bbyler_tho_ nathan7 arrdem schwap_ terom_ jimt_ TMA kreg_ qz anekos

22:28 sova: hey does anybody have a tedious listing of all the users on this channel handy?

22:28 rksm_: varioust addisonj ggherdov tcrawley-away gignosko pickledonion__ mrb_bk

22:28 michaniskin andy_c_ andrewstewart bcarrell sundbp chenglou zrl

22:28 *** Users on #clojure: rhg135 rjknight__ tomobrien katratxo hugod mynomoto

22:28 martinklepsch sross07 canassa akkad owenb____ TrafficMan_ SHODAN fvt tpope

22:28 fryguy wunki honkfestival octane--_ ianhedoesit Shambles_1 ctrlrsf

22:28 swgillespie: sova: oh boy, we're in luck!

22:29 rksm_: noncom|3 apetresc matt_d thearthur erdic peted misv Deraen jml cmiles74

22:29 Mandus Jaood j0ni snzmn philandstuff zoldar anon-6857 mearnsh ipostelnik

22:29 jefelante _ato kerneis_ lpvb axylos bool_ HeXFuRy timvisher llasram

22:29 dyreshark David iamdustan mgaare sethalves whee

22:29 godd2: sova what order did you want them in?

22:29 rksm_: *** Users on #clojure: filabrazilska metellus merlinsbrain bobpoekert

22:29 bsansouci awwaiid cyraxjoe hipsterslapfight tazjin newgnus log0ymxm spicyj

22:29 danneu myguidingstar rlr leathekd Adr1 Licenser pcn emacsnw lokydor

22:29 jgdavey lotia enn danlarkin JSON_voorhees tomhs yacin maio DerGuteMoritz

22:29 olivierrr: huh?

22:29 rksm_: Chousuke certainty mrLite lazybot sfa laurio manytrees jeregrine

22:29 Raynes: rksm_: I will murder you and your family.

22:29 rksm_: jakebasile_ howard sivoais alexbaranosky groot_ kmicu lancepantz ozzloy

22:29 amano-- matthavener TimMc beppu machuga rasmusto ikitommi

22:29 *** Users on #clojure: mikko raek shwouchk kungi slpsys_ yumike bobwilliams

22:29 sova: godd2: loosely sorted is fine

22:29 rksm_: l_ch_nm_y_r @ChanServ Meeh septomin Nahra m1dnight_ taij33n tac-tics

22:29 nmontecc klobucar______ beawesomeinstead leifw gf3 gregburd_ l2x dj_ryan

22:29 dselph_____ seabre leptonix squeedee MerryL235 zeapo gazarsgo n1ftyn8

22:29 jzelinskie pmbauer_ danlucraft nwjsmith bruceadams Scorchin hyPiRion

22:29 kikkerbrood ToxicFrog dean someplace raoul ddima ikitommi_ segmond

22:29 dottedmag georgej162__ locks tephra FliPPeh kraft Morgawr

22:29 *** Users on #clojure: alloyed coffeejunk halorgium wormphle1m mrowe_away

22:29 peeja kral zymurgy Tristam lpaste wjlroe suvash_away JStoker nathanic

22:30 deadghost octe knyppeldynan danlentz eagleflo mdeboard kandinski

22:30 brainproxy TheMoonMaster saiam gfredericks expez cmbntr hfaafb silven

22:30 Viesti ucb harrigan thomas Floyd_ Blkt _jimrthy f3ew scgilardi adammh

22:30 Riviera_ ephemeron marienz julienXX arianvp_ brackets p_l rippy obobobo

22:30 yunfan: rksm_: what's up? are you detecting zombie?

22:30 rksm_: Foxboron chouser_log tmarble stain zakwilson AWizzArd

22:30 *** Users on #clojure: yocapybara joelkuiper sorenmacbeth ontoillogical acagle

22:30 olivierrr: ban?

22:30 rksm_: puyo grim_radical kitallis cross rotty_ pepijndevos splunk_ kenrestivo

22:30 Shambles_1: rksm_: Guessing you're using a out-of-date EMACS IRC client. Might want to get that looked at.

22:30 rksm_: tomaw honza swen ivan


22:30 Raynes: So here's the deal folks.

22:30 There are no moderators around.

22:30 n1ftyn8: Yikes

22:30 Raynes: You can /ignore this fella if it continues.

22:30 swgillespie: looks like he's done

22:30 sova: The calm before the storm

22:30 godd2: anarchy!!!

22:30 olivierrr: #freenode can help.

22:31 Shambles_: It's a old EMACS client bug.

22:31 swgillespie: Shambles_: that's a hell of a bug

22:31 olivierrr: hahah.

22:31 Shambles_: swgillespie: Still happens every few weeks years later on the #emacs channel.

22:32 swgillespie: lol

22:33 yogthos: jonathanj: if you're using lein-ring then you don't need to have a main

22:34 jonathanj: in your project.clj there should be a :ring key that points to the handler

22:36 ztellman: what's going on

22:45 sova: ztellman: listening to the doors and learning some clojure

22:46 gfredericks: ztellman: ###"(?<=x*)"

22:46 I mean

22:46 ,#"(?<=x*)"

22:46 clojurebot: #"(?<=x*)"

22:46 gfredericks: ,#"(?<=x**)"

22:46 clojurebot: #<NoClassDefFoundError java.lang.NoClassDefFoundError: Could not initialize class java.util.regex.PatternSyntaxException>

22:46 gfredericks: oh constantinople

22:46 &#"(?<=x**)"

22:46 lazybot: java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 6

22:47 gfredericks: &#"(?<=xx*)"

22:47 lazybot: java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 6

22:47 gfredericks: this is a terrible demonstration

22:47 but that is what is going on with me

22:51 sova: gfredericks: you fight the good fight

22:54 gfredericks: going to give up for the night the good give up for the night

22:56 adamwarlock: if i do (go (>! some-chan (blocking-call)) will it park the thread or block it?

23:05 ddellacosta: adamwarlock: I was curious as well, and I think this stackoverflow answer gives a good response which answers your question: http://stackoverflow.com/a/21467918

23:05 " The magic non-blocking nature of go-blocks comes from "parking," which is a special sort of pseudo-blocking that core.async's state machine uses — but since your database calls genuinely block instead of putting the state machine into a parked state, you'd just be blocking some thread from the core.async thread pool."

23:21 kenrestivo: it'd sure be nice if there were shifts such that there were ops around 24/7

23:21 concurrent with that... if there were more ops

23:21 many hands make light work. it is the way of open source.

23:23 adamwarlock: oh, so as long blocking-call blocks so will the thread

Logging service provided by n01se.net