#clojure logs

2014-10-28

00:01justin_smithfairuz: I'd avoid things like database interaction in the live mode - I think it will try to
00:01justin_smithfairuz: and as you edit the code it will likely repeatedly execute the command, which likely isn't what you want?
00:02justin_smithfairuz: if you want the advantage of live mode you could make a function that generates the *data* that generates the db action, and then use live mode to look at that data
00:02justin_smithand finally have a trivial function that takes that data and plugs it into a db call
00:02justin_smith(that you don't use in a live repl, of course)
00:02justin_smith*live mode
00:06fairuzyeah that's what I realize too
00:07fairuzI made a mistake of trying to connect to the database in live mode
00:07fairuzand it create some files along the way as I type the path
00:07fairuzso need to clean that up :('
00:07justin_smithfairuz: having one function that does all the purely argument based logic and has no side effects (only a return value) and another (minimal) one that makes the side effects happen is pretty much the right way to do things in fp
00:08justin_smithfairuz: this also makes things like testing much more powerful, and easier to use
00:08fairuzjustin_smith: ok great. I will slowly trying to adapt fp in my work :)
00:09justin_smithin clojure fp style is pretty much best (until performance backs you into a corner)
00:10justin_smithand even then, much of clojure is tailored so the fp way to do it will be the way that performs decently
00:15fairuzj
00:47justin_smithTIL lein beanstalk is broken with clojure 1.7 :(
00:48sm0kefeeling adventurous?
00:49justin_smithsm0ke: feeling like getting staging deployed and I found out at the last minute that 1.7 breaks my deploy step
00:50justin_smithI've been working with 1.7 for the past month, everything was great - until the part where I package it up for AWS
00:50sm0kehurm there is a lein docker builder or something .. but probably too much?
00:50justin_smithbeanstalk does not use docker
00:51justin_smiththey run tomcat, you upload a war file
00:51sm0kenever used beanstalk, so you dont get a machine?
00:51justin_smithyou do get one, but its cheaper because things are pre-configured, streamlined
00:51sm0keweird, what if you needed some native libs to be installed?
00:51justin_smithhas automatic scaling etc. that works because the boxes are generic
00:52justin_smithsm0ke: then you don't use beanstalk I guess
00:52sm0ke:/
00:52justin_smithit's not for everyone
00:52justin_smithbut if it works for your project, it is simpler and cheaper than a regular aws instance
00:52sm0keaws is awful for long running services imo
00:53sm0keand costly too
00:54justin_smithit's not very general or flexible, but it's very plug and play, which is why the client uses it
00:54justin_smithI'm just using their preferred stack
00:55sm0ke"But it works perfectly on my machine!"
00:55sm0kethis sould be printed on a t shirt
00:55justin_smithsm0ke: beanstalk actually prevents that - it wasn't that my project wouldn't run on beanstalk, it's that my clojure based deployment / building plugin broke with 1.7
00:56sm0kehurm but building part is done locally right? why did you not see this before?
00:56justin_smithsm0ke: because I was not building it
00:57justin_smithjust running it
00:57sm0keah
00:57justin_smithto deploy, I pack up a war file
00:57sm0kelein ring?
00:57justin_smithwhich is a jar with certain special classes defined
00:57justin_smithlein beanstalk, it uses lein ring, but also has its own stuff
00:58sm0kejust revert to 1.6 than ? dont tell me you areusing transducers?
00:58justin_smithsm0ke: I reverted
00:58sm0kegood :D
00:59justin_smithI was just griping about a) the process of narrowing down the root cause of my issue
00:59justin_smith(which wasted about 45 minutes of my precious time)
00:59justin_smithand
00:59justin_smithwell, mainly just that
01:28n_blownaparthi anyone here advocate using lighttable to learn clojure? I know a little ruby but never quite learned how to properly use the repl gem pry.
01:29justin_smithn_blownapart: light table is not very actively developed right now
01:29justin_smithif you want an IDE I hear nothing but good things about cursive, which is a plugin for intellij idea
01:30n_blownapartjustin_smith, really? ok, thanks, I heard clojure runs great on lighttable and its a good learning tool but I'm not very experienced with programming.
01:30justin_smithOK
01:31justin_smithlight table is kind of cool, and don't feel like you shouldn't try it out
01:31justin_smithit just isn't very actively developed, and hasn't been for a while
01:31n_blownapartjustin_smith, thanks kindly
01:31justin_smithalso, especially when you are first learning, you can just use the repl from a terminal
01:32justin_smithwith the basics of require with :reload and the command line editing keys you can get a lot done
01:32justin_smithn_blownapart: also, if you aren't yet, start with lein
01:32justin_smithit makes clojure much simpler
01:32n_blownapartlein? one sec.
01:33justin_smithn_blownapart: lein is our package manager and build tool of choice
01:33justin_smithit finds and downloads dependencies, and helps with the automation of building / running your app
01:34justin_smithn_blownapart: if you used the "gem" tool just about every time you used ruby (except maybe on production) that is kind of the role lein has with clojure for most of us
01:35n_blownapartI'm new to programming. I went through a ruby book and learning linux now. a confused noob still not grasping oop very well.
01:35n_blownapartjustin_smith, ^
01:35justin_smithOK
01:36justin_smithwell that's helpful, because we don't do a whole lot of OOP
01:36justin_smithand the hard part for many newcomers to Clojure is expecting to do things the OO way and being confused
01:36n_blownapartgood advice. thanks justin_smith I'll check out your suggestions.
01:37justin_smithn_blownapart: lein is very easy to install, it's just a single file and downloads everything else it needs
01:37justin_smithmake sure you use 2.x and not 1.x though (your linux package manager may only have 1.x)
01:37n_blownapartcool I heard clojure was tough to learn . wish me luck ! justin_smith
01:38justin_smithn_blownapart: and don't be afraid to ask questions
01:38n_blownapartexcellent thanks.
01:38justin_smithI think it's easier if you don't know other languages yet - the really hard parts about clojure are how it diverges with many of the mainstream assumptions
01:39justin_smithn_blownapart: also, there is a really good tutorial oriented for people who are new to programming
01:39justin_smithn_blownapart: http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome
01:39n_blownapartno prob. I have no assumptions formed. got it thanks justin_smith !
01:43justin_smithn_blownapart: also, I just double checked, that tutorial starts with downloading lein and using it, so it's a great resource right off the bat
03:08zhcpklAnyone have any experience with tess4j?
03:18fairuzHi guys. How to list down all available functions from a library?
03:30roelof_hello, why do I get this error message ( Map literal must contain an even number of forms) on this form : http://pastebin.com/HHDpfbL9
03:34roelof_hello, why do I get this error message ( Map literal must contain an even number of forms) on this form : http://pastebin.com/HHDpfbL9
03:35broquaintroelof_: I don't think that form is causing that error, there are no map literals in it and it's valid code.
03:35nhanHThat snippet of code by it self is fine, are you sure the error is not somewhere else?
03:36roelof_broquaint: wierd, when I do lein midje I see this error appear
03:36broquaintMost odd.
03:38roelof_broquaint: yep.that is why i asked here for help
03:39broquaintWhy do you think it's that piece of code in particular?
03:39roelof_broquaint: because that is the last what I have changed
03:42broquaintAnd if you drop that 'lein midje' works ok?
03:43nhanHAnyone here familiar with at-at?
03:44roelof_broquaint: when I do the same in repl and do (do-a-thing 5) I get a answer and no error message
03:45roelof_very wierd., I deleted the file and did a fresh download from github. Changed it to the script and everything works
03:46mavbozoroelof_: i presume you have done 'lein clean'?
03:47roelof_mavbozo: nope, just deleted the file and did a git clone command
03:49m00nlight_lein deploy will only deploy the jar not the standalone.jar?
03:53jonathanji don't suppose there is Dash (the Mac app) integration with clojuredocs.org? :(
03:54jonathanj(that i don't have to generate manually)
04:00mavbozom00nlight_: yes
04:03m00nlight_mavbozo: So why the building jar report an error unbound var of function I write in a file and I required in another file?
04:09mavbozom00nlight_: have u try 'lein clean' & 'lein compile'
04:10m00nlight_mavbozo: Yes
04:11foofoobarHi. Is there something like tour.golang.org for clojure?
04:16mavbozom00nlight_: you try to build the jar with 'lein jar'?
04:16m00nlight_lein uberjar
04:34eredfoofoobar: did you look at http://www.tryclj.com/
04:34ered?
04:35foofoobarered: yes, it’s very short :/
04:35eredah
04:35eredyou're looking for something more in depth then?
04:36foofoobarered: yes
04:36eredhmm
04:36foofoobarThe golang tour showed a lot of the go language with examples etc.
04:36eredah wow
04:36eredgolang tour is a lot more in depth than i remember
04:37eredcould have sworn tryclj is longer
04:38eredhmm
04:38eredtrying to think of stuff, most of what i learned from initially was reading and following along in my own repl, not on a website
04:39eredi bet there's better stuff now though
04:39eredreading books*
04:40eredclojure wiki links to this article, but it's not interactive like golang tour is http://java.ociweb.com/mark/clojure/article.html
04:41eredworst case there you could read through that and install lein so you have your own repl to follow along
04:41ered:\ there should definitely be something better though
04:41foofoobarokay, thank you.
04:41foofoobarI have lein installed (and it’s up to date when running upgrade), but I get the following error when running lein repl: Exception in thread "main" java.lang.IllegalArgumentException: Cannot open <#<Socket Socket[addr=localhost/127.0.0.1,port=54060,localport=54080]>> as an OutputStream. (form-init4763471810287640460.clj:1)
04:41eredthankfully lein isn't too bad to install, i know go can be a little bit of a hassle to set up the environment
04:42eredah okay
04:42foofoobarah sorry, I was in a wrong directory.
04:42eredah
04:42foofoobarCalling it in an empty directory it works
04:42eredyeah true
04:43eredor in a tiny project directory should be safe too
04:43eredthe article i linked recommends doing it that way
04:43foofoobarok
04:43foofoobarthanks
04:45irctcI am currently reading programming clojure 2nd edition and I enjoy it so far..
04:45eredirctc: true, i mean i learned from a book too
04:45eredbut books cost money :)
04:45irctcfoofoobar, maybe try with this book
04:45ered(though a lot of books have online editions)
04:45ered(joy of clojure's site is broken atm)
04:45eredi really like joy of clojure
04:46irctcIll check that out once I finish with this.
04:46eredoh, i originally learned from the o'reilly book
04:46irctcThe only part I don't like about clojure books is that they tend to be really hefty
04:46eredyeah there's... a lot of material
04:46eredplus if you get into the rich hickey talks and all that
04:47eredi still have clojure in action on my backlog too
04:47eredbought it forever ago but still haven't gotten to reading it yet
04:47irctcThere are other means to obtain electroci copies of the book, if you are really poor and thirsty
04:47ered:3
04:47eredirctc: oh another one i was following was brave clojure
04:47eredthat one had a section on setting up emacs which i thought was nice
04:48irctcI currently use vim, is there any reason to switch to emacs ?
04:48irctcI see lots of people using emacs for clojure
04:48eredirctc: personal preference mostly
04:48eredhistorically (like 3 years ago) vim was terrible for lisp development
04:48eredi know this from personal experience
04:48eredcommon lisp specifically
04:49eredthat's what got me to switch to emacs in the first place
04:49eredi still use evil-mode though
04:49eredso vim keybinds and all that
04:49eredthe login button on manning is an image so it's impossible to find :|
04:50irctcah I see, well i use vim-clojure-static and fireplace and raibow_parentheses plugin and it works fine,
04:50irctcI can eval in the same buffer
04:50eredyeah i hear fireplace is nice now
04:50eredit used to be for common lisp, all there was was like slimv and it barely worked
04:50eredcompared to slime
04:50eredin emacs
04:51eredokay finally redownloaded joy of clojure, remembered why i liked it
04:51eredit has chapters at the end on stuff like clojurescript and core.logic
04:52irctcthere is also this enormous book called Clojure in small peices :)
04:53irctcI like the whole literate programming idea
04:53eredi know haskell people love it
04:53irctcTimothy Daly is the editor :)
04:53eredthey have that whole .lhs format that's parsed completely different from .hs
04:53ered(literate haskell)
04:54eredthere's the one doc library in clojure that really promotes literate too
04:54eredi think that one is marginalia?
04:54eredyeah
04:54eredhttps://fogus.github.io/marginalia/
04:54aztakare we talking about books? I'm currently working through this one: https://leanpub.com/fp-oo -- recommended :)
04:55irctccool, and clojurescriptone too i think
04:55eredneat, that book has an interesting approach
04:55irctchttp://clojurescriptone.com/documentation.html
04:55erednot so useful to me personally but i can see where it comes in handy for coming from heavy OOP world
04:56eredhmm
04:56eredyeah i haven't done enough clojurescript to say for sure how i'd do it
04:56eredi'd like to get into it more though
04:56irctci bought that one too, didn't like it much
04:56eredisn't clojurescriptone the one that's big on coupling the server and browser to the same framework?
04:56irctctoo slow
04:56eredor is that pedestal?
04:57eredoh, this one is just docs
04:57erednvm
04:57eredi am thinking of pedestal
04:57eredi will definitely look at this one
04:58aztakered: the interesting thing with the fp-oo book is that you slowly (well) discover that OO is basically FP with implicit scopes :) In that way it's a nice companion to http://www.smashcompany.com/technology/object-oriented-programming-is-an-expensive-disaster-which-must-end
04:59irctcisn't pedestal just a web server for clojure..need to check
04:59eredaztak: neat
04:59irctcWell OO should not be used for storing data into object, it should be storing behaviours.
05:00eredmy style in OO languages is as "functional" (read: defensive) as i can get away with these days
05:01irctcaztak, thanks for the link, I like reading about horrible OO concepts :)
05:02aztakirctc: it's a looooong read.. I confess that I didn't read every single word.. but there are some interesting quotes in there.
05:27sveriThis link took me about 90 minutes to read, however, a text ending with a citation of joel spolsky is almost always worth it :D
06:31Urza-Hi, im looking for some information regarding the benefits of clojure (have to give a presentation about it on friday). I've been looking around the web, and have done a couple of tutorials, but the main "why would you actually want to use this language" still eludes me. Any golden tips?
06:31SagiCZ1Urza-: how about some of the classic rich hickey presentations?
06:32aztakUrza-: functional programming in itself is an argument. Also the 'decomplecting' syntax of Clojure is a big win compared to other FP languages in the JVM imo.
06:33SagiCZ1i would focus on the fact that clojure emphazises immutability and pure functions which lead to code that is easier to reason about, also it inherently reduces problems with concurrency
06:34aztakhttp://thecleancoder.blogspot.se/2010/08/why-clojure.html ?
06:34aztak(that was the first google hit for "why clojure?" ;))
06:34SagiCZ1also point out the advantages of JVM as a mature platform which is thouroughly tested, fast and reliable and the ability of using the whole java plethora of open source and/or commercial libraries
06:34hyPiRionUrza-: http://www.infoq.com/presentations/Simple-Made-Easy – great talk regardless of whether you adopt Clojure or not
06:35hyPiRionbut Clojure is more or less built around this (simplicity)
06:35Urza-ah thanks for the info guys
06:36Urza-rick hickey presentations seem like a good starting point, shame i forgot my headphones today :(
06:36SagiCZ1Urza-: you can go through the slides on infoq
06:36Urza-ah yeah
06:39Urza-SagoCZ1, why clojure over other FP languages? also what do you mean 'decompleting'?
06:39Urza-err aztak I mean
06:40justin_smithUrza-: the term is decomplecting
06:40justin_smithreducing complexity
06:40kungiUrza-: Mostly because clojure is "modern" and on the JVM. This alone makes it much more valuable for real world use.
06:40aztakjustin_smith: (sorry - typo)
06:41justin_smithaztak: you got it right
06:41Urza-I see, most of the tutorials i've done so far have focussed on that aswell. Heres how you you would write program x in java (25 lines), and here it is in clojure (3 lines).
06:41aztakah, sorry for complecting the discussion with noise :) I should have scrolled up and read what I wrote *grin*
06:42mavbozoUrza-: "Clojure: the JFDI language" can be a inspiration https://docs.google.com/presentation/d/15-7qFy6URdE7Owi2LitkQI_OHBu1AFWPUwHxgBc-O4E/edit?usp=sharing
06:42justin_smithaztak: though I would argue that syntax is only a trivial case of decomplecting in clojure, and it's more about the simle vs. easy philosophy of the lang semantics
06:42Urza-however the benefits do seem closely tied to the data structure (lists, vectors, maps)
06:43justin_smith*simple
06:43mavbozoUrza-: lots of materials, but in the end, depends on your audience
06:44Urza-audience consists of junior programmers
06:44aztakjustin_smith: yeah, true. But to me a simple (and unambigious) syntax is a great selling-point compared to (for example) Scala.
06:44SagiCZ1Urza-: yes, because data and its processing is what programming is about.. if you make data easy and efficient you solved many problems of today's languages
06:45aztakThe language syntax is more complex in Java than in Clojure. But again - have a look at the Simple/Easy video..
06:45SagiCZ1aztak: the syntax of clojure has less concepts than any other language i know, but knowing and understanding core functions is not easy at all
06:45justin_smithUrza-: I think a big aspect of Clojure's niche is the overlap of default immutability / jvm platform / dynamic typing - those three combined are kind of unique
06:45mavbozoUrza-: what languages that most of those junior programmers familiar to?
06:45justin_smithUrza-: my employers would not have been able to use Clojure if it was not hosted on the jvm
06:46Urza-mostof them have recently completed their java certification (or are still working on it)
06:46aztakSagiCZ1: agreed. But at least you can focus on that without spending time on accidental complexity introduced by a big syntax :)
06:46SagiCZ1aztak: agreed
06:46hyPiRionthe Clojure syntax is to some extent more complex. You cannot distinguish function calls and control flow (macros) in Clojure, but you can in Java.
06:47SagiCZ1hyPiRion: the question is do you need to distinguish them?
06:48mavbozoUrza-: Clojure by Java Programmers by Rich Hickey could be a great starting point http://www.youtube.com/watch?v=P76Vbsk_3J0
06:48hyPiRionSagiCZ1: Imagine (foo t (bar x) (bar y)) – bar is a function with side effects (say println). How many times will we see a println in this case?
06:49hyPiRionI'm not saying it's worse than Java, but it's different.
06:49mavbozoUrza-: It's long, more than 2 hours, but because you know your audience's knowledge about java, you can adapt it
06:49SagiCZ1hyPiRion: i see your point
06:49Urza-yeah good tip, thanks
06:51justin_smithhyPiRion: vastly outweighed by Foo.bar(baz) - how exactly has the internal state of baz been pushed around (not an issue in a majority of clojure code)
06:52Bronsajustin_smith: that has nothing to do with syntax though
06:53hyPiRionjustin_smith: I agree, but that hasn't that much to do with syntax
06:53justin_smithhyPiRion: right, not a syntax issue!
06:53justin_smitha counterbalancing complexity is all
06:53BronsahyPiRion: we actually have a way to distinguish between macro calls & function calls -- indentation :)
06:54justin_smithBronsa: don't forget syntax highlighting
06:54justin_smithhaha
06:54Bronsaheh
06:55BronsaI was actually quite serious btw, indentation plays a huge semantic role in lisps
06:55justin_smithBronsa: it does, but like highlighting it's not enforced or evaluated by the compiler
06:55Bronsaright
06:55SagiCZ1justin_smith: what seems complex to me in clojure are the exit points of functions, since there is no return keyword, it is very hard to see for me if i didnt forget to add correct exit path
06:55hyPiRionBronsa: and binding forms. They are quite noticable
06:56justin_smithSagiCZ1: but that can be determined by the paren nesting - a macro aware editor program can determine it
06:56kungijustin_smith: Does Emacs differentiate between macros and functions when syntax highlighting?
06:56SagiCZ1justin_smith: i guess i just have to train my eye to see it
06:57justin_smithkungi: no, but it should imho
06:57mavbozobtw, talking about indentation, any of you guys using lisp code beautifier
06:57hyPiRionkungi: for known macros, not self-defined ones
06:57kungimavbozo: Is there such a thing
06:57Bronsaa tools.analyzer backed editor might be able to highlight differently the exit points of a functino
06:57justin_smithhyPiRion: oh, yeah, I guess they have a consistent color...
06:58mavbozokungi: c family has code beautifier program
06:58justin_smithBronsa: that would be awesome
06:58kungimavbozo: I know but I haven't found one for clojure
06:58justin_smithBronsa: for example highlighting each "tail" of a form would be great
06:58kungiI like the go philosophy in this case. "Use goformat or go ...."
06:58mavbozokungi: agree
06:59justin_smithkungi: use the clojure-mode indentor for emacs?
06:59kungijustin_smith: I already do, but this does not solve the problem completely.
06:59justin_smithwe have a clojure lib that does indenting / pretty printing for code though right?
06:59justin_smithkungi: agreed
07:00kungijustin_smith: I would like to have a tool where I can say: I want my lines to be 100 characters wide => Go and produce nice lisp indetation for me.
07:00mavbozojustin_smith: it doesnot fix trailing parenthesis last time i checked
07:00kungiThen run on all source files before saving them.
07:01justin_smithmavbozo: yeah, it's incomplete and not as bossy as a proper formatter
07:01justin_smithit doesn't override any line-break decisions
07:01justin_smithonly indentation ones
07:02kungiA tool to enforce a company wide style would be great
07:02mavbozokungi: c has formatter that let's you choose, say, kernighan-richie style and others that i forgot.
07:03kungimavbozo: I know about indent which helped a lot
07:03mavbozoweird, for all those talks about letting machine do our job, but no formatters come from lisp programmers for ~50 years
07:04dysfuni don't think i agree. i find that a lot of my clojure has to be manuall reindented to read the easiest
07:04justin_smith,(clojure.pprint/write '(let [a 0 b 1] (+ a b)) :dispatch clojure.pprint/code-dispatch)
07:04clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint>
07:04dysfunthere's some sort of subconscious logic balancing brevity with ease of reading
07:04justin_smith,(require 'clojure.pprint)
07:04clojurebot#<SecurityException java.lang.SecurityException: denied>
07:04justin_smithblerg
07:05justin_smithmavbozo: won'twork with the bot, but check out what pprint/write does there
07:06dysfunspeaking of the bot, where's the evaluator source code? i want to see how it's dealing with the securitymanager stuff
07:06SagiCZ1why would clojure repl use both of my cores when i didnt design for parallelism anywhere, is it normal?
07:07justin_smithSagiCZ1: are you using lein repl?
07:07justin_smithor nrepl
07:07SagiCZ1lein
07:07dysfunlein has to trampoline another instance
07:07justin_smithlein repl opens an nrepl process, and also a client of the process
07:07Bronsajustin_smith: the issue w/ using t.a for backing an editor is that to be accurate t.a needs to evaluate code
07:08justin_smithBronsa: yeah that could get very messy
07:08justin_smithBronsa: our kingdom for purity and an IO monad, huh
07:08dysfunjustin_smith: haskell is --> that-a-way
07:08Bronsajustin_smith: I know that somebody in the cider team is trying to use it anyway, I've added some hooks that should allow for unevaluated code to be analysed but have no idea how that's working out for them
07:09justin_smithdysfun: just pointing out that feature addresses that issue
07:09Bronsajustin_smith: the need for evaluating code comes from macros actually
07:09SagiCZ1justin_smith: what is a "client of the process" ?
07:09Bronsait's a known "limitation" of lisps
07:09mavbozojustin_smith: i tried in in my emacs cider repl and it returns (let [a 0 b 1] (+ a b)) in one line
07:09mavbozojustin_smith: is that what you expect?
07:10justin_smithSagiCZ1: the thread that reads your input, and then sends it over the network to the one that does the eval part, and then reads the result over the network, and prints it
07:10SagiCZ1justin_smith: thank you
07:11justin_smithmavbozo: no, that's less than ideal - but try a do form with multiple printlns
07:11Bronsamavbozo: writing a lisp code formatter is not an easy task, because of how little syntax lisp has
07:13dysfunBronsa: writing macros in other language is also not an easy task because of how much syntax they have :)
07:15SagiCZ1what is the best way to store timestamps in clojure? just a string? or some sort of long? or java's Date object? i need it to be efficient and reasonably small
07:16SagiCZ1maybe java.sql.Timestamp
07:17daniel__SagiCZ1: to store them in a database?
07:17daniel__then yes, java.sql.Timestamp
07:17SagiCZ1daniel__: no, just to use them internally
07:17dysfunwhy not just use joda time?
07:18SagiCZ1dysfun: i could, so there is no idiomatic clojure way?
07:18dysfunwell, clj-time is an idiomatic clojure wrapper for joda time
07:19SagiCZ1dysfun: sounds greay
07:19daniel__i was about to say clj-time and to-sql-date
07:19SagiCZ1*great
07:19justin_smithSagiCZ1: I usually just use numeric timestamps, but it really depends on what properties you need - I just need offsets between two of them and the numbers suffice for that
07:19dysfunthe moment i hear someone talking about 'efficient and reasonably small'
07:19dysfuni get a little twitchy
07:20justin_smith,(.getTime (java.util.Date.))
07:20clojurebot1414495153784
07:20dysfundata is just data, it can be transformed into various shapes
07:20dysfunthe 'efficiency' is in how you manipulate it
07:20justin_smithdysfun: cache-line and heap usage are things you know
07:21dysfunand have you profiled and discovered there's a problem?
07:21mavbozoSagiCZ1: designer of datomic chose java.util.Date. So, I think it suffices for lots of cases
07:21clgv:(
07:21dysfunand frankly if you're going to be optimising cache lines, why on earth are you programming clojure?
07:22clgvthen better use clj-time - java.util.Date and the surrounding API is just broken
07:22justin_smithdysfun: not saying they are the only things, just saying they are things, and sometimes they matter
07:22clgveverything is a thing, right? :P
07:23justin_smithclgv: it's an idiom
07:23perplexais anybody here familiar with clj-time? i'm trying to figure out the most elegant way to get a datetime object for the current hour, (t/now) gives me #<DateTime 2014-10-28T11:14:21.597Z>, i get #<DateTime 2014-10-28T11:00:00.000Z> with (t/date-time (t/year (t/now)) (t/month (t/now)) (t/day (t/now)) (t/hour (t/now))) but there must be a more elegant way, maybe (tc/from-long (* (long (/ (tc/to-long (t/now)) 3600000)) 3600000)) - that works, too.
07:23dysfunthey do indeed. but perhaps something where you actually control memory allocation directly might be a better solution for dealing with cache lines
07:23perplexabut i don't know what would be prefered ;x
07:25justin_smithdysfun: and also, thinking about it a bit more, they are just criteria for putting your data into a specific shape, which does not contradict your point, in fact it re-enforces it in a way
07:26justin_smithdysfun: see for example disruptor - they use the jvm to get high performance cache line usage (by shoving everything into a ring buffer array)
07:27justin_smiths/everything/the part that matters/
07:29dysfuni'm not saying it can't be done
07:31dysfunsee, in perl, if i had a performance problem, i'd just go write a little bit of. Granted, I have to do that more often in perl because standard performance is not nearly as good as clojure. But when performance does become a problem in clojure, it's not nearly as easy to make it run faster
07:31dysfun"little bit of C"
07:31justin_smithwell, we do have interop, and to re-use my prior example, disruptor outperforms any c++ alternative
07:32justin_smith(but that's because of good design, and a smart c++ project could replicate it and out do them, of course)
07:34dysfunis there a nice clojure wrapper for disruptor?
07:34justin_smithnot that I know of
07:34dysfunpity. i was looking at immutant, but it all feels a bit "enterprise"
07:34justin_smithand it's a pretty niche tool (low latency message queue with a very opinionated architecture)
07:34dysfunthe app i'm building, well i'd quite like to ship a single config file with it, not about 40
07:34dysfunthough embedding something like hornetmq would be awesome
07:36dysfunthere's this enormous tendency of java apps to support every config option under the sun, i've noticed :(
07:36dysfunit all confuses my poor little brain
07:36justin_smithdysfun: yeah, disruptor is not inter-process, it's for in-process queues
07:36dysfunimmutant embeds hornetmq if you let it
07:37justin_smithhugo duncan code is often good https://github.com/hugoduncan/hornetq-clj
07:37dysfunheh, i used ritz for the longest time
07:37justin_smiththough the typo in the readme is a bad sign...
07:38justin_smithhotnetq
07:38dysfunyeah, i saw
07:38dysfunthey're next to each other. easy to do
07:38dysfunand when i used to work with magento, i never did stop myself from typing 'magneto' and correcting it every tie
07:39justin_smithhaha
07:39perplexai think i've found the answer to my question :P
07:39perplexa(-> (t/now) (.withMinuteOfHour 0) (.withSecondOfMinute 0) (.withMillisOfSecond 0))
07:39justin_smithsomeone should come out with a magento-killer named Xaiver
07:39perplexaunless that massive joda datetime has a better way ;x
07:40justin_smithdysfun: or perhaps proeffserX
07:40dysfunoh, right, i get you now. the intentional misspelling
07:56SagiCZ1justin_smith: yeah i guess plain numbers wouldnt suffice here.. i need to parse various formats of dates from the source data, so i need clj-time.format anyways.. might use the core as well
07:57mbacso i have a tick function and a draw function. i want the tick function to update world state that the draw function reads. i guess the tick function also needs to watch an event stream whereas the draw function gets driven by a library timer. do i want to use vars to share the world-state and async to drive the tick function?
07:57mbaca stm approach seems like inefficient overkill for this, on cursory reading
07:58justin_smithmbac: one thing that has worked for me is to have a pure-data representation of world state, and a function that takes a world state, and a series of events since last update, and returns an updated state
07:59justin_smithmbac: the result of this calculation can then be fed to a "generate scene" function, the output of that offered to the drawing function
07:59mbacsounds elegant, but really i just want a buffer that one function running in a loop can update and the other function running in a loop can read
08:00mbacthe ugly imperative thing is the way forward :P
08:00justin_smithmbac: "just" is tricky here, but you can put it in an atom if you like
08:01mbaci think atom is what i was looking for. it seems like i would need to alternate buffers to avoid making state-swaps so costly
08:02SagiCZ1mbac: i was dealing with similar problems and with many tips from this channel i managed to avoid stm altogether so far.. i basically used what justin_smith just described
08:06sveriHi, are there any advantages that liberator provides over compojure routes?
08:06justin_smithsveri: liberator simplifies a bunch of the patterns that you have with a REST service
08:07justin_smithsveri: it makes it easy to do a bunch of things that are all possible with compojure, just more tedious
08:07sverijustin_smith: so basically it's an abstraction?
08:08justin_smith(on the other hand, if what you are doing is not a RESt service, I think liberator would be a pain in the ass)
08:08justin_smithsveri: compojure is an abstraction too, they are different abstractions :)
08:08justin_smithsveri: I like how this page presents it http://clojure-liberator.github.io/liberator/tutorial/decision-graph.html
08:09justin_smiththere's a "decision graph" on that page, showing the amount of logic liberator simplifies
08:09sveriHm, I see
08:09justin_smithand REST services tend to have common decision trees, deriving from the spec
08:10justin_smithso why not have a layer that is formed around that
08:10sveriI guess, no one rly implements all that logic if he goes without liberator
08:10justin_smithall that said I haven't used liberator yet - but I did a lot of work on another clojure web platform and I like the design from what I have seen
08:11justin_smithsveri: but good code should have :)
08:11sverijustin_smith: that's the problem with good code, a lot of things should be in there, but, well, I guess you know yourself
08:12justin_smithsveri: I like the fact that it makes it simple to handle the error cases with the right response codes, and to describe the status you would present to a client
08:13sverijustin_smith: Hm, I guess I just give it a go and see how it works, thank you very much
08:14justin_smithsveri: also, unless I am mistaken liberator and compojure are orthogonal - you could plug a resource definition into any router you like, and the docs show using compojure because that is the router most people use
08:15justin_smithsveri: for the tool I worked on we ditched compojure because we used a db to describe routes (for internal workflow reasons) and compojure makes data-driven route generation more difficult than it should be
08:16sverijustin_smith: yea, I just saw the compojure example
08:17justin_smithsveri: oh wow, I am just looking at this for the first time and after years of doing webapps it's making me so happy: http://clojure-liberator.github.io/liberator/tutorial/debugging.html
08:17dysfunjustin_smith: high praise indeed
08:17justin_smithsveri: it is an automatic and smart way to do the ad-hoc stuff I end up doing when debugging a site...
08:18justin_smithdysfun: just got done updating all routes on a client site to use textual slugs from the db rather than numeric ids...
08:18justin_smithI wish I had that debugging functionality they are showing here while doing that
08:19justin_smithdysfun: when I was a kid, at one point my dad jacked up our house to put a new foundation underneath it - it felt kind of like that :)
08:20dysfunjustin_smith: so what *does* it gie you for all this fancy debugging?
08:20sverijustin_smith: yep, that looks rly awesome, one more reason to try it out
08:20jeffterrellWow, that is nice. Just started using Liberator (after doing my last API by hand), and I'm so looking forward to all of this.
08:20dysfunjust all this X-Liberator-Trace?
08:20justin_smithdysfun: and that flow chart
08:21sveriI mean, even developers like flow charts!
08:21mavbozojustin_smith: my sympathy for dealing with url schema without identifier for machines
08:21justin_smithdysfun: what I was doing with way too many logging calls
08:21justin_smithmavbozo: the customer is always right, right?
08:21dysfunnice to have that integrated, yeah
08:22dysfunmight have to steal some of that
08:23mavbozojustin_smith: no, but we must live to fight another day
08:24mavbozojustin_smith: so, what do you use to make routes as compojure route replacement?
08:25justin_smithmavbozo: https://github.com/caribou/polaris it allows creating routes based on functions taking edn data
08:26justin_smithmavbozo: using db to govern the routes isn't always a smart choice, but we used it for a particular workflow to some success
08:27justin_smithmavbozo: and I can imagine other routes-as-data use cases
08:28mavbozojustin_smith: wow, I didn't know that polaris exists. makes me wonder why it does not exist in clojure-toolbox.com cause I use it first to find libraries. At first, I thought you use bidi https://github.com/juxt/bidi
08:29mavbozoit seems there are lots more routing libraries out there
08:29pandeiroliberator users: is there an easy way to marshall java.sql.Timestamp values in my tables into JSON?
08:30justin_smithmavbozo: polaris is part of caribou, which is listed there
08:31mavbozojustin_smith: i looked for libraries not frameworks :p
08:32mavbozopandeiro: tables from sql databases?
08:32justin_smithmavbozo: there's a gray area :) we aimed to make each part of caribou independently repacible
08:35pandeiromavbozo: yeah, doing it with this way: https://github.com/clojure-liberator/liberator/issues/71#issuecomment-54992507
08:35dysfuninteresting. that works similarly to something i've written (and not yet released)
08:36dysfun(polaris)
08:36justin_smithdysfun: that's a good sign I think :)
08:36dysfunif two different people come up with similar looking things, it's generally the case
08:37justin_smithdysfun: polaris was made by three of us, after a lot of arguing and speculating and heavy collective design work
08:37justin_smith(based on limitations in our previous ad-hoc solution)
08:38dysfunarguing is totally necessary
08:39justin_smithdysfun: indeed, it's good if you can keep things functional and avoid side effects on the arguments too :)
08:40dysfunwell a lot of stuff i've been doing really has been making stuff declarative with data
08:40dysfunfor various reasons
08:40justin_smithdysfun: yup, I was attempting a subtle pun
08:40justin_smithbut yes
08:41dysfunyes, i chose to save you the embarrassment :)
08:41justin_smithhaha
08:41justin_smith(side effects in our case being any damage to the professional or friend relationship of course)
08:42mavbozojustin_smith: hohoho
08:42dysfunyes. having just gone into business with two friends, this is going to be entertaining
08:43dysfuni can't count how many people have told me not to do this. but i also realised that there was basically no other way of getting the thing off the ground without sacrificing things i didn't want to sacrifice
08:48mavbozopandeiro: i guess there's no easy way because in that link you gave there's a statement that says liberator use clojure.data.json but they do not parametrize data.json's :value-fn
08:49pandeiromavbozo: yep that's the issue; extending the type is easy enough
09:00justin_smithpandeiro: you can extend clojure.data.json by extending a type to the JSONWriter protocol
09:01justin_smithhttps://github.com/clojure/data.json/blob/master/src/main/clojure/clojure/data/json.clj#L395
09:01justin_smithsee how it is done for the built in types, but you can do this from your own namespace for whichever types you like
09:02justin_smith(btw this is what I like about protocols)
09:02pandeirojustin_smith: yeah the link i posted does exactly that
09:03pandeiroi admit i never use protocols or types/records so it feels foreign to me
09:03pandeirobut this seems like the ideal use case
09:03justin_smithalso, instead of (str date) you could use (bean date)
09:03justin_smith,(bean (java.util.Date.))
09:03clojurebot{:day 2, :date 28, :time 1414501376263, :month 9, :seconds 56, ...}
09:03pandeiroha nice
09:04justin_smiththat uses reflection though
09:04justin_smithcheaper to grab the fields you care about
09:05justin_smithpandeiro: I saw your question regarding an easy way, but did not see that link before
09:05justin_smithpandeiro: but to me what's in that link *does* look like an easy way :)
09:05pandeirojustin_smith: np thanks for the explanation
09:05pandeiroi hadn't found that link when i asked :)
09:07justin_smithpandeiro: it's all coming together, perhaps I should have some coffee
09:08kungiWhy is Java so meh! :-(
09:08kungiI start to get a real aversion against this builder pattern.
09:11borkdudeI'm doing java right now, and I feel so bored with ti
09:11CookedGryphonjustin_smith: be careful with that bean, notice the month
09:11kungiborkdude: ti?
09:11borkdudeit
09:11kungiborkdude: I thought ti was some kind of elaborate Java thingy :-)
09:12borkdudeespecially the style that every domain object should have its own class I find perverted
09:12borkdudeonly as a layer between the database, while not much is happining in these things
09:15mavbozoborkdude: I just did some PHP, well, most of my work is in PHP. Same here.
09:15kungiWhy do i have to politely ask a config class to give me a ConfigBuilder which then builds the config which I can then give the Class I want to instantiate ...
09:20dysfunbecause someone wanted to write way more code than was necessary
09:21kungidysfun: maybe he was payed by lines of code?
09:21dysfuni knew a manager that judged progress by numbers of +s in svn diffs per week
09:22dysfunif anything, i'd be inclined to judge it by net negative lines of code without breaking tests
09:22kungidysfun: I know at least one person who would have shown him the middle finger and went away
09:22dysfunyeah, i did :)
09:26kungiI am currently trying to use metrics-clojure with riemann. I found a riemann reporter and some code showing how it's done. Now this riemann reporter is an AbstractPollingReporter and not the needed ScheduledReporter.
09:38clgvdysfun: haha, I encountered something similar where I had to implement a scheduler, it associated configuration object and an associated provider class. in clojure a similar solution just involved one function that needed to be passed as argument
09:39joshhead,(= "(some code)" (str '(some code)))
09:39clojurebottrue
09:39joshhead(= "(some code)" (str '(some code))) This is true in simple cases but not generally. Why?
09:39joshheadTagged literals, printing issues?
09:40stuartsierrajoshhead: Could be any number of things.
09:40stuartsierrawhitespace, nonprintable objects, ...
09:41joshheadWhitespace is definitely going to cause a difference yeah. But I don't think that will matter for Datomic transaction fns (which is where I wished this would work)
09:41stuartsierracompiled functions aren't printable
09:42joshheadHmm like datomic.api/q for example?
09:43stuartsierraAny function. Once it's compiled, it's going to print like #<datomic.api.q__4224907>
09:45joshheadMaybe I'm confused about the semantics of the single quote. If I quote a list that is a function call, won't I just get a symbol at the head of the list and not the function itself?
09:45stuartsierrayes you will
09:46stuartsierraget a symbol in a list, that is
09:46joshheadHmm okay. If I quote something with a tagged literal, does the handler function get called before it gets quoted?
09:47stuartsierraYes
09:48stuartsierraTagged literals are a mess. Don't use them in code if you can avoid it.
09:49joshheadstuartsierra would you recommend avoiding #db/fn literals too?
09:49stuartsierrajoshhead: yes, in code (.clj) files.
09:49stuartsierraUse d/function or whatever it's called.
09:50joshheadall right
09:50joshheadas for the code in tx fn's, I guess string literals are the way to go? Is there an emacs plugin or something to make paredit and indenting work inside strings?
09:51stuartsierrajoshhead: Clojure code can be quoted
09:51joshheadoh d/function will just accept quoted code instead of a string?
09:52joshhead"a string or data containing the code of the body" I guess so
09:52stuartsierrayes, quoted string
09:52stuartsierraI mean quoted literal code
09:52stuartsierrasingle-quote
09:53joshheadOK cool that is way more convenient than editing strings. Thanks for the tips
10:11agarmanhow do I force (into-array ...) to use a base type?
10:12clgvagarman: what is a "base type"?
10:12agarmanI'm trying (into-array [^Base a ^Base b]), but that doesn't seem to be working
10:12agarmanclgv: in this case my base type is OtpErlangObject
10:12agarmanclgv: sub-types are OtpErlangTuple & OtpErlangPid
10:13clgvagarman: why does that matter? for primitives it makes a difference for anything derived from object it doesnt
10:13Bronsaagarman: into-array has a 2 arg arity
10:13Bronsa(into-array Base [a b])
10:13Bronsa,(class (into-array Object ["foo"]))
10:13clojurebot[Ljava.lang.Object;
10:13Bronsa,(class (into-array ["foo"]))
10:13clojurebot[Ljava.lang.String;
10:13clgvBronsa: but does that really make any difference for objects?
10:14agarmanBronsa: ty ty
10:14agarman(inc Bronsa)
10:14lazybot⇒ 64
10:14clgvpower of two :D
10:15Bronsaclgv: I guess if your array is heterogeneous you need that
10:15borkdudewhy is it that some developers are fluent in server side languages, but find CSS difficult and are bad at it?
10:15Bronsa,(into-array ["foo" 1])
10:15clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: array element type mismatch>
10:15stuartsierracsgv: Java arrays are strongly-typed
10:15Bronsa,(into-array Object ["foo" 1])
10:15clojurebot#<Object[] [Ljava.lang.Object;@548719>
10:16clgv,(into-array Object [[] "foo"])
10:16clojurebot#<Object[] [Ljava.lang.Object;@c087be>
10:17clgv,(into-array Object [[] {}])
10:17clojurebot#<Object[] [Ljava.lang.Object;@1829097>
10:17clgvBronsa: it seems arrays of strings are special, right?
10:17Bronsano?
10:17clojurebotno is tufflax: there was a question somewhere in there, the answer
10:17Bronsa,(into-array [1 1])
10:17clojurebot#<Long[] [Ljava.lang.Long;@a19cc5>
10:17Bronsa,(into-array [[] []])
10:17clojurebot#<PersistentVector[] [Lclojure.lang.PersistentVector;@e44dd3>
10:18Bronsaclgv: if you don't give the array type to into-array, it will use the class of the first element
10:18clgvBronsa: so why is it able to use object for the case with a vector and a hashmap?
10:18Bronsaclgv: because they are both Objects, while an hashmap is not a persistentvector
10:18Bronsa,(into-array clojure.lang.IPersistentCollection [{} []])
10:18clojurebot#<IPersistentCollection[] [Lclojure.lang.IPersistentCollection;@1dbbaab>
10:19Bronsayou just need a superclass
10:19clgvBronsa: yeah, but if it looks only at the first element it should choose the vector class
10:19Bronsaclgv: but you explicitely gave Object as the array class
10:20clgvBronsa: damn, copied the wrong one. sorry
10:20clgv,(into-array [[] {}])
10:20clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: array element type mismatch>
10:20clgvah, that's what I wanted to know
10:21andrewhrborkdude: I guess, because browsers are inconsistent? Not that languages are much better though
11:16jonathanjhrm, what's a concise way of taking the last item from a vector?
11:17CookedGryphonpeek
11:17CookedGryphonand most importantly, never ever last
11:17jonathanji was going to say, last seems kind of not good
11:17jonathanjis there not something that combines peek and pop?
11:17borkdudeafter my CSS question, I just discovered this podcast : http://dotnetrocks.com/default.aspx?showNum=1053
11:18Bronsajonathanj: no but you can use (juxt pop peek)
11:19CookedGryphonjonathanj: why would you want to combine peek and pop? Are you thinking of destructure-last sorts of things?
11:20jonathanjCookedGryphon: i want to take the last item from a vector, prepend ":" to it and put it back in the vector
11:20Bronsajonathanj: you can use assoc then
11:20clgvjonathanj: peek, pop, conj
11:20CookedGryphonsounds more like you want to (update (count coll) (prepend :))
11:20clgvor assoc ;)
11:20Bronsa(assoc [1 2 3] 2 4)
11:20Bronsa,(assoc [1 2 3] 2 4)
11:20clojurebot[1 2 4]
11:21clgvget + assoc that is
11:21CookedGryphonoh wait, but only if you have clojure 1.7, otherwise you won't have update
11:21Bronsaah yeah, update is definitely better in this case
11:21Bronsa(inc CookedGryphon)
11:21lazybot⇒ 4
11:21jonathanjhrm, too bad i can't specify a negative index
11:21BronsaCookedGryphon: well update-in works just as fine
11:22CookedGryphonyep, only a little clunkier
11:22Bronsa,(let [v [1 2 3]] (update-in v [(count v)] inc))
11:22clojurebot#<NullPointerException java.lang.NullPointerException>
11:22Bronsa:(
11:22Bronsa,(let [v [1 2 3]] (update-in v [(dec (count v))] inc))
11:22clojurebot[1 2 4]
11:22jonathanj(dec (count xs)) is kind of yuck
11:23CookedGryphon(defn update-last [coll f & args] (apply update-in coll [(dec (count coll))] f args))
11:24CookedGryphonit's a pity nth doesn't support negative indices
11:25CookedGryphonit's something I really like in python
11:25Bronsayeah
11:27jonathanjis there a destructuring syntax for the last item in a vector?
11:27CookedGryphonnope
11:27CookedGryphonit's been discussed a few times, but generally agreed would get a bit clunky and magical
11:39the_dankogot a little destructuring question, fellows. motivated by something in brave clojure
11:39the_danko(defn my-first
11:39the_danko [[first-thing]] ; Notice that first-thing is within a vector
11:39the_danko first-thing)
11:39the_danko=> (var user/my-first)
11:39the_danko(my-first #{"oven" "bike" "waraxe"})
11:39the_dankoUnsupportedOperationException nth not supported on this type: PersistentHashSet clojure.lang.RT.nthFrom (RT.java:857)
11:40the_dankoso this destructuring doesn't work on a set it seems?
11:41stuartsierrathe_danko: that's correct, sequential destructuring doesn't work on non-sequential things like sets.
11:42the_dankostuartsierra: thanks!
11:42stuartsierraYou can call `seq` on the set to get a sequential thing, or just call `first` (which calls `seq`).
11:42CookedGryphonyou could call seq on it to make it sequential, but you will get an unpredictable element out of it
11:42clgvis there something like (gen/subset (range 10)) in test.check?
11:43clgvultimately, I need a vector of different elements in "random" order from a given list/set of values
11:44puredangeryou can use gen/bind and gen/return to creators generators out of generators while applying arbitrary functions
11:45stuartsierraOr shuffle and take.
11:45reiddraperclgv: there is a 'shuffle' generator on test.check master, but not subset
11:45clgvreiddraper: subset would be quite handy as well, since it is pretty general
11:45reiddraperclgv: subset should be pretty simple, there's an explanation of writing one with Erlang quickcheck here: http://roberto-aloi.com/erlang/notes-on-erlang-quickcheck/
11:45CookedGryphonor perhaps sample, which could work on vectors too
11:45reiddraperclgv: but I agree it'd be handy
11:46dagda1_is this the right syntax for querySelector in clojurescript (.querySelector js/document "btn.btn-primary")
11:50pandeiroHow can I deal with this error: #<CompilerException java.lang.IllegalStateException: var: #'ring.middleware.file-info/make-http-format is not public, compiling:(clj_webjars.clj:32:12)>
11:50pandeirodagda1_: yes correct syntax
12:06sdegutisQuestion of the day http://stackoverflow.com/questions/7295016/clojure-method-missing
12:09clgvsdegutis: hehe
12:09sdegutisI was wondering it myself.
12:09sdegutisSo I googled it and found the answer.
12:09clgvsdegutis: well defmulti comes quite close ;)
12:10clgvsdegutis: what did you find?
12:10sdegutisThat in Clojure you use macros instead of method_missing.
12:10sdegutisBecause Clojure doesn't have a concept of "objects" or "classes".
12:11sdegutisExcept things like deftype.
12:11sdegutisAnd defmulti and defrecord.
12:11clgvhow'd you use a macro with similar semantic?
12:11sdegutisI don't know yet :)
12:11sdegutisI'm still learning how to do Clojure well.
12:11sdegutisIdiomatic Clojure is an ever-evolving thing, a moving target.
12:11technomancylifehack: doing clojure well does not involve method_missing functionality.
12:12technomancys/clojure/programming/
12:12clgvhehe
12:12sdegutistechnomancy: you can't do that my sentence is immutable
12:12sdegutisAlso this is good for learning http://stackoverflow.com/questions/11662084/why-does-clojure-distinguish-between-symbols-and-vars
12:15sdegutisIs dynamic function generation via macros a good practice?
12:18nooniansdegutis: i think it depends on the use case and how magical the macro is. defrecord defines new constructor fns and such for the record type defined for example
12:18sdegutisSo then what is the rule of thumb for deciding when "it depends" applies to a given case?
12:19kenrestivohuh. i reach for function composition first... and it's been a few years since i needed to reach past that to macros, unless the library i'm dealing with is already macro-heavy and the only way around is to out-macro the macros.
12:19arrdemmacros are more or less only for userland compilers and def generation that cannot be achieved by function composition or partial application
12:19stuartsierrasdegutis: Always use the fewest, and the simplest, tools available to solve any problem.
12:20sdegutisstuartsierra: But that excludes the use of macros, incorrect?
12:20arrdemsdegutis: no, it means that macros are appropriate if and only if they are the lowest power tool for the job
12:20sdegutisOh.
12:20arrdemsdegutis: if they are not the lowest power tool, use a lower power one
12:21sdegutisI am anticipating using a lot more macros soon. That is why I wonder.
12:21sdegutisRight now we use almost no macros (except those that Compojure come with).
12:21stuartsierraIn roughly *decreasing* order of simplicity: data structures, functions, protocols, multimethods, macros.
12:21sdegutisThat's a good chart stuartsierra. You should tweet it.
12:21stuartsierrasdegutis: it's Stuart Halloway's hierarchy, more or less
12:22sdegutisstuartsierra: Whatever, if you don't, I will. And I'll take credit.
12:22sdegutis(I mean, assuming we don't definitively know who said it.)
12:22stuartsierraSheesh, what is this, publication by blackmail?
12:22sdegutisI don't know what that means :)
12:23stuartsierraneither do I
12:23sdegutisAnyway, I'm starting to not like the explicitness of a typical Compojure app.
12:23sdegutisI'm starting to think we should do something more magical like "convention over configuration" and "automatic stuff".
12:24sdegutisWow, I think every Heroku app is down.
12:24noonianlol
12:24sdegutishttp://speclj.com/ http://joodoweb.com/ http://joyofclojure.com/
12:24technomancynot the cool ones https://syme.herokuapp.com/
12:24sdegutisOh, ok.
12:24kenrestivoinsider trading!
12:24dbaschthis is up too http://dalai.herokuapp.com/
12:25wink3 with own domains vs 2 with subdomains
12:25kenrestivook, now is the time to hype up your not-down heroku app.
12:25winkpoint not proven
12:25winkeverything is a dns problem until proven otherwise
12:26nooniansdegutis: Aaron Bedra's talk 'Ready Set Clojure!' might be interesting to you. He walks through writing a simple redis client lib that used macros to generate the fns. At the end he goes a little overboard so you might get a feel for why you might choose to use macros
12:26sdegutishttp://joodoweb.herokuapp.com/ works
12:26sdegutisThis is a good thing: http://joodoweb.herokuapp.com/tutorial/basics
12:26winkapparently I can mind read
12:27sdegutisnoonian: Isn't he a Rubyist?
12:27eredjoyofclojure is back
12:27sdegutisNot for me. http://joyofclojure.com/
12:28nooniansdegutis: i don't know his background but it wouldn't suprise me; a lot of clojurists come from a ruby background.
12:28sdegutisOh no!
12:28sdegutisWell I suppose that's fine.
12:29sdegutisI came from Python.
12:29eredmaybe there's some weird routing thing going on
12:29eredjoodo's site is down for me
12:29sdegutisI like the magical implicitness this library uses, very similar to Rails: http://joodoweb.herokuapp.com/tutorial/basics
12:29eredmaybe it's heroku dns fail
12:29technomancyjoy of clojure is on the ancient deprecated stack =\
12:29eredi don't mind compojure personally because in other languages i like web frameworks like sinatra or flask
12:29eredah
12:30winkthe joy of legacy
12:30sdegutistechnomancy: it's deprecated!?
12:30sdegutistechnomancy: I was just going to buypurchas it.
12:30winkdidn't he say "stack"?
12:30winkas in "on heroku"?
12:30eredthe heroku stack, not the book
12:30eredif i read that right
12:30sdegutisI thought it was more about concepts than APIs, and thus is generally still applicable!?
12:31sdegutisOh.
12:31sdegutisYes, that makes the sense.
12:31winksdegutis: and there should be a 2nd release yea
12:31winkof the book
12:31winkblargh :)
12:31winks,release,edition,. hell. time to go home
12:31sdegutisGood night wink.
12:31eredif joyofclojure.com doesn't work for you try http://joyofclojure.herokuapp.com/
12:31sdegutisered: I heard there's going to be a second addition.
12:32sdegutisSo I'll hold out.
12:32eredit should be out already
12:32sdegutisOh.
12:32sdegutisWith transducers?
12:32eredhttp://www.manning.com/fogus2/
12:32eredthis is the 2nd edition
12:32winkwtf @ naminh
12:32technomancyjust emailed chouser offering to help
12:33technomancysince he doesn't hang out on freenode any more =(
12:33eredmy copy doesn't mention transducers
12:33winkapparently only one guy named smith wrote one manning book.
12:33eredwink: maybe it's like the WGA where they make people change their name if there are collisions? :3
12:33sdegutisAlso, https://twitter.com/_sdegutis/status/527135858017984512
12:33winkered: hehe
12:34eredsdegutis: i forgot where i first read this, but i only ever use macros for 3 cases - with-foo, do-foo, create-foo
12:34sdegutisHmm.
12:34eredwhere in the create-foo case it's to make like 5 related objects
12:34nooniandidn't stuartsierra say that in this chat?
12:34sdegutisI want to start using Macros to design my routing system.
12:35sdegutisI think the "composability" style is not working out as greatly as first imagined.
12:35kenrestivosdegutis: let no one's work evade your eyes, plagiarize, plagiarize
12:35technomancydon't start with macros =(
12:35winka lot of people have an irrational hatred for macros
12:35sdegutiswink: I can see that already!
12:35noonianyeah, functions are awesome
12:35technomancystart with functions and tough it out for a while so you have a better appreciation for where the pain points are and how macros can help you
12:35kenrestivowink: i didn't until i got stuck using a library that was macro heavy
12:35winkI'd love to see something like korma without a macro
12:36sdegutisThe primary point of macros is to reduce the number of times you have to type (fn [] ...)
12:36sdegutisThat's what I read.
12:36winkwrite and show me ;)
12:36eredimo you just know when you need a macro
12:36eredif that makes any sense
12:36sdegutistechnomancy: I think I'm quite experienced enough with functions by now to know how to use Macros.
12:36sdegutisI've used Functions for quite a few years, even Clojure ones.
12:36winkhehe
12:36kenrestivosomeone explained that macros were for creating custom syntax. i should tweet that
12:36technomancysdegutis: you're not experienced in the domain of writing this library that doesn't exist yet though.
12:36winksdegutis: wow, have you ever looked into methods?
12:37technomancyneither am I, believe it or not.
12:37winkkenrestivo: yeah, that's where I don't see a way arounf
12:37nooniani don't usually look to write a macro until i've written the code i want without macros and just want to clean up boilerplate and make it more concise
12:37sdegutistechnomancy: How are you so confident?
12:37sdegutiswink: Yes, I used to use method_missing like a pro.
12:38winksdegutis: wow, that's brave :)
12:40technomancycall it a hunch
12:41sdegutisWe just learned about that on Word Girl. The word you're looking for is "intuition"
12:45stompyjI wonder how much money method_missing cost businesses
12:45sdegutisNot as much as null
12:45stompyjduring its reign of terror, in the early rails days
12:45sdegutisWhich Java still has! :)
12:46sdegutisIs there a language that doesn't have nil problems?
12:46technomancylots
12:46eredrust
12:46eredhaskell
12:46eredanything with an option type
12:46technomancyracket
12:46technomancyerlang
12:46eredi think F# has option types too
12:46technomancyjava has option types
12:46technomancythat's not enough to fix the problem by a long shot
12:46technomancyyou have to actually use them =)
12:47eredjava's option types don't work well iirc
12:47eredat least the ones in guava
12:47eredthey don't play nice with flatmap, so i'm told
12:47technomancythey come with the jdk now
12:47eredkeep forgetting java 8 is a thing
12:47eredsince iirc a huge chunk of the world is stuck on 6
12:48sdegutisso which one?
12:48sdegutisi would love to use java
12:48sdegutisive never written it before. it sounds like a lot of fun.
12:49eredschema has option types now too but iirc schema's validations are technically optional
12:49eredby which i mean only run when you tell them to run
12:49eredat least when i remember last using them
12:49noonianyeah i think you can annotate the fns so they always run or call them with validation turned on when you want it
12:49eredyeah that sounds right
12:50eredi want to say it has a performance hit is why it's not on by default
12:50sdegutisIf you were to write a brand new web app today, what language would you choose?
12:51technomancyHTML
12:51sdegutisNo I mean a dynamic website, the back-end.
12:51sdegutisSome examples are: Ruby, Python, Clojure.
12:51technomancyDHTML
12:51the_dankoha
12:51sdegutisNo I mean ones that still exist.
12:51technomancythe D stands for Dynamic, you know
12:51eredCGI? :3
12:51the_dankohaha
12:51sdegutisCGI is an interface not a language.
12:51nooniani'm going to go out on a limb here and say a lot of people here might choose clojure
12:51sdegutisThis isn't that hard, people.
12:52the_dankohaha
12:52sdegutisnoonian: you know what they say about assuming
12:52sdegutis"don't"
12:52nooniani heard it was the brother of all fuckups or something
12:53sdegutiswat
12:53sdegutisecho -n '' > quine && chmod +x quine && ./quine
12:53lazybot-n '' > quine && chmod +x quine && ./quine
12:53nathan7that's not much of a quine, is it
12:53nooniananyway, a lot of dynamic sites these days are single page js apps talking to api servers
12:53mavbozois HTML a programming language?
12:53sdegutis$ ./quine > quine && ./quine
12:54mavbozois DHTML a programming language?
12:54pandeiroanyone know why a lib would produce this when I try to require it: #<CompilerException java.lang.IllegalStateException: var: #'ring.middleware.file-info/make-http-format is not public, compiling:(clj_webjars.clj:32:12)>
12:55mavbozopandeiro: make-http-format is private?
12:55the_dankoi am sorry to interrupt the HTML merriment. i do have a quick question if anyone is feeling game.
12:55the_danko(defn p [x] (println x))
12:55the_danko=> (var user/p)
12:55the_danko(map p [1 2 3])
12:55the_danko=> (1 2 3 nil nil nil)
12:55the_dankowhy is there a 1 2 3 in the return from the map?
12:56the_dankoi thought that the function p there should always return nil
12:56the_dankowhy does the println go into the returned list?
12:56pandeiromavbozo: it is private; but that doesn't matter when i run a repl from the lib's project; and i thought you could use fully qualified vars even if not public
12:57eredfunctions you use with map shouldn't have side effects
12:57eredalso because println returns nil
12:57eredhmm
12:57eredhang on i'm confused now
12:57bostonaholicthe_danko: which version of clojure?
12:57noonianthe_danko: the 1 2 3 just happens to be printing as the repl is printing the return value so it looks like its in the seq returned
12:58the_danko(def r (map p [1 2 3])
12:58the_danko )
12:58the_danko=> (var user/r)
12:58the_danko(println r)
12:58the_danko(1
12:58the_danko2
12:58the_danko3
12:58the_dankonil nil nil
12:58eredwhat are you trying to do? print each element of the list on its own line?
12:58the_dankobostanaholic: 1.6
12:59the_dankoered: i am just trying to learn what is happening here. i stumbled into this example and realized it means i don't know how map works.
12:59the_dankoered: ok, so i am trying to learn clojure and how map works is the answer.
12:59eredi'm not sure if this explains it entirely (someone else feel free to jump in), but since println has side effects you don't want to use map
12:59eredinstead you should use doseq
13:00noonianthe prints will happen when the map is realized, which at the repl is immediately since the repl is trying to print the return value
13:01nooniantry (def res (map p [1 2 3])) then (do res nil)
13:01noonianyou should just see 1 2 3 nil or something
13:01the_dankonoonian: AHH! yes. (count r) is 3!
13:02the_dankonoonian: thanks!
13:02noonianthe_danko: np
13:02pandeirowhy does accessing a fully namespaced private var cause an IllegalStateException when a project is required but not when running a repl within the project itself?
13:06nooniani just don't use private anymore :P
13:10mavbozopandeiro: what do you mean by "when a project is required"?
13:10bacon1989Does anyone know of some good defmacro exercises I could do to get more familiar with macros?
13:10mavbozopandeiro: is it '(require '[ring.middleware.file-info :refer [make-http-format]])'?
13:25stompyjbacon1989: Why do you need exercises? You mean with the semantics of how they work?
13:27stompyjDoes anyone here use kafka in clojure? If so, what client are you using? All of them seem a bit out-of-data
13:27stompyjdate*
13:36mindbender1Is there a function that evaluates `value expr` pairs and returns the first truthy value of expr?
13:36justin_smithmindbender1: cond?
13:36noonianmindbender1: cond
13:37justin_smith,(cond false 0 nil 1 true 2)
13:37clojurebot2
13:37noonian,(cond nil :falsey :truthy :truthy)
13:37clojurebot:truthy
13:38mindbender1I want (cond :truthy :falsy :falsy :truthy) => :truthy
13:38justin_smiththan reverse the args?
13:38hyPiRion2[3~
13:38justin_smith*then
13:39Bronsamindbender1: that doesn't make much sense? what would the expr part be there for then?
13:39justin_smithmindbender1: wait - what's the logic there?
13:39mindbender1I am trying to port a js code but it doesn;t translate easily into reversing.
13:40sdegutis,CLOJURE_VERSION
13:40clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: CLOJURE_VERSION in this context, compiling:(NO_SOURCE_PATH:0:0)>
13:40mindbender1e.g....
13:40Bronsa,*clojure-version*
13:40clojurebot{:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}
13:40sdegutis,*clojure-version*
13:40clojurebot{:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}
13:40Bronsa,(clojure-version)
13:40clojurebot"1.7.0-master-SNAPSHOT"
13:40sdegutis,(map identity)
13:40clojurebot#<core$map$fn__4341 clojure.core$map$fn__4341@1eb41e5>
13:40sdegutisWHOA LOOK A TRANSDUCER
13:41noonianmindbender1: everything in clojure is truthy except nil and false
13:41sdegutismindbender1: Clojure is basically Ruby
13:41Bronsasdegutis: what?
13:42sdegutisBronsa: nil and false
13:42sdegutis(and nil false)
13:42noonianSgeo: thems fightin words!
13:42Bronsasdegutis: and that.. makes it "basically Ruby"?
13:42sdegutisnoonian: whoa dude, calm down.. I'm over here
13:42nooniansdegutis: opps :P
13:42sdegutisYou're on the roll today my friend.
13:42nooniancan't type this morning
13:43sdegutislol the guy who wrote Dash said I was "on the roll" and I was like "lol wat"
13:43sdegutisI had to break the news that it's "on a roll" and he took it rather well.
13:44justin_smithsdegutis: "on the roll" means like you are like part of the breakfast food conspiracy
13:46noonianim on the english muffin this morning
13:47sdegutishi
13:48mindbender1switch (e.keyCode) {case "esc": if true {return true;} else {return false} break; case "end": if true {return true;} else {return false;} break; }
13:48mindbender1something like that in clojure?
13:49mindbender1the return value of the expression determines if it continues
13:50noonian,(let [val "foo"] (cond (= val "bar") "it was bar" (= val "foo") "it was foo" :else nil))
13:50clojurebot"it was foo"
13:51noonianthere are less general ways to do this also, case works if you know your switch values at compile time, and condp if you always use the same predicate
13:51mindbender1noonian: sorry the exprs are different for each case
13:52noonian,(let [val "foo"] (cond (#"ar" val) "it contains 'ar'" (= val "foo") "the val is foo"))
13:52clojurebot#<ClassCastException java.lang.ClassCastException: java.util.regex.Pattern cannot be cast to clojure.lang.IFn>
13:52noonian,(let [val "foo"] (cond (re-find #"ar" val) "it contains 'ar'" (= val "foo") "the val is foo"))
13:52clojurebot"the val is foo"
13:52noonianmindbender1: i think you can do everything you want with cond
13:53justin_smithmindbender1: that's just a case, where the right hand side of each case is an if
13:53justin_smithexactly like in js
13:53justin_smith(case "esc" (if true true false) "end" (if true true false))
13:53justin_smithis literally that code
13:53mindbender1justin_smith: yes and the right hand determines if it keeps going further.
13:54justin_smitherr (case e.keyCode ...)
13:54justin_smithno, the breaks happen after the if
13:54justin_smithin that code
13:54justin_smiththey apply regardless of branch
13:56noonianbut you can have arbitrary code in the right hand side of cond, you might want to break it into helper functions to keep it readable though
13:56justin_smithmindbender1: it is true that we don't have a convenient version of case with fallthrough and early return
13:56noonianyou can usually refactor that into the top level cond though
13:56justin_smithmindbender1: but you can replace return with a promise / deliver combo
13:56justin_smithand check the value of the promise at the end
13:59justin_smith,(let [return (promise)] (if false (deliver return 0)) (if nil (deliver return 1)) (if true (deliver return 2)) @return)
13:59clojurebot2
13:59justin_smithnot as pretty as case with fallthrough / return statements, but capable of the same semantics
14:03justin_smith,(let [return (promise)] (if false (deliver return 0)) (if nil (deliver return 1)) (if true (deliver return 2)) (if :redundant (deliver return 3)) @return) ; for good measure
14:03clojurebot2
14:25pandeiromavbozo: no, the lib in question is clj-webjars, which uses the aforementioned private fn
14:25pandeirowhen i run a repl in the clj-webjars project, it compiles
14:26pandeirowhen i require the lib from another project, it doesn't
14:29justin_smithpandeiro: do you need to be able to use that private var from another project?
14:29pandeirojustin_smith: no, a third party lib is using it
14:29pandeiroit seems that it works unless ring (owner of private fn) is also included in deps
14:30justin_smithoh - so both the definition and usage are both in 3rd party tools
14:30justin_smithweird
14:30justin_smithpandeiro: perhaps you get a different version of the code that makes the var private if you explicitly depend on ring?
14:30pandeirojustin_smith: just tested that
14:31pandeiroclj-webjars depends on ring 1.3.0; even using that version as a dep in my project causes clj-webjars to fail to compile
14:31pandeiromaybe i need exclusions
14:32the_dankoyo fellas, got a little quandry.
14:32the_danko(defn my-partial
14:32the_danko [partialized-fn & args]
14:32the_danko (fn [& more-args]
14:32the_danko (apply partialized-fn (into args more-args))))
14:32the_dankook so i know that into works differently if the first argument is a list or a vector
14:32justin_smiththe_danko: that's gonna screw up the arg order
14:32the_dankojustin_smith: just what i am asking!
14:32justin_smithunless you want more-args reversed on the front of the args
14:33justin_smith& more-args makes a list, that puts things on the front with into
14:33lazybotjava.lang.RuntimeException: Unable to resolve symbol: more-args in this context
14:33pandeiroexclusions doesn't solve it...
14:33pandeirolesson here is: don't use a lib that uses other lib's private stuff?
14:33the_dankojustin_smith: so this is an example from brave clojure. ok so doesn't the type of the return from the into statement depend on the type of args?
14:34the_dankojustin_smith: not more-args?
14:34the_dankojustin_smith: my question is the same as your issue. i can't figure out how the order works.
14:34justin_smiththe_danko: ahh, right
14:34justin_smithargs will also be a list
14:34justin_smiththe order will be each arg appended to the front of the initial
14:34the_dankojustin_smith: so here args is a rest-param? correct? is that the correct term?
14:35justin_smiththat is what into does with lists
14:35justin_smiththe_danko: yes
14:35justin_smith,(into '(0 1 2) 3 4 5)
14:35clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: core/into>
14:35justin_smith,(into '(0 1 2) [3 4 5])
14:35clojurebot(5 4 3 0 1 ...)
14:36justin_smiththe_danko: & args creates a list, into adds each element from mor-args to the front of args
14:37sdegutisIf you use a font that came with your OS in making an app icon for your closed-source commercial Clojure app, do you have to pay for licensing or something?
14:37the_dankojustin_smith: sweet, so rest-params is always a list?
14:37the_dankojustin_smith: i'll email mr brave clojure about this example
14:37justin_smith,((fn [a & r] (class r)) (range))
14:37clojurebotnil
14:37justin_smithhmm
14:37llasramjustin_smith: `apply`?
14:37justin_smith,((fn [a & r] (class r)) 1 2 3 4 5 6)
14:37clojurebotclojure.lang.ArraySeq
14:38justin_smiththe_danko: technically an ArraySeq, but it has the same conj and into behavior as a list
14:39llasram,(apply (class %&) (range))
14:39clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: %& in this context, compiling:(NO_SOURCE_PATH:0:0)>
14:39llasram,(apply #(class %&) (range))
14:39clojurebotclojure.lang.ChunkedCons
14:39llasramIt can be many things
14:39justin_smithllasram: good point
14:39llasram,(apply #(class %&) [1 2 3])
14:39clojurebotclojure.lang.PersistentVector$ChunkedSeq
14:39justin_smithllasram: many things that all have the conj behavior of list :)
14:39llasramfair
14:40the_dankojustin_smith: llasrma: thanks guys. very helpful!
14:47bacon1989stompyj: kinda late, but I just like exercises creating macros. I suppose I could just take any clojure.core macros and try and reimplement them my self
14:47stompyjbacon1989: fair enough
14:47bacon1989i'm going to a point in my project where I think a few macros would simplify things creatly
14:47mdrogalisbacon1989: Go implement `let` :)
14:48justin_smithbacon1989: use macros to create a C style case statement with fallthrough if you don't invoke (break)
14:48mdrogalisEr, I think it was the destructuring code actually. It's pretty wild.
14:48bacon1989sounds interesting
14:49bacon1989yeah, idk about 'let', i'd assume that would be a monster
14:49mdrogalisIt happens to be a function https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L4045
14:49justin_smithlet* is doing the binding part though :)
14:49bacon1989yikes
14:50justin_smith,(special-symbol? 'let*)
14:50clojurebottrue
14:58justin_smithmindbender1: a more general approach to your translating case question, btw https://www.refheap.com/92434
15:00mindbender1justin_smith: I'm checking it.
15:00justin_smithmindbender1: just updated again, refresh
15:01mindbender1okay
15:01justin_smithmindbender1: you could have any number of those (if-not (realized? return) ...) blocks for further logic that should be skipped if return has been delivered but run otherwise
15:03justin_smithmindbender1: of course there is always a clean idiomatic solution, but the possible advantage here is that the code would linearly follow the same sequence read top to bottom
15:04amalloybacon1989: re trying to implement 'let: of course doing all the destructuring from scratch is a nightmare, but you don't have to: you can define let as a macro that expands into fn, which does the same destructuring
15:05puredangerthere is of course the destructure function
15:05amalloythe reason it's a cool exercise is it reminds you that fn is all you really need; if you had fn and macros, you could build all of lisp
15:06TimMcAnd of course macros could be avoided by passing lambdas.
15:06TimMc*most macros, whoops
15:06amalloypuredanger: it's pretty rare to need that though, i'd think. i've only used it once
15:06puredangeryup
15:07kanobe_`
15:07hiredmanI've been fiddling with a lisp interpreter in emacs lisp (to get csp style concurrency, to avoid callbacks, to write an nrepl client, to shave a yak) they are fun
15:14amalloymy one use of destructure, if anyone is curious, since it came up: https://github.com/flatland/useful/blob/develop/src/flatland/useful/utils.clj#L224-L253
15:14bodie_anyone have a preferred testing kit for clojurescript? I was looking at maybe jasmine-cljs or specljs
15:14justin_smithamalloy: very cool
15:15bodie_specifically I'm working with Om so I don't know if there's something better or worse suited to that
15:15bodie_I'm kinda new to cljs, so any thoughts are welcome :)
15:15amalloyjustin_smith: version one only supported delaying symbol bindings; at some point i realized i can use destructure to reduce the destructuring cases to N symbol bindings
15:16justin_smithlooks like a very useful macro
15:17gfredericksCSP == "Continuation Stassing Pyle"
15:18hiredmancontinuation stashing program maybe
15:18bodie_continuation style passing
15:18bodie_:P
15:19hiredmanwhich is basically what it is, to "block" on putting to a channel you basically stash a continuation of the program in the channel, and when someone comes along and takes it restarts the continuation
15:20hiredmancsp as in the core.async kind of stuff
15:29bacon1989amalloy: thanks, maybe i'll try and reimplement let, and read through the oreilly macros section some more
15:55sdegutisWhat's the prevaling concurrent philosophy on templating engines in Clojure?
15:55sdegutisIs Hiccup still the champain?
15:55justin_smithconcurrent philosophy?
15:55sdegutisI mean modern.
15:56amalloycontemporary, perhaps
15:56sdegutisOh, contemporary.
15:56sdegutisYes, thank you.
15:56sdegutisDoes Hiccup still rain supreme?
15:56xemdetiarain=reign
15:56justin_smithI have never tried hiccup, but I doubt it tastes like champaign
15:57jeffterrellThough champagne has been known to incur hiccups.
15:57cbpi left the template score list in my other pants
15:57sdegutisWhat is this, criticism our?
15:57justin_smithsdegutis: in all seriousness, I use something mustache derived, because the frontend guys don't do clojure and they write the templates
15:57borkdudesdegutis who still renders html on the server? ;)
15:58sdegutisborkdude: where else do you render it, friend?
15:58borkdudesdegutis in javascript
16:00sdegutisborkdude: heresy sir!
16:01sdegutisThat would be slow as heck.
16:01sdegutisor, wait.. is it?
16:02borkdudesdegutis this is what react apps do all the time
16:02justin_smithom is faster than the equivelent number of page loads you would need to do to see the same amount of page update
16:02jeffterrellI think it's not that bad actually.
16:02arohnerom is way faster than an HTTP request
16:03sdegutisHmm.
16:03justin_smithclearly sdegutis just isn't up to speed with web 2.0
16:03sdegutiswait I thought we were at web 3.5 already
16:03borkdude3.11
16:03justin_smithsdegutis: some of us are
16:03sdegutisjust not me? :(
16:03jeffterrellSingle-page apps like trello.com have a really thin static DOM but a big fat javascript file, and the JS creates the page. Cf. http://blog.fogcreek.com/the-trello-tech-stack/
16:03borkdudesdegutis even when not using react it can be feasible to render in js
16:03sdegutislook, whatever, my hands are fricken cold in this awesome autumn weather so thats that
16:04danneuusing a websocket as an event bus with React was a lot cooler until i realized i need to pay Cloudflare $5000/mo for websocket ddos protection
16:04justin_smithsdegutis: if you were rendering more in-browser your notebook could be warming your hands!
16:04sdegutisbut wait, dont you still need to make ajaj calls?
16:04arohnersdegutis: only for side-effects
16:04sdegutisdoesnt that diminish the upside of rendering clientside?
16:04sdegutiswell also for loading sensitive per-user data
16:05arohnerGET logic is all client-side
16:05sdegutisor something
16:05sdegutiswe're still using jquery :(
16:05arohnerbut the page still *renders* way faster
16:05arohneryou put up a spinner, and you transfer less data
16:05pandeirosdegutis: if you are dynamically building the initial HTML payload you can stick data in there; otherwise yes, 1 or more ajax calls to get your stuff
16:06justin_smithpandeiro: the downside there is for anything that needs to be updatable without a refresh, you can end up duplicating render logic, so even then you end up passing in some json and the javascript that renders it
16:07borkdudejustin_smith not with react
16:07pandeirojustin_smith: (defn get-data [f] (if inlined-data (f inline-data) (get-ajax-data f)))
16:07justin_smithborkdude: pandeiro: yes - but you aren't using something like hiccup for this
16:08pandeirojustin_smith: what do you mean? why not?
16:08borkdudejustin_smith you can have hiccup style templating in clojurescript
16:08pandeiroyou could easily inline data into the server-side hiccup vectors if need be, right?
16:08borkdudereagent has it out of the box, om + sablono or non react: crate
16:09justin_smithpandeiro: borkdude: OK, I did not realize hiccup templating in cljs was a thing
16:09borkdudejustin_smith light table uses crate for cljs templating
16:10justin_smithor perhaps even worse I knew this once because I actually used it and I totally forgot
16:10justin_smithcool
16:10pandeirojustin_smith: of course :)
16:11sdegutisborkdude, justin_smith, pandeiro: how do you handle clients that disabled JS?
16:11borkdudesdegutis haha, you don't
16:11sdegutis!?
16:11pandeirothe state of the art is doing the client as a SPA with React and rendering it on the server in Java 8's js env -- i know people have started doing that but i'm sure it's still thorny
16:11clojurebotCLABANGO!
16:11justin_smithsdegutis: this is clearly the downside of doing so much in the client
16:11pandeirosdegutis: yeah that's a different app
16:11sdegutislol clojurebot what the crap?
16:12justin_smith!?
16:12borkdudepandeiro I rendered a a component to a string yesterday in chrome and then just pasted the initial html in the static html file: works :)
16:12clojurebot! is suddenly
16:12pandeiroborkdude: yeah that's something else though
16:13borkdudepandeiro what do you mean?
16:13pandeiroi'm talking about rendering the string in the jdk's js env, not a browser env
16:13borkdudepandeiro what does it matter, it's only for initial page load right?
16:14sdegutistrue
16:14pandeiroborkdude: ah yeah sure, if it's not going to change
16:14pandeirobut here's what i was getting at (kinda): http://augustl.com/blog/2014/jdk8_react_rendering_on_server/
16:15borkdude'There's a glaring problem here. If you create React components that invokes 3rd party code, such as jQuery plugins, Bootstrap's JS components, and so on, you're in for trouble."
16:15borkdudea no go for me then
16:15pandeiroborkdude: yeah the issue is the missing browser stuff i imagine
16:15pandeirodocument.getElementById
16:15pandeirolocalStorage
16:15pandeirothat kind of stuff
16:16sdegutisWhat JS lib do you use for rendering HTML?
16:16justin_smithsdegutis: web 2.0 has been pretty terrible for accessibility, and the whole concept of browsing the web without js
16:16sdegutisI use Hiccup in Clojure right now.
16:16sdegutisjustin_smith: ... go on
16:16pandeirosdegutis: React is what everyone* is using
16:18borkdudesdegutis I know someone who uses crate for non react stuff, but reagent for everything else
16:18sdegutisAnyone here comfortable telling how much they make? I'm wondering how much someone who does a job like I do would get paid.
16:18borkdudesdegutis but you are just building a simple app without lots of interactivity server side hiccup is fine, just do what works for you
16:19sdegutisborkdude: I thought people were using Om for React within Cljs?
16:19borkdudesdegutis there are also lots of people using the more minimalistic reagent
16:19pandeirothere are at least three React wrappers in cljs
16:19borkdudeom, reagent, quiescent in descending popularity
16:20sdegutisso om is the most popular but reagent is the best?
16:20borkdudesdegutis there is no best, it depends
16:20borkdudesdegutis om is very good at undo-able snapshottable apps
16:20borkdudesdegutis provided you aren't using local state
16:21pandeiroreagent's api is much more idiomatic for people used to clojure; om has a bunch of new vocabulary
16:21borkdudesdegutis you can have the same effect in reagent, but it may require more thinking, because reagent doesn't enforce using only one atom
16:21sdegutisoh
16:21sdegutisthanks everyone
16:21borkdudesdegutis that said, reagent is much simpler to learn, less verbose
16:21joeltand there's hoplon which isn't reactjs based.
16:22sdegutisso react is the foreseeable future?
16:22borkdudesdegutis react changes the clojurescript landscape quite a bit I think, if I'm right
16:22borkdudesdegutis pedestal app development stopped because of om
16:23sdegutiswonderful
16:23joeltreactjs is fundamentally more "correct" and funcitonal-like
16:24joeltwhile on this reactjs thread... has anyone written an HTML -> om/template (or reagent/template) converter?
16:24sveriborkdude: you have any sources for this?
16:24borkdudesveri on what?
16:24borkdudethis requires context, just like in javascript :P
16:24sveriborkdude: that pedestal development stopped because of om
16:24pandeirothe pedestal thing was mentioned on the pdestal google group
16:25borkdudesveri yes, the pedestal-users mailing list
16:25pandeirohttps://groups.google.com/forum/#!topic/pedestal-users/jODwmJUIUcg
16:26mr_rmdoes anyone know how to tell ring to add app server specific deployment descriptors to the WEB-INF folder?
16:26justin_smithmr_rm: put them in your :resource-path
16:26sveriborkdude: pandeiro thanks, didn't know that
16:26justin_smithmr_rm: wait, that may not be it...
16:28mr_rmjustin_smith: yes i don't want it in WEB-INF/lib but rather at WEB-INF. alongside web.xml
16:29mr_rmi've pored over the docs but just not seeing it
16:29ssahey does anyone know how to *not* require a library in a library i want to depend on
16:29moquistborkdude: thx for the om, reagent, quiescent list. I didn't know about the latter two and I'm glad I now do.
16:29pandeirossa: :exclusions
16:29justin_smithpandeiro: that excludes a dep version
16:29ssae.g., A -> B -> C (where -> is a dependency)
16:30justin_smithpandeiro: that can't prevent a lib from requiring other clojure code
16:30TimMcsdegutis: Hiccup doesn't have anything to help you avoid JS injection attacks, by the way.
16:30pandeiroah yeah of course
16:30pandeiroderp
16:30ssajustin_smith is right :)
16:30justin_smithssa: provide another version of the namespace and exclude the dep? dunno, at that point why not rewrite the problematic lib
16:30ssayeah, so i have the exclusion, but B will still bail because it tries to find C
16:31justin_smithssa: you can create the ns such that it will be found rather than the other version, but this is a huge hack
16:31pandeiroTimMc: hiccup.util/escape-html ?
16:31ssajustin_smith: yeah, that's what i was trying to avoid :/
16:31mr_rmi tried add :web-content pointing to a folder with WEB-INF under that but it doesn't get included either. so far the only way i found is to manually add the deployment descriptor :\
16:32technomancyclojurebot: terminal quirks |are| a long, sad list of historical reasons why paredit's bindings don't work inside a terminal http://catern.com/posts/terminal_quirks.html
16:32clojurebotc'est bon!
16:32ssathe problematic require is not used anywhere in the lib, which is why i can exclude it
16:32ohpauleezThis is where I'll jump in and just say - everyone should give Pedestal Service a look when building out web-based services
16:33ssaok, was hoping there was an easy solution, but maybe not!
16:33justin_smithmr_rm: the ns in question is pretty small https://github.com/weavejester/lein-ring/blob/master/src/leiningen/ring/war.clj
16:33justin_smithmr_rm: any funcitonality you need should be in there - I couldn't see it though
16:33justin_smithmr_rm: but I only skimmed
16:34justin_smithssa: sounds like some codomain to monkey patching
16:34justin_smithssa: monkey-surgery?
16:35mr_rmjustin_smith: yes, sadly, my quick skimming looks like it doesn't do anything extra for other files except "web.xml"
16:35justin_smithmr_rm: the ugly way to do it would be to just add the file manually
16:35justin_smithmr_rm: it's just a zip file after all
16:35mr_rmjustin_smith: unfortunately i am forced to deploy this into weblogic and i need to make it prefer my local jars
16:36TimMcpandeiro: If you have to call a fn to escape output, you've already lost.
16:36justin_smithmr_rm: isn't this what uberwar is for?
16:36mr_rmjustin_smith: right, i already know that works. it just seems like this is basic functionality and i thought i must be missing something
16:36sdegutisTimMc: oh no!
16:36mr_rmjustin_smith: uberwar will put all the jar files there, that's true. however weblogic has an old version of the jar file in question and it before mine in teh classpath
16:36justin_smithmr_rm: weavejester tends to err on the side of leaving features out. On the plus side the things he leaves in tend to be really solid.
16:37mr_rmjustin_smith: i have to tell weblogic to prefer my classes from WEB-INF/lib
16:37pandeiroTimMc: really? can't you predict where user-generated content might show up in your templates?
16:37pandeiroTimMc: your gripe is that should be the default?
16:37justin_smithmr_rm: maybe it calls for a jar-surgery lib (if we don't have such a thing already)
16:37TimMcpandeiro: Exactly.
16:38technomancypandeiro: people make mistakes, unfortunately
16:38pandeirosure makes sense
16:38TimMcIt's unsafe by default, and we're not getting any reliability upgrades for people any time soon.
16:38technomancybetter to have the mistake be embarassing than catastrophic
16:38TimMctechnomancy: That's well-put -- &amp; is not so bad if you compare it to the laternative.
16:39pandeirowas the reason against it performance-related or?
16:39TimMcTime to do my yearly check if my old employer's site still has that double-escape bug...
16:39sdegutis
16:40Bronsatechnomancy: which keybindings are you talking about? I use emacs -nw and it all works fine
16:40pandeiroBronsa: C-arrows
16:41Bronsapandeiro: they work fine for me
16:41pandeiroBronsa: xterm?
16:41Bronsai might have unmapped them though
16:41Bronsapandeiro: urxvt
16:41sdegutispandeiro, Bronsa: st
16:41TimMcpandeiro: I would assume neglect or complacency. Almost every templating library has this proble, though.
16:41technomancyBronsa: urxvt has a few nonstandard tricks that work locally but not inside tmux/ssh
16:41Bronsasdegutis: what?
16:42sdegutisI thought we were randomly naming linux browsers.
16:42Bronsatechnomancy: ah I don't use tmux/screen
16:42sdegutisI mean terminals.
16:42technomancyBronsa: but yeah, it's not a limitation of terminal emulators per se, but rather the standards for representing keycodes across the wire.
16:42Bronsagotcha
16:43Bronsatechnomancy: isn't there an emacs something to edit files over ssh though? that could be a nice work-around :P
16:43technomancyBronsa: you'd think ... =)
16:43justin_smithxterm / rxvt can also hand pointer events to ncurses clients that know how to use them. For obvious reasons this doesn't work over a multiplexer / the wire either
16:43technomancybut since Emacs isn't concurrent it's pretty brutal in the presence of network lag
16:43pandeiroyeah I still don't see the point of emacs' M-x term
16:44justin_smithBronsa: yeah, tramp is awesome
16:44mr_rmjustin_smith: actually i do have my own private jar surgery library
16:44Bronsatechnomancy: .. yeah I notice that when my network drops & erc tries to reconnect
16:44justin_smithmr_rm: haha, nice
16:44sdegutisI will hold my tongue on the subject of Emacs.
16:44mr_rmjustin_smith: guess i need that extra step :)
16:44sdegutisI will hold it so tightly it will bleed tears.
16:44joobussdegutis: those are blood tears of love right?
16:45llasramsdegutis: Your tongue has tears for blood...?
16:45Gurkenmasterusing emacs over LAN with a forwarded X server works surprisingly well
16:45sdegutisI see this channel has never been christened to the concept of hyperbole yet.
16:46justin_smithsdegutis: it's less the hyperbole and more the surreality of said hyperbolic image
16:46sdegutisjustin_smith: whatever I don't know English things I just like mixing things that almost work together but don't quite
16:47joobussdegutis: that's the dumbest thing I've ever heard...
16:47sdegutisjustin_smith: most fun hobby. try it every day.
16:47sdegutisjoobus: Sir, you seem to be irate, please do explain why?
16:47technomancyfinely-tuned nonsense is an art form
16:47technomancya la Pavement
16:47sdegutisI'm glad /someone/g agrees with me
16:48sdegutisDid you see I snuck a regular exp in the emphasis?
16:48justin_smithtechnomancy: sdegutis: the Residents have a song with the lyrics "smelly tongues look just like they feel", I like it because if you include the medium of the data it encompasses all five of the primary senses
16:51sdegutisjoobus: the proper way to express such outspoken disagreement is to challenge someone to a duel with a glove slap
16:51sdegutisjoobus: please note this for future posterity
16:52TEttingerget a glove, sdegutis
16:52TEttingergloves can help you grab things, like oven mitts help grab hot things
16:52TEttingerfun fact for the day
16:52sdegutisWhy isn't /trout working
16:53sdegutisTEttinger: i use driving gloves to grab the steering wheel
16:53sdegutisotherwise i would miss
16:53justin_smithsdegutis: most of the world has not caught up to the optional fish-slap extension to the irc protocol
16:53sdegutistricky things those wheels are
16:54sdegutisthis has been a fun afternoon, thank you all
16:54justin_smithsdegutis: even if implemented, the client may only dispense canned tuna at best
16:54sdegutisi count it as R&D
16:54sdegutisbecause i learned about react.js
16:54sdegutisand got good feedback on it
16:54sdegutisjustin_smith: related to http 418 ?
16:55justin_smithsdegutis: no, that's just silly
16:58sdegutisi do a really good Bane voice
17:10sdegutisbrainproxy: Hi :)
17:23sdegutistechnomancy: you're a nerd, right?
17:23SagiCZ1is there some way to write functiona arguments that the function would accept both [a b c d e] and [a b [c d e]] ? without overloading? some destructuring magic?
17:24sdegutistechnomancy: I am thinking of getting a foot pedal with a usb hookup, and making it send a "ctrl" key while pressed
17:24sdegutisthe firmware should be significantly simpler than https://github.com/sdegutis/atreus-firmware
17:25technomancysdegutis: guilty as charged
17:25technomancysdegutis: wait, are you on a macintosh computor?
17:25sdegutisyes
17:25sdegutishaha! i like how you slightly spelled computer differently for effect!
17:25sdegutisvery well done
17:25technomancymacintoshes don't support having modifiers pressed on one device affecting keycodes from another device
17:25technomancythank you
17:25sdegutiswell im sure i can hack it in
17:26sdegutisim a programmer, see...
17:26technomancya what?
17:26sdegutisthat means i can create anything i can imagine
17:26sdegutiswatch this
17:26sdegutissee? did you see that?
17:27sdegutisi created something just now
17:27technomancyinconceivable
17:27sdegutisoh contrare.
17:28sdegutisso im thinking all i have to do is find a big switch and a microcontroller
17:28sdegutisthen ill be able to use emacs without being in pain all the time! :D
17:29technomancyyou would probably have to modify your OS's keyboard driver or something
17:29sdegutisi have my ways sir
17:29sdegutisCGEventTapRef or something
17:29sdegutisill map out every ";" at the hardware level to be Ctrl
17:29sdegutis(who uses ; anyway)
17:30Bronsasdegutis: so you don't write comments
17:30sdegutisok fine &
17:30sdegutisnobody uses &
17:31Bronsano varargs?
17:31sdegutisoops i mean F16
17:31technomancyjust use the arrow keys
17:31technomancythose are lame
17:31BronsaI use them :(
17:31sdegutisthanks everyone for your feedput
17:35sdegutisOh wow, Sticky
17:36sdegutisKeys is great!
17:39SagiCZ1any ideas for my question?
17:39TimMctechnomancy: Wait, they don't? So those Kinesis foot pedals are useless on a Mac?
17:40BronsaSagiCZ1: why no overloading?
17:40BronsaSagiCZ1: you can do (fn x ([a [b c]] (x a b c)) ([a b c] (do-stuff)))
17:42SagiCZ1Bronsa: its easy with overloading.. i was thinking about the '& more' thing.. if it can be used to recognize that im putting in a collection as 'more' and not wrap it in a list as usual
17:42technomancyTimMc: they plug into the keyboad itself; they're not independent deivces
17:43TimMchuh
17:44sdegutisI actually know how to write the Stick Keys feature on OS X.
17:44sdegutisPerhaps I should use that knowledge to build something similar but better, and sell it.
17:47BronsaSagiCZ1: do you have a use case in mind or?
17:54sdegutisThe website I write gets between 2k and 4k page views per day. I could probably use SQLite3 with WAL and get a significant performance improvement over using Datomic.
17:55SagiCZ1Bronsa: my function foo uses & varargs so it is convinient when calling like this (foo 42 "name" :a :c :d ..) instead of (foo 42 "name" [:a :b :c ...]) note that there can be any number of arguments after "name".. another function -bar- uses foo internally and receives :a :b :c .. in the same way as foo but that wraps it in a list so i cant call (foo 42 "name" other-arguments) in this function.. maybe i should just use 'apply' and be d
18:04the_dankoamigos, i have a little recur question if anyone is feeling bored
18:04the_danko(defn triang ([] (triang 0 1))
18:04the_danko ([presum n]
18:04the_danko (let [newsum (+ presum n)]
18:04the_danko (cons newsum (lazy-seq (recur newsum (inc n)))) ))
18:05the_dankoso this doesn't work
18:05the_dankoi need to change the recur to triang
18:05the_dankoit looks like it is trying to recur to the let []
18:05the_dankoand it gets an argument count mismatch
18:06the_dankoso recur goes to the closest assignment block, i.e. []?
18:06the_dankomaybe i have already answered my own question . . .
18:06cflemingthe_danko: No, it won't go to the let
18:07cflemingthe_danko: The problem is that recur has to be in tail position in your function, and you have it inside a lazy-seq
18:07the_dankoCompilerException java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 0 args, got: 2, compiling:(/private/var/folders/df/0z098cs56496gxlycxf2688c0000gn/T/form-init5659419162470671422.clj:4:29)
18:07the_dankocfleming: thanks!
18:08cflemingthe_danko: I'm actually not sure why you're getting that particular error, but recur will definitely not work inside lazy-seq.
18:08Bronsathat confusing exception is because lazy-seq wraps the body in a fn
18:08cflemingBronsa: Ah right, of course.
18:09the_dankoBronsa: cfleming: ahh. by the body, you mean? (recur newsum (inc n)
18:09dbaschthe_danko: you’re not in tail position
18:09Bronsa,(macroexpand-1 '(lazy-seq 1))
18:09clojurebot(new clojure.lang.LazySeq (fn* [] 1))
18:09dbaschyou can’t recur from there
18:09TimMcBronsa: Imagine how mcuh worse it would be if lazy-seq's wrapper fn took more than 0 args.
18:10dbaschoh, cfleming already said it
18:10BronsaTimMc: yep. it would be useful if there was a primitive that acted like ^:once fn* but did not set a recur point
18:10Bronsamacros could use that & error messages could be better
18:10TimMc^:passover
18:11Bronsaprobably :once would be fine aswell
18:11the_dankoBronsa: cfleming: dbasch: thanks a lot! i'll be getting to macros soon and thus will understand then.
18:11dbaschthe_danko: replace recur by triang and it should work
18:11cflemingSo I'd like to write a macroexpander that takes a form and expands it step by step
18:12TimMcIt would be nice if macros and specials highlighted differently from fns.
18:12BronsaTimMc: yeah it doesn't really make any sense to recur a ^:once fn*
18:12Bronsacfleming: sounds like tools.analyzer might help you there
18:12TimMcBronsa: I guess it is only called once, for that matter.
18:12cflemingSo each time I call it I pass it the results of the previous step, and it will recurse down into the form until it can perform a macroexpand-1, and then return the results of doing the expansion at that point.
18:13Bronsa, ((let [a (Long. 2)] (^:once fn* [] (when a (println a) (recur)))))
18:13clojurebot2\n
18:13cflemingBronsa: how would t.a help?
18:13cflemingIt's a surprisingly tricky problem - neither Riddley nor tools.macro are well structured to do it.
18:14Bronsacfleming: you want to macroexpand subforms too right?
18:14cflemingBronsa: Right. I'm going to make an interactive macro stepper for Cursive.
18:14TimMcBronsa: freeeaky
18:15Bronsae.g. (let [a (when 1 2)]) => (let* [a (when 1 2)]) => (let* [a (if 1 (do 2))]) cfleming ?
18:15BronsaTimMc: well that's the whole point of ^:once :P
18:15cflemingBronsa: Exactly.
18:16the_dankocfleming: boom! go cursive! ha, i am sure i'll get and appreciate what you are suggesting soon.
18:16Bronsacfleming: well t.a.jvm saves all the macroexpansion steps for every expr so if you don't mind macroexpanding everything even if you only need n steps, it should be trivial to use t.a.jvm for that
18:17TimMcBronsa: I was vaguely aware that there was some kind of optimization, but I didn't realize it was that one.
18:17cflemingPerformance isn't a huge concern, so I could potentially recurse down into the form like tools.macro and just try all the potential expansion points until I find one that actually expands.
18:17BronsaTimMc: it basically tells the compiler "the body is only going to be evaluated once so you're free to clear all the closed over vals"
18:18Bronsas/vals/locals
18:19cflemingBronsa: Yeah, that would be fine - I was thinking about modifying tools.macro to do something like "perform n macroexpand-1's on this form" which would give me what I want.
18:19cflemingBut the stateful iteration is quite ugly.
18:19seangrove"Languages with static typing that don't need validation (e.g. Om in ClojureScript), and production level compilers will be able to generate these objects inline instead of going through the validation step. This optimization will allow significant performance improvements in React.
18:20cflemingBronsa: Any pointers as to where I should look in the t.a.jvm code?
18:20seangroveOm doesn't bring any static typing to the table, does it? Definitely the production-level compiler
18:20cflemingthe_danko: Hopefully it'll help you understand macros better!
18:20cflemingthe_danko: When it's done, that is.
18:20seangroveI wonder if they put the Om reference after the wrong point
18:22Bronsacfleming: a bunch of pointers: - t.a's macroexpander is swappable, - if present in a node, :raw-forms holds the macroexpansion steps for the original :form of that node
18:22Bronsacfleming: also passes.jvm.emit-form might help, it's an AST to clojure code compiler
18:23Bronsacfleming: it's late-ish now but if you want I can write a quick POC of how that might work by tomorrow
18:24cflemingBronsa: Ok thanks. It's morning here, I'll see what I can come up with today and if that would be helpful I'll drop you a mail.
18:24cflemingBronsa: I suspect there's a fairly simple solution in there somewhere, I just haven't seen it yet.
18:25cflemingBronsa: BTW while I have you, can you see any problems with this? https://github.com/cursiveclojure/cursive/issues/567
18:26Bronsacfleming: the same problems we have for eastwood: you can't attach metadata to everything
18:26cflemingBronsa: I remember some discussion on the mailing list between Ambrose and Andy Fingerhut about this WRT Eastwood and Dynalint
18:27cflemingBronsa: Right, I guess in the worst case your exclusion scope is too big
18:27Bronsayeah
18:27cflemingBronsa: Ok, I'll investigate that a bit more, thanks.
18:28cflemingBronsa: Does Eastwood have anything like this now? I should use the same mechanism if so.
18:28Bronsacfleming: no it's still an open question
18:28cflemingBronsa: Ok, thanks.
18:28Bronsacfleming: the only 100% accurate solution is to put the directive in a #_comment before the form to affect but that requires dropping the reader and using a parser
18:29cflemingBronsa: Ok, I can do that trivially in Cursive, thankfully
18:29cflemingBronsa: Since I'm working from source
18:29Bronsacfleming: well if you can do that than I'd use #_{:suppress [whatever]} syntax
18:31cflemingBronsa: Ok, I'll look into that - that's pretty trivial for me, although it's a little ugly too. I can probably fold it though.
19:04mr_rmjustin_smith: remember that question i had about WEB-INF/weblogic.xml?
19:04justin_smithmr_rm: yeah
19:05mr_rmjustin_smith: :war-resources-path is the answer. i'm such a retard at times :)
19:05justin_smithmr_rm: oh, I thought that was just the same as :resource-path when I looked at it
19:05justin_smithmr_rm: good to know!
19:05justin_smithwonder if it's worth a pr on the ring docs?
19:05mr_rmjustin_smith: :resources-path puts stuff on the classpath so it will go under WEB-INF/classes
19:07mwfoglemanjustin_smith: I just found out that the bug I've been having is in core
19:07mwfoglemanjustin_smith: http://dev.clojure.org/jira/browse/CLJ-1413
19:07mr_rmjustin_smith: well it's in there toward the bottom. it would be nice if it mentioned something about app server specific descriptors to give you an easy search. really that's exactly what you need when you're deploying to JEE servers with a lot of special config
19:08mr_rmjustin_smith: i'll try to tweak it a bit and offer a PR and see
19:09justin_smithmwfogleman: weird - so what exactly are the combination of factors that make this happen?
19:11mwfoglemanjustin_smith: in user.clj, trying to require a namespace with a defrecord
19:12mwfoglemanit's nice to know i'm not the only one ;)
19:12mwfoglemani've felt kind of crazy, especially since fixing the hyphens didn't fix it.
19:12justin_smithyeah, the weirdest bugs are the worst when you have less experience with the language
19:13justin_smithbecause you have more reasons to second guess your own code
19:13mwfoglemanexactly.
19:14mwfoglemanwhat have you folks been working on in here?
19:16justin_smithmwfogleman: some features updates on a client web site
19:16AeroNotixmwfogleman: I just wrote a dispatcher/multiplexer thing for Amazon SQS messages
19:16AeroNotixand a payments system using auth.net
19:16AeroNotixalso, messing with riemann
19:16justin_smiththey wanted routing to be based on freeform strings from db data rather than unique identifiers (ugh)
19:17justin_smithAeroNotix: that sounds so much nicer than messing with routing to pages based on db data
19:17AeroNotixjustin_smith: it does indeed
19:17AeroNotix:)
19:18justin_smithAeroNotix: has anyone written "core.async for multiple servers" yet?
19:18mwfogleman:D
19:18AeroNotixjustin_smith: I think I saw that some where. "net chan" or something
19:19AeroNotixit's kind of broken doing that. It's cool that you get the same API n all. But network failures aren't part of the "api" for core.async
19:19AeroNotixStill, I'd probably use it for certain things
19:19justin_smithAeroNotix: my intuition is that once you have the layers on the network in place on both ends, not much else about core.async would have to change
19:19AeroNotixjustin_smith: I saw a really nice library for using Zookeeper backed atoms
19:20justin_smithAeroNotix: it's cool as long as you never use watches
19:20AeroNotixjustin_smith: why?
19:20justin_smiththe watches in that lib are pathologically broken
19:20justin_smithAeroNotix: the watch api for zookeeper lets you set a watch, but that watch is removed immediately when it is triggered
19:20AeroNotixgotcha, noted. I was gonna use it a couple of months ago for a linearly scalable STUN design we ended up not needing
19:20AeroNotixjustin_smith: ah yes, you need to reset the watch. I thought that was very odd.
19:21justin_smithAeroNotix: the semantics just do not agree with the clojure semantics, and so things you would expect to work just break
19:21AeroNotixjustin_smith: yeah, the raw ZK library doesn't make you do that.
19:21justin_smithAeroNotix: and the watch resetting could miss changes that happen between trigger and reset ...
19:21AeroNotixyupp, it's messed up doing that.
19:21justin_smithAeroNotix: but if you just want a reference type over the network, without watches, yeah, that seems to work in my experience
19:22AeroNotixjustin_smith: I didn't use it in anger. I was just prototyping a couple of designs for scalable STUN.
19:22AeroNotixEnded up looking at riak_core in the end. Then that project got shit-canned
19:22AeroNotixand never mind that STUN itself is ridiculously scalable even on a single node.
19:23AeroNotixI wouldn't mind a proper automation tool written in Clojure for AWS.
19:23justin_smiththis stun? http://en.wikipedia.org/wiki/STUN
19:23AeroNotixjustin_smith: yeah
19:24justin_smithAeroNotix: I have a multi-part-stream-upload patch for clj-aws-s3 that I mean to resubmit upstream as soon as I have time to clean it up
19:24AeroNotixnice!
19:24AeroNotixWhat i mean is some kind of declarative way to describe your infrastructure, ec2/elb/sec groups etc
19:24justin_smithAeroNotix: I was doing streaming transforms on file data, and decided putting it on my own disk was a waste
19:24AeroNotixbut in EDN or something
19:25justin_smithAeroNotix: ahh, cool
19:25AeroNotixand the Clojure library would parse that and make the necessary changes
19:25AeroNotixjustin_smith: yeah if you're in EC2 there's no point putting stuff on your own disk that you want
19:25AeroNotixthat you want to keep*
19:26justin_smithyeah - the disk usage was just a temp file - but I was like "why can't I just use an inputstream and an outputstream with my algo in the middle?" so that's what I did, but multi-part-upload that doesn't use files was a pre-req for that
19:27AeroNotixGotcha. I find the java streams stuff a of a crappy API
19:27AeroNotixYou can do a lot of neat stuff with them though
19:27AeroNotixa of a?
19:27AeroNotixa bit of a*
19:28seancorfieldorg.clojure/java.jdbc 0.3.6 is coming soon - fixes JDBC-100, JDBC-101, JDBC-102 (all minor stuff)
19:28justin_smithAeroNotix: also, the existing multi-part-upload impl in clj-aws-s3 seems to be trying to do parallel upload of chunks - but I intend to benchmark that and prove that there is no situation where out of order chunked upload from a disk (ssd or hd) is faster than linear access
19:28AeroNotixfrom a disk you're probably right
19:29justin_smithAeroNotix: and the API demands a File
19:29justin_smithso it all seems a bit silly to me :)
19:29AeroNotixdoes seem it
19:29justin_smithI guess a File object could be on a ramdisk partition...
19:30justin_smithbut that seems like a big iff
19:30AeroNotixI find those kind of optimizations are often just done for the sake of it
19:30AeroNotix"optimizations"
19:30justin_smithAeroNotix: ;; this is the part where we turn optimization up to 11
19:30AeroNotixjustin_smith: haha
19:40Bronsacfleming: http://sprunge.us/JLdM?clj this is hackish and totally not efficient, but it should work fine as a POC
19:43amalloyBronsa: i totally don't have the context to comment on the meat of that code, but it seems weird to me that you're writing (concat asts [a]) when asts appears to be a vector throughout the process, and you even do (conj asts a) to append to it in a different spot. is there something i'm missing there?
19:45Bronsaamalloy: no, I was doing something else before where asts was a seq rather than a vector and just left it that way
19:46Bronsaamalloy: there are other things worse than concat in that code, I just threw it together to see how it might work
19:53amalloyBronsa: it's a feature i'd be happy to have, though, and it's great the analyzer is powerful enough you can throw it together in a short time. i don't really think i need a stepping macroexpansion debugger, because if i write a macro complex enough that i can't do it in my head i'm making a mistake, but i can see this being really useful for someone with less practice
19:54Bronsaamalloy: yeah it's definitely something I wish I had when I started learning lisps
19:56Bronsacfleming: http://sprunge.us/KMgD?clj a less inefficient version
19:59justin_smithBronsa: cfleming: now add colorization so that each expanded form gives its color highlighting to its expansion in the next form down, put it in a box, wrap it in a bow, and bob's your uncle
20:01lazybotwhy not try using MONADS!?
20:02amalloyBronsa: i judged it but found it a reasonable enough approach to not criticize you
20:03amalloylazybot: thanks, man. good idea
20:03Bronsahah
20:03Bronsa(inc lazybot)
20:03lazybot⇒ 31
20:03amalloyBronsa: i set that monad timebomb 24 hours ago and had forgotten all about it. i do enjoy surprising myself with these things
20:05BronsaI just panicked thinking I found a t.a.j bug
20:05Bronsaturns out it's just a clojure bug so all is good
20:05justin_smithhaha
20:05amalloyoh yeah?
20:05justin_smith"my platform is broken, that's so much better"
20:05Bronsa,'^{:foo (println "foo")} []
20:06clojurebot[]
20:06Bronsait's CLJ-something in JIRA
20:07amalloyBronsa: http://dev.clojure.org/jira/browse/CLJ-1137? http://dev.clojure.org/jira/browse/CLJ-1017?
20:08amalloyhttp://dev.clojure.org/jira/browse/CLJ-1235
20:08amalloyhttp://dev.clojure.org/jira/browse/CLJ-1187, apparently
20:08Bronsahttp://dev.clojure.org/jira/browse/CLJ-1093 actually
20:09amalloyyes, i just got there as well
20:09Bronsawhat a wild ride
20:09amalloyfollowing the chain of "x closed as dupe of Y by Bronsa"
20:10Bronsaamalloy: there are a number of similar but slightly different issues related how the compiler handles empty collections
20:10amalloyyes. and also how it handles reader meta applied to "runtime" objects vs "compile-time" objects
20:10Bronsayup
20:11amalloypersonally, i choose to never use ^ to apply metadata to objects i want my program to manipulate, and always use with-meta instead. then ^ is only for information i want to give the compiler, and i avoid such ambiguities
20:11Bronsaamalloy: yeah that's a more than reasonable stance
20:12BronsaI've spent a good number of hours trying to come up with a fix for all the edge-cases in the Compiler, then gave up
20:14amalloyhttp://dev.clojure.org/jira/browse/CLJ-1017 is a weird one from bbloom
20:15bbloomamalloy: side effects in metadata expressions? psha, who needs those?
20:18justin_smithI decided to back up and read up about the general concept of metadata
20:19justin_smithit seems that an alternate name for metadata as we use it in clj is metacontent
20:19bbloomi've flip flopped on whether or not metadata is a good idea so many times, i've lost track
20:19justin_smith(the destinction being according to some that metadata is about data structures / architecture, and metacontent about a particular piece of data)
20:19bbloomwhich i guess means that it's motivated by genuine use cases, but not quite the right solution yet
20:20justin_smithbbloom: got any good articles or papers to recommend on the subject?
20:20bbloomnot really, no
20:20bbloomif you find any, please share
20:20justin_smithit seems like there must be at least one good 40 page dissertation on metadata in compiler implementation out there somewhere
20:20bbloomthere's lots of related stuff, like writing about the "identity crisis" with respect to proxy objects
20:20bbloomi'm sure there's something about alists in CL somewhere
20:22justin_smithhttp://www2.informatik.uni-freiburg.de/~keilr/papers/pos2013-proxy.pdf a paper about the proxy identity crisis in js
20:25dbaschthat paper confuses schizophrenia and multiple identity disorder
20:25bbloomheh
20:26dbascha schizophrenic proxy would be quite strange
20:26dbaschget array -> “here’s the rhinoceros you asked for”
20:26justin_smithdbasch: a proxy that fundamentally does not "get* the protocols it is expected to implement
20:26AeroNotixdbasch: lots of people confuse the two
20:28justin_smithdbasch: body without organs / code without datastructures (?)
20:36amalloydbasch: a rhinoceros is just an array of cells anyway, right?
20:37dbaschamalloy: don’t tell that to the next rhinoceros you meet
20:37dbaschespecially if it just came through a proxy over the wire
20:39amalloydbasch: incidentally, you caused me to realize that rhinoceros is a word i have no idea how to spell. the first half is super-easy, but after that it seems i'm completely lost
20:41havenwoodrhinawserous
20:41justin_smithcute rhino https://www.youtube.com/watch?v=0bL02GyIsKw
20:42justin_smithhe tries to pronk like his friend
20:42mlb-I've got a list of functions and want to execute them all, is there something cleaner than: (->> fun-list (map (fn [f] (f))) dorun) ?
20:43justin_smith(dorun (map #(%) fun-list))
20:43justin_smithactually (doseq [f fun-list] (f))
20:43justin_smiththat's the right way
20:45gfredericksI know why I like doseq better. it doesn't create a sequence for no reason.
20:45dbaschmlb-: curious about the situation in which you have to execute a bunch of functions with no arguments for side effects
20:45justin_smithyup
20:45TimMc&(format "lib-%04d" (rand-int 1e4))
20:45lazybot⇒ "lib-1113"
20:46TimMcthanks lazybot!
20:46gfredericks^ great lib name
20:46TimMcIsn't it?
20:46TimMcYou have the best naming scheme.
20:47justin_smith,(format "lib-%s" (java.util.UUID/randomUUID))
20:47clojurebot"lib-9ae7bac8-3c4f-4f4a-ade0-ef92fae94649"
20:47gfrederickstoo hard to remember
20:47dbaschthx-1138
20:47gfredericksdoesn't roll off the tongue
20:47gfredericks~lib-1113 is the new hotness
20:47clojurebotIn Ordnung
20:47justin_smith,(format "lib-%s-jure" (java.util.UUID/randomUUID))
20:47clojurebot"lib-9e5e6624-24aa-45e4-8ca8-d9b15fb4c211-jure"
20:47gfrederickslol
20:48TimMcha!
20:48gfredericks(inc justin_smith)
20:48lazybot⇒ 106
20:49TimMc,(apply str "lib-" (map char (repeatedly 15 #(rand-int 65536))))
20:49clojurebot"lib-彖ổ?쑡몀⧹鯏䢭艠ᐑ뤪ﶒ枌"
20:50gfredericksoh dear
20:50justin_smith,(lib-彖ổ?쑡몀⧹鯏䢭艠ᐑ뤪ﶒ枌.core/summon-old-one)
20:50clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: lib-彖ổ?쑡몀⧹鯏䢭艠ᐑ뤪ﶒ枌.core>
20:50TimMcphew
20:54justin_smithTimMc: who am I kidding, it would be a java lib, and I would need to invoke the static AbstractOldOneSummonerFactory method, then use that to do the summoning with
20:54justin_smithafter inheriting from the proper classes etc.
20:54TimMcNoneuclidianAbstractSingletonProxyFactoryBean would *definitely* be involved.
20:55dbaschsomeone should put together a lib to generate clojure library names, all you need is a list of obscure characters from tolkien books and similar
20:55TimMc.ia().ia().ia()
20:55justin_smith(inc TimMc)
20:55lazybot⇒ 76
20:56TimMcAll those incantations probably use builder methods.
20:58dbaschCamelCaseNamesForJavaClassesWhoCantReadGoodAndWantToDoOtherStuffGoodTooFactory
20:59nwolfeHeh, www.classnamer.com gives you some good ones :D
21:49arrdemjustin_smith: I would totally use a lob with an AbstractOldOneSummonerFactory. Not nearly enough tentacles and too much sanity in my code.
21:49arrdems/lob/lib/g
21:58justin_smitharrdem: the prophecy will be revealed and then it shall come to pass, nyalothep will gaze upon our code and find it unwanting, and his indifference will delete it, and along with it all of the bugs it held. So it shall be.
21:59arrdemarrdem: http://www.marlborotech.com/Zalgo.html <- I would use the crap out of a Clojure lib that did that
21:59justin_smitharrdem: my buddy patchwork made one
21:59arrdemjustin_smith: https://www.youtube.com/watch?v=FOHJUrcVdJk
21:59arrdemas long as we're off topic..
22:00arrdemjustin_smith: clojars or it didn't happen
22:00justin_smitharrdem: I introduced him to zalgo, and he was like, awesome, bam https://github.com/prismofeverything/zalgo
22:00justin_smitharrdem: clojars as requested https://clojars.org/zalgo
22:01arrdemjustin_smith: whelp... I guess Grimoire 0.3.10 is totally gonna have a zalgo mode now
22:07justin_smitharrdem: the obvious extension is zalgoize-stacktrace
22:08justin_smithwhen you know clojure too well, and the stacktraces actually seem useful...
22:08arrdemAHAHAHA
22:08justin_smithfor the nostalgia, of course
22:08arrdemthat would be an amazing cider module
22:08arrdemhum... https://github.com/clojure-grimoire/grimoire/issues/131
22:08arrdemshould this be a feature? I'm torn
22:08arrdemI should fix it, since it's broken, but should it be a feature.
22:09justin_smithoffline mode is a good thing
22:09celwellHi, how can I test a coll to determine if all the value in it are equal?
22:09gfredericks(apply = coll)
22:09celwellah, nice
22:11celwellworks well thanks
22:12arrdemjustin_smith: so my thing with the "offline" build is that you can totally clone Grimoire and run it locally
22:12arrdemjustin_smith: as time goes by the static HTML build makes less and less sense
22:12justin_smithhmm
22:21bbloomhow do people feel about crazy language embeddings, such as https://github.com/pallet/stevedore ?
22:25justin_smithbbloom: woah, how well does that actually work?
22:26bbloomjustin_smith: *shrug* i guess that's the real question
22:26bbloomi've seen it in use, and my initial reaction is horror
22:26justin_smithyeah, can't say just from the source / unit tests, would have to use it
22:26bbloombut then i realize i'm writing cljs, which is basically the same idea
22:26bbloomso i'm not sure where the horror comes from
22:26bbloomor how to characterize it
22:27justin_smithbbloom: I think my default horror comes not from the act of translation (which we know can be done well) but from the known pitfalls of half-assed or overambitious translation
22:28bbloomjustin_smith: yeah, i guess that's it
22:28justin_smithbbloom: but it takes real usage or significant examples to know which is going on (unless you are a language-converting tool master of some sort I guess)
22:29bbloomso i mention stevedore b/c i experienced it in a production system, but i'm actually more interested in other metaprogramming/cross-compiling tasks
22:29justin_smithbbloom: it's like - if my buddy says "I'm gonna jump out the second story window, it's gonna be awesome", I am going to try to stop him. But if a guy at the circus jumps from an equivalent height, I kind of figure he has that under control
22:29bbloomjustin_smith: heh, intersting analogy
22:30bbloomi have a far-far-far from complete version of https://github.com/Constellation/escodegen in clojure built on my Fipp library
22:30justin_smithof course this means rich hickey = evel knevil
22:31justin_smithbbloom: fascinating - what's the use case for that, js as compiler backend?
22:31bbloomyeah
22:32bbloomi wanted to do a compile to js language and i wanted to implement the compiler in clojure
22:32bbloombut i was hand crafting ast nodes like {:head :if :test {...} :then {...} :else {....}} and it was just veeeerbose compared to (if a b c)
22:33bbloomso i started to create a ns of factory methods and an elaboration pass that basically macroexpands things like "foo" in to things like {:head :string :value "foo"}
22:33bbloombut after using this for 20 minutes, i immediatley got annoyed that the factory syntax didn't cover a corner case and i got annoyed
22:34bbloomhence my question about stevedore, etc
22:34justin_smithout of left field thought seeing those ast data structures: I wonder how useful it would be if a tool like t.a.jvm transformed clojure code into a "normalized" form where each symbol is replaced by a map with a :value key or something similar alongsize the metadata (with a reverse translation available as well, of course)
22:35bbloomi'm not sure i follow
22:35justin_smithfolks were talking about how many bugs there are in metadata handling
22:36justin_smithso what about a transformation of clojure code into a form where the data is embedded in a map with the metadata
22:36justin_smiththis would be inefficient
22:36justin_smithbut it could also be a more explicit form where the metadata is now regular data, and is part of the printed representation etc.
22:37justin_smithit's total speculation, probably not actually useful
22:38bbloomthe other frustrating thing is that these little embedded languages never compose
22:38bbloomstevedore is basically lexical macro
22:39justin_smithwell, that two way transformation thing would fix that, but I guess you need to design in a very particular way for the translation to be reliably two-way
22:40bbloomhow does a two way transformation help?
22:40justin_smithbbloom: it's composible when you bring it back into the common format
22:40justin_smiththen transform to the other one, doing the operations native to that format?
22:40justin_smithmaybe this is silly
22:41bbloomwhat's the common format?
22:41justin_smithbbloom: haha, I guess that's the problem, I assumed such a thing would just be natural
22:41bbloomwhen your meta language and your object language are both a lisp, things are easy
22:42justin_smithbbloom: having to do with what I was talking about above, a normalized, extremely explicit (if less efficient) form
22:42justin_smithbbloom: but then metadata (or in older lisps, plists) kind of complicate that
22:43bbloomi'm not worried about metadata at all
22:43justin_smithOK
22:44bbloomi'm worried about constructing syntax trees and emitting code with minimal mental gymnastics of an incomplete translation and an idiosyncratic factory library
22:48justin_smithyeah, I was going off on a tangent tying this to the previous discussion
22:48justin_smithbbloom: but I think the benefits of lispyness are undeniable for what you want to do
22:49bbloomwell, unfortunately, js is not a lisp :-P
22:49bbloomi don't particularly want to invent a js-in-clojure embedding just to write a compiler for another language to that intermediate language
22:50justin_smithbbloom: if we had a single reliable two way transformation that did not lose information, between ecmascript and something lispy, other tools could leverage that
22:50bbloombut i guess that's what i really do have to do if i don't want to write ASTs long form
22:50bbloomthe other idea is to go all the way on concrete syntax
22:51bbloomimplement a js parser too, extend it with an unquote operation
22:51bbloombasically like js* in the cljs compiler, if you're familiar
22:51justin_smithright, I've seen it (though not looked at the impl)
22:51justin_smithbbloom: is that parsing js, or embedding js in the output?
22:52bbloomi'm saying you'd basically parse a variant of js that supports an operator like #{...clojure code here....}
22:52bbloomand then define a syntax-quote style operator that takes a string
22:53justin_smithahh, so the inverse
22:53bbloom(let [x 2 y 3] (js "console.log(#{x} + #{y})")) would produce a JS AST with 2 and 3 substituted in
22:53bbloomyou'd still need an "elaboration" pass that returns something like {:head :binop :left 2 .... in to something like {:head :binop :left {:head :number :value 2 .....
22:55justin_smiththat makes it almost sound like a kind of templating or string interpolation
22:55cflemingjustin_smith: (re: macroexpansion a couple of hours ago) that's my plan - single step macro expansion, and highlight what's changed in each one.
22:55bbloomsyntax-quote is templating :-P
22:56cflemingjustin_smith: The bow would be a nice touch though.
22:56bbloombut yeah, the idea is to basically make js-syntax-quote by adding interpolation to a js grammar
22:56justin_smithcfleming: very nice
23:00bbloomjustin_smith: i think i realize what my big objection to something like stevedore is though
23:00justin_smithdo tell
23:00bbloomspeaking concretely, stevedore tries to make shell look like clojure
23:00bbloommimicking another language is the problem
23:00bbloomnot translation
23:00bbloomb/c when the embedded object language mimicks the metalanguage, you get in to an uncanny valley sort of situtation
23:01bbloomwhere it doesn't look or feel right
23:01bbloomthe closer it gets w/o being the metalanguage, the stranger it seems
23:01justin_smithbbloom: another way to put it maybe is syntactic translation (trivial) vs. semantic (nearly impossible to get right)
23:01bbloombut stevedore doesn't try to put clojure semantics in to your shell
23:02bbloomother than some superficial stuff like namespacing locals or whatever
23:02bbloomit is mostly a syntactic translation
23:02justin_smithbbloom: I would assume it at least gets the three parts of an if right, etc.
23:02justin_smithbut that's the semantics that overlaps
23:03bbloomcljs is a major semantic AND syntactic shift from js, but it's not so awkward b/c cljs looks like clj and works like clj, rather than looking sorta like clj and working sorta like js
23:03bbloomthat's the problem w/ stevedore and many other embeddings, i think
23:03bbloomlooking sorta like the meta language and working mostly like the object language
23:03justin_smithbbloom: that uncanny valley thing is also why I find trailing parens in a lisp / sticking ones in a non-lisp so annoying - I can read faster when there are no ambiguous clues about which language type I am looking at
23:03bbloomhm
23:04bbloomcoffeescript for example looks like something totally different and works exactly like js
23:04bbloomno uncanny valley
23:04justin_smithright
23:05bbloomamusingly, this exists: https://github.com/Gozala/wisp
23:07sxAre there popular lisps besides clojurescript which compile to javascript?
23:07bbloomsx: i don't know how popular it is, but there's http://common-lisp.net/project/parenscript/
23:07sxbbloom: thx checking it out
23:08justin_smithsx: I am sure someone has made a scheme -> js compiler. I mean it has to have happened.
23:08sxjustin_smith: true. i guess I said "popular" since the underlying languages undergo changes and it is not always easy for a compiler to keep up
23:08justin_smith:)
23:09sxit looks like parenscript latest release is more than two years old. so unlikely to support new ecmascript features
23:09justin_smithsx: scheme has the advantage of having standards, on that front, and tools that verify compliance to said standards
23:10justin_smithahh, features in the target language
23:10justin_smiththat's different, yeah
23:10sxyeah in this case
23:11justin_smithso, this exists https://github.com/jashkenas/coffeescript/wiki/list-of-languages-that-compile-to-js
23:11sxjustin_smith: sweet. thats what i was just about to google for..
23:12justin_smithclojure-like, scheme-like, other are the lisp subheadings :)
23:12sxyes a lot more than I expected. good stuff
23:13bbloomjustin_smith: i probably should have checked that list, there's likely something i could use :-)
23:13justin_smithsx: it would be nice to have a version of that page annotated with project activity levels, adoption rates
23:14TEttingerKi looked good, justin_smith -- uses clojurescript data structures but can be used as js macros within js code
23:14sxyes I am looking at Ki now.. caught my eye too
23:14TEttingerso you have stuff like map, filter, apply, -> with a different name
23:14TEttingerjustin_smith, yeah, I have https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS bookmarked
23:15TEttingerit used to reside at http://altjs.org , but I think it's been taken
23:15TEttingeryep
23:18bbloomjustin_smith: https://github.com/krisajenkins/yesql embodies the parser approach, only they don't have a particularly sophisticated parser (they just look for questions, mostly)
23:19bbloommaybe better to call it the "interpolation" approach
23:19justin_smithbbloom: yeah, another kind of macro that looks a lot like templating
23:19justin_smithright, interpolation is the word
23:20bbloomi think i like this approach much better than what i started to do
23:20bbloomb/c what i started to do basically amounts to designing both an AST as an "API" aaaaand a language as embedded in clj
23:20bbloomthen also implementing a code generator for that language w/ a js backend
23:20justin_smithbbloom: what I like about yesql is it isn't a hinderance to someone who knows some actual sql
23:20justin_smithbbloom: unlike so many sql interaction libs
23:21bbloomyeah, my goal isn't to make the prettiest programs ever that all feel perfectly uniform
23:21bbloommy goal is nicely formatted js compiler output w/o breaking my desk via head banging in trying to generate precisely the js i want
23:21bbloomany embedding of js is going to be the uncanny valley thing
23:25bbloomok, but that involves a parser too ... of some kind
23:25bbloomheh, a task for another day
23:28joshheadsx: lispyscript looks pretty cool. I think it keeps mostly javascript semantics but with different syntax and macro support
23:28joshheadno idea who uses it
23:29justin_smithjoshhead: an amazing thing with lisp is you can find a small obscure thing and even though it is not popular you can actually do stuff with it
23:29justin_smithjoshhead: I made some cool things with lush, which nobody here has likely heard of
23:30TEttingerjustin_smith, the lisp shell?
23:30TEttingeram I confusing it with fish?
23:30justin_smith(a lisp that compiles to c, with an emphasis on linear algebra, dsp, and the ability to do things without gc)
23:30justin_smithTEttinger: the lisp one
23:30TEttingeroh yeah, that sounds familiar
23:30justin_smiththough I think the shell part is misleading here
23:31TEttingerfish is an array programming language IIRC
23:31justin_smiththere is also a shell called fish
23:31justin_smithstatements which are totally absurd out of context for 100, alex
23:31bodie_what is a cursor?
23:31justin_smithbodie in om?
23:32bodie_yeah
23:32bodie_I'm reading the swannodette breakdown on it, and it just made it worse
23:32bodie_I want to either not understand it at all, or actually understand it, lol
23:32justin_smithIIRC the general concept is it tracks a place for update, but deeper than that I can't help you
23:32bodie_yeah, I think it's a reference to a location
23:33bodie_.... I think
23:33bodie_but he refers to lenses and zippers and I think my brain exploded
23:33puredangerfirst poll done by Rich on what people wanted in Clojure (Sept 2008): https://groups.google.com/d/msg/clojure/BUlpZTDMvQ0/ko-5Q7mtoDAJ
23:33justin_smithbodie_: a lense is named after the fact that it can be a microscope or a telescope
23:34bodie_hm
23:34justin_smithbodie_: it lets you insert a value into a nested place, or extract one out, with the same abstract construct
23:34joshheadjustin_smith: do you think obscure projects are more likely to be useful if they leverage a lisp? :)
23:35justin_smithjoshhead: that is my theory but I cannot prove it
23:36justin_smithjoshhead: often the problem with these small obscure things is they are incomplete
23:36justin_smithjoshhead: a lisp self-evidently contains the tools to round itself out as needed, within your program
23:39TEttingerpuredanger, it's somewhat entertaining that almost everyone mentions error messages. have there been any improvements other than core.typed?
23:40hiredmanthere have been many
23:41puredangersure, every release makes improvements to error messages
23:41TEttingerI mostly just infer what the error message probably means from experience, and look for whatever line numbers are in my code
23:41justin_smithbodie_: OK, I am reading the docs, and yeah it is like a lens
23:41clojurebotIn Ordnung
23:41hiredmanhttps://github.com/clojure/clojure/commit/b8181b7e424230b8d43008f86d03645dbef8edb0 is maybe the most recent commit that improves error messages
23:41puredangerif y'all would just stop making errors, this wouldn't be an issue
23:41joshheadbodie_: An om cursor has an interface similar to an atom. you can dereference it you get dome value, and you can apply a function to it to update the value
23:42justin_smithbodie_: or very similar to the way you can use the same path in get-in / assoc-in / update-in
23:42bbloompuredanger: the part that stands out to me is map-same
23:42justin_smithbodie_: I can go into more detail about any of that if you like
23:42bbloom,(defn map-same [f coll] (into (empty coll) (map f coll)))
23:42clojurebot#'sandbox/map-same
23:42bbloom,(map-same inc [1 2 3 4])
23:42clojurebot[2 3 4 5]
23:42puredangerhiredman: look at https://github.com/clojure/clojure/blob/master/changes.md for error message changes
23:42bbloombut he didn't try lists!
23:42bbloom,(map-same inc '(1 2 3 4))
23:42clojurebot(5 4 3 2)
23:42bbloom:-(
23:43bbloomi've encountered that problem several times
23:43joshheadbodie_: but the data that an atom references actually lives lives at a path in an atom or another cursor. when you update the curso, the changes are reflected in the atom as well
23:43puredangerbbloom: heh
23:44bbloomseems like it might be possible to create a sort of concat-ing lazy seq thing
23:45bbloombut of course stack overflows would strike
23:55numbertendoes anyone know why the implemention of core/pmap adds 2 to the number of availableprocessors? https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L6465
23:56justin_smithnumberten: perhaps related to the fact that the agent thread pool multiplies by 2 and adds 42
23:56bodie_justin_smith, joshhead, thanks for that, didn't see your responses :)
23:56bbloomnumberten: first, regarding pmap...
23:56bbloom~pmap
23:56clojurebotpmap is not what you want
23:57bbloomnumberten: second, the reason it adds 2 is probably purely heuristic for dealing with the operating system scheduler
23:57bodie_justin_smith, if you could tell me which docs you're looking at for cursors, that's probably the best I could get. I assume clj home
23:58bodie_thanks again fellas
23:58numbertenbbloom: alright thanks
23:58bbloomreally, if you had exactly the same number of threads as processors, you'd want that, but other threads are running on the machine, so in reality 1-to-1 doesn't work out quite right
23:58bbloomi'd imagine 2 just happens to work for some cases (maybe not even *many* cases)
23:58joshheadbodie_: good luck
23:58numberteni see
23:59bbloombut pmap is horribly broken since lazy seq chunking and other such changes to clojure... but it was always more of a cool demo than a useful function
23:59puredangerN + 2 is the perfect number of threads
23:59puredangerfor all values of N