#clojure logs

2013-11-11

00:10arrdemTimMc: trash-cli is quite nice... thanks!
00:19`cbpbitemyapp: give me your steam id sometime ;)
00:20arrdem`cbp: starcrafts?
00:20`cbparrdem: only broodwar
00:27arrdem`cbp: aw.. bitemyapp and I've been playing when I have access to an sc2 capable box.
00:27bitemyappmy main games lately have been starcraft 2 and LoL. I'll play DotA2 if somebody invites me.
00:28`cbparrdem: maybe ill get it once i remember my damn blizzard password :P
00:29bitemyapparrdem: DotA2 is available for Linux.
00:29bitemyapparrdem: if you played that, you wouldn't need the other boxen.
00:29bitemyapparrdem: why not install Steam and see how it goes?
00:29arrdemM-x pacman -S steam
00:34arrdemoh right. now I remember why I didn't have steam on linux....
00:34bitemyapparrdem: ?
00:34arrdemthere's a Kerbal Space Program build for linux.
00:35bitemyapparrdem: well install steam, I'm really curious if DotA2 works.
00:35arrdembitemyapp: installed and installing..
00:35bitemyappI like DotA2 quite a bit, better than LoL in most respects and would like to play it if possible.
00:37arrdemI know a bunch of people who favor d2 over LoL I've just never gotten into d2
00:37technomancykerbal sounds nuts (in a good way)
00:37bitemyapparrdem: it's like any other MOBA. It's somewhere in between HoN and LoL in design principle.
00:38bitemyappthe pacing and design of DotA2 is a lot better though. Much more balanced and interesting game.
00:38`cbpdota2 works kinda crappily on my macbook air
00:38`cbpnot like its a machine meant for gaming
00:38`cbpnot that*
00:38bitemyapp :(
00:38`cbp(i play on a pc though)
00:39bitemyappI keep thinking about getting a gaming PC so that I don't have to play on a mac.
00:39`cbpit should be pretty affordabe to build one :P
00:39arrdembitemyapp: if you do don't just build a gaming box. build a multihead dev box with enough power to play games.
00:40bitemyapparrdem: I have a Thinkpad for work, what specifically are you angling for with your recommendation?
00:42arrdembitemyapp: I got a 3x 23" monitor desktop with more than reasonable specs out of a research position freshman year
00:42bitemyappI don't want a ton of hardware.
00:42bitemyappjust a machine that can game.
00:42arrdemshrug. I don't mind the metal, and I don't know enough about portable gaming boxes to comment.
00:43technomancyany machine can game; you just have to pick the games right
00:43arrdemmy perception is that there's a significant price and power primium, but I know some people who are happy with theirs.
00:44arrdemtechnomancy: that's more of an operating system than a game...
00:44technomancydon't get me started on nethack
00:46arrdembitemyapp: it's gonna take a bit to get dota2 downloaded.. I'll let you know what happens tomorrow.
00:47bitemyapparrdem: okiedokie.
00:48swarthynethack the Roguelike? I really enjoy Roguelikes but I haven't played nethack. I loved Brogue, I have a hope to one day code a squad based ala Dungeon Siege style rogue-like.
00:49bitemyappswarthy: have you played dungeon crawl stone soup?
00:49swarthybitemyapp: I have that one was fun as well, I need to fire that one up again soon.
00:50bitemyappI like roguelikes a lot partly because of the ephemerality
00:50bitemyappI was really pleased to see the indie game scene learn from the genre and incorporate it into new ideas.
00:50bitemyappI really like 2d games too.
00:51swarthyYeah, making a word out of ascii or bland tilesets is amazing fun.
00:51swarthyI played d&d for the first time the other day and realized how advanced modern gaming is. The average gamer copes with a ton of systems.
00:51swarthyOther than making up and 'playing a role' d&d was so simple.
00:51bitemyappI like 2d pixel based graphics too.
00:52swarthyBastion is really cool. 3d but locked into isometric.
00:52swarthySo it has this cool 2d feel.
00:54bitemyappI really liked that.
00:55john2xooh roguelikes. I love Brogue. It's so pretty, considering it's ASCII "graphics"
00:55justin_smithnethack is my jam
00:56justin_smithI want to port nethack.el to clojure
00:56justin_smithmake clojure nethack bots
00:56swarthyyeah Brogue did look really good. I'm eager to play the new Dwarf Fortress style game from the makes of Dungeons of Dredmor when it comes out.
00:57swarthymakers*
00:58bitemyappswarthy: oh damn, I really liked Dredmor, what game is that?
01:00bitemyappohhh clockwork empires.
01:00bitemyappyeah that's been long coming
01:00justin_smithone of these weekends I will play amnesia: a machine for pigs some more
01:00justin_smithworks great on my linux system
01:01justin_smith(no wine, native support)
01:01bitemyappjustin_smith: yeah, indie folk are pretty good about mac and linux support.
01:01swarthyI have played games most of my life, and I've recently killed all my old Windows for Gaming Only harddrives. I thought I would rarely play games now. Turns out the Linux story for games is really good now. So that didn't curb my addiction at all.
01:02bitemyappthat's partly why I'm struggling with whether or not I want a dedicated gaming machine.
01:02bitemyappI would consider outsourcing that to consoles, if consoles had the kind of games I like.
01:02arrdembitemyapp: wait 12 months see what happens with steambox, re-evaluate.
01:03justin_smithI used to have a really good rhythm, where I would play some nethack, and when I started doing real good I knew my wits were sharp, so I would do some coding, then I would get stumped and play some more nethack
01:03bitemyapparrdem: that was one option I was considering.
01:03justin_smithbut people at work would think I was just slacking
01:03bitemyappjustin_smith: that's a good idea.
01:03bitemyappjustin_smith: I usually take a walk or make tea to accomplish the same thing.
01:03justin_smithheh, maybe healthier :)
01:04bitemyappI suppose so.
01:04bitemyappThe real point is to empty my mind.
01:04justin_smithI keep my instrument by my desk, so I can stop and play if I am home
01:04justin_smithyeah
01:04justin_smithplaying an instrument is good for that
01:05swarthyYeah I built an HTPC but it turns out it was so cheap and so nice I could just put my gaming GFX card in it was a gaming pc.
01:05swarthyTechnology is too good to get any real work done.
01:05justin_smithalter right next to me on the first level, first room
01:05justin_smith*altar
01:06bitemyapparrdem: http://i.imgur.com/tOTISJF.jpg
01:07arrdembitemyapp: nice
01:15muhoowait, did thrown? get removed from the language since these docs? http://clojuredocs.org/clojure_core/clojure.test/is
01:16muhooit isn't in clojure.test ns public vars AFAICT
01:25coventrymuhoo: I've used thrown? relatively recently. It's a method of the assert-expr multimethod.
01:33mindbender1Please can somebody delete the page at http://en.wikipedia.org/wiki/Communicating_sequential_processes?
01:33justin_smithwhy?
01:33clojurebotwhy is startup slow is busy compiling the `for` macroexpansion
01:34mindbender1justin_smith: because of http://en.wikipedia.org/wiki/Communicating_sequential_processes#Examples
01:35mindbender1How does that represent the objectives of CSP?
01:35mindbender1Boring!
01:36justin_smith /ignore mindBender1
01:39bitemyappmindbender1: you just got plonked old school style son, you should consider that a Sign (TM)
01:40justin_smithbitemyapp: my classic newb mistake, typing a space before the / that made it a command
01:40muhoocoventry: CompilerException java.lang.RuntimeException: Unable to resolve symbol: thrown? in this context, compiling:(/tmp/form-init1896962088566288833.clj:1:771)
01:42muhoomaybe i don't understand multimethods then. i thought the symbol would resolve. pretty sure i've been able to (doc some-multimethod) before
01:56arrdembitemyapp: dota2 is totally playable
01:56arrdemnow bed
01:57bitemyapparrdem: awesome, catch you later.
02:18amalloymuhoo: clojure.test/assert-expr is a multimethod that dispatches on first
02:18amalloyit has a defmethod for the symbol 'thrown?
02:18amalloybut there is no multimethod named thrown? anywhere
03:26muhoooh! duh. then thrown? isn't a function, it's the firt arg to (is
03:26muhoo(is thrown? (expr....)) not (is (thrown? (expr....)))
03:28amalloyno, it's (is (thrown? ...))
03:28amalloybut it's still not a function
03:28muhoonow i have to go look at the source of assert-expr
03:29amalloy'is is a macro that uses the assert-expr multimethod to decide how to expand
03:29amalloyit passes assert-expr the first symbol in the list you're expanding
03:30Jardahmm https://github.com/mylesmegyesi/metis seems great but does anyone know of a variant that could be used to export a 'sanitized' version of the passed data?
03:32JardaI mean, if I hava data like {:my-number "123.4"} and I run it through a validator that :my-number actually is numeric and I would then get {:my-number 123.4} as output
03:32Jardaor do I have to bake it myself
03:37muhooamalloy: thanks, just looked at it, saw where the dispatch is. neat.
05:33sm0kei just copied my project to a new one a changed namespaces
05:34sm0kenow lein repl fails with Unable to resolve symbol create: is in this context
05:34sm0kei doesnt give anything useful in stack trace
05:35sm0keoh wow i misspelled a namespace
05:46sm0kewtf is :ssl :yes!!!11} in
05:46sm0keposta wiki
05:46sm0kepostal*
05:46sm0kecant he just use a straight :yes!
05:59CookedGryphonsm0ke: you can just use true
05:59CookedGryphonthat annoyed me too
05:59CookedGryphoni think it's just anything truthy
06:01sm0keCookedGryphon: thanks i thought that so
06:01sm0kefunny that author would give such contrived example
06:01CookedGryphonsend a pull request chganging the docs? It genuinely put me off using postal for a while
06:02sm0kehehe yea i will do that
06:02CookedGryphonI only used it as a last resort, and functionally it's the best I've tried
06:02sm0keCookedGryphon: do you seem to have used html formatting in your mails?
06:02sm0keany easy way to do that?
06:02CookedGryphonyeah
06:02sm0ketell me
06:02CookedGryphonone second, i'll find it
06:04CookedGryphonInstead of a plain text string, send it [:alternative {:type "text/plain" :content "blah"}{:type "text/html; charset=utf-8" :content (hiccup [:html [:body [:p "blah"]]])}]
06:05CookedGryphonthat was probably too long to type inline, sorry, should have done a refheap
06:05sm0keawesome sauce
06:05sm0kei am copying that
06:10sm0keCookedGryphon: just wondering whats that :alternative?
06:10sm0kefallback from clients which dont have html
06:10sm0kefor*
06:13CookedGryphonI can't remember, I think so yes. It's in the README
06:13CookedGryphonyou can do attachments, multipart and all sorts in that format
06:13sm0keok thanks
07:00ambroseb_only 20 hours left in the Typed Clojure dev campaign. Don't miss out! ;) http://www.indiegogo.com/projects/typed-clojure
07:01rstandyhello Clojure community
07:01ambroseb_rstandy: hello there
07:01Jardaambroseb_: why should I care about typed clojure
07:02rstandyI'm sorry to ask a possible flame war starting question, but, what framework do people use in Clojure when developing webapps?
07:02justin_smithrstandy: not a flame-invoking question at all
07:03rstandywell, then this is a really neat community :-)
07:03ambroseb_Jarda: it's AFAIK the only way to make strong static claims about Clojure code.
07:03carkrstandy: i only use ring, but it's not a full featured framework
07:03justin_smithliberator, pedastel, Luminous are popular
07:04CookedGryphonI tend to avoid frameworks and use the small libraries i need
07:04justin_smiththere have been flames about the design of Noir in the past, but even the autor of noir depricated it :)
07:04gwillickersrstandy: i just started too, i went with compojure
07:04ambroseb_Jarda: prevents you from misusing null, *really* helps using plain maps.
07:04gwillickerswhich sits atop ring
07:04rstandyjustin_smith: thank, I've seen there are various frameworks, but being new to Clojure I would love to invest some time in the "right" one...
07:04ambroseb_Jarda: and it's just a library, sprinkle it where you want.
07:05carkrstandy: most frameworks are based on ring, you c&n't go wrong by learning that
07:05JardaI'm using compojure for routing, haven't felt the need for anything else than compojure+ring
07:05rstandyjustin_smith: "the right one" being that which is popular enough to give me documentation, great community to ask, ecc.
07:05CookedGryphonthing is, if you just go with small libraries, building on top of ring and maybe compojure, anything else you use isn't a large investment
07:05noidiJarda, +1
07:05CookedGryphonyou can swap out smaller components when a better library comes along
07:05justin_smithrstandy: I actually am a developer for a framework, that will likely be getting its official "public release" in a day or two, I could say more after that, don't want to overshare before the event
07:05noidiwe've been happily using ring + compojure + stencil for templating
07:06justin_smithCookedGryphon: yeah, start with ring and compojure, most things should modularly combine with those
07:06justin_smithinc CookedGryphon
07:06JardaI use hickup templates, haven't really looked into alternatives
07:06justin_smith(inc CookedGryphon)
07:06lazybot⇒ 1
07:06justin_smiththere we go
07:06rstandywow so many choices
07:06gwillickersi went hiccup too, no complaints
07:06justin_smithrstandy: they are made of modular parts, mostly
07:06Jardaanything that builds on top of ring is fine as long as they do not try to hide ring
07:07justin_smithyeah
07:07rstandyany commercial site I can see to have an idea of what I can accomplish with which framework?
07:07justin_smithit is not so much "frameworks" you get with clojure as 'sets of libs that work together'
07:07carkthere are some frameworks
07:07rstandyjustin_smith: right, I understand it's one of the objectives of Clojure too
07:07carkmedestal maybe ?
07:07rstandyjustin_smith: this is so good
07:07carkpedestal*
07:08Jardain my philosophy: frameworks that try to do everything _always_ fail at doing every possible use case -> go with the one that helps but doesn't block you when you need to go low-level
07:08justin_smiththe one my group is releasing in a day or two from now is a similar model to luminous - giving you a decent set of default libs as middleware, and leaving things modular
07:08rstandyJarda: very true! I used Weblocks from CL, which is very nice, but forced me again to work its way
07:09carkah there was hunchentoot in CL ... nothing else was need"ed, and so easy to use !
07:09justin_smithpedastel is a more "total solution" top to bottom design (for better and/or worse)
07:10CookedGryphona rule of thumb I have found from experience - avoid anything which requires you to use a defblah macro
07:10rstandyok, so pedestal force you to model in its way
07:10justin_smithCookedGryphon: you are trying to get inced by me again aren't you?
07:10CookedGryphonusually means they are doing something unidiomatic which isn't going to compose or play nice with other things down the line
07:10justin_smithvery good advice
07:11CookedGryphon:)
07:11rstandylooking for compojure
07:11carki think the defXXXX thing isn't too bad as long as there is a functional interface as well
07:13CookedGryphoncark: yeah, and as long as it's not doing too much to obscure how it actually works underneath. I've never really liked the magic of compojure's defroutes, but it does make for a good quick-start guide
07:13rstandyso for example, if I need a webapp with session management and login/registration, what can I use to start very fast?
07:13justin_smithrstandy: there are ring middlewares for session and auth
07:13justin_smithfriend is great for auth
07:14justin_smithI did a kind of roll-my-own but plan to upgrade to friend
07:14justin_smithring-session for session management
07:14rstandyjustin_smith: thanks! looking for friend right now
07:14justin_smithhttps://github.com/cemerick/friend
07:14justin_smithhttp://clojuredocs.org/ring/ring.middleware.session/wrap-session
07:17rstandythank you very much guys, very helpful!
07:18justin_smithCookedGryphon: regarding def-foo ugliness, for the webapp template I've been working on, we ended up dropping compojure because it was so defroutes centric, and we wanted to manage the routes via the cms
07:19justin_smithso that a frontend guy who does no clojure could use the cms interface to define the page he needs
07:19justin_smithand it is messy integrating routes created as data in a db with a defroutes model
07:20rstandylooking for all of this libraries
07:20justin_smithrstandy: that is what lein templates are good for
07:21justin_smithit basically copy/pastes a sane default app setup, complete with requiring the right deps
07:23justin_smithhttps://clojars.org/search?q=lein-template
07:24justin_smithfor anything that defines a foo/lein-template you should be able to run lein new foo
07:26justin_smithso from that list you have compojure-app, cljs-template, mies, noir, pedestal-service, luminus, each providing some kind of web service / web app functionality
07:27justin_smithsadly clojars has not been auto-indexing quite right, because I know of others that exist that are not on that results page
07:37sm0kewhat a mess i am unable to send mails with postal
07:37justin_smiththere is a good postmark lib for clojure
07:37sm0keit says {:code 0, :error :SUCCESS, :message message sent} but i dont get no mail
07:38CookedGryphonodd, spam?
07:38justin_smithsm0ke: the reason people use postmark, is email providers use whitelists
07:38CookedGryphonwhat sort of account are you sending from sm0ke
07:38sm0kenothing in spam too
07:38justin_smithroll your own email server is very hard because you need to get on whitelists and shit, easier to use a whitelisted service
07:39CookedGryphondepending on your use case though, you might want to just send from a gmail account (that's what i have been doing)
07:39justin_smithCookedGryphon: from the looks of it, postal is not imap or such, it is actual smtp, so it would not get far on the open net
07:39sm0keCookedGryphon: yes me too
07:39sm0kei am using a gmail accout
07:39CookedGryphonall the appropriate gmail options set?
07:39sm0kewhy would postal be so cruel to give success message
07:40CookedGryphonit's not suspicious about the sending and asking for a captcha on the web interface is it?
07:40sm0keCookedGryphon: i guess so .. everything he has in docs
07:40CookedGryphoni mean on the gmail site itself
07:40CookedGryphonimap and smtp aren't on by default
07:40sm0kei am using smtp settings only
07:40CookedGryphonbut presumably you wouldn't then get a success message
07:40sm0kei only need to send
07:41justin_smithsm0ke: does mail within localhost work?
07:41sm0kehmm i guess i need only sendmail installed on my machine right?
07:41justin_smithpostal should be doing what sendmail does already
07:42sm0kei think it uses a mail agent underneath
07:42CookedGryphonyou don't need anything set up locally to send with a gmail account
07:42justin_smithCookedGryphon: the reason I suggested localhost testing, is that eliminates a bunch of weird variables
07:43CookedGryphonyeah, introduces a load more though to have a working local mailserver
07:43sm0kehmm weird i jusr installed ssmtp and everything fails now
07:43justin_smithsm0ke: what os are you using? a normal linux os will set up local mail (for system messages to administrator)
07:43sm0kei get {:code 1, :error nil, :message nil}
07:43sm0keubuntu 12.04
07:43justin_smithyeah, ubuntu already has mail out of the box
07:44sm0keeee
07:44justin_smiththat is how root gets messages about system status stuff
07:44justin_smithwith a normal install
07:44justin_smitherr... maybe I was wrong
07:45justin_smithdebian does this, but ubuntu may not
07:45justin_smithpostfix sets it up though
07:45sm0kei have postfix
07:45sm0kessmtp stopped it though
07:45sm0keand now i get errors
07:45sm0kerightfully*
07:46CookedGryphonsm0ke: so my settings for sending via gmail are (send-message {:username "...@gmail.com" :password "***" :host smtp.gmail.com :port 465 :ssl true} {:to "" :subject "" :body ""})
07:46CookedGryphonare you doing exactly the same?
07:47justin_smithsm0ke: you can test local mail by using mail or mutt, it should just install and work
07:47justin_smithCookedGryphon: so you are able to use the postal lib with gmail?
07:47CookedGryphonyeah
07:47CookedGryphonwait, sorry, user and pass, not username and password
07:47sm0kehmm weird
07:48CookedGryphoni rename them on teh way in so my config is consistent
07:48gunsI use postal with smtp.gmail.com; works well. Maybe the machine sm0ke is hitting is failing
07:48sm0kei am using ^{:user "... " :pass "**"} ..with that meta sign
07:48sm0keweird thats what the doc mentions
07:48CookedGryphonyeah, don't know what on earth that's about
07:48CookedGryphonteh docs need editing
07:48CookedGryphonmakes far more sense to just send settings then message
07:49sm0kehmm let me try your version
07:49CookedGryphoni was including a :from in the message too
07:49CookedGryphongmail might need that
07:49sm0keyup i have that already
07:51CookedGryphonhmm, there's a pull request to fix the docs from 2 years ago...
07:58sm0kesome progress, i get com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required. now
07:58justin_smithsounds like its time to fork it just to get better docs
07:58justin_smithlol
07:58sm0keweird though
08:04sm0keCookedGryphon: hey it worked
08:04sm0keactually it needs :user and :pass
08:04sm0kenot :username and :password
08:04sm0kei think main problem was with the meta sign
08:06sm0kebye for now
08:17tim___dnolen: ping
08:26gtuckerkelloggforcer, with the simple setup, elpy-shell-send-region-or-buffer only seems to work for me with an active region
08:27justin_smithgtuckerkellogg: wrong channel?
08:27gtuckerkelloggjustin_smith, indeed!
08:29justin_smiththis here city slicker thinks he can use INDENTATION instead of PARENTHESIS as God intended
08:29justin_smithget 'im boys
08:29noidi:D
08:33tbaldridge~guards
08:33clojurebotSEIZE HIM!
08:33mdrogalisHeh
08:33gtuckerkellogglol
08:53hyPiRion~gourds
08:53clojurebotSQUEEZE HIM!
09:26teromThere seems to be a JSON-RPC library for Clojure called clj-json-rpc for the server side. I'm looking for a library to help building a JSON-RPC client, is there a such thing already?
09:28justin_smithterom: seems like with cheshire and one of the http client libs it would be pretty simple without a dedicated json-rpc client
09:29justin_smithterom: the spec is simple enough http://json-rpc.org/wiki/specification
09:30justin_smithoh, I see that version 2 is a bit more complex http://www.jsonrpc.org/specification
09:37rstandyjust another newbie question: is there some in production web app or site developed in clojure?
09:37justin_smithI have deployed a few
09:37justin_smith(my company, I did the clojure part on the backend)
09:38justin_smiththere is an out of date list on clojure.org somewhere
09:38justin_smithsoundcloud
09:38rstandyjustin_smith: wow, can I see of them (those which are publicly available)
09:38justin_smithhttp://corp.zinio.com/ the only evidence of clojure is how fast it loads
09:38justin_smithI guess
09:39justin_smithhttp://weareinstrument.com/work/featured/the-build this one is pretty awesome actually
09:39rstandyjustin_smith: souncloud.org is simply wonderful!
09:39justin_smithboth that blog, and the site it links to, use clojure with the framework I helped write, though I have not coded much for those two projects
09:40justin_smithhttp://thebuildfilm.com/ be sure to see this, the actual site that last blog post was about
09:40justin_smithflash-like ui in html5
09:41justin_smithwith clojure backend, of course
09:42justin_smithalmost forgot this one: done in clojure + clojurescript http://onenorthpdx.com/
09:42rstandyjustin_smith: by backend you mean that clojure builds the html pages or not?
09:42justin_smithit handles the cms
09:42justin_smithit serves all the data
09:42justin_smithhandles the requests
09:42justin_smithrenders templates
09:42rstandyjustin_smith: ok, got it
09:43justin_smithresizes images for your screen resolution (caching existing resizes)
09:43rstandyjustin_smith: thank you very much for the info man
09:43justin_smithwith that last one (one north) the whole UI is built in clojurescript using core.async to handle events
09:44rstandyjustin_smith: wow
09:44rstandyjustin_smith: awesome sites!
09:44justin_smiththanks, that's mostly because we have awesome designers
09:44justin_smithand very meticulous frontend devs that can realize those designs
09:45justin_smithbut it helps that I can make sure the pages load fast and get the right data too :)
09:45rstandyjustin_smith: is your backend donwlodable free software? :-)))
09:45justin_smithrstandy: it is open source, we will be announcing and publicising it soon
09:46rstandyjustin_smith: this is very interesting!!! Will you email the clojure ml?
09:46justin_smithbasically "watch this space", we have a nice frontend site for intro and docs that will be public in a day or two
09:46justin_smithyeah, I think that is the plan
09:47rstandyjustin_smith: exciting news, I hope to be productive with clojure pretty soon, I want to push it in my workplace
09:47justin_smithit is a pretty cool setup, I can take only marginal credit, the main dev is an old friend of mine that pulled me in to help because he knew I liked programming lisp
09:48justin_smithrstandy: huge selling points are reduced server resources (thus less deployment cost) massively reduced development time (meaning more agile to accomidate design changes, and your project will never be behind schedule for backend reasons)
09:48rstandyjustin_smith: nice, what was your language and environment before clojure
09:48rstandyjustin_smith: huge selling points!
09:48justin_smithI got hired to do clojure
09:49justin_smithbefore that they were using ruby
09:49justin_smithbut server costs and reliability sucked
09:49rstandyjustin_smith: dream job for me :D
09:49justin_smithbefore that php
09:49justin_smithrstandy: it is very nice
09:49rstandyjustin_smith: yeah, ruby sucks in many ways
09:49rstandyjustin_smith: are you coming from CL+Emacs
09:49rstandy+Slime?
09:49justin_smithit is especially since I can be productive enough in clojure that I spend more of my time honing my skills and improving our libs than I spend developing sites
09:50justin_smithyeah, common lisp / scheme / ocaml
09:50justin_smithdefinitely emacs no matter what, but that's the tool not the medium :)
09:51rstandyjustin_smith: yeah, any advice/tip for an CL+Emacs+Slime developer approaching clojure?
09:51justin_smithactually I was not even a professional programmer before jumping into this, I was just fascinated by algorithms and functional programming
09:51justin_smithhmm
09:51justin_smithget cider
09:51justin_smithwhich is the update to nrepl.el
09:52justin_smithuse paredit, after a few days learning it it is indespensible
09:52rstandyjustin_smith: yeah! Wonderful mode I already use in CL
09:52justin_smithand (source fn) (doc fn) are your friends :)
09:53justin_smithoh, and throw (ns-publics ns) in the mix too
09:53rstandyjustin_smith: I installed cider, and I'm starting to explore clojre through it, but I miss the Slime Inspector
09:53justin_smithwe are working on a cdt web frontend
09:53justin_smithI have not had much luck with ritz
09:54rstandyjustin_smith: so a Slime-like inspector is still missing in clojure
09:54justin_smithcdt assumes you are connecting to a separate program that is being debugged, so we can connect to the process with the server, have an html UI, and click on stack trace lines to evaluate expressions in that context / see locals
09:54nDuff...well, there _is_ ritz
09:55nDuff...if you're willing to go through the pain to set it up.
09:55justin_smithrstandy: theoretically ritz can do that stuff, I have not had luck with it
09:55rstandyjustin_smith: will check that then
09:55justin_smithwe looked at ritz as the backend for our web-based debugger, and decided cdt was easier and had all the functionality we needed
09:55rstandyjustin_smith: ok, sometimes do you miss some CL and Slime features when using clojure (sorry for so many questions)?
09:55justin_smithyeah, for sure
09:56justin_smithlike the step debugging etc.
09:56rstandyjustin_smith: just trying to understand what I'll miss and what I'll gather with clojure
09:56justin_smithbut, with immutible data structures and a more strictly functional approach, I find invasive debugging less neccessary
09:56justin_smithI can do a lot just by verifying each function produces the right output for the expected input
09:57justin_smithalso I often miss static checks and currying from ocaml
09:58rstandyjustin_smith: man your answers are really useful for me, many thanks!
09:58justin_smithspeaking of debugging, I released a middleware for ring the other day called groundhog, that archives requests so that they can be reconstructed and replayed to verify bugfixes
09:58justin_smithhttps://github.com/noisesmith/groundhog
09:58rstandyjustin_smith: wow, nice
09:59justin_smithI need to update that readme, the latest is 0.4
09:59justin_smith*0.0.4
10:00rstandyjustin_smith: You gave me so much info to starts with that I'm tempted to abandon the idea to learn clojure... :D
10:01justin_smith?
10:01justin_smithwhy would you not want to learn clojure?
10:01rstandyjustin_smith: just joking, it's so much good info that I want to learn everything now!
10:01justin_smithhah
10:02rstandyjustin_smith: very intriguing language and community with fantastic libraries, this is what the clojure world is for me right now
10:02justin_smithI concur
10:02justin_smithit's great to work with a language that I unreservedly love
10:03rstandyjustin_smith: hope to be able to become very productive soon. You know, when the boss ask what work has been done, I have to answer something :D
10:03rstandyjustin_smith: I tried to stick with CL, but lack of libraries is becoming to restrictive
10:03mdrogalisrstandy: Just take your time. It's worth learning, but go slowly and thoroughly.
10:03justin_smithwell, clojure does have some features (and default / recommended coding style) that leads to productivity once you internalize it
10:04rstandyjustin_smith: very interesting perspective about OOP. I think I more or less agree. It's interesting to see how complexity is managed with the clojure way
10:05cemerickdnolen: is continuing to support :export meta carrying an alternative name (rather than truthiness) a real objective? In the face of supporting downstream mutability, it complicates things significantly.
10:06rstandyjustin_smith: thanks, man, very nice and helpful!
10:06rstandyjustin_smith: have a nice day and hope to talk with you again
10:06justin_smiththanks, you too
10:07dnolencemerick: I don't really understand what you just said
10:07shoshinhello
10:07shoshinhow does one iterate in clojure?
10:08shoshini want to iterate a body twice. how do i achieve this using doseq?
10:08justin_smithshoshin: iterate to do an action, or iterate a transformation of a sequential input?
10:08cemerickdnolen: right now, you can (defn ^{:export "foo"} bar 5); bar will be emitted and optimized away by GClosure, foo will be an exported "symbol", changes to which will not affect any fns that refer to bar in cljs source.
10:08Morgawr,(doc dotimes)
10:08clojurebot"([bindings & body]); bindings => name n Repeatedly executes body (presumably for side-effects) with name bound to integers from 0 through n-1."
10:08justin_smith,(dotimes [i 2] (print i))
10:08clojurebot01
10:09justin_smithMorgawr: beat me to it
10:09Morgawr:P
10:09Morgawrhow do you @ clojurebot to somebody?
10:09Morgawr(if it's even possible)
10:09justin_smithhmm
10:09llasram,(str "like this?") ; Morgawr
10:09clojurebot"like this?"
10:09MorgawrI could do something like
10:10dnolencemerick: yes I know that, but I don't understand what you said above.
10:10cemerickdnolen: The fix for CLJS-670 will make such an arrangement impossible, since two properties will need to change in order to maintain consistency between the exported property, and the "internal" one that GClosure has renamed, etc.
10:10Morgawr,(str "shoshin:" (doc dotimes))
10:10clojurebot"shoshin:([bindings & body]); bindings => name n Repeatedly executes body (presumably for side-effects) with name bound to integers from 0 through n-1."
10:10Morgawr:D
10:10shoshinMorgawr thanks! will try!
10:10Morgawrrefer to justin_smith's example (which was probably more useful)
10:10seangrove,(println (str "seangrove:" (doc dotimes)))
10:10clojurebotseangrove:([bindings & body]); bindings => name n Repeatedly executes body (presumably for side-effects) with name bound to integers from 0 through n-1.\n
10:11Morgawrseangrove: that's better
10:11seangroveMorgawr: Just wondering if there's another chance for a bot quine... it's almost been one year now
10:11dnolencemerick: I'm pretty sure this has come up before, what's the problem with ^:export ^:expose or something like that?
10:11Morgawra bot quine?
10:12justin_smithMorgawr: making the bots trigger one another, infinitely
10:12rstandyjustin_smith: so, one last question: the most advanced ide, editor, tool for writing and debugging cloujre apps?
10:12Morgawrhaha
10:12cemerickdnolen: you mean expose in the @expose GClosure sense?
10:12shoshinMorgawr http://clojuredocs.org/clojure_core/clojure.core/dorun i'm looking for something like example in the first case. repeat some action n number of times.
10:12Morgawrrstandy: probably emacs. I personally use both vim and LightTable (LightTable is getting really good)
10:12seangroveMorgawr: Yeah, last one was in December 2012...
10:12justin_smithrstandy: : we had a "show your editing environment" night for the last clojerks pdx
10:12Morgawrshoshin: that's another way, yes
10:13justin_smithrstandy: emacs and vim looked the most impressive
10:13justin_smiththough cursive looked nice if you want a java style IDE experience
10:13shoshinMorgawr doesn't seem to work though. :/
10:13shoshini get a null pointer exception.
10:13Morgawrdorun is to resolve lazy sequences
10:13justin_smithlight table was surprisingly disappointing, though it could be because the guy presenting it wasn't adept enough with it
10:13Morgawrdotimes is to run N times the same expression
10:13rstandyjustin_smith: I'm definately on the Emacs side, but what should I use? swank-clojure + swank-cdt? Or cider?
10:14rstandyand nrepl?
10:14justin_smithrstandy: cider or nrepl
10:14justin_smithswank is to be avoided at this point
10:14dnolencemerick: yes, if I recall.
10:14rstandyjustin_smith: no one is the real winner right now, then
10:14justin_smithrstandy: try cider first, since nrepl is transitioning to that
10:14Morgawr,(dotimes [_ 5] (println "hi"))
10:14clojurebothi\nhi\nhi\nhi\nhi\n
10:14Morgawr^
10:14rstandyoh ok, so cdt is not recommended anymore
10:14Morgawror use n instead of _ if you care about the variable bound to the iteration count
10:14justin_smithrstandy: cdt is only partially tied to swank
10:15justin_smithrstandy: I use it without using swank at all
10:15rstandyjustin_smith: ah ok
10:15justin_smithvia the browser
10:15justin_smithnot even in the editor
10:15rstandyjustin_smith: sorry for the silly question
10:15justin_smithnp
10:15justin_smithglad to help
10:15rstandyjustin_smith: :-)
10:16CoconutCrabokay, maybe it would be more proper to ask in #emacs instead, but how can one remove nrepl from emacs (via package.el) to install cider?
10:16dnolencemerick: I'm guess didn't affect *set-print-fn* because we didn't give it an initial value?
10:16dnolener *print-fn*
10:16cemerickdnolen: Two different topics, really. First, we definitely don't want @expose, it takes a bunch of analysis/optimizations off the table when applied to fns, which inevitably yields piles of (spurious AFAICT based on testing) warnings.
10:17cemerickdnolen: the issue with the alternative ^:export name is that we're setting up two different properties when it's used, a natural source of inconsistency if there's mutability about.
10:17justin_smithCoconutCrab: in the package interface, d will mark a package for deletion, and x will act on all marks
10:18CoconutCrabjustin_smith: oh, silly me... sorry for bothering you...
10:18CoconutCraband thank for answering
10:18justin_smithCoconutCrab: no problem, it is not intuitive unless you are used to gnus, mh, dired, and all the other little emacs things that use the mark / act paradigm
10:19justin_smiththe downside with emacs is it is not consistent with "normal", the upside is it is pretty good at being internally consistent
10:19CoconutCrabjustin_smith: I see now uninstall option and tend to use '-' for marking
10:19CoconutCrab(like in debian's aptitude)
10:20CoconutCrabthen I forgot that emacs has C-h m...
10:20justin_smithyeah, never expect emacs to act like another program you are used to...
10:20augustlwhat _does_ harmonikit sound like? :) https://twitter.com/richhickey/status/399918185450704897
10:20cemerickdnolen: well, set-print-fn! was never really "exposed", at least w.r.t. mutation, because it was just aliased to the exported symbol.
10:21justin_smithaugustl: I would say a clojure library for midi controlled compressed air actuated harmonica robots
10:21napperdoes anyone have a recconmendation for image manipulation libs with clojure?
10:21justin_smithaugustl: and I will be severely disappointed if it is not that
10:21justin_smithnapper: what kind of manipulations?
10:22justin_smithnapper: for basic stuff interop with BufferedImage has worked well for me, but there is also imgscalr
10:22cemerickdnolen: anyway, my fundamental Q is whether I can sacrifice e.g. ^{:export "some.other.name"} in order to support downstream mutation of exported properties. They're really fundamentally incompatible. Alternatively, we could say that properties exported with alternative names are read-only.
10:23cemericki.e. retain the same semantics they have now, and don't get the same support as described in CLJS-670
10:23napperjustin_smith: to begin, just plastering images together to make css sprites - but I'm always a fan of graph-based-algorithum-image-manipulation
10:23karlsnapper: i tried to find an image manipulation library that does more than scale/rotate, but couldn't. had to drop down to java.
10:24napperkarls: it's been a few years for me. what is the current java img-lib?
10:24napperkarls: ie, in python its PIL
10:25justin_smithnapper: I use java.awt and javax.imageio
10:25karlsnapper: i re-wrote something that originally used PIL, in clojure. i didn't use a library at all. the interop is so good that i just ended up using BufferedImage related java facilities.
10:26karlsnapper: what justin_smith said :-)
10:26justin_smiththat's java.awt.image.BufferedImage, if you are looking for the javadoc
10:26napperjustin_smith, awesome, I'll look into them. BufferedImage + those libs
10:27justin_smithnapper: they come as part of the jvm, you just need to import them
10:27napperjustin_smith, karls, I'll see what I can do about building something more then just rotation and scaling. :)
10:27justin_smithnext part is adapting yourself to learning via javadoc
10:27justin_smithnapper: please do! though you may just find the built in interop is enough (as we did)
10:28napperjustin_smith, heh, there was a time when I was a j2ee dev, then I found python o:
10:28napperthanks for the leads!
10:28justin_smithnp
10:34johnpeteHi - I'm trying Clojure and Compojure for the first time. The lein template has given me some code that has an application of some function called -> How do I find what this function is? I can't google it!
10:35seangrovecemerick dnolen: Any tickets or help you'd like with cljs or cljsbuild?
10:35justin_smithwow, it looks like the analemma svg generation library doesn't use java interop, so it may be clojurescript compatible
10:35karls,(doc ->)
10:35clojurebot"([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."
10:35karlsor http://clojuredocs.org/clojure_core/clojure.core/-%3E
10:35seangrove,(println (str "johnpete: " (doc ->)))
10:35clojurebotjohnpete: ([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc.\n
10:36mdrogalisjohnpete: Yeah it's a weird one. It's called "thread first".
10:36justin_smithjohnpete: also there is a cool site for searching symbols that other engines don't index http://symbolhound.com/?q=clojure+-%3E
10:36johnpetegreat, thanks everyone
10:38cemerickseangrove: cljsbuild is semi-frozen until 1.0.0 is out, then we can start seriously recasting it. If you're in an investigative mood, you could look into what is in certain Chrome extensions that breaks the browser-REPL, e.g. https://github.com/emezeske/lein-cljsbuild/issues/262 and https://github.com/cemerick/austin/issues/17
10:38seangrovecemerick: Uhg
10:39cemerickheh
10:39cemerickThe one in the first link is far simpler than the Google Voice extension, so it might be tractable.
10:39seangrovecemerick: Will check into it, we make a chrome extension as our primary product right now :)
10:39cemerickseangrove: my exact sentiment
10:40cemerickseangrove: That's interesting. As the primary business, or is the extension a complement to an online service, etc?
10:40seangrovecemerick: http://www.zenboxapp.com/ - clojure and clojurescript
10:41seangrovecemerick: As an extension working inside of gmail with other unaware extensions... it's all a nightmare
10:42cemerickseangrove: what's the business model, if I may ask?
10:42seangrovecemerick: We charge people for premium features, pretty straightforward
10:43cemerickseangrove: oh, cool; I guess the upsell is in the extension itself? I didn't see anything obvious about it on the site.
10:43seangrovecemerick: Yeah, exactly. Most things are free and it just works, but when someone reaches deeper into the integrations we start a time trial, and then get cc info, charge, etc.
10:44cemericknice
10:44cemerickseangrove: the reviews are glowing, congrats. :-)
10:44justin_smithor if they want the sidebar to wear a custom hat or get that powerup they need to beat the level...
10:44seangrovecemerick: Wsan't always that way, but things have been moving in the right direction :) Getting reified keywords into cljs helped quite a bit
10:45justin_smithseangrove: that does look cool, our producers all use gmail, I'll see if they use it already or might find it useful
10:45seangrovejustin_smith: IAP for level upgrades coming soon, I suppose
10:45justin_smithheh
10:45justin_smithangry birds does well with holiday editions
10:46justin_smith"$1 to add the christmas theme, $100 to remove it again"
10:46seangrovehah
10:47justin_smithso for a chrome extension do you basically compile to a javascript package?
10:48seangrovejustin_smith: I believe it's a tar, but we use openforge to take care of the gritty details these days
10:48justin_smithcool
10:54mdrogalisAnyone here using ZooKeeper for coordination? #zookeeper is a bit quiet.
10:54justin_smithit's near the top of my "we should be using this lib" pile
10:54justin_smithhaven't tried it though
10:54TheLastProject,(println ((first '[One Two Three]) (nth '[One Two Three] 2)) (second '[One Two Three]))
10:54clojurebotnil Two\n
10:54TheLastProjectHmm...
10:54mdrogalisNot really a lib, more of a service.
10:55justin_smithmdrogalis: I meant the clojure client lib
10:55mdrogalisjustin_smith: Ah, understood.
10:55TheLastProject,(println (join " "((first '[One Two Three]) (nth '[One Two Three] 2))) (second '[One Two Three]))
10:55clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: join in this context, compiling:(NO_SOURCE_PATH:0:0)>
10:55justin_smithTheLastProject: did you mean (println [(first ...
10:55mdrogalisIt has some annoying semantics around watching for changes.
10:56TheLastProjectjustin_smith: I'm trying to get the dispatch feature to work better, but every attempt I throw at it just turns into chaos
10:56justin_smithTheLastProject: ((first '[One Two Three])) will try to execute 'One as a function
10:57TimMcmdrogalis: We are, but I can't claim to be familiar with it.
10:57mdrogalisTimMc: Hmm, alrighty. Thanks anyway :)
10:57justin_smithone of these weekends I plan to make a zookeeper client as a ring middleware
10:57mdrogalisIt pretty much supports "watching" a piece of state. But after the event triggers, it kills the watch.
10:57justin_smithso coordination is ensured with each request
10:58mdrogalisSo it's more like "watch-once" semantics.
10:58justin_smithcan't you make your response action create the watch again?
10:58justin_smithrecursion :)
10:58TheLastProjectjustin_smith: http://pastebin.com/F9rEx7KG (line 29) - I still have two problems with it. It somehow complains about "java.lang.String cannot be cast to clojure.lang.IFn", but I can't figure out why, and I still need to figure out how to have it also send all additional arguments given, ugh...
10:58mdrogalisjustin_smith: It's a distributed system. Interesting things can happen inbetween that would be missed.
10:59justin_smithmdrogalis: true
10:59justin_smithTheLastProject: that error means that you put something that returns a string in the calling position
11:00TheLastProjectjustin_smith: I can't see what that would be, though. If I use print to test it it nicely resolves to "list clothing" and the likes, which (dispatch) should resolve to the function before calling...
11:01justin_smithTheLastProject: I am going to do a small cleanup of your code to make it a little easier to think about, one moment
11:01ltwwhat's the best approach for creating a library with support for core.typed, but that doesn't require it?
11:01TheLastProjectjustin_smith: I guess it could need that. I can't say it doesn't look like an utter mess. Wonder how much different your version will be from mine, hmm
11:02ltwi was thinking multiple versions (i.e. 0.1.0 and 0.1.0-typed)
11:03justin_smithTheLastProject: mainly I am using let so you don't have repeated calls to the same function noising things up, I'll paste it in a moment
11:05justin_smithTheLastProject: https://www.refheap.com/20719
11:06justin_smiththat is not yet correct, but I think it is easier to read
11:06justin_smithI put it on refheap because refheap is less spammy
11:06teromjustin_smith: thanks. I've heard of cheshire but not used it. Version 2.0 of JSON-RPC definetely seems a little bit more complex... maybe I'll try to come up with a library of my own.
11:07justin_smithterom: cheshire is very easy to use, it turns clojure vectors / maps / strings / numbers into json, and the reverse
11:10TheLastProjectjustin_smith: I should've probably updated the println above, but I'm trying to make it execute (list-clothing upper) if the user types "list upper clothing" and, after I get that working, also take the other parameters so I can get add-clothing to work, but those as just strings
11:11TheLastProjectjustin_smith: I see that your command thing only takes the first parameter :P
11:11justin_smithTheLastProject: was that my mistake? I thought I was just following the nesting of the original, one sec
11:12justin_smithoh, I did mess it up, but neither of our versions are correct :)
11:12TheLastProjectWell, I know mine isn't correct
11:12TheLastProjectAt least yours looks more readable
11:13justin_smithin your original, if you linebreak and autoindent, you can see that the result of calling dispatch on the third arg is being called as a function
11:13justin_smithwith (collection ...) as its arg
11:14TheLastProjectHuh. I tried to very carefully retype it with print and it returned "first third" when I tried to do that. Now I wonder if I'm really so used to how most object-oriented languages use () that I just can't even read it properly
11:15TheLastProjects/print/println
11:17justin_smithTheLastProject: https://www.refheap.com/20719
11:17justin_smithedited, I think closer to what you want
11:17justin_smithusing amalloy_'s suggestion to use apply
11:18justin_smithso we split that input into tokens, first of those looks up the command, rest are args, first arg looks up the collection, and then we just pass in the rest
11:18TheLastProjectThe first and third arg combined is supposed to be the command :x
11:18justin_smithok, but you know how to fix that, right?
11:19justin_smithby changing the definition of command in the let statement
11:19TheLastProjectWell, no, because command ((first tokens) (nth tokens2)) causes Clojure to complain about it being a string
11:19TheLastProjectErr...
11:20TheLastProjectYeah, that's what I'm trying to do, but I can't understand why it complains it is a string that it can't convert to a function
11:20justin_smith((first tokens)) tries to execute the return value of (first tokens)
11:20TheLastProjects/tokens2/tokens 2
11:20TheLastProjectOh...
11:20TheLastProjectOh, darn it
11:20justin_smith, (:hello {:hello "world"})
11:20clojurebot"world"
11:20justin_smith, ((:hello {:hello "world"}))
11:20clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
11:20justin_smiththat is your error
11:21justin_smith() is not for grouping in clojure
11:21justin_smithever
11:21justin_smithit can make a literal list, or apply a function
11:21justin_smiththat's it
11:21TheLastProjectOkay, I need to get that in my head
11:21TheLastProjectBut now I wonder how to "group" it then because otherwise it will complain about having too many arguments, hmm...
11:22justin_smithwhat you want is to construct the string so it matches your lookup table
11:22justin_smith,(str "add" \space "clothing")
11:22clojurebot"add clothing"
11:22justin_smith,(clojure.string/join " " ["add" "clothing"])
11:22clojurebot"add clothing"
11:22bja,(+ 1 2 3)
11:22clojurebot6
11:22bjawow, didn't realize that worked for anybody
11:23justin_smithbja: you can also send a private message to clojurebot
11:23TheLastProjectAh...
11:24justin_smithTheLastProject: the funny thing is you even use clojure.string/join at the top of the file
11:24TheLastProjectOkay, yeah
11:24TheLastProjectI get it, [] is for turning it into a list, which is the closest to grouping you get
11:24justin_smiththere is also the list function
11:24TimMc[] is for creating a vector
11:24TimMc,[1 2 3]
11:24clojurebot[1 2 3]
11:25TimMc,(list 1 2 3)
11:25clojurebot(1 2 3)
11:25justin_smithor () if quoted
11:25TheLastProjectUgh, yeah
11:25TheLastProjectYou people call it a vector
11:25TheLastProjectMy bad
11:25TimMcWell, we also *have* lists.
11:25TheLastProjectEvery language uses different names, and a "list" isn't the same thing in all of them :P
11:25justin_smitheventually keeping track of which one you are using avoids weird bugs :)
11:25TheLastProjectOkay, well, thanks
11:26TheLastProjectNow I just need to do the args stuff, let's see how that goes
11:26justin_smithTheLastProject: here is a trick I sometimes use when debugging
11:26justin_smith,(let [a 2 _ (println a) b 3] (+ a b))
11:26clojurebot2\n5
11:26justin_smithso it prints a, then returns 5
11:27TheLastProjectI'm having trouble following that, heh...
11:27justin_smiththe _ is a convention that says "I am not using this return value" in a let
11:27justin_smithso I assign a with the value 2
11:27justin_smithI assign _ with the value nil (returned by print)
11:27justin_smiththe reason to do it there is I can then look at things as I construct them
11:27justin_smithit helps sometimes
11:27TheLastProjectHmm
11:28TimMcClojure lists are basically stacks (append and peek at the front); vectors are log-time random-access and append at the end.
11:28justinjaffrayjustin_smith: that is so useful, thanks :D
11:29justin_smithjustinjaffray: np
11:29TheLastProjectIs there a way to have something like (rest) but starting at the 4th point in the list, instead of the third?
11:29TheLastProjects/third/second/
11:29TheLastProjectOh man, such a headache, heh...
11:29TheLastProjectI'm not used to coding this way
11:30TheLastProjectIt's interesting, but it's... different
11:30justin_smithTheLastProject: nthrest
11:30justin_smithTheLastProject: http://clojure.org/cheatsheet is helpful
11:30TheLastProjectThat actually makes sense
11:30justin_smithTheLastProject: the pain is your brain growing stronger!
11:31TheLastProjectYay! It works!
11:31TheLastProjectThank you SO much justin_smith
11:31justin_smithvery nice, can I see the final result?
11:32justin_smithno problem, glad I could help
11:32TheLastProjectOf course
11:32TheLastProjectjustin_smith: https://www.refheap.com/20722
11:32faust45is it possible assign metadata to types ?
11:33faust45like (deftype User ^{})
11:33TimMcWhat would the behavior be?
11:34justin_smithTheLastProject: the order of assigning the values in the let is a little tangled, but yeah, that looks great
11:34justin_smithby tangled I don't mean incorrect, just not in the easiest to read order
11:34TheLastProjectI guess collection-string should go for args
11:34TheLastProjectMakes more sense
11:35TheLastProjectBut I'm mostly glad it works now, heh...
11:35justin_smithheh, yeah, it is an accomplishment
11:36napperhas anyone putout a repl like ipdb in clojure?
11:36justin_smithanother suggestion is to put everything after the last defn (and all the printlns) into a -main function
11:36justin_smiththen lein run will work
11:36napperI'd like the opition to break in my code without having to use an ide.
11:36TheLastProjectAh, I'm running it with "clojure" but I've heard leiningen is really popular, should probably strive for leiningen-compatibility
11:37justin_smithTheLastProject: it makes things much easier, eventually
11:37justin_smithand even if you are just running the clojure command, you can put (-main) at the end of the file, to explicitly execute it
11:38TheLastProjectclojure-main?
11:38justin_smithnapper: cdt can do breaks that you define in a repl, and you can use it without swank pretty easily
11:39justin_smithnapper: we've been working on a web UI that would let us set breakpoints and investigate values / run code in a clojure project we attach to
11:39justin_smithwe use cdt for that
11:40justin_smithTheLastProject: ?
11:40TheLastProjectjustin_smith: I'll take that question mark as a "no"
11:40justin_smithI don't understand the question
11:40justin_smiththe magic function name defaults to -main
11:41TheLastProjectjustin_smith: (defn -main [] (doseq [line (repeatedly read-line) :while line] (getinput line) (request-command)))
11:41TheLastProjectSo, that stuff?
11:41napperjustin_smith, interesting, I'm curious as to how you would break on a line with a gui per thread. - How do you trace anom functions?
11:41TheLastProject(Put it on one line to not spam, I'm not undoing your improvements)
11:41justin_smithyeah, put all the printlns in there too
11:41TheLastProjectAh
11:41justin_smithnapper: that is a UI for stack traces on exception
11:41TheLastProjectSo that they execute when it is first run
11:41TheLastProjectGot it!
11:42justin_smithnapper: we haven't done source line breakpoints, but that would be a different UI
11:43napperjustin_smith: when using ipdb, it would break/stop tho code execution in a single thread allowing you to inspect what is in memory. Much like the gdb interface ( at least what I know of the gdb interface. )
11:43justin_smithnapper: yes, same idea
11:43napperjustin_smith: ideally, you'd build a pure function and concat them together with threads in mind.
11:43justin_smithbut we show all the available stacks at once
11:44napperjustin_smith: neat, I'm eager to see it - it's the last thing I need to convert. :P
11:44justin_smith*available frames
11:44justin_smithsource line breakpoints is something we may do later - but that gets weird when you are using the repl / debugger to redefine things
11:46CookedGryphonjustin_smith: it'd be cool if defn attached the source as metadata
11:46justin_smithCookedGryphon: it does
11:46justin_smithbut that doesn't give you line number breaks inside it :)
11:46CookedGryphonoh, cool, well in that case I don't care what line it is in a file, as long as i can look at the source.
11:46justin_smithCookedGryphon: (source fn)
11:46napperjustin_smith: redefine? Well, yeah, but if a user does that at run time, it's their prerogative - using in debugging would be ideal, redfined code at runtime, I agree can create issues
11:46CookedGryphonor is it that your stack traces no longer relate to anything
11:47justin_smiththat's in the clojure.repl ns, so you may need to use that first
11:47justin_smithnapper: this debugger lets you redefine things while debugging
11:47napperare we talking about cdt or your webui?
11:48justin_smiththe webui is just a view of cdt
11:48justin_smithall the functionality, including changing remote definitions, is in cdt
11:48napperright
11:49napperI'm reading over the main-page. it looks like what I want is already accomplishable via the debug-repl
11:49justin_smithnapper: I think the problem with that is it is swank
11:49napperoh
11:50justin_smithritz tries to provide an alternative
11:50justin_smithbut I couldn't make any sense of ritz
11:53justin_smithif your workflow is "I am starting the debugger and the debugged process as one action", then the nrepl ritz module probably does what you want
11:53justin_smithin my case, I am running ring, ring creates a repl I can interact with, and I want to fire up an external debugger to connect to it and investigate if something breaks
11:54muhoohttp://www.youtube.com/watch?v=9m3lu59Cz4g
11:54justin_smithmuhoo: nice
11:54nappereventually I'll be running ring, my next question is how can you pause execution. looking through cdt, it seems that might be pretty straightforward. - I think I have what I need.
11:55dnolencemerick: yeah I don't think we should change the current behavior
11:55justin_smithnapper: yeah, you can set a break, if you know how to specify the location
11:55napperjustin_smith, is your webui public or closedsource?
11:55justin_smithnapper: open source, but not really "there" yet
11:55napperI understand
11:55napperdo let me know when it's there
11:56justin_smithsomeone else is doing the main development, I don't even know how much he has pushed as opposed to just mostly working on his box at this point
11:56justin_smithhttps://github.com/prismofeverything/schmetterling repo
11:56justin_smithmay be a pile of bugs right now
11:56cemerickdnolen: hah, here I just finished a writeup on the ticket :-P
11:57justin_smithnapper: it is something you would check out and run, standalone
11:57justin_smithnot a lib you include
11:58napperthis would be great for pointing it to production servers if anything ever went south
11:58justin_smithyeah, though you would need to open a tunnel with ssh -X
11:58justin_smithbecause you sure as hell don't want a dt-thread socket available to the outside world :)
11:59dnolencemerick: also I don't really like the idea of adding any compiler support for this - just export a config function?
11:59napperhah
11:59napperi take it you've seen that before?
12:00justin_smithno, but it's something that could be a disaster
12:00justin_smithfull control of your app's state
12:00justin_smithand full access and introspection
12:00justin_smithsomeone with malice could do a lot with that
12:00lpvbhow do I use vector-of to create a filled vector of a specified length?
12:01lpvb(vector-of :int & elements)
12:01lpvb,(vector-of :int)
12:01clojurebot[]
12:01lpvb,(vector-of :int (repeat 5 0))
12:01clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Character>
12:02justin_smith,(apply vector-of :int (repeat 3 6))
12:02clojurebot[6 6 6]
12:02justin_smithlml
12:04cemerickdnolen: The original use case was being able to change test-time parameters. There are workarounds, including the config function notion, having a fixture that looks up params set from the test runner on window, etc.
12:04lpvboh cool
12:05justin_smithlpvb: apply is good when a function expects a bunch of args at the end that you already have in a list
12:05justin_smithwith how many varargs functions clojure has, this comes up a lot
12:06cemerickWhat ^:export does now is pretty surprising tho. If someone wants some low-hanging contrib fruit, documenting that @ https://github.com/clojure/clojurescript/wiki/Quick-Start#using-clojurescript-on-a-web-page (the only place I know of that mentions ^:export?) would be one such spot.
12:06justin_smith,(apply vector-of int "Hello World")
12:06clojurebot#<NullPointerException java.lang.NullPointerException>
12:06justin_smitherm
12:07justin_smith,(apply vector-of :int (seq "hello world"))
12:07clojurebot[104 101 108 108 111 ...]
12:07justin_smithneato
12:07dnolencemerick: you're one of the few people that have asked for this or been surprised by the behavior. ^:export is mostly used for exporting functions note constants that will be mutated as this isn't considered good CLJS style. The testing case is not even particularly interesting IMO since it's trivially worked around.
12:07dnolens/note/not
12:09dnolencemerick: it has come up once before in a different ticket I believe, but I'm not convinced any of this requires compiler changes. I think just make the documentation more clear is sufficient for now.
12:10cemerickdnolen: Fair enough, I'm not lobbying hard or anything. :-) My understanding of ^:export was that it was primarily there to provide entry points and to make providing JS-friendly APIs (where mutable properties are common).
12:11cemerickAPIs easy*
12:11dnolencemerick: I don't recall anyone suggesting ^:export for mutable properties, nor do I see such documented anywhere (could be wrong)
12:12cemerickdnolen: No, I inferred "JS APIs" => "mutable properties".
12:13cemerickI'll close the issue and leave a note potential workarounds, etc.
12:13dnolencemerick: cool, thanks
12:14technomancyhuh; I could have sworn the `hub` CLI tool had gist support in it; am I making that up?
12:14nDuff...I've seen a separate ''gist'' tool
12:15nDuffperhaps its functionality has been split out from ''hub''.
12:15Sigmatechnomancy: not that I remember. there's a separate "gist" tool though
12:15technomancyoh, I was thinking of gist-mode for emacs
12:16technomancywhich supports fetching but not cloning; oh well
12:16Sigmatechnomancy: patches welcome :)
12:17deechHi all, how do I make a set with a custom comparator?
12:17technomancySigma: nice =)
12:17Sigmabtw I'm considering (as of yesterday) implementing a tramp method for accessing gists. guess it might make the whole experience a bit better
12:17faust45guys, how i can attache some static info to my deftype ?
12:18TEttingerdeech, like sorted-set-by but not sorted?
12:18technomancySigma: huh... I never thought of it that way, but tramp can be considered a FUSE alternative in a way.
12:18Sigmatechnomancy: I already have one for git itself, sounds like a logicial next step :)
12:19technomancythat's wild =)
12:19deechTEttinger: I thought that function took a set and sorted it. Guess I was wrong.
12:19justin_smithtramp access to well designed RESTful apis all over the web would finally catch us all up to plan9 networking
12:19faust45any ideas ?
12:20technomancySigma: lemme know if you ever end up tackling issues; that's the main pain point for me with github currently
12:20faust45how attach static info to deftype ?
12:20Sigmatechnomancy: I guess the final step would be to reimplement magit over a tramp method that would use github API instead of local git commands. Then I can die
12:21technomancySigma: the technical term is "ascend"
12:21justin_smithfaust45: you could make the data be a method that ignores the value of this and returns the data
12:22faust45justin_smith: yes, but sounds strange
12:23faust45justin_smith: i don't need behavior i need static data
12:23justin_smith(getStatic [this] {:foo "bar"})
12:23TEttingerdeech, fun stuff: ##(sorted-set-by #(= %1 %2) 1 1 1 2 2 3 3)
12:23lazybot⇒ #{1 1 1}
12:23justin_smitha behavior can mimic static data :)
12:23faust45ok thanks
12:23justin_smithfaust45: or you could use genclass instead of deftype
12:24justin_smiththey generate the same kind of thing under the hood
12:24justin_smiththen you can have a final data member in the class itself
12:24justin_smithjust think of how java would do it, then figure out the interop that would make that happen, because all this is defined by the java model
12:34TimMcfaust45: I think you can attach :static to methods in a gen-class :methods form.
12:45justin_smithTimMc: is that the only way to make static methods?
12:45justin_smithI was looking at it, it seemed like you would only be able to define one :static key?
12:46justin_smithsorry
12:46justin_smithnot :static
12:46justin_smithit's :state
12:46justin_smithor are these two separate things?
12:46justin_smithhttp://clojuredocs.org/clojure_core/clojure.core/gen-class
12:46dobry-dengen-class OO in clojure is fun
12:47dobry-denfeels like some newfangled OO language
12:47tbaldridgefor certain definitions of fun
12:47dobry-den^
12:48dobry-denfunny*
12:48justin_smithclearly gen-class is missing the essential :laffs key
12:48dobry-denevery time i use gen-class, i do the same google search to knit together the same 4 blog posts that show how to use it
12:52lpvbhow do I split a vector into chunks of a specified length like [1 2 3 4 5 6 7 8 9] -> [[1 2 3] [4 5 6] [7 8 9]]
12:52AimHerelpvb > partition
12:52rasmusto,(partition 3 (range 10))
12:52clojurebot((0 1 2) (3 4 5) (6 7 8))
12:53justin_smith,(partition-all 3 (range 10))
12:53clojurebot((0 1 2) (3 4 5) (6 7 8) (9))
12:53justin_smithif you wanted all of it :)
12:53rasmusto,(partition 3 1 (range 10))
12:53clojurebot((0 1 2) (1 2 3) (2 3 4) (3 4 5) (4 5 6) ...)
12:53rasmustoif you want overlap
12:53lpvbthanks
13:18danneuI've never done something like this before - If I wanted to distribute Datomic along with my app.jar, what would that sort of thing look like?
13:18llasramI've come to the opinion that there's ~0 situations where `gen-class` is the right solution
13:19danneuNaively, I imagine my app.jar would boot another jvm that runs the transactor and java would handle things like shutting down the child jvm
13:20mdrogalisdanneu: Can you put a wire between those 2 components?
13:20mdrogalisJust avoid all that.
13:20danneuWhat do you mean?
13:20bitemyappyeah don't do that.
13:21mdrogalisWell, if I was to tell you that you can avoid the oddness that is multiple JVMs on a machine, doesnt that sound nice?
13:21danneuBasically, all I know is that I can't distribute a single jar that contains my app + datomic-db, so I'm looking up solutions
13:21mdrogalisdanneu: What's your deployment scenario?
13:22danneumdrogalis: I have a bitcoin node that uses datomic to store the blockchain. I'm not sure how to distribute it to other people
13:24danneureally, just a project that uses datomic as the db, and im not sure how to package it for end users
13:24mdrogalisdanneu: I mean, do you *have* to ship just 1 jar?
13:25mdrogalisI dont think there's anything wrong with saying "Here's my app jar. Go stand up Datomic and they'll place nicely."
13:25nDuff...folks don't try to ship PostgreSQL built into their applications. :)
13:25mdrogalisnDuff: Thanks, was trying to verbalize that.
13:25bitemyappdanneu: yeah I'm not buying that should be baked in.
13:25bitemyappdanneu: use environment variables so users can point your app at their datomic instance.
13:26coventrydanneu: Could you pull in the datomic depepndency from your code using something like pomegranate?
13:26bitemyappdanneu: This is a good library for that: http://github.com/weavejester/environ/
13:26bitemyappcoventry: dude. No.
13:29danneunDuff: yeah, you're right. i'm just trying to arrive at the easiest solution for the end-user
13:31lpvb,(replace {1 0} (vector-of :int 0xF0))
13:31clojurebot[240]
13:31lpvbwhy is that not working
13:31coventrylpvb: What answer are you expecting?
13:31lpvboh wait I get it now
13:32lpvbI thought the key was the index to replace
13:33justin_smith ,(replace {0 0} (vector-of :int 0xF0))
13:33clojurebot[240]
13:33justin_smithok, that I did not expect
13:34justin_smith ,((vector-of :int 0xF0) 0)
13:34clojurebot240
13:35bitemyappjustin_smith: what are you even doing that these experiments come to mind? seriously, wtf.
13:35justin_smithbitemyapp: it was lpvb's question
13:35MorgawrI have a static java method that can take 1, 2 or 3 parameters, I want to write a wrapper in clojure, but I can't get it to work with "apply"
13:35bitemyapplpvb: okay, my question, applied to you. What the fuck?
13:35Morgawr(apply StaticClass/method args) doesn't work
13:35lpvbbitemyapp: ?
13:35sritchieMorgawr: you could write a macro that expands out into all the arities
13:35bitemyappMorgawr: make a clojure function
13:35coventry"Here's a nickle, kid. Buy yourself your own goddamn repl." :-)
13:35llasramlpvb, justin_smith: `replace` replaces by value, not key
13:35lpvbI know that now
13:36llasramkk
13:36noncomwhat is the fastest and the most idiomatic way to add N same elements to a vector?
13:36sritchieMorgawr: but I think you need to recreate each one
13:36MorgawrI know I could do that but a one liner feels better, isn't there a way?
13:36justin_smithllasram: the doc string says key
13:36mdrogalisbitemyapp: Possibly relevant for encryption, by the way
13:36justin_smithoh, = key, not at key
13:36MorgawrI mean, I can't use "apply"?
13:36justin_smithnever mind
13:36sritchieMorgawr: nope
13:36danneunoncom: conj with repeat?
13:36Morgawrwhy not? doesn't apply work with java methods?
13:37noncomdanneu: is it the fastest? i can think of several ways, but i wonder which is the fastest...
13:37danneu,(into [1 2 3] (repeat 5 :a))
13:37clojurebot[1 2 3 :a :a ...]
13:37bitemyappMorgawr: why would some random Java method implement IFn?
13:37Morgawrbitemyapp: I don't know how apply works, so I don't know why it wouldn't work ^^
13:37bitemyappMorgawr: it's not like java libraries are designed with Clojure integration in mind.
13:37rasmusto,(replace {0xF0 1} (vector-of :int 0xF0))
13:37danneunoncom: oh. in that case i would just mock up those several ways and bench them
13:37clojurebot[1]
13:37bitemyappMorgawr: well...learn how Clojure works :)
13:37bitemyappMorgawr: in particular, Seqable, IFn, etc.
13:38MorgawrI'll go check apply's source
13:38bitemyappenables you to anticipate what should and shouldn't work, what makes sense, etc.
13:38sritchieto be fair that's what he's trying to do
13:38noncomdanneu: yeah, looks liek..
13:38danneunoncom: oh, you asked for the fastest
13:38sritchieMorgawr: a clojure function is an object, a first class object
13:38noncomyes, speed is the criterium
13:38sritchiethat implements IFn
13:39coventryMorgawr: The only way I can think of doing it in one line is uglier than using multiple lines.
13:39sritchiea static method isn't first class, it's defined on a particular class -
13:39MorgawrI see
13:39Morgawrmakes sense
13:39sritchieso you have to make a first-class clojure function that delegates through in each arity
13:39Morgawralright, thanks
13:39justin_smithlpvb: this is what you wanted, I think:
13:39justin_smith,(assoc (vector-of :int 0xF0) 0 0)
13:39clojurebot[0]
13:40lpvbI know how to use assoc, I thought I could use replace to do a list of assocs at a time though
13:40justin_smithassoc is varargs
13:40justin_smith,(assoc (vector-of :int 0xF0) 0 0 1 6)
13:40clojurebot[0 6]
13:40lpvbah I keep forgetting most clojure functions like this have varargs
13:41llasramMorgawr: Not necessarily recommended, but you can use reflection to wrap methods as functions w/ correct arities, then `apply` those functions
13:41justin_smith,(apply < (range 42))
13:41clojurebottrue
13:41Morgawrllasram: sounds like a lot of work for nothing
13:41llasramMorgawr: https://github.com/llasram/method-fn for a proof-of-concept
13:41llasramhaha
13:41llasramWell, depends on what you're trying to do
13:42Morgawrllasram: I was just being lazy
13:42danneunoncom: is (concat [1 2 3] (repeat n :a)) too slow?
13:42Morgawrhoping I could get a simple and elegant one-liner for a java wrapper
13:42llasramI see
13:42coventryAs long as we're proposing awkward ideas, there's (eval `(StaticClass/method ~@args)). :-)
13:42Morgawrbut it's just a function with 3 different parameter combinations
13:42Morgawrso I can just wrote those, no biggie
13:43Morgawrcoventry: that's actually interesting
13:43coventryMorgawr: Yeah, it's interesting, but people will look askance if you do that.
13:43justin_smitheval is a big gun for such a small rabbit
13:43noncomdanneu: umm, looks quite fast.. "Elapsed time: 0.08244 msecs" after warm-up
13:44noncomthats faster than with (into)
13:44MorgawrI mean, wouldn't it just possible to do (defmacro wrapped-method [& args] `(Static/Methodname ~@args)) ?
13:44danneunoncom: right, into uses conj for each element. concat does it all at once
13:44Morgawrbe possible*
13:44llasramnoncom, danneu: Er, `concat` is lazy, so just calling `concat` does almost nothing
13:45coventryMorgawr: You lose function composition that way.
13:45Morgawrmmm.. true
13:46noncomllasram: well, i tried it and it printed the output to the console, so it actualle did evaluate it. however, i wonder, if it did before or after (time) :)
13:46danneunoncom: you can realize it trivially with `count` or `dorun`
13:46justin_smithnoncom: if you are wondering what is efficient, use criterium
13:46llasramnoncom: If you use criterium for benchmarking, it handles many of these issues
13:47justin_smithalso, criterium is very simple to use, so there is no excuse
13:48Morgawris there any downside in using eval?
13:48llasramEspecially if you also use hugod's alembic, because then you can slurp it into any REPL :-)
13:48danneusometimes you've just gotta grind it out on that dollar menu with (time (dotimes [_ N] ...))
13:48llasramdanneu: 100% in disagreement!
13:48justin_smithMorgawr: it creates a whole environment context, we were using eval in our templates and when we switched to read our performance shot up more than an order of magnitude
13:49danneu;)
13:49justin_smithdanneu: that would make sense if criterium somehow cost money
13:49Morgawrthis is just for a simple function (binding to OpenAL) that creates an audio device, it's used just in the initialization of a game engine
13:49MorgawrI'm wondering how lazy I can be
13:49danneuit's nice to have criterium's `bench` and `quick-bench` imported into your util namespace so theyre always handy
13:49Morgawras in, I know I'm talking about bike shedding atm
13:49danneuquick-bench because time is money
13:50Morgawrbut honestly unless there's any security/consistency/stability problem, if it's only just losing a bit of performance, then I'd say that eval looks more elegant
13:50Morgawrunless I'm missing something
13:50justin_smithclient data sneaking arbitrary code into the string?
13:50justin_smithhah
13:50Morgawrit's a library, it's not an end-user application
13:51Morgawras in, other developers call that function
13:51Morgawrif they want to break their own application, it's not my fault D:
13:51lpvbwhat complexity is concat on two vectors?
13:51justin_smithjust covering the bases, mentioning other downsides that may apply :)
13:51Morgawrtrue true
13:52justin_smithlpvb: they are implemented by narrow hash trees, with something like 7 items on each level iirc
13:52coventryMorgawr: If you want to use eval, you probably actually want something more like (eval (list* StaticClass/method args)), so that it works at runtime.
13:52justin_smithlpvb: http://hypirion.com/musings/understanding-persistent-vector-pt-1
13:53Morgawrcoventry: alright, thanks
13:53TimMclpvb: O(1), i think
13:53coventryMorgawr: And wash your hands afterwards.
13:53TimMc(It's lazy.)
13:53justin_smithTimMc: no way, it is log something
13:53Morgawrdoesn't seem to be working though
13:53noncomdanneu, llasram: thanks, i'll check the criterium out!
13:54Morgawrshould it be (list* 'StaticClass/metod args) ?
13:54Morgawrwith the quote?
13:54coventryMorgawr: Right.
13:54Morgawrah ok, at least I understand what it does ;) thanks
13:55TimMcjustin_smith: concat returns a lazy seq; I'm pretty sure it does nothing involving the elements of input vectors
13:55coventry,(eval (list* 'System/getProperty '("java.vm.version")))
13:55clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
13:55Morgawrhaha
13:55TimMclpvb: Concat returns a seq; if you want a vector from a seq you have to call vec on it. If you want to combine two vectors into another vector, the efficient thing is to use clojure.core/into.
13:56TimMc&(into [1 2 3] [4 5 6])
13:56lazybot⇒ [1 2 3 4 5 6]
13:56justin_smithTimMc: ok, now I get it
13:56TimMcThat should be something like O(n) or O(n log n).
13:56noncomconventry: what is the difference of list* and list?
13:56justin_smithso since concat only returns a seq, you look at the complexity of realizing the seq (if it needs full realization)
13:57coventrynoncom: &[(list* 'System/getProperty '("java.vm.version")) (list 'System/getProperty '("java.vm.version"))]
13:57justin_smithrealizing a seq will be O(n) for the length you need to realize
13:57danneuI see that `into` uses transients
13:58noncomconventry: sorry i don't get it..
13:58danneujustin_smith: yeah, i made that mistake too. i didn't think about how concat is a lazy-seq of `cat`s
13:58coventrynoncom: list* splices the last argument into the list, like ~@ in a syntax quote.
13:58noncomoh!
13:58coventry,[(list* 'System/getProperty '("java.vm.version")) (list 'System/getProperty '("java.vm.version"))]
13:58clojurebot[(System/getProperty "java.vm.version") (System/getProperty ("java.vm.version"))]
13:59cYmenIs there a list of clojure user groups somewhere?
13:59coventryHmm, I could have used juxt, there. :-)
14:00justin_smithcoventry: so is what differentiates list* from cons the resulting data type?
14:01Morgawrtalking about clojure user groups... anybody from Amsterdam/Netherlands going to wednesday's clojure meeting in Amsterdam?
14:01danneuSpeaking of juxt, I often do this: ((juxt :a :b :c) {:a 1, :b 2, :c 3}) -> [1 2 3]. Is there a different way to do that?
14:01coventryjustin_smith: It's a series cons under the covers.
14:01coventry~def list*
14:01Morgawrdanneu: vals
14:01Morgawrif you want all of them, of course
14:02justin_smithcoventry: ahh, so it is a reverse varargs with the conses in front
14:02danneuMy trouble with `cons` is that I don't know what to do with the resulting Cons object
14:02cYmendanneu: the result is a list not a cons object ;)
14:03cYmenwell...I guess it could also be a tree
14:03cYmennevermind ;)
14:03danneu,(class (cons 1 [2 3]))
14:03clojurebotclojure.lang.Cons
14:03justin_smith,(map type [(list* 1 [2]) (cons 1 [2])])
14:03clojurebot(clojure.lang.Cons clojure.lang.Cons)
14:04amalloydanneu: ##(map {:a 1, :b 2, :c 3} [:a :b :c])
14:04lazybot⇒ (1 2 3)
14:05llasramjustin_smith: Yeah, `list*` returning a `Cons` is kind of brutal
14:05Morgawr,(vals {:a 1 :b 2 :c 3})
14:05clojurebot(1 3 2)
14:05Morgawr:V
14:06justin_smithllasram: from an implementation perspective, it is perfectly understandable though - a list is just a cons tacked onto another cons
14:07llasramjustin_smith: That's actually not quite true in the Clojure implementation. Clojure's actual persistent list is `Counted` and supports acts as a (counted) stack with `conj`, `peek`, and `pop`
14:08justin_smithoh, interesting
14:09llasramIf you just need a seq, `Cons`es work fine, but sometimes you really want a PersistentList
14:09justin_smith,(pop (into () (list* 1 [2])))
14:09clojurebot(1)
14:09justin_smithI never though I would need (into ())
14:09llasramI think then you might as well just ##(apply list 1 [2])
14:09lazybot⇒ (1 2)
14:10justin_smithllasram: yeah, probably true
14:10llasramOh, yeah -- `into` will end up reversing the list
14:10danneureduces with conj
14:10justin_smithahh
14:10justin_smithfun!
14:11TimMclist* is awful
14:11justin_smithit seems so!
14:11amalloyTimMc: aw, list* is great!
14:12TimMcThe funcionality is nice; the name is not.
14:12TimMcand the doc
14:12amalloyit's much nicer than repeated conses, and it's not like i've ever in my life cared that it doesn't return a List
14:12amalloyif it did, i'd have to stop using it
14:14RaynesTimMc: Don't be so mean to list*.
14:14amalloy(defn all-integers [n] (lazy-seq (list* n (- n) (all-integers (inc n))))), for example, suddenly can't use list*
14:14RaynesHe doesn't mean to be different.
14:15coventryWhat are the drawbacks to list*?
14:15mischovHe's just looking for a connection.. :(
14:15llasramcoventry: It doesn't actually return a list
14:15amalloycoventry: whenever you use it, you have to listen to someone in irc reminding you it doesn't return a list
14:15llasramheh
14:15TimMc(inc amalloy)
14:15lazybot⇒ 76
14:15llasram(inc amalloy)
14:15lazybot⇒ 77
14:15danneuhaha
14:17technomancyno, it's the other way around
14:17amalloyanyway, it does return a list*, so what's the problem?
14:17amalloy* sequence
14:17technomancylist? is the rubbish one; list* is entirely reasonable
14:17TimMchrmph
14:17technomancyfocusing on concrete types is misguided
14:18TimMcActually, the problem is memoize.
14:18amalloyyeah, list? is awful. i love to agree with technomancy when he wanders in to say that
14:18llasramI'm sure this will never happen to me again, but I once did want the behavior `pop` documents for "a list", and was surprised the result of `list*` didn't work with it
14:18justin_smithwe should have a database of functions in core clojure and everyone's yes or no opinions on them
14:18justin_smiththen we could find the winner
14:19justin_smithjuxt for president!
14:19llasram~juxt
14:19clojurebotjuxt is the bestest option though if it doesn't weird you out
14:19technomancywhaaat why is pop a c.l.RT method?
14:19llasramAww, not the one I was hoping for
14:19justin_smith~juxt
14:19clojurebotjuxt is a little hard to grok but it's the best thing ever
14:19rasmusto~grok
14:19clojurebotgrok is a little hard to juxt but it's the best thing ever
14:19llasramlol
14:19coventryIt would be pretty handy to have a table of which clojure.core functions suck and why, actually.
14:19mdrogalisHah
14:20ToBeReplaced~complement
14:20clojurebotIt's greek to me.
14:20justin_smithcoventry: we could make a funcation that puts a :sucks and a :rocks metadata on each function
14:20technomancyam I right in recalling that contains? isn't as bad as it used to be?
14:20ToBeReplacedas long as "flatten" is marked with :worst
14:21justin_smithyes!
14:21amalloytechnomancy: i forget if it's contains? or get
14:21ToBeReplacedwhat's wrong with either of those?
14:21justin_smithmaybe if we could just inc or dec core functions in irc
14:21coventryjustin_smith: I think we should hack the compiler so that it instruments code with calls to lazybot to (inc) and (dec) the author when :sucks and :rocks functions are used.
14:21technomancyToBeReplaced: contains? is actually contains-key?
14:21justin_smithlol
14:21lpvbhow do I coerce the types of record fields, do I just type hint them?
14:21technomancyToBeReplaced: and it's worse because there's a .contains method that actually does what you'd expect
14:22ToBeReplacedyeah, that doesn't smell fishy to me for some reason
14:22technomancyI think at least now it throws instead of silently returning false
14:22ToBeReplacedthrows on what, nil/
14:23justin_smithnon-int key on a sequential type
14:23ToBeReplaced,(contains? [] :foo)
14:23clojurebotfalse
14:23amalloy,(contains? 'q :foo)
14:23clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.Symbol>
14:24justin_smithbut for that case, I think it always threw
14:24amalloyno
14:24justin_smithoh
14:24justin_smithnever mind then
14:24amalloy&(contains? 'q :foo)
14:24lazybot⇒ false
14:24ToBeReplacedamalloy: what's the diff between those two commands?
14:25ToBeReplacedthe & vs the ,
14:25amalloydid you notice anything different happen when i used them?
14:25coventry&*clojure-version*
14:25lazybot⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}
14:25coventry,*clojure-version*
14:25clojurebot{:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}
14:25ToBeReplacedkk sweet
14:30TimMcToBeReplaced: The bots have different Clojure versions in their sandbox evaluators.
14:30RaynesFunfact: I have 396 public pastes and 395 private pastes. This was not intentional.w
14:31Raynes(on refheap)
14:31amalloyRaynes: really? that number seems way too low
14:32amalloyor do you mean, just pastes you, personally, made
14:32Raynesamalloy: Me of course.
14:32cYmenIt says here that the vector returned by subvec shares structure with the original one. Isn't that rather odd considering all the immutabiliy everywhere?
14:32RaynesIf Refheap only had 791 pastes, I should probably have given up on it ages ago :P
14:33dnolencYmen: Clojure data structures generally share structure
14:33cYmendnolen: But that doesn't matter if I never mutate any...
14:33justin_smithcYmen: that is one of the advantages of immutability, is being able to safely share structure whenever possible
14:33justin_smithin terms of memory usage
14:34dnolencYmen: structure sharing is how/why Clojure data structures perform well
14:34amalloywell, not so much memory usage as time, justin_smith
14:34justin_smithmaybe make that saving graces, making up for the extra mem usage because you don't update in place
14:34technomancycYmen: what you pasted is not odd, but subvec does have some weirdness in its trade-off between efficiency and possible memory leaks
14:34danneucYmen: mutability is opt-in.
14:35amalloyusually you just throw away the old version, so the fact that you share structure with it impacts only speed, not space
14:35amalloyof course, you don't *have* to throw it away, which is the point of immutability
14:35technomancyamalloy: except it's a reference to the whole original vector, not just part
14:35amalloytechnomancy: i'm not talking about subvec; that's your hobby horse
14:36amalloyjust sharing in general
14:36technomancyoh, I didn't bring it up
14:36justin_smithsee, more evidence that we need a :sucks or :rocks metadata on every core function
14:36technomancyjustin_smith: dunno; I think subvec is more nuanced. needs :perilous.
14:36cYmenso if I go (let [foo [1 2 3] bar (subvec foo 2)] ...) I can screw myself because changes to foo or bar also change the other?
14:37technomancycYmen: no
14:37TimMc:docs-actually-important
14:37technomancyyou can screw yourself up because of a memory leak, but you can't change either vector
14:37amalloycYmen: it's impossible to change foo or bar
14:37amalloyso that doesn't matter
14:38cYmenso how is immutability opt-in?
14:38justin_smithcYmen: you can use java arrays
14:38justin_smithor java lists
14:38danneumutability*
14:38TimMcYou can change vectors if you do some very naughty things, but you really can't do it by accident.
14:38technomancycYmen: just try to modify a clojure vector
14:38TimMccYmen: *Mutability* is opt-in.
14:39danneucYmen: You can also 'mark' clojure datastructures as "mutable" http://clojure.org/transients
14:39justin_smithit is opt in, in that you can choose what data structures you use
14:39amalloydanneu: that is totally wrong. transients do not make data structures mutable
14:39danneudamn
14:39amalloythey permit the data structures to use mutability as an optimization; they do not allow you to mutate them without restraint
14:40technomancywelllll. not *totally* wrong.
14:40technomancyjust misses the point.
14:40danneuyeah, it was too haste a simplification
14:40Raynesamalloy technomancy fight: go!
14:40danneutoo dumb*
14:40danneui really just wanted to share the link
14:40nDuff...more than that, one can't assume that calculating a mutated version of a transient will change it.
14:40nDuffone simply can't assume that doing so _won't_.
14:41cYmenWhere is #clojure-noobs? :)
14:41danneuright hurr
14:41danneuright hurr with me, homie
14:43TimMcHmm, what's this TransactionalHashMap thingy?
14:43justin_smithtechnomancy: http://memegenerator.net/instance/42894672
14:43TimMcpublic TransactionalHashMap() { this(421); } Nothing like a magic number to spice things up.
14:44TimMchttps://github.com/clojure/clojure/blob/clojure-1.5.1/src/jvm/clojure/lang/TransactionalHashMap.java
14:44technomancyjustin_smith: it's like you read my mind
14:44justin_smithor maybe your words on irc
14:45technomancyit's another possibility
14:45danneuQuestion: Some contributors on my project have started bikeshedding about my preference to refer to coordinates as {:x _, :y _} instead of a tuple [x y]. [x y] is only nice if you're always destructuring it. but otherwise, (coords 0) and (coords 1) are heinous to my eyes.
14:46justin_smithdanneu: I agree, I even do :x :y :x' :y' for quads
14:46danneuthanks. bro-support. i'll remain adamant
14:46justin_smiththen you can just do a {:keys [x y x' y']} and be done with it
14:46justin_smithdestructuring ftw
14:47TimMchttps://groups.google.com/forum/#!msg/clojure/A9Y9wml49_s/EUF4E43PJRIJ
14:53cYmenCould somebody please explain this to me: Also, in some cases keys can be used as functions of maps. For example, keyword keys can, but string and integer keys cannot.
14:54`cbp,(:a {:a 1})
14:54clojurebot1
14:54cYmenI apparently have no useful notion of what a keyword is internally.
14:54cYmenBecause I am very surprised that it can be looked up in a way that allows using it as a function.
14:54cYmenWouldn't that require knowing that it is in a map?
14:55justin_smithcYmen: it is an object, that is callable
14:55justin_smithit has the right method to try and look itself up if the arg is a map or struct
14:56tbaldridgecYmen: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java it's pretty simple stuff
14:56`cbpcYmen: here https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java#L24
14:56`cbp:-(
14:57poppingtonicHello
14:57`cbphi
14:58poppingtonicIs ClojureScript One still relevant? I'm working through it, but the instructions in the Getting Started guide aren't working out...
14:59poppingtonicI'm not sure what needs to be fixed
14:59tbaldridgepoppingtonic: it was replaced by Pedestal App
14:59tbaldridgepoppingtonic: http://pedestal.io/
15:02cYmentbaldridge, `cbp: thanks
15:07danneutbaldridge: it seems like https://github.com/magomimmo/modern-cljs is more of a Clojurescript One surrogate (a ground-up tutorial)
15:08tbaldridgedanneu: true, I was just stating that the author of Pedestal App is the same as ClojureScript One.
15:09TimMccYmen: It's more that keyword-as-function and map-as-function are convenient ways to call get.
15:09tbaldridgeBrenton Ashworth dropped ClojureScript one when he started on the Pedestal App code, so one could be considered the spiritual successor of the other.
15:10cYmenTimMc: I totally get map as function but the benefit of allowing to turn the function and the argument around elude me.
15:11ToxicFrogI've actually gotten into the habit of using (:key map) and I'm not sure why.
15:11`cbpcYmen: so you can get the same attribute from many maps using the function `map` and other such things
15:12danneucYmen: (map :username users)
15:12justin_smithalso filtering by key (filter :key [{:key false} {} {:key true} {:key 1}])
15:12cYmenhm... as opposed to #(% :foo) ?well I mean...why not ..whatever I won't be confused by it any longer! harr!
15:12justin_smithor even something like (filter (comp zero? :key) coll)
15:13justin_smiththat gets all items with :key that is 0
15:13justin_smithvery handy
15:13danneucYmen: there are some other good cases that are just hard to think of on the spot
15:14`cbplike avoiding null pointer exceptions
15:14lpvbis there a table somewhere of clojure data structure complexities
15:14danneu`cbp: that's a good pt i often take for granted
15:15danneu,(:a nil)
15:15clojurebotnil
15:20bjaapparently we can now set! *print-fn* in cljs. Whenever that support landed was a good day.
15:21danneuIs there a good place to manipulate the jvm state like inserting a provider (Security/insertProviderAt (BouncyCastleProvider.) 1)
15:21danneuA central place*
15:21lpvb,(range \a \z)
15:21clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number>
15:23lpvb,(map char (range (int \a) (inc (int \z))))
15:23clojurebot(\a \b \c \d \e ...)
15:23poppingtonictbaldridge: ok, pedestal is a great starter
15:24danneulpvb: frankly i like (seq "abcdef...xyz") better
15:27TimMc&(map (comp char (partial + 16r61)) (range 26))
15:27lazybot⇒ (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y \z)
15:27TimMc^ magic numbers like the palindromic 16r61 are just better :-P
15:28lpvb,16r61
15:28clojurebot97
15:28TimMc61 is 97 in base (radix) 16
15:29lpvbI know
15:29lpvbwhy not just
15:29lpvb,0x61
15:29clojurebot97
15:30TimMcBecause palindromes!
15:30lpvblol
15:30TimMcExactly.
15:30danneuisn't it so you can use decimal 26 in the range?
15:30danneuoh
15:31danneuhope a convo starts so thatll get pushed above the fold.
15:32TimMc&(map read-string (for [n (range 10)] (str 1 n \r n 1)))
15:32lazybot⇒ (1 12 25 40 57 76 97 120 145 172)
15:32lpvbhow do I define namespace privte constants?
15:32lpvb(def- x 5) doesn't work
15:33lpvb(defn- x [] 5) is tedious
15:33llasram(def ^:private foo ...)
15:33TimMcdefn- is just sugar for defn ^:private
15:34TimMc(Macro sugar, not reader sugar.)
15:35TimMclpvb: Private vars are overrated; people will argue about this, but you should know that it's still easy to get ahold of private vars from outside of the namespace.
15:35lpvbseems like a def- macro should be included by default
15:35lpvbunless that isn't idiomatic
15:35tbaldridge(inc TimMc)
15:35lazybot⇒ 52
15:35justin_smithlpvb: information hiding is not very popular with clojure
15:35llasramI think people decided that having separate private variations for everything was a bad idea
15:35tbaldridgeprivate vars are just wrong, imo
15:35llasramI just use ^:private even for defn
15:35danneuyeah me too
15:35llasramtbaldridge: Er. Why so?
15:36mdrogalisThere was a good talk by Stu Halloway about why. Can't remember which one.
15:36tbaldridgellasram: they make code harder to test, and manage imo. It's much better to put your public API in a different ns. Put all the "private" stuff somewhere else.
15:36mdrogalisIt was just a slide or two, but he nailed it..
15:36danneu:private is mostly helpful for me as the developer since a namespace is otherwise an interleave of "public" functions and helper functions
15:36TimMc,@#'*loaded-libs*
15:36clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve var: *loaded-libs* in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:37danneuNot :private, but the idea of private
15:37`cbp(ns cant.touch.this)
15:37TimMc,@#'clojure.core/*loaded-libs*
15:37clojurebot#<Ref@1071e40: #{clojure.core.protocols clojure.instant clojure.java.io clojure.repl clojure.string ...}>
15:37TimMc,clojure.core/*loaded-libs*
15:37clojurebot#<CompilerException java.lang.IllegalStateException: var: clojure.core/*loaded-libs* is not public, compiling:(NO_SOURCE_PATH:0:0)>
15:37danneuin fact, it's hard to scan a clojure namespace for the intended entry-points.
15:38lpvbmdrogalis: can you show me the slides?
15:38mikerodmdrogalis: I'd be interested in these slides
15:38TimMclpvb: All it does is control what is exported from the namespace when it is refer'd by another.
15:38mdrogalislpvb: Looking.. Not successful yet.
15:39mikerodI've struggled over the idea of no :private vars
15:39mikerodhard to say it is frowned upon when it is done in clojure.core though right
15:39llasramtbaldridge: I could see that if you're testing private functions. Usually functions I mark as :private I see no value in testing independently
15:39logic_progwe have number?
15:40logic_progis there a bool? or boolean?
15:40`cbpthere is no bool?
15:40`cbpahem, there is no `bool?`
15:40tbaldridgellasram: I just don't see a reason to restrict code for no apparent reason. Putting private vars into foo.impl.bar is a much better I idea.
15:40tbaldridgellasram: then it's just normal code, why does it have to be special?
15:41TimMcmikerod: clojure.core is not a good example -- there's some weird-ass code in there
15:41mikerodTimMc: fair enough
15:42TimMcIt's also supposed to be fairly stable, so minorly bad decisions do not get corrected.
15:42logic_progwtf
15:42logic_progthere is no bool?
15:42mikerodI have started questioning myself when I want to do a defn-
15:42logic_proghow do I check if a varaible is a bool in java?
15:43logic_progmaybe insanity like (== x (not (not x)) ?
15:43`cbplogic_prog: if by that you mean clojure: (or (false? x) (true? x))
15:43TimMc&(== true (not (not 5)))
15:43lazybotjava.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number
15:43mikerodI start thinking *maybe I shouldn't need so many one-off-specific-case private implementation functions*
15:43tbaldridgelogic_prog: perhaps instance?
15:43TimMc&(= true (not (not 5)))
15:43lazybot⇒ true
15:43llasramtbaldridge: I see it mostly as a hint that a function is internal. Putting in a separate namespace gets the same result, but having a separate ns & file seems like a heavier solution programmer-wise than just a :private annotation
15:44mikerodprivate function needed? `letfn` local binding
15:44tbaldridgellasram: I hear that, I just hate it whenever I decide to tap into someone's library and find out something is private, because they thought they knew more about it than I did. :-P
15:44logic_prog`cbp: nice, thanks
15:44mdrogalisDang, I can't find it. He was making a point that if you only emit X amount of information, you can only perceive, at most X information
15:44tbaldridge,(instance? Boolean true)
15:44TimMcI tend to use :private if *most* of my namespace is intended to be public and people should be able to use ns-publics to browse it.
15:44clojurebottrue
15:44mdrogalisAnd private minimizes X
15:44tbaldridge,(instance? Boolean false)
15:44clojurebottrue
15:44llasramtbaldridge: I feel the same way in languages like Java, but I've never had a problem accessing a :private Clojure var when I needed it :-)
15:44TimMcI also make dangerous fns private -- ones that back safer interfaces.
15:45mikerodprivate functions are sort of a "code smell" of non-reusable code aren't they? :)
15:45TimMcIf I have only a couple of API fns in a namespace, I just list them in the namespace's docstring and default to leaving things public.
15:45mikerodI guess not if you are using it all over in a lib of some sort, but you don't wnat others to get involved with it
15:46mdrogalisThere are probably more valuable problems you can spend your brain cycles on that something small like this :)
15:46mdrogalisThan*
15:46noonianyeah i think they are mainly used to hide things that aren't part of the public api
15:46TimMcThe problem is that namespaces conflate namespacing and APIs.
15:46TimMcAPIs/modules
15:48mikerodtrue
15:50dnolentbaldridge: it seems it would be possible to improve core.async source map support w/o waiting on that ticket no? but I guess you would need to change core.async macros to pass around line/col info
15:51tbaldridgednolen: yeah I could use some help on that. I had a patch that passed around line/col info but it doesn't go far enough.
15:51dnolentbaldridge: ok cool is this in a branch somewhere?
15:52tbaldridgednolen: from what I can tell, there's a general issue with how metadata is handled in Clojure. I haven't figured it out yet.
15:52tbaldridgednolen: not yet, I'll try to get it up soon
15:53dnolentbaldridge: I guess I don't see how this could be true since macros seems to ok w/ source maps for the most part?
15:53dnolen"seem to be ok"
15:55bjahas anyone seen: "Uncaught Error: URI file:/robots.txt is invalid for field ppu " out of the browser repl lately?
15:55bjaI get it when I attempt to clojure.browser.repl/connect
15:55tbaldridgednolen: it's been over a month since I tried out this code, so I could have a bug in it. I'll dig into it again and see what I find.
15:57dnolentbaldridge: I'm happy to contribute here, would give me an excuse to understand the macro stuff
15:58mdrogalistbaldridge: Do you have a general stance on serialization formats like Thrift and Protocol Buffers? e.g. when is it appropriate?
15:59tbaldridgemdrogalis: not really. I used Fressian the other day and really liked it.
15:59tbaldridgemdrogalis: https://github.com/Datomic/fressian
15:59mdrogalisFressian doesn't really fall into the same category as those two, does it?
16:00mdrogalisIts self-describing IIRC?
16:03tbaldridgemdrogalis: yeah it is, that's what I default to I guess. I don't have much of a use for contract based serialization.
16:03mdrogalisHm, alright. Thanks.
16:07llasrammdrogalis: If you're evaluating thrift, protobufs, etc, I've got Clojure integration for Avro I'm quite happy with: https://github.com/damballa/abracad </pitch>
16:55danneuDoes anyone have a workflow for frequently running typedclojure type checks?
17:01rasmustodanneu: I've heard this is good: https://github.com/typedclojure/lein-typed
17:01rasmustohaven't used anything but in-line checks personally, so can't tell you more
17:03rasmustotoo soon
17:08danneurasmusto: yeah, i'm trying to roll my own emacs hotkey to check the current ns
17:09jtoyis there a library that finds the difference between a schema and a db adds those changes to the db?
17:09jtoyits not a migrations im looking for, its more auto migration
17:11justin_smithjtoy: http://clojuredocs.org/clojure_core/clojure.data/diff would be a start, if you have to make it yourself
17:11justin_smithjust make schema->map and map->schema functions, and use data/diff to find the differences
17:13jtoyjustin_smith: do you know of a library that will deal with the lowl levle db stuff ? i also want to write my migration in clojure and not in sql so i can make it db agnotistic
17:13justin_smithhmm, if you don't mind a macro-heavy solution there is korma
17:14jtoyjustin_smith: i use it anyway for writing sql, i'll see if i can continue to use it for this part
17:24lpvb,(vector-of :bool true false)
17:24clojurebot#<NullPointerException java.lang.NullPointerException>
17:24lpvbwhy is that
17:25lpvboh
17:25lpvbnvm needs :boolean
17:33jtoyhmm, a lot of work for now
17:41justin_smithjtoy: https://github.com/budu/lobos this actually may help you
17:45justin_smithjtoy: note it has a db analyzer - you could run that on two dbs, then use data.diff on their tables
17:45justin_smith*table-definitions
18:03tbaldrid_dnolen: my WIP for source map fixes is in meta-fixes (in the core.async repo)
18:03clojurebotYou don't have to tell me twice.
18:04tbaldrid_dnolen: it should work, but it doesn't for some reason. If you run cljsbuild adv it'll spit out a bunch of info at compile time about the metadata it finds. It looks correct but doesn't seem to make it into the source map
18:08bitemyapp(is (= madness?-this-is-sparta blah also)))))
18:08bitemyappdescriptive nomenclature? kinda not really.
18:18akurilinbitemyapp, Korma defaults to RETURNING for every insert/update, correct?
18:21bitemyappakurilin: I remember changing something about that at some point. might be keys only.
18:22bitemyappakurilin: I dunno, you tell me.
18:22bitemyappI've forgotten most of what I've changed in Korma ^_^
18:22bitemyappspecifically I made it so that bulk inserts would "work okay" by not RETURNING
18:22bitemyappwhat I made the default is not within my memory.
18:24akurilinbitemyapp, I remember talking to the PG folks about always using RETURNING even if you don't need the results, and they were revolted by the idea. In practice most of the time you actually benefit from returning that one row you insert/update
18:24akurilinfor large updates Korma right now returns either the first or the last one, forgot
18:24akurilinbut essentially only 1 row
18:27bitemyappakurilin: the choices, if I recall were none, keys, and values
18:28bitemyapphow those map to what data actually gets returned is a little obtuse.
18:29bitemyappakurilin: you'd benefit most from reading the code, by my estimation.
18:29bitemyappBetter than reading tea leaves and guessing.
18:29akurilinbitemyapp, I am actively doing that in parallel to this.
18:31bitemyappakurilin: you use korma heavily enough that the familiarity should pay dividends.
18:31bitemyappakurilin: I'm pretty sure you use Korma about 99x more than I do these days.
18:33bitemyappakurilin: in fact, I'm not really sure when I'll use a SQL database at all again in the future.
18:33akurilinbitemyapp, I am actively doing that in parallel to this.
18:33akurilinoops
18:33bitemyappakurilin: most of my future database use is slated for Datomic, with some falling over to RethinkDB/Cassandra/HBase/etc
18:33akurilinI was going to say: it's interesting when maintainers stop being consumers.
18:34akurilinGuess it's our job to step up and start tossing some pull requests at you guys.
18:34bitemyappakurilin: I don't think baranosky would be opposed to you contributing to Korma at all if you decided to learn the codebase.
18:34bitemyappakurilin: yeah, exactly.
18:35bitemyappI will say this though, I still think a stripped down "micro-Korma" that wasn't complected with things like connection pooling would be really cool.
18:35bitemyappbut that's not really my "problem" right now, so I'm choosing not to be opinionated about it specifically because I'm not a consumer.
18:35bitemyappAlex and I are keeping the lights on and accepting PRs.
18:36akurilinbitemyapp, and I appreciate that :)
18:37akurilinWould be curious to find out how many people are activeling using this stuff in production
18:37bitemyappquite a few, if I had to guess.
18:37bitemyappnot as many as cjj, but they're out there.
18:37akurilinOk, just making sure I'm not survivor man there.
18:37bitemyappnot that I've taken a census.
18:38bitemyappHoneySQL is pretty neat, but I'm not convinced it's the right level of abstraction.
18:38bitemyappconcatenating predicates is kind of tedious.
18:39akurilinSort of related topic: korma exception handler loves to println stuff. I have my own sql exception handling and logging layer, and extra crap in the terminal is confusing in test runs. Is rebinding *out* around each korma db call the way to go to /dev/null it?
18:40bitemyappakurilin: the logging in Korma is log4j yo.
18:40bitemyappjust configure it.
18:40bitemyappunless I've missed something.
18:40bitemyappI mean, you could do that too, but you don't need to.
18:41Somelauwkinda hacky, but i think you can do (define *out* (StringIO.)) to disable println globally
18:41akurilinI'm completely unfamiliar with log4j. Can I specify that I want logging exceptions only for selects for example?
18:45akurilinWarnock's dilemma.
18:49bitemyappplease don't do what Somelauw just said :P
18:50bitemyappakurilin: I have no idea @ log4j, obviously it would be ideal if you could just dependency inject/AOP the log-fn and handle it yourself.
18:50bitemyappwhiiiiich is why I usually just have a *log-fn* dilly that people can override...
19:01bitemyappanother day, another error arising from an unexpected nil creating a nonsensical error when it blows up in my face somewhere unexpected. Delightful.
19:01bitemyapptechnomancy: ^^ grumble grumble.
19:02technomancybitemyapp: imma write a fuse adapter for github issues in ocaml
19:02technomancyI've Decided.
19:02bitemyapptechnomancy: that's pretty brilliant.
19:03technomancywell I haven't done it yet
19:03bitemyapptechnomancy: grom is still a thing, now that I've written the error handling for Revise grom and Simonides are my next projects.
19:03technomancycools
19:03bitemyapptechnomancy: I really like the concept in general...you should write it in Haskell instead though :)
19:03bitemyappI need to shanghai noprompt into helping me with Grom since he wanted it too.
19:04technomancymaybe if I didn't want it to get written quickly I could use haskell
19:04bitemyapphrm. good point.
19:04technomancybut the web UI is buggin' me and I don't want any yaks in the way
19:04technomancycontext: I just started using noscript for conkeror, and its whitelisting doesn't work on github.
19:05technomancywhich is mostly a win, but it turns all the icons into stupid unicode-not-found glyphs
19:05zeebrah I would like to have an alias λ for core/fn
19:05zeebrahis there a way to achieve that?
19:06technomancyzeebrah: do it locally in your editor, not on disk
19:06zeebrahtechnomancy: good idea!
19:07bitemyappzeebrah: Haskellers have a pretty well established history of doing stuff like that with the glyph replacement stuff Emacs provides.
19:07bitemyappI forget the proper name for it, #emacs surely knows.
19:08technomancyhttp://marmalade-repo.org/packages/pretty-mode-plus this one maybe
19:09zeebrahi like how it is assumed i'm using emacs lol :) Light Table but i'll try to figure it out
19:12`cbpemacs live has that by default
19:13technomancyit has issues in a few cases
19:13akurilinThose of you who worked with PG and JDBC, have you ever noticed the driver throwing a SQLException wrapping a PSQLException rather than directly the latter?
19:13technomancyit can affect line-length calculation and in some cases cause wrong indentation
19:13akurilinI think the latter case is there most of the time, but I swear I've seen the former once or twice in certain situations
19:16bitemyappawwww yissss. Breaking test case that reproduces my problem.
19:16akurilinSo the # and the end of a symbol in a macro is there to make sure there isn't accidentally a naming collision once the macro is expanded, avoiding interesting debugging sessions?
19:16bitemyappakurilin: it's a shortcut for gensym.
19:17akurilinOh ok, I didn't know its actual name.
19:17bitemyapp,(gensym 'blah-this-fucking-rocks)
19:17clojurebotblah-this-fucking-rocks31
19:17bitemyapp,(gensym 'blah-this-fucking-rocks)
19:17clojurebotblah-this-fucking-rocks60
19:17bitemyapp,(gensym 'blah-this-fucking-rocks)
19:17clojurebotblah-this-fucking-rocks89
19:17bitemyapp,(gensym 'blah-this-fucking-rocks)
19:17clojurebotblah-this-fucking-rocks118
19:17`cbpno!
19:17bitemyapp`cbp: wut
19:17`cbpstahp
19:17bitemyapp`cbp: sorry :(
19:18bitemyappakurilin: it's to avoid the tedium of managing your gensym aliases yourself.
19:18bitemyappakurilin: which...you had to do in Common Lisp.
19:18bitemyappit sucked.
19:18bitemyappa lot of things sucked. This was one of those things.
19:18akurilinbitemyapp, ok but the point was collisions?
19:18`cbpunintentional symbol capture
19:18bitemyappyou dun wanna shadow the users code.
19:18bitemyappyeah
19:18akurilinThere you go.
19:19coventryIt doesn't explicitly check for collisions, though, just updates an internal counter each time you call it.
19:20akurilincoventry, I get it, thanks.
19:20akurilinWeird, the docs say it should append _number
19:20akurilinbut there's no _ either here or in my repl
19:21bitemyappakurilin: # appends _ + gensym.
19:21akurilinbitemyapp, ah, got it now.
19:24bitemyapp`cbp: DotA2 tonight?
19:25bitemyapparrdem: ^^
19:29TEttingerDefense of the Ancients 3: The Ancients are in a nursing home for senior citizens. Defend them by giving them their applesauce and meds 3 times a day.
19:29swarthyahhaha
19:32bitemyappTEttinger: hahahaha, that's pretty good :)
19:34akurilinbitemyapp, I saw the *exec-mode* dynamic var approach Korma does to determine how to execute the queries. Is that a pretty good pattern to follow as opposed to passing options to functions to customize their behavior?
19:34bitemyappakurilin: no no no no no
19:34bitemyappakurilin: Korma isn't a good example of many things.
19:34bitemyappThe thing it got right was passing around query maps, but even that was done in a brittle fashion.
19:34`cbpbitemyapp: sure
19:35akurilin(how to learn Clojure: get intimately familiar with other people's code, then forget everything they did)
19:35bitemyappakurilin: if you want to see *good* code, Revise is a good place to look.
19:35bitemyappthere's some mess due to young the codebase is, but `cbp did a damn good job.
19:36bitemyappthe patterns and design are solid, there's no global/dynamic bullshit.
19:36akurilinbitemyapp, I think the one advantage that approach has is that you can group an unlimited amount of queries under the binding of that dynamic var, without having to do the pure approach for every call.
19:36bitemyappyou pass a connection to execute a query. no global singletons.
19:36bitemyappakurilin: yuo can solve that problem just with closures...don't make my eyes roll that hard, it hurts :(
19:37bitemyappthere are times when dynamic vars are called for, that wasn't one of them.
19:37akurilinActually the same pattern was there in noir validation with a dynamic var accumulator of validation errors.
19:37swarthybitemyapp: I'm about to grab a smoking jacket and some other people's code for reading. What do you think are good clojure libs to learn from?
19:37bitemyappakurilin: that was a bad fucking idea too.
19:37akurilinbitemyapp, I think it's just the author's style.
19:37bitemyappakurilin: well it's the same author.
19:38bitemyappRegardless, it's a bad fuckin' idea.
19:38akurilinbitemyapp, yes, my point.
19:38akurilinbitemyapp, fair enough, point taken.
19:39bitemyappswarthy: https://github.com/weavejester/hiccup https://github.com/weavejester/environ github.com/bitemyapp/revise/ github.com/bitemyapp/bulwark/ github.com/bitemyapp/blackwater/
19:39bitemyappswarthy: if you want scary code: https://github.com/bitemyapp/brambling
19:39bitemyappswarthy: https://github.com/dakrone/clj-http/
19:39akurilinbitemyapp, can you expand a bit on the closure pattern?
19:39bitemyappswarthy: https://github.com/dakrone/cheshire
19:40swarthybitemyapp: Thanks a bunch! I've used a few of those while learning! Can't wait to dig much deeper.
19:40bitemyappakurilin: https://github.com/bitemyapp/bulwark/blob/master/src/bulwark/core.clj#L88-L91
19:41bitemyappswarthy: heavily optimized and kin da razy but still interesting: https://github.com/aphyr/riemann
19:41bitemyappriemann is NOT representative of typical Clojure code (this is true for a lot of aphyr and ztellman's stuff)
19:41akurilinbitemyapp, so you're basically being pretty pure there, passing config values around downstream?
19:41bitemyappquestionable libraries are the order of the day for those blokes.
19:41bitemyappakurilin: pure'ish, there's an atom, but the closure takes precedence.
19:41bitemyappalso the atom isn't dynamic, it's global.
19:42akurilinbitemyapp, to avoid magic?
19:42swarthybitemyapp: questionable libraries are the order of the day for those blokes. Care to elaborate?
19:43bitemyappakurilin: to keep it async safe.
19:43bitemyappakurilin: long story.
19:43coventryIs there ever any reason to use dorun as opposed to doseq?
19:43bitemyappswarthy: long story, and I'm about to go eat with a friend.
19:43swarthynp I'll be idling here plenty I'll ask again later
19:43bitemyappswarthy: suffice it to say, Mr. Tellman and Mr. Kingsbury have very different needs from the rest of us mere mortals.
19:43akurilinbitemyapp, mind if I dump that list of libraries you recommended to my tumblr for future reference?
19:43swarthyah cool!
19:43bitemyappswarthy: big distributed systems high performance stuff blah blah bvalh
19:43bitemyappakurilin: go for it.
19:43amalloycoventry: of course. if you already have a lazy sequence that contains side effects, and you want to run them now, rather than run new side effects based on an existing sequence
19:43swarthythat says enough thanks!
19:44amalloyor it can be easier to write (dorun (map foo! xs)) than (doseq [x xs] (foo! x))
19:44coventryamalloy: Oh, ofcourse. Thanks.
19:49coventryztellman's sleight and riddley libraries touch clojure's guts in slightly icky ways, but for totally clear and sensible reasons. Reading them with those reasons in mind won't leave any harmful impressions.
19:59seangroveI have a string: "2012-10-07T20:23:56.000+0000", and I would like a timestamp. Can't quite figure out the straightforward way to do this
20:00AimHereIf there's nothing inbuilt, you could split it up into bits with re-match and then look at the individual fields
20:00amalloyAimHere: that way lie madness and shattered dreams
20:00AimHereOh ye of little faith
20:01seangroveAimHere: Going to have to side with amalloy there
20:01swarthyseancorfield: I had to mess with dates recently and I ended up using this: https://github.com/seancorfield/clj-time
20:01amalloyseangrove: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
20:01amalloythere may be a wrapper in clj-time, but SDF isn't that complicated to use
20:01swarthyswarthy: I also did what amalloy mentions if you won't need to mess with it much.
20:02seangroveI'll check out SDF
20:02akurilinclj time or underlying joda should be able to take care of all of those concerns
20:02akurilinunless it's some odd edge case
20:02seangroveThanks amalloy and swarthy, and of course AimHere
20:02seangroveakurilin: No, just interop with SFDC, nothing too bad
20:02AimHereSo much for adding on the regex problem to all your other problems!
20:04swarthyseangrove: if you haven't already seen it I use clojure-toolbox.com to find libraries for various things
20:04akurilinThe full list of Joda's out-of-the-box formats is: http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html
20:04akurilinWrapped by this guy: https://github.com/clj-time/clj-time/blob/master/src/clj_time/format.clj#L82
20:08jtoyif I have 2 arrays like [1 2] and [:foo :bar] jow can I join them so i get {:foo 1 :bar 2} ?
20:08justin_smithjtoy: zipmap
20:08justin_smith,(zipmap [:foo :bar] [1 2])
20:08clojurebot{:bar 2, :foo 1}
20:09jtoysweet
20:11brehautjtoy: to generalize into and map are also useful. zipmap ~== (fn [a b] (into {} (map vector a b)))
20:12brehautjtoy: which is to say, map is a general purpose zipping function for stitching n sequences together, and into lets you pour a sequence into a collection type
20:12jtoybrehaut: I should use that more but that confuses me more often
20:13brehautwhats confusing about it?
20:13justin_smith,(apply assoc {} (interleave [:foo :bar] [1 2]))
20:13clojurebot{:bar 2, :foo 1}
20:13justin_smithanother option :)
20:15jtoybrehaut: i dont know why i would do map vector
20:15jtoyjustin_smith: ye, even more confusing
20:16brehautjtoy: ok so map takes a function of N arguments and N sequences
20:16brehautjtoy: it takes items at the same index from all the sequences and passes tehm to the function
20:16amalloyjustin_smith: any time you apply assoc, you've probably made a mistake. into is just better for that kind of thing
20:16brehautjtoy: vector takes N arguments and creates a new vector from it.
20:17brehaut,(map vector [:a :b] [1 2]) ;; jtoy
20:17clojurebot([:a 1] [:b 2])
20:17brehautjtoy: thats the interstitial datastructure we need to use into to fill a map
20:17brehautjtoy: conj on a map takes a key value pair as a vector
20:17brehautjtoy: and into uses conj from memory
20:19brehaut,(map + [1 2 3] [4 5 6]) ;; jtoy this zips together two sequences by adding the values at each index, as another example of map as zip
20:19clojurebot(5 7 9)
20:25jtoybrehaut: ah I see, I havent used multiple lists with map before
20:35zeebrahWhen i enable clojure-mode in a cider repl, i can no longer evaluate any expression in the repl. Any way to solve this?
20:36coventryzeebrah: Use nrepl instead. The cider package is not stable yet.
20:36justin_smithdon't turn on clojure mode?
20:36zeebrahjusticefries: I don't get the font locking then
20:37justin_smithclojure mode and the repl mode are both major modes, the one replaces the other
20:37coventryzeebrah: Oh, you were turning on clojure mode in the repl buffer? It's not meant to be used that way.
20:37zeebrahcoventry: yep
20:49amalloybrehaut: into actually uses conj! and transients, by the way
20:49amalloynot observably different, of course
20:49brehautamalloy: yeah i figured, but that can be brushed under the carpet
20:51brehautnot observable without a timer anyway
20:59ddellacostaif you were going to re-write some Clojure code which uses refs in CLJS, generally speaking, are atoms the most appropriate (only) answer?
21:00ddellacostaI guess the big distinction is between "coordinated" vs. "independent," huh
21:02amalloyddellacosta: since there are no threads in cljs, atoms are just as good as refs: no swap! ever retries
21:03amalloyyou have to make sure you don't split up a dosync block onto different event handlers, or whatever js calls them, but otherwise it's pretty hard to go wrong
21:04bitemyappddellacosta: what did you need the coordination refs offer originally?
21:05ddellacostaamalloy, thanks, that's helpful.
21:06ddellacostabitemyapp: I'm just playing around now playing with FSMs
21:06ddellacostabitemyapp: I was converting this code to work in CLJS: http://nakkaya.com/2010/06/22/finite-state-machine-implementation-in-clojure/
21:06ddellacostabitemyapp: now I'm reviewing how core.async works, since I understand that uses state-machines under the covers
21:07bitemyappddellacosta: FSMs are very useful when they fit your problem.
21:08ddellacostabitemyapp: yep. Specifically I'm managing a validation system which validates as you move from field-to-field, so it seemed like a good approach. And we have a help system we will need to update later on, so I thought I could kill two birds with one stone.
21:08ddellacosta*managing -> re-factoring
21:08bitemyappddellacosta: I'm not convinced that code needed a ref though. They're just doing flat ref-sets.
21:08bitemyappunless you're THAT worried about stale reads.
21:08bitemyappthat's pretty paranoid though.
21:09ddellacostabitemyapp: yeah, I wasn't quite sure why that code did what it did, although I suppose if it gets accessed in a multi-threaded context it could be a problem, no?
21:09bitemyappddellacosta: for contrast, 99% of SQL database access is generating writes that use stale reads that are milliseconds, if not whole seconds, old. A stale read with an atom will be microseconds old and involve only one process whereas my database example might involve hundreds of readers and writers.
21:09amalloybitemyapp: well, it's over three years old - atoms might not have existed back then?
21:09bitemyappddellacosta: if the SQL database scenario isn't biting 99% of users, it's extremely unlikely an atom would.
21:10ddellacostaamalloy: good point
21:10bitemyappamalloy: aha, good call. I hadn't even noticed.
21:10bitemyappI wasn't critiquing, just explaining why I don't think stale reads are a big deal most of the time.
21:10amalloyi think atoms were around then, but i'm not really sure
21:11bitemyappNarullah wrote a lot of good stuff about Clojure.
21:11ddellacostayeah, really love his blog
21:11bitemyappI need to update my blog with an updated projects list.
21:11bitemyappI've added a lot since I last updated it.
21:11logic_progis there any fringe implementation of clojure on go rather than java?
21:11nightflyjavaSCRIPT
21:12nightflycljs
21:12bitemyapplogic_prog: you'd be better served by explaining your needs.
21:12bitemyappnightfly: cljs isn't fringe.
21:12logic_progpurely intellectual curiosity
21:12nightflyand feels ashamed for a word earlier
21:12logic_progto see if someone has a implmentation of clojure that runs on Go (the langauge) rather than the JVM
21:12bitemyapplogic_prog: no, and it's unlikely to happen.
21:12logic_prognightfly: lol, was wondering how cljs / javascript fit in
21:13ddellacostaoh it's almost the conj isn't it
21:14bitemyappddellacosta: hey I'm stuck in SF, so we can suffer together (apart)
21:17lpvb(defn destructuring [{x :x y :y}] ...)
21:17lpvbthe problem with ^ is that I lost the name of what's being passed in
21:18lpvbwhich is a reminder for what should be passed in
21:19lpvbor am I being pedantic?
21:19technomancylogic_prog: the go runtime has no dynamic loading capabilities at all; it's completely unsuitable for interactive development
21:20technomancy(which by extension makes it unsuitable for basically any good development, because good development is interactive)
21:20xeqilpvb: you can name the arg with :as. {:keys [x y] :as point}
21:21lpvbxeqi: thanks :)
21:25coventryAre there any projects I should look at for examples of extending nrepl.el? Aside from nrepl-discover?
21:25technomancycoventry: lein.el maybe; but that's kinda stalled
21:26technomancyprobably ritz
21:26brehautddellacosta: what distant clime are you in?
21:26coventrytechnomancy: Thanks.
21:27technomancycoventry: what's your plan?
21:30coventrytechnomancy: Well, I was trying to use nrepl-discover, but I need more logic on the elisp side, so I cargo-culted the output of nrepl-discover-command-for and hacked it up a bit (https://www.refheap.com/20753). I'm getting complaints that (".../tst.clj" 1 198) is not a string, which is the result of the (cons fn defun-region) form in that snippet.
21:32coventrytechnomancy: What I'm really trying to do is write an emacs function which will take the current region, get all the top-level forms which intersect with it, pass that to clojure, and instrument all forms in the region with clojure.tools.trace/trace.
21:32coventrytechnomancy: I have the clojure side of this written. Just need the emacs integration now.
21:33coventrytechnomancy: Currently, I'm looking for examples or instructions on how to pass a non-string argument through nrepl-send-op.
21:34arrdembitemyapp, `cbp : eeeeeh not really Q_Q
21:36technomancycoventry: huh; that should be doable without any elisp if nrepl-discover is working properly
21:37ddellacostabrehaut: I am in Tokyo
21:37technomancybut I haven't tested some of the arg types yet
21:37ddellacostawishing I could get to conferences more easily. :-(
21:38brehautddellacosta: yup totally. its mighty expensive to fly to the US
21:39ddellacostabrehaut: I'm thinking I'll try for Clojure West next year though
21:39coventrytechnomancy: nrepl-discover is working to the extent that nrepl-discover-command-for is being run with the nrepl/op metadata I put on the clojure fn, but I don't see a way to get the buffer-substring through to the clojure side within the nrepl-discover framework, at least not without saving the buffer to disk first.
21:40technomancycoventry: oh... do you have to send the substring? can't you send the file/positions and do reading server-side
21:40technomancyas long as you force a save before it's invoked
21:40technomancy(you should compile anyway, so that's probably fine)
21:42coventrytechnomancy: Yeah, I'd rather not have to force a save. The idea is to go in and just change the vars affected by the given region, like C-M-x rather than C-c C-k.
21:43coventryIf I have to force a save, I have to ask the user whether it's OK, which slows things down in my experience.
21:44coventryBut my more immediate problem is that sending a list as an argument in nrepl-send-op doesn't seem to work. Normally I'd assume it's my fault, but I'm a little more agnostic here since I'm ape-ing untested code.
21:44technomancyhm; maybe adding region-contents as an arg type is a thing we should do
21:45technomancyI gotta take off though; feel free to open an issue
21:45coventrytechnomancy: region-contents and nrepl-region-for-expression-at-point contents would work here, yeah.
21:46coventryYeah, I'll open an issue, but may take a bit for me to get to it.
22:11lpvb,(-> 1 (fn [x] (+ 3 x)))
22:11clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Parameter declaration 1 should be a vector>
22:11lpvbcan someone explain why this doesn't work? I don't think I'm understanding ->
22:12amalloy,(macroexpand-1 '(-> 1 (fn [x] (+ 3 x))))
22:12clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Parameter declaration 1 should be a vector>
22:12amalloy&(macroexpand-1 '(-> 1 (fn [x] (+ 3 x))))
22:12lazybot⇒ (fn 1 [x] (+ 3 x))
22:12beppu,(-> [1] (fn [x] (+ 3 x)))
22:12clojurebot#<Exception java.lang.Exception: Unsupported binding form: 1>
22:13amalloythat's a rather unfortunate fallout of the change to fix how -> nests, gfredericks (or was it TimMc who noticed the problem?)
22:14lpvbso how do I accomplish what I intended?
22:14amalloy(+ 3 1)
22:14clojurebot4
22:15beppu,(-> 1 (+ 3))
22:15clojurebot4
22:15amalloyactually i don't understand at all why clojurebot fails to macroexpand that
22:15bitemyapp,(-> [1] first (+ 3))
22:15clojurebot4
22:15bitemyapparrdem: DotA2?
22:15lpvb,(-> {:x 1} (assoc :x 5))
22:15clojurebot{:x 5}
22:16bitemyapplpvb: macros operate on code structure, not data.
22:17bitemyapplpvb: (-> [1] (fn [x] (+ 3 x))) turns into (fn [1] [x] (+ 3 x))
22:17lpvbI defined a function (defn setm [m k f v] (assoc m k (f (get m v))))
22:18lpvband (-> {:x 1 :y 2} (setm :x (fn [x] (+3 x)) :y))
22:18lpvbdoes the same error
22:18lpvbshouldn't the macro inject that map after setm
22:20arrdembitemyapp: neg. homework.
22:20lpvboh wait it is working
22:21lpvbthanks guys
22:22amalloy,(macroexpand-1 '(-> 1 (fn [x] (+ 3 x)))) ;; seriously i'm baffled as to why this no longer returns (fn 1 [x] (+ 3 x)). any ideas, guys? a clojurebot issue somehow?
22:22clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Parameter declaration 1 should be a vector>
22:24`cbpbitemyapp: wanna play?
22:24`cbpamalloy: it does return that?
22:24amalloyyeah, it must be clojurebot. hiredman, any idea why clojurebot now expands macros even if they're quoted? eg, ,'(with-open x) throws an exception
22:25`cbpoh but it shouldnt evaluate
22:26`cbpnevermind me :)
22:26amalloyright, `cbp. i'm guessing clojurebot does a dumb clojure.walk/macroexpand-all or something
22:27coventryamalloy: There's no macroexpand-all in clojurebot master.
22:28amalloycoventry: looks like https://github.com/hiredman/clojurebot/blob/master/clojurebot-eval/src/clojurebot/sandbox.clj#L147 to me, a hand-rollwed reimplementation of macroexpand-all
22:29coventryYep.
22:32akurilinDoes anybody know of any neat tools out there that can tell you what the "state" was when an exception happened? As in, I'm thinking of a mix of clojure.tools.trace and an exception handler
22:33akurilinI can write my own, but I'm suspecting this must have been done before.
22:33akurilinSo something like: function f blows up with exception e, I want to know what the input was.
22:43amalloyakurilin: slingshot's throw+ automatically includes the in-scope locals into the exception
22:44akurilinamalloy, oh interesting, never heard of slingshot.
22:44akurilinamalloy, strongly recommended?
22:44amalloymeh
22:44akurilinlol...
22:45amalloyalthough, now i think of it, shouldn't that cause head retention? like, (defn last* [xs] (try (last xs) (catch Exception e (throw+ "broken")))) ought to prevent xs from being GCed, since the throw+ clause will attempt to include xs in the ex-info, right? that sounds bad
22:49akurilinCan you actually list locals in Clojure without having to wrap anything?
22:53justin_smithakurilin: here is code that displays locals in another clojure process: https://github.com/GeorgeJahad/cdt/blob/master/src/cdt/reval.clj
22:54justin_smithas you could imagine, it is a very low level thing
22:54akurilinjustin_smith, yeah, definitely looks like serious business.
22:54akurilinthx
22:55akurilinMan, the stuff you can do.
22:55justin_smithakurilin: here is a webapp that connects to another clojure process, and when the remote gets an exception, it lets you examine the stack frame and eval in context: https://github.com/prismofeverything/schmetterling
22:56justin_smithuses clojurescript and websockets
23:00echo-area`defmacro' doesn't work inside (binding [*warn-on-reflection* true] ...).
23:01amalloyecho-area: (binding [*warn-on-reflection* true] ...) doesn't do anything, so that's not a super-compelling complaint
23:01echo-areaamalloy: What I wanted to say is that, is it because the context is changed?
23:01amalloyanyway, defmacro needs to be a top-level form, since each top-level-form is compiled as a whole; *warn-on-reflection* is a red herring
23:03bitemyapp`cbp: grabbing a drink with a buddy, then we can.
23:03bitemyapp`cbp: I'll be back soon.
23:04akurilinjustin_smith, wow that's awesome, thanks for sharing. What is the advantage of attaching a process to it rather than just dumping the entire context somewhere in a log?
23:04akurilinjustin_smith, is there some kind of killer app of evaling within the context?
23:05echo-areaamalloy: Why does that binding form not do anything?
23:05amalloybecause it sets *warn-on-reflection* at runtime, and *warn-on-reflection* is only meaningful at compile time
23:08echo-areaSo is it not idiomatic to enclose def's inside such a form? I thought that way the enclosed forms are then compiled with *warn-on-reflection* being true
23:10amalloythat is simply not the case. the entire form is compiled, and then *warn-on-reflection is bound to true, and then the entire form is eval'd
23:11echo-areaOh right, it should be set before loading
23:12justin_smithakurilin: seeing exactly what is going on in each context
23:12justin_smithat the exact moment that the exception occured
23:12justin_smithie. not only having a log of the things you intended to record, but being able to interactively query status of things you had not thought of beforehand
23:12akurilinjustin_smith, any way you can just dump that to disk and reload it later?
23:13justin_smithI think there is a way to dump and reload a vm
23:13justin_smiththat would be a java thing I guess
23:13echo-areaamalloy: Is it correct that during loading .clj files the forms are compiled one by one, rather than entirely?
23:13justin_smithI think the problem would be that a bunch of things in the dump would refer to stale resources
23:14akurilinjustin_smith, my issues are pretty simple for now, but I'm sure that with size I'll need to look into more adult debugging practices
23:14justin_smithie. some values on a bytecode level refer to open files or streams, or process ids of other processes
23:14amalloyyes
23:14justin_smithakurilin: our use case is sometimes you just get that one bug you cannot reproduce and you just wish you could have had a repl in the context where the answer happened
23:14echo-areaI see. Thanks
23:15justin_smithakurilin: complementary to that app I also made a request recorder replayer ring middleware
23:15akurilinjustin_smith, yeah, I hear you. Right now my solution is: dump the prod db, load on my machine, repro, but that doesn't scale very well with # of external services and size of db :(
23:16justin_smithwhich you may find useful if you are using ring, and want to be able to test updated code with a request that is known to have triggered a bug
23:16justin_smithakurilin: also the repro can be odd
23:17justin_smithone particular bug I remember: we were using the default name for the cookie "ring-session", and one of our frontend devs had tried some friend's buggy webapp that created a broken localhost ring-session cookie
23:17justin_smithso the bug was only reproducible on his machine
23:17justin_smithand it wasn't even us, it was a corrupted cookie causing an exception
23:17justin_smithwell I guess we learned to handle that better :)
23:17akurilinjustin_smith, ah damn, must have been a pain
23:18akurilinI'm also a ring-session cookie kind of guy heh :)
23:18justin_smithclassic "error only happens for the one guy who can't read the stack trace"
23:21akurilinjustin_smith, a lot of things get much easier once you can see the full stack trace, huh?
23:21justin_smithwell, its a first step
23:22akurilinOn an unrelated note: how do I replace a fn in a library I don't own? Bitemyapp was saying something about AOT
23:22akurilinbut I haven't found anything useful on Google \
23:23`cbpakurilin: alter-var-root
23:23justin_smithI don't know how aot plays into that
23:24justin_smithI have seen someone actually run their whole app inside a with-redefs foorm
23:24justin_smithlol
23:25akurilin`cbp, the idea is that I do that once at boot and it'll be set for the rest of the app's lifetime?
23:25`cbpakurilin: yeah
23:25`cbpunless theres an evil alter-var-root somewhere in that lib i guess
23:25akurilinso do people end up with a "do stuff at boot" function ?
23:26justin_smithakurilin: yeah, with ring you can register an :init action
23:26justin_smiththat way you can make sure you have no stateful events other than var bindings at the top level of any of your code
23:26justin_smithjust def the init in each ns, and call all of them from the main ring init
23:27justin_smiththat way reloading source doesn't have weird side effects
23:27justin_smithof course without ring you have -main
23:27akurilinjustin_smith, what does it mean to def the init in each ns?
23:28justin_smithit is a convention that is useful
23:28justin_smithin each ns you make, if the code needs any initialization, you (defn init [] (initialize this namespace... ))
23:29justin_smiththen you call each of these functions from the function you register with ring as your :init
23:30akurilinjustin_smith, what if it's some initialization that multiple namespaces need, you still put it up there?
23:30akurilinAs long as it's idempotent I guess.
23:30justin_smithyou define it in each ns
23:30justin_smiththen call them from the init function
23:31akurilinjustin_smith, so the initialized thing is defined once per namespace this way?
23:31justin_smithwell for the ones that need it, each gets their own
23:31justin_smithreally most namespaces don't need an init function
23:32justin_smithjust the ones that do things like load config files at boot
23:32justin_smithor set up a db connection pool
23:32justin_smithor create a pool of worker tasks
23:32justin_smiththat kind of stateful startup stuff
23:32akurilinYeah I have stuff like that and logging levels
23:34akurilinjustin_smith, well thanks for sharing, that's interesting
23:35justin_smithno problem, hope it proves helpful
23:35akurilinCan I even alter-var-root private vars?
23:36akurilinGuess I'm about to fin dout
23:36Raynesakurilin: Yes.
23:37RaynesPrivacy is more of a "Yo, this person thought you should probably not use this." instead of a "GET ON THE GROUND HANDS BEHIND YOUR BACK HANDS BEHIND YOUR BACK DROP THE WEAPON."
23:40akurilinRaynes, well it does seem to be making things a bit trickier. For example, this fn I'm replacing calls another private inside of it, so it's throwing an exception when I try to alter var root it
23:41justin_smithakurilin: (in-ns target-ns)
23:42akurilinjustin_smith, that seems to be stateful, can I do the same with rebinding *ns*?
23:42akurilinor at least I only ever used in-ns from a repl
23:43justin_smithhmm
23:43justin_smithyeah, that could be tricky I guess
23:44justin_smithakurilin: http://clojure.org/namespaces
23:44justin_smith"The current namespace, *ns* can and should be set only with a call to in-ns or the ns macro"
23:44RaynesIf it throws another private inside it then call the var and not the function, I guess.
23:45Raynes&(#'+ 3 3)
23:45lazybot⇒ 6
23:45justin_smithakurilin: you could always just fork the library instead of monkey patching it
23:45justin_smithit may be easier
23:46akurilinjustin_smith, that's fair, I need to get used to doing that anyway.
23:46akurilinsupposedly pushing stuff to clojars is pretty braindead these days
23:46justin_smithvery easy
23:48justin_smiththe nice thing to do is if you actually fixed a bug or extended functionality you can issue a pull request
23:48akurilinjustin_smith, that's fair. In my case it's more of a flavor thing which I don't want to impose on other folks who might have their own.
23:49justin_smithin that case, you may be yak shaving ;)
23:50akurilinwell, korma by convention defaults to FKs being named %table-name%_id, which doesn't work if your naming convention is plural for tables and singular for FKs
23:50akurilinso I'm overriding their fn to compute that to support that case
23:51akurilinand folks name their stuff however they want
23:51akurilinI guess the better option would be to let people define their own table name to fk function
23:51akurilinwith a default
23:52akurilinso maybe that'd be a PR
23:53akurilinWelp, there's an inflections library, there you go :D